From 595b99969df06a4e6f7660bbbb7792b84ad12daa Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 9 Oct 2017 11:11:49 +0200 Subject: optee: fix invalid of_node_put() in optee_driver_init() The first node supplied to of_find_matching_node() has its reference counter decreased as part of call to that function. In optee_driver_init() after calling of_find_matching_node() it's invalid to call of_node_put() on the supplied node again. So remove the invalid call to of_node_put(). Signed-off-by: Jens Wiklander --- drivers/tee/optee/core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 58169e519422..18c8c0a50d37 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -589,7 +589,6 @@ static int __init optee_driver_init(void) return -ENODEV; np = of_find_matching_node(fw_np, optee_match); - of_node_put(fw_np); if (!np) return -ENODEV; -- cgit v1.2.3 From bed7cb3191699212ea84cdbc35232492682ae27e Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Tue, 23 Jan 2018 20:11:32 -0600 Subject: scsi: ibmvfc: fix misdefined reserved field in ibmvfc_fcp_rsp_info commit c39813652700f3df552b6557530f1e5f782dbe2f upstream. The fcp_rsp_info structure as defined in the FC spec has an initial 3 bytes reserved field. The ibmvfc driver mistakenly defined this field as 4 bytes resulting in the rsp_code field being defined in what should be the start of the second reserved field and thus always being reported as zero by the driver. Ideally, we should wire ibmvfc up with libfc for the sake of code deduplication, and ease of maintaining standardized structures in a single place. However, for now simply fixup the definition in ibmvfc for backporting to distros on older kernels. Wiring up with libfc will be done in a followup patch. Cc: Reported-by: Hannes Reinecke Signed-off-by: Tyrel Datwyler Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ibmvscsi/ibmvfc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 9a0696f68f37..b81a53c4a9a8 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -367,7 +367,7 @@ enum ibmvfc_fcp_rsp_info_codes { }; struct ibmvfc_fcp_rsp_info { - __be16 reserved; + u8 reserved[3]; u8 rsp_code; u8 reserved2[4]; }__attribute__((packed, aligned (2))); -- cgit v1.2.3 From 239ef9cf2695c7e6d2d0dc673b34a4123dde7425 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 13 Feb 2018 12:18:41 +0200 Subject: RDMA/uverbs: Protect from command mask overflow commit 3f802b162dbf4a558ff98986449eddc717826209 upstream. The command number is not bounds checked against the command mask before it is shifted, resulting in an ubsan hit. This does not cause malfunction since the command number is eventually bounds checked, but we can make this ubsan clean by moving the bounds check to before the mask check. ================================================================================ UBSAN: Undefined behaviour in drivers/infiniband/core/uverbs_main.c:647:21 shift exponent 207 is too large for 64-bit type 'long long unsigned int' CPU: 0 PID: 446 Comm: syz-executor3 Not tainted 4.15.0-rc2+ #61 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 Call Trace: dump_stack+0xde/0x164 ? dma_virt_map_sg+0x22c/0x22c ubsan_epilogue+0xe/0x81 __ubsan_handle_shift_out_of_bounds+0x293/0x2f7 ? debug_check_no_locks_freed+0x340/0x340 ? __ubsan_handle_load_invalid_value+0x19b/0x19b ? lock_acquire+0x440/0x440 ? lock_acquire+0x19d/0x440 ? __might_fault+0xf4/0x240 ? ib_uverbs_write+0x68d/0xe20 ib_uverbs_write+0x68d/0xe20 ? __lock_acquire+0xcf7/0x3940 ? uverbs_devnode+0x110/0x110 ? cyc2ns_read_end+0x10/0x10 ? sched_clock_cpu+0x18/0x200 ? sched_clock_cpu+0x18/0x200 __vfs_write+0x10d/0x700 ? uverbs_devnode+0x110/0x110 ? kernel_read+0x170/0x170 ? __fget+0x35b/0x5d0 ? security_file_permission+0x93/0x260 vfs_write+0x1b0/0x550 SyS_write+0xc7/0x1a0 ? SyS_read+0x1a0/0x1a0 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x18/0x85 RIP: 0033:0x448e29 RSP: 002b:00007f033f567c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f033f5686bc RCX: 0000000000448e29 RDX: 0000000000000060 RSI: 0000000020001000 RDI: 0000000000000012 RBP: 000000000070bea0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 00000000000056a0 R14: 00000000006e8740 R15: 0000000000000000 ================================================================================ Cc: syzkaller Cc: # 4.5 Fixes: 2dbd5186a39c ("IB/core: IB/core: Allow legacy verbs through extended interfaces") Reported-by: Noa Osherovich Reviewed-by: Matan Barak Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/uverbs_main.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 44b1104eb168..c5e921bf9130 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -735,12 +735,21 @@ static int verify_command_mask(struct ib_device *ib_dev, __u32 command) return -1; } +static bool verify_command_idx(u32 command, bool extended) +{ + if (extended) + return command < ARRAY_SIZE(uverbs_ex_cmd_table); + + return command < ARRAY_SIZE(uverbs_cmd_table); +} + static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { struct ib_uverbs_file *file = filp->private_data; struct ib_device *ib_dev; struct ib_uverbs_cmd_hdr hdr; + bool extended_command; __u32 command; __u32 flags; int srcu_key; @@ -770,6 +779,15 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, } command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; + flags = (hdr.command & + IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; + + extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED; + if (!verify_command_idx(command, extended_command)) { + ret = -EINVAL; + goto out; + } + if (verify_command_mask(ib_dev, command)) { ret = -EOPNOTSUPP; goto out; @@ -781,12 +799,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, goto out; } - flags = (hdr.command & - IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; - if (!flags) { - if (command >= ARRAY_SIZE(uverbs_cmd_table) || - !uverbs_cmd_table[command]) { + if (!uverbs_cmd_table[command]) { ret = -EINVAL; goto out; } @@ -807,8 +821,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, struct ib_udata uhw; size_t written_count = count; - if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) || - !uverbs_ex_cmd_table[command]) { + if (!uverbs_ex_cmd_table[command]) { ret = -ENOSYS; goto out; } -- cgit v1.2.3 From 97e604775d4170c4c6daea5318adf43d7a1f7f5f Mon Sep 17 00:00:00 2001 From: Stefan Windfeldt-Prytz Date: Thu, 15 Feb 2018 15:02:53 +0100 Subject: iio: buffer: check if a buffer has been set up when poll is called commit 4cd140bda6494543f1c1b0ccceceaa44b676eef6 upstream. If no iio buffer has been set up and poll is called return 0. Without this check there will be a null pointer dereference when calling poll on a iio driver without an iio buffer. Cc: stable@vger.kernel.org Signed-off-by: Stefan Windfeldt-Prytz Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 158aaf44dd95..5d05c38c4ba9 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -174,7 +174,7 @@ unsigned int iio_buffer_poll(struct file *filp, struct iio_dev *indio_dev = filp->private_data; struct iio_buffer *rb = indio_dev->buffer; - if (!indio_dev->info) + if (!indio_dev->info || rb == NULL) return 0; poll_wait(filp, &rb->pollq, wait); -- cgit v1.2.3 From 964e8ceadfe6c30483e4b1131b9ddc9b1c069d50 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 14 Feb 2018 15:43:00 +0100 Subject: iio: adis_lib: Initialize trigger before requesting interrupt commit f027e0b3a774e10302207e91d304bbf99e3a8b36 upstream. The adis_probe_trigger() creates a new IIO trigger and requests an interrupt associated with the trigger. The interrupt uses the generic iio_trigger_generic_data_rdy_poll() function as its interrupt handler. Currently the driver initializes some fields of the trigger structure after the interrupt has been requested. But an interrupt can fire as soon as it has been requested. This opens up a race condition. iio_trigger_generic_data_rdy_poll() will access the trigger data structure and dereference the ops field. If the ops field is not yet initialized this will result in a NULL pointer deref. It is not expected that the device generates an interrupt at this point, so typically this issue did not surface unless e.g. due to a hardware misconfiguration (wrong interrupt number, wrong polarity, etc.). But some newer devices from the ADIS family start to generate periodic interrupts in their power-on reset configuration and unfortunately the interrupt can not be masked in the device. This makes the race condition much more visible and the following crash has been observed occasionally when booting a system using the ADIS16460. Unable to handle kernel NULL pointer dereference at virtual address 00000008 pgd = c0004000 [00000008] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.9.0-04126-gf9739f0-dirty #257 Hardware name: Xilinx Zynq Platform task: ef04f640 task.stack: ef050000 PC is at iio_trigger_notify_done+0x30/0x68 LR is at iio_trigger_generic_data_rdy_poll+0x18/0x20 pc : [] lr : [] psr: 60000193 sp : ef051bb8 ip : 00000000 fp : ef106400 r10: c081d80a r9 : ef3bfa00 r8 : 00000087 r7 : ef051bec r6 : 00000000 r5 : ef3bfa00 r4 : ee92ab00 r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : ee97e400 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none Control: 18c5387d Table: 0000404a DAC: 00000051 Process swapper/0 (pid: 1, stack limit = 0xef050210) [] (iio_trigger_notify_done) from [] (__handle_irq_event_percpu+0x88/0x118) [] (__handle_irq_event_percpu) from [] (handle_irq_event_percpu+0x1c/0x58) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x38/0x5c) [] (handle_irq_event) from [] (handle_level_irq+0xa4/0x130) [] (handle_level_irq) from [] (generic_handle_irq+0x24/0x34) [] (generic_handle_irq) from [] (zynq_gpio_irqhandler+0xb8/0x13c) [] (zynq_gpio_irqhandler) from [] (generic_handle_irq+0x24/0x34) [] (generic_handle_irq) from [] (__handle_domain_irq+0x5c/0xb4) [] (__handle_domain_irq) from [] (gic_handle_irq+0x48/0x8c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0xa8) To fix this make sure that the trigger is fully initialized before requesting the interrupt. Fixes: ccd2b52f4ac6 ("staging:iio: Add common ADIS library") Reported-by: Robin Getz Signed-off-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/adis_trigger.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index f53e9a803a0e..93b99bd93738 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -47,6 +47,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) if (adis->trig == NULL) return -ENOMEM; + adis->trig->dev.parent = &adis->spi->dev; + adis->trig->ops = &adis_trigger_ops; + iio_trigger_set_drvdata(adis->trig, adis); + ret = request_irq(adis->spi->irq, &iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING, @@ -55,9 +59,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) if (ret) goto error_free_trig; - adis->trig->dev.parent = &adis->spi->dev; - adis->trig->ops = &adis_trigger_ops; - iio_trigger_set_drvdata(adis->trig, adis); ret = iio_trigger_register(adis->trig); indio_dev->trig = iio_trigger_get(adis->trig); -- cgit v1.2.3 From 2146b6ec0e96ab283c46f7391ddf3bf01f7975e2 Mon Sep 17 00:00:00 2001 From: Shanker Donthineni Date: Wed, 31 Jan 2018 18:03:42 -0600 Subject: irqchip/gic-v3: Use wmb() instead of smb_wmb() in gic_raise_softirq() commit 21ec30c0ef5234fb1039cc7c7737d885bf875a9e upstream. A DMB instruction can be used to ensure the relative order of only memory accesses before and after the barrier. Since writes to system registers are not memory operations, barrier DMB is not sufficient for observability of memory accesses that occur before ICC_SGI1R_EL1 writes. A DSB instruction ensures that no instructions that appear in program order after the DSB instruction, can execute until the DSB instruction has completed. Cc: stable@vger.kernel.org Acked-by: Will Deacon , Signed-off-by: Shanker Donthineni Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index a37576a1798d..fd4a78296b48 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -616,7 +616,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) * Ensure that stores to Normal memory are visible to the * other CPUs before issuing the IPI. */ - smp_wmb(); + wmb(); for_each_cpu(cpu, mask) { unsigned long cluster_id = cpu_logical_map(cpu) & ~0xffUL; -- cgit v1.2.3 From c529ff430693180d0f2a57a44a19cc51009de3a4 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 15 Feb 2018 20:03:18 +0530 Subject: PCI/cxgb4: Extend T3 PCI quirk to T4+ devices commit 7dcf688d4c78a18ba9538b2bf1b11dc7a43fe9be upstream. We've run into a problem where our device is attached to a Virtual Machine and the use of the new pci_set_vpd_size() API doesn't help. The VM kernel has been informed that the accesses are okay, but all of the actual VPD Capability Accesses are trapped down into the KVM Hypervisor where it goes ahead and imposes the silent denials. The right idea is to follow the kernel.org commit 1c7de2b4ff88 ("PCI: Enable access to non-standard VPD for Chelsio devices (cxgb3)") which Alexey Kardashevskiy authored to establish a PCI Quirk for our T3-based adapters. This commit extends that PCI Quirk to cover Chelsio T4 devices and later. The advantage of this approach is that the VPD Size gets set early in the Base OS/Hypervisor Boot and doesn't require that the cxgb4 driver even be available in the Base OS/Hypervisor. Thus PF4 can be exported to a Virtual Machine and everything should work. Fixes: 67e658794ca1 ("cxgb4: Set VPD size so we can read both VPD structures") Cc: # v4.9+ Signed-off-by: Casey Leedom Signed-off-by: Arjun Vynipadath Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 -------- drivers/pci/quirks.c | 39 ++++++++++++++++++------------ 2 files changed, 23 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 9e073fb6870a..6fd3be69ff21 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2596,7 +2596,6 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) } #define EEPROM_STAT_ADDR 0x7bfc -#define VPD_SIZE 0x800 #define VPD_BASE 0x400 #define VPD_BASE_OLD 0 #define VPD_LEN 1024 @@ -2634,15 +2633,6 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p) if (!vpd) return -ENOMEM; - /* We have two VPD data structures stored in the adapter VPD area. - * By default, Linux calculates the size of the VPD area by traversing - * the first VPD area at offset 0x0, so we need to tell the OS what - * our real VPD size is. - */ - ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE); - if (ret < 0) - goto out; - /* Card information normally starts at VPD_BASE but early cards had * it at 0. */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 98eba9127a0b..0c9edc9d7c44 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3369,22 +3369,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE, static void quirk_chelsio_extend_vpd(struct pci_dev *dev) { - pci_set_vpd_size(dev, 8192); -} - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd); + int chip = (dev->device & 0xf000) >> 12; + int func = (dev->device & 0x0f00) >> 8; + int prod = (dev->device & 0x00ff) >> 0; + + /* + * If this is a T3-based adapter, there's a 1KB VPD area at offset + * 0xc00 which contains the preferred VPD values. If this is a T4 or + * later based adapter, the special VPD is at offset 0x400 for the + * Physical Functions (the SR-IOV Virtual Functions have no VPD + * Capabilities). The PCI VPD Access core routines will normally + * compute the size of the VPD by parsing the VPD Data Structure at + * offset 0x000. This will result in silent failures when attempting + * to accesses these other VPD areas which are beyond those computed + * limits. + */ + if (chip == 0x0 && prod >= 0x20) + pci_set_vpd_size(dev, 8192); + else if (chip >= 0x4 && func < 0x8) + pci_set_vpd_size(dev, 2048); +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, + quirk_chelsio_extend_vpd); #ifdef CONFIG_ACPI /* -- cgit v1.2.3 From 4a41d4412de0517eaa531ae273c3a847c8031984 Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Fri, 2 Feb 2018 13:51:39 +0800 Subject: ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and io_watchdog_func() commit b2685bdacdaab065c172b97b55ab46c6be77a037 upstream. Running io_watchdog_func() while ohci_urb_enqueue() is running can cause a race condition where ohci->prev_frame_no is corrupted and the watchdog can mis-detect following error: ohci-platform 664a0800.usb: frame counter not updating; disabled ohci-platform 664a0800.usb: HC died; cleaning up Specifically, following scenario causes a race condition: 1. ohci_urb_enqueue() calls spin_lock_irqsave(&ohci->lock, flags) and enters the critical section 2. ohci_urb_enqueue() calls timer_pending(&ohci->io_watchdog) and it returns false 3. ohci_urb_enqueue() sets ohci->prev_frame_no to a frame number read by ohci_frame_no(ohci) 4. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer() 5. ohci_urb_enqueue() calls spin_unlock_irqrestore(&ohci->lock, flags) and exits the critical section 6. Later, ohci_urb_enqueue() is called 7. ohci_urb_enqueue() calls spin_lock_irqsave(&ohci->lock, flags) and enters the critical section 8. The timer scheduled on step 4 expires and io_watchdog_func() runs 9. io_watchdog_func() calls spin_lock_irqsave(&ohci->lock, flags) and waits on it because ohci_urb_enqueue() is already in the critical section on step 7 10. ohci_urb_enqueue() calls timer_pending(&ohci->io_watchdog) and it returns false 11. ohci_urb_enqueue() sets ohci->prev_frame_no to new frame number read by ohci_frame_no(ohci) because the frame number proceeded between step 3 and 6 12. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer() 13. ohci_urb_enqueue() calls spin_unlock_irqrestore(&ohci->lock, flags) and exits the critical section, then wake up io_watchdog_func() which is waiting on step 9 14. io_watchdog_func() enters the critical section 15. io_watchdog_func() calls ohci_frame_no(ohci) and set frame_no variable to the frame number 16. io_watchdog_func() compares frame_no and ohci->prev_frame_no On step 16, because this calling of io_watchdog_func() is scheduled on step 4, the frame number set in ohci->prev_frame_no is expected to the number set on step 3. However, ohci->prev_frame_no is overwritten on step 11. Because step 16 is executed soon after step 11, the frame number might not proceed, so ohci->prev_frame_no must equals to frame_no. To address above scenario, this patch introduces a special sentinel value IO_WATCHDOG_OFF and set this value to ohci->prev_frame_no when the watchdog is not pending or running. When ohci_urb_enqueue() schedules the watchdog (step 4 and 12 above), it compares ohci->prev_frame_no to IO_WATCHDOG_OFF so that ohci->prev_frame_no is not overwritten while io_watchdog_func() is running. Signed-off-by: Shigeru Yoshida Signed-off-by: Haiqing Bai Acked-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 10 +++++++--- drivers/usb/host/ohci-hub.c | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f6c7a2744e5c..a646ca3b0d00 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -73,6 +73,7 @@ static const char hcd_name [] = "ohci_hcd"; #define STATECHANGE_DELAY msecs_to_jiffies(300) #define IO_WATCHDOG_DELAY msecs_to_jiffies(275) +#define IO_WATCHDOG_OFF 0xffffff00 #include "ohci.h" #include "pci-quirks.h" @@ -230,7 +231,7 @@ static int ohci_urb_enqueue ( } /* Start up the I/O watchdog timer, if it's not running */ - if (!timer_pending(&ohci->io_watchdog) && + if (ohci->prev_frame_no == IO_WATCHDOG_OFF && list_empty(&ohci->eds_in_use) && !(ohci->flags & OHCI_QUIRK_QEMU)) { ohci->prev_frame_no = ohci_frame_no(ohci); @@ -501,6 +502,7 @@ static int ohci_init (struct ohci_hcd *ohci) setup_timer(&ohci->io_watchdog, io_watchdog_func, (unsigned long) ohci); + ohci->prev_frame_no = IO_WATCHDOG_OFF; ohci->hcca = dma_alloc_coherent (hcd->self.controller, sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); @@ -730,7 +732,7 @@ static void io_watchdog_func(unsigned long _ohci) u32 head; struct ed *ed; struct td *td, *td_start, *td_next; - unsigned frame_no; + unsigned frame_no, prev_frame_no = IO_WATCHDOG_OFF; unsigned long flags; spin_lock_irqsave(&ohci->lock, flags); @@ -835,7 +837,7 @@ static void io_watchdog_func(unsigned long _ohci) } } if (!list_empty(&ohci->eds_in_use)) { - ohci->prev_frame_no = frame_no; + prev_frame_no = frame_no; ohci->prev_wdh_cnt = ohci->wdh_cnt; ohci->prev_donehead = ohci_readl(ohci, &ohci->regs->donehead); @@ -845,6 +847,7 @@ static void io_watchdog_func(unsigned long _ohci) } done: + ohci->prev_frame_no = prev_frame_no; spin_unlock_irqrestore(&ohci->lock, flags); } @@ -973,6 +976,7 @@ static void ohci_stop (struct usb_hcd *hcd) if (quirk_nec(ohci)) flush_work(&ohci->nec_work); del_timer_sync(&ohci->io_watchdog); + ohci->prev_frame_no = IO_WATCHDOG_OFF; ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); ohci_usb_reset(ohci); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ed678c17c4ea..798b2d25dda9 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -310,8 +310,10 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) rc = ohci_rh_suspend (ohci, 0); spin_unlock_irq (&ohci->lock); - if (rc == 0) + if (rc == 0) { del_timer_sync(&ohci->io_watchdog); + ohci->prev_frame_no = IO_WATCHDOG_OFF; + } return rc; } -- cgit v1.2.3 From 31fec948b3a25899647eb9f88284e54b6a8a4614 Mon Sep 17 00:00:00 2001 From: AMAN DEEP Date: Thu, 8 Feb 2018 11:55:01 +0800 Subject: usb: ohci: Proper handling of ed_rm_list to handle race condition between usb_kill_urb() and finish_unlinks() commit 46408ea558df13b110e0866b99624384a33bdeba upstream. There is a race condition between finish_unlinks->finish_urb() function and usb_kill_urb() in ohci controller case. The finish_urb calls spin_unlock(&ohci->lock) before usb_hcd_giveback_urb() function call, then if during this time, usb_kill_urb is called for another endpoint, then new ed will be added to ed_rm_list at beginning for unlink, and ed_rm_list will point to newly added. When finish_urb() is completed in finish_unlinks() and ed->td_list becomes empty as in below code (in finish_unlinks() function): if (list_empty(&ed->td_list)) { *last = ed->ed_next; ed->ed_next = NULL; } else if (ohci->rh_state == OHCI_RH_RUNNING) { *last = ed->ed_next; ed->ed_next = NULL; ed_schedule(ohci, ed); } The *last = ed->ed_next will make ed_rm_list to point to ed->ed_next and previously added ed by usb_kill_urb will be left unreferenced by ed_rm_list. This causes usb_kill_urb() hang forever waiting for finish_unlink to remove added ed from ed_rm_list. The main reason for hang in this race condtion is addition and removal of ed from ed_rm_list in the beginning during usb_kill_urb and later last* is modified in finish_unlinks(). As suggested by Alan Stern, the solution for proper handling of ohci->ed_rm_list is to remove ed from the ed_rm_list before finishing any URBs. Then at the end, we can add ed back to the list if necessary. This properly handle the updated ohci->ed_rm_list in usb_kill_urb(). Fixes: 977dcfdc6031 ("USB: OHCI: don't lose track of EDs when a controller dies") Acked-by: Alan Stern CC: Signed-off-by: Aman Deep Signed-off-by: Jeffy Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-q.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 641fed609911..24edb7674710 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -1018,6 +1018,8 @@ skip_ed: * have modified this list. normally it's just prepending * entries (which we'd ignore), but paranoia won't hurt. */ + *last = ed->ed_next; + ed->ed_next = NULL; modified = 0; /* unlink urbs as requested, but rescan the list after @@ -1076,21 +1078,22 @@ rescan_this: goto rescan_this; /* - * If no TDs are queued, take ED off the ed_rm_list. + * If no TDs are queued, ED is now idle. * Otherwise, if the HC is running, reschedule. - * If not, leave it on the list for further dequeues. + * If the HC isn't running, add ED back to the + * start of the list for later processing. */ if (list_empty(&ed->td_list)) { - *last = ed->ed_next; - ed->ed_next = NULL; ed->state = ED_IDLE; list_del(&ed->in_use_list); } else if (ohci->rh_state == OHCI_RH_RUNNING) { - *last = ed->ed_next; - ed->ed_next = NULL; ed_schedule(ohci, ed); } else { - last = &ed->ed_next; + ed->ed_next = ohci->ed_rm_list; + ohci->ed_rm_list = ed; + /* Don't loop on the same ED */ + if (last == &ohci->ed_rm_list) + last = &ed->ed_next; } if (modified) -- cgit v1.2.3 From 9b99be3b9e1d1ee5758f52df8ff76ccdad4ea815 Mon Sep 17 00:00:00 2001 From: Jack Stocker Date: Thu, 15 Feb 2018 18:24:10 +0000 Subject: Add delay-init quirk for Corsair K70 RGB keyboards commit 7a1646d922577b5b48c0d222e03831141664bb59 upstream. Following on from this patch: https://lkml.org/lkml/2017/11/3/516, Corsair K70 RGB keyboards also require the DELAY_INIT quirk to start correctly at boot. Device ids found here: usb 3-3: New USB device found, idVendor=1b1c, idProduct=1b13 usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 3-3: Product: Corsair K70 RGB Gaming Keyboard Signed-off-by: Jack Stocker Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c05c4f877750..774c97bb1c08 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -225,6 +225,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + /* Corsair K70 RGB */ + { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Corsair Strafe RGB */ { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, -- cgit v1.2.3 From 6f1e00f5e3f123ed0313d3f736f9c583bd6441cc Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sun, 18 Feb 2018 16:53:59 +0800 Subject: drm/edid: Add 6 bpc quirk for CPT panel in Asus UX303LA commit 06998a756a3865817b87a129a7e5d5bb66dc1ec3 upstream. Similar to commit e10aec652f31 ("drm/edid: Add 6 bpc quirk for display AEO model 0."), the EDID reports "DFP 1.x compliant TMDS" but it support 6bpc instead of 8 bpc. Hence, use 6 bpc quirk for this panel. Fixes: 196f954e2509 ("drm/i915/dp: Revert "drm/i915/dp: fall back to 18 bpp when sink capability is unknown"") BugLink: https://bugs.launchpad.net/bugs/1749420 Signed-off-by: Kai-Heng Feng Reviewed-by: Mario Kleiner Cc: # v4.8+ Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180218085359.7817-1-kai.heng.feng@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 0151ed2de770..c6b281aa762f 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -107,6 +107,9 @@ static const struct edid_quirk { /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ { "AEO", 0, EDID_QUIRK_FORCE_6BPC }, + /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */ + { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC }, + /* Belinea 10 15 55 */ { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, -- cgit v1.2.3 From 3c0cbbf693968e55b024648637ff15581043aad0 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Fri, 12 Jan 2018 18:18:05 -0800 Subject: usb: dwc3: gadget: Set maxpacket size for ep0 IN commit 6180026341e852a250e1f97ebdcf71684a3c81b9 upstream. There are 2 control endpoint structures for DWC3. However, the driver only updates the OUT direction control endpoint structure during ConnectDone event. DWC3 driver needs to update the endpoint max packet size for control IN endpoint as well. If the max packet size is not properly set, then the driver will incorrectly calculate the data transfer size and fail to send ZLP for HS/FS 3-stage control read transfer. The fix is simply to update the max packet size for the ep0 IN direction during ConnectDone event. Cc: stable@vger.kernel.org Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f483c3b1e971..26efe8c7535f 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2528,6 +2528,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) break; } + dwc->eps[1]->endpoint.maxpacket = dwc->gadget.ep0->maxpacket; + /* Enable USB2 LPM Capability */ if ((dwc->revision > DWC3_REVISION_194A) && -- cgit v1.2.3 From f04280fd570e2aad2cc0b8f6f678fe737efe829d Mon Sep 17 00:00:00 2001 From: Karsten Koop Date: Fri, 9 Feb 2018 09:12:06 +0000 Subject: usb: ldusb: add PIDs for new CASSY devices supported by this driver commit 52ad2bd8918158266fc88a05f95429b56b6a33c5 upstream. This patch adds support for new CASSY devices to the ldusb driver. The PIDs are also added to the ignore list in hid-quirks. Signed-off-by: Karsten Koop Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 3 +++ drivers/hid/hid-ids.h | 3 +++ drivers/usb/misc/ldusb.c | 6 ++++++ 3 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 03cac5731afc..49406e106cee 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2443,6 +2443,9 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 244b97c1b74e..9347b37a1303 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -608,6 +608,9 @@ #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 +#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040 +#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042 +#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043 #define USB_DEVICE_ID_LD_JWM 0x1080 #define USB_DEVICE_ID_LD_DMMP 0x1081 #define USB_DEVICE_ID_LD_UMIP 0x1090 diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 9ca595632f17..c5e3032a4d6b 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -46,6 +46,9 @@ #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 /* USB Product ID of Micro-CASSY Time (reserved) */ #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 /* USB Product ID of Micro-CASSY Temperature */ #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 /* USB Product ID of Micro-CASSY pH */ +#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040 /* USB Product ID of Power Analyser CASSY */ +#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042 /* USB Product ID of Converter Controller CASSY */ +#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043 /* USB Product ID of Machine Test CASSY */ #define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */ #define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */ #define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */ @@ -88,6 +91,9 @@ static const struct usb_device_id ld_usb_table[] = { { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) }, { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, -- cgit v1.2.3 From fe80d7385e744824443276fdfc6cfaa0a93da0cb Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 20 Feb 2018 07:31:35 -0600 Subject: Revert "usb: musb: host: don't start next rx urb if current one failed" commit 44eb5e12b845cc8a0634f21b70ef07d774eb4b25 upstream. This reverts commit dbac5d07d13e330e6706813c9fde477140fb5d80. commit dbac5d07d13e ("usb: musb: host: don't start next rx urb if current one failed") along with commit b5801212229f ("usb: musb: host: clear rxcsr error bit if set") try to solve the issue described in [1], but the latter alone is sufficient, and the former causes the issue as in [2], so now revert it. [1] https://marc.info/?l=linux-usb&m=146173995117456&w=2 [2] https://marc.info/?l=linux-usb&m=151689238420622&w=2 Cc: stable@vger.kernel.org # v4.7+ Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 55c624f2a8c0..43033895e8f6 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -418,13 +418,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, } } - /* - * The pipe must be broken if current urb->status is set, so don't - * start next urb. - * TODO: to minimize the risk of regression, only check urb->status - * for RX, until we have a test case to understand the behavior of TX. - */ - if ((!status || !is_in) && qh && qh->is_ready) { + if (qh != NULL && qh->is_ready) { musb_dbg(musb, "... next ep%d %cX urb %p", hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); musb_start_urb(musb, is_in, qh); -- cgit v1.2.3 From 8bedacf13d59b6da429780ba67f16fd0a92b1b8e Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 24 Jan 2018 00:11:53 -0800 Subject: usb: gadget: f_fs: Process all descriptors during bind commit 6cf439e0d37463e42784271179c8a308fd7493c6 upstream. During _ffs_func_bind(), the received descriptors are evaluated to prepare for binding with the gadget in order to allocate endpoints and optionally set up OS descriptors. However, the high- and super-speed descriptors are only parsed based on whether the gadget_is_dualspeed() and gadget_is_superspeed() calls are true, respectively. This is a problem in case a userspace program always provides all of the {full,high,super,OS} descriptors when configuring a function. Then, for example if a gadget device is not capable of SuperSpeed, the call to ffs_do_descs() for the SS descriptors is skipped, resulting in an incorrect offset calculation for the vla_ptr when moving on to the OS descriptors that follow. This causes ffs_do_os_descs() to fail as it is now looking at the SS descriptors' offset within the raw_descs buffer instead. _ffs_func_bind() should evaluate the descriptors unconditionally, so remove the checks for gadget speed. Fixes: f0175ab51993 ("usb: gadget: f_fs: OS descriptors support") Cc: stable@vger.kernel.org Co-Developed-by: Mayank Rana Signed-off-by: Mayank Rana Signed-off-by: Jack Pham Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_fs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d90bf57ba30e..48f52138bb1a 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -2956,10 +2956,8 @@ static int _ffs_func_bind(struct usb_configuration *c, struct ffs_data *ffs = func->ffs; const int full = !!func->ffs->fs_descs_count; - const int high = gadget_is_dualspeed(func->gadget) && - func->ffs->hs_descs_count; - const int super = gadget_is_superspeed(func->gadget) && - func->ffs->ss_descs_count; + const int high = !!func->ffs->hs_descs_count; + const int super = !!func->ffs->ss_descs_count; int fs_len, hs_len, ss_len, ret, i; struct ffs_ep *eps_ptr; -- cgit v1.2.3 From 18ec706ed4ce3fe5c9381471ef414fef6a82c779 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 5 Feb 2018 17:12:35 +0900 Subject: usb: renesas_usbhs: missed the "running" flag in usb_dmac with rx path commit 17aa31f13cad25daa19d3f923323f552e87bc874 upstream. This fixes an issue that a gadget driver (usb_f_fs) is possible to stop rx transactions after the usb-dmac is used because the following functions missed to set/check the "running" flag. - usbhsf_dma_prepare_pop_with_usb_dmac() - usbhsf_dma_pop_done_with_usb_dmac() So, if next transaction uses pio, the usbhsf_prepare_pop() can not start the transaction because the "running" flag is 0. Fixes: 8355b2b3082d ("usb: renesas_usbhs: fix the behavior of some usbhs_pkt_handle") Cc: # v3.19+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/fifo.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 6c6a3a8df07a..968ade5a35f5 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -1001,6 +1001,10 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt, if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1)) goto usbhsf_pio_prepare_pop; + /* return at this time if the pipe is running */ + if (usbhs_pipe_is_running(pipe)) + return 0; + usbhs_pipe_config_change_bfre(pipe, 1); ret = usbhsf_fifo_select(pipe, fifo, 0); @@ -1191,6 +1195,7 @@ static int usbhsf_dma_pop_done_with_usb_dmac(struct usbhs_pkt *pkt, usbhsf_fifo_clear(pipe, fifo); pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len); + usbhs_pipe_running(pipe, 0); usbhsf_dma_stop(pipe, fifo); usbhsf_dma_unmap(pkt); usbhsf_fifo_unselect(pipe, pipe->fifo); -- cgit v1.2.3 From cf7780a6b0d242e77d8432298087fc4833f3a6ec Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 21 Nov 2017 12:10:57 -0500 Subject: drm/amdgpu: Add dpm quirk for Jet PRO (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f2e5262f75ecb40a6e56554e156a292ab9e1d1b7 upstream. Fixes stability issues. v2: clamp sclk to 600 Mhz Bug: https://bugs.freedesktop.org/show_bug.cgi?id=103370 Acked-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 4cb347e88cf0..002862be2df6 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -3507,6 +3507,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, max_sclk = 75000; max_mclk = 80000; } + if ((adev->pdev->revision == 0xC3) || + (adev->pdev->device == 0x6665)) { + max_sclk = 60000; + max_mclk = 80000; + } } else if (adev->asic_type == CHIP_OLAND) { if ((adev->pdev->revision == 0xC7) || (adev->pdev->revision == 0x80) || -- cgit v1.2.3 From 3a66f9739da86cb552336eb20664d16e757e3fc6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 20 Dec 2017 13:29:58 -0500 Subject: drm/amdgpu: add atpx quirk handling (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 052c299080cd6859f82a8154a7a673fafabe644c upstream. Add quirks for handling PX/HG systems. In this case, add a quirk for a weston dGPU that only seems to properly power down using ATPX power control rather than HG (_PR3). v2: append a new weston XT Signed-off-by: Alex Deucher Signed-off-by: Junwei Zhang (v2) Reviewed-and-Tested-by: Junwei Zhang Reviewed-by: Alex Deucher Acked-by: Christian König Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 57 +++++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 6c343a933182..d451c40def0d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -14,6 +14,16 @@ #include "amd_acpi.h" +#define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0) + +struct amdgpu_px_quirk { + u32 chip_vendor; + u32 chip_device; + u32 subsys_vendor; + u32 subsys_device; + u32 px_quirk_flags; +}; + struct amdgpu_atpx_functions { bool px_params; bool power_cntl; @@ -35,6 +45,7 @@ struct amdgpu_atpx { static struct amdgpu_atpx_priv { bool atpx_detected; bool bridge_pm_usable; + unsigned int quirks; /* handle for device - and atpx */ acpi_handle dhandle; acpi_handle other_handle; @@ -205,13 +216,19 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) atpx->is_hybrid = false; if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { - printk("ATPX Hybrid Graphics\n"); - /* - * Disable legacy PM methods only when pcie port PM is usable, - * otherwise the device might fail to power off or power on. - */ - atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; - atpx->is_hybrid = true; + if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) { + printk("ATPX Hybrid Graphics, forcing to ATPX\n"); + atpx->functions.power_cntl = true; + atpx->is_hybrid = false; + } else { + printk("ATPX Hybrid Graphics\n"); + /* + * Disable legacy PM methods only when pcie port PM is usable, + * otherwise the device might fail to power off or power on. + */ + atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; + atpx->is_hybrid = true; + } } atpx->dgpu_req_power_for_displays = false; @@ -547,6 +564,30 @@ static const struct vga_switcheroo_handler amdgpu_atpx_handler = { .get_client_id = amdgpu_atpx_get_client_id, }; +static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { + /* HG _PR3 doesn't seem to work on this A+A weston board */ + { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0, 0, 0, 0, 0 }, +}; + +static void amdgpu_atpx_get_quirks(struct pci_dev *pdev) +{ + const struct amdgpu_px_quirk *p = amdgpu_px_quirk_list; + + /* Apply PX quirks */ + while (p && p->chip_device != 0) { + if (pdev->vendor == p->chip_vendor && + pdev->device == p->chip_device && + pdev->subsystem_vendor == p->subsys_vendor && + pdev->subsystem_device == p->subsys_device) { + amdgpu_atpx_priv.quirks |= p->px_quirk_flags; + break; + } + ++p; + } +} + /** * amdgpu_atpx_detect - detect whether we have PX * @@ -570,6 +611,7 @@ static bool amdgpu_atpx_detect(void) parent_pdev = pci_upstream_bridge(pdev); d3_supported |= parent_pdev && parent_pdev->bridge_d3; + amdgpu_atpx_get_quirks(pdev); } while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { @@ -579,6 +621,7 @@ static bool amdgpu_atpx_detect(void) parent_pdev = pci_upstream_bridge(pdev); d3_supported |= parent_pdev && parent_pdev->bridge_d3; + amdgpu_atpx_get_quirks(pdev); } if (has_atpx && vga_count == 2) { -- cgit v1.2.3 From 3a58e8489cf51772810cb7d1e20147e21c255c69 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Jan 2018 23:13:32 -0500 Subject: drm/amdgpu: Avoid leaking PM domain on driver unbind (v2) commit 458d876eb869d5a88b53074c6c271b8b9adc0f07 upstream. We only support vga_switcheroo and runtime pm on PX/HG systems so forcing runpm to 1 doesn't do anything useful anyway. Only call vga_switcheroo_init_domain_pm_ops() for PX/HG so that the cleanup path is correct as well. This mirrors what radeon does as well. v2: rework the patch originally sent by Lukas (Alex) Acked-by: Lukas Wunner Reported-by: Lukas Wunner Signed-off-by: Alex Deucher Signed-off-by: Lukas Wunner (v1) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ce9797b6f9c7..50f18f666d67 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1678,8 +1678,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, * ignore it */ vga_client_register(adev->pdev, adev, NULL, amdgpu_vga_set_decode); - if (amdgpu_runtime_pm == 1) - runtime = true; if (amdgpu_device_is_px(ddev)) runtime = true; vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); -- cgit v1.2.3 From 65aeceb58fe4e49dc1e4a581296e21cc5186ce6d Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 8 Feb 2018 17:46:01 +0800 Subject: drm/amdgpu: add new device to use atpx quirk commit 6e59de2048eb375a9bfcd39461ef841cd2a78962 upstream. The affected system (0x0813) is pretty similar to another one (0x0812), it also needs to use ATPX power control. Signed-off-by: Kai-Heng Feng Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index d451c40def0d..0e8f8972a160 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -568,6 +568,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { /* HG _PR3 doesn't seem to work on this A+A weston board */ { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0, 0, 0, 0, 0 }, }; -- cgit v1.2.3 From febf108e6c82d981ac6306978129dccb75db8b64 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 26 Feb 2018 10:56:45 -0800 Subject: binder: add missing binder_unlock() When commit 4be5a2810489 ("binder: check for binder_thread allocation failure in binder_poll()") was applied to 4.4-stable and 4.9-stable it was forgotten to release the global binder lock in the new error path. The global binder lock wasn't removed until v4.14, by commit a60b890f607d ("binder: remove global binder lock"). Fix the new error path to release the lock. Reported-by: Guenter Roeck Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 3b6ac80b2127..49199bd2ab93 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2628,8 +2628,10 @@ static unsigned int binder_poll(struct file *filp, binder_lock(__func__); thread = binder_get_thread(proc); - if (!thread) + if (!thread) { + binder_unlock(__func__); return POLLERR; + } wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo) && thread->return_error == BR_OK; -- cgit v1.2.3 From 29c969c3031b20595f6c3a0d16348cf6d11d8a13 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 23 Feb 2018 14:05:38 -0800 Subject: libnvdimm: fix integer overflow static analysis warning commit 58738c495e15badd2015e19ff41f1f1ed55200bc upstream. Dan reports: The patch 62232e45f4a2: "libnvdimm: control (ioctl) messages for nvdimm_bus and nvdimm devices" from Jun 8, 2015, leads to the following static checker warning: drivers/nvdimm/bus.c:1018 __nd_ioctl() warn: integer overflows 'buf_len' From a casual review, this seems like it might be a real bug. On the first iteration we load some data into in_env[]. On the second iteration we read a use controlled "in_size" from nd_cmd_in_size(). It can go up to UINT_MAX - 1. A high number means we will fill the whole in_env[] buffer. But we potentially keep looping and adding more to in_len so now it can be any value. It simple enough to change, but it feels weird that we keep looping even though in_env is totally full. Shouldn't we just return an error if we don't have space for desc->in_num. We keep looping because the size of the total input is allowed to be bigger than the 'envelope' which is a subset of the payload that tells us how much data to expect. For safety explicitly check that buf_len does not overflow which is what the checker flagged. Cc: Fixes: 62232e45f4a2: "libnvdimm: control (ioctl) messages for nvdimm_bus..." Reported-by: Dan Carpenter Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/bus.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 0392eb8a0dea..8311a93cabd8 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -812,16 +812,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, int read_only, unsigned int ioctl_cmd, unsigned long arg) { struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; - size_t buf_len = 0, in_len = 0, out_len = 0; static char out_env[ND_CMD_MAX_ENVELOPE]; static char in_env[ND_CMD_MAX_ENVELOPE]; const struct nd_cmd_desc *desc = NULL; unsigned int cmd = _IOC_NR(ioctl_cmd); void __user *p = (void __user *) arg; struct device *dev = &nvdimm_bus->dev; - struct nd_cmd_pkg pkg; const char *cmd_name, *dimm_name; + u32 in_len = 0, out_len = 0; unsigned long cmd_mask; + struct nd_cmd_pkg pkg; + u64 buf_len = 0; void *buf; int rc, i; @@ -882,7 +883,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, } if (cmd == ND_CMD_CALL) { - dev_dbg(dev, "%s:%s, idx: %llu, in: %zu, out: %zu, len %zu\n", + dev_dbg(dev, "%s:%s, idx: %llu, in: %u, out: %u, len %llu\n", __func__, dimm_name, pkg.nd_command, in_len, out_len, buf_len); @@ -912,9 +913,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, out_len += out_size; } - buf_len = out_len + in_len; + buf_len = (u64) out_len + (u64) in_len; if (buf_len > ND_IOCTL_MAX_BUFLEN) { - dev_dbg(dev, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__, + dev_dbg(dev, "%s:%s cmd: %s buf_len: %llu > %d\n", __func__, dimm_name, cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); return -EINVAL; -- cgit v1.2.3 From be38759eb2d697f9e907eddfbb8d33aa26d37acc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 23 Feb 2018 14:05:43 -0800 Subject: device-dax: implement ->split() to catch invalid munmap attempts commit 9702cffdbf2129516db679e4467db81e1cd287da upstream. Similar to how device-dax enforces that the 'address', 'offset', and 'len' parameters to mmap() be aligned to the device's fundamental alignment, the same constraints apply to munmap(). Implement ->split() to fail munmap calls that violate the alignment constraint. Otherwise, we later fail VM_BUG_ON checks in the unmap_page_range() path with crash signatures of the form: vma ffff8800b60c8a88 start 00007f88c0000000 end 00007f88c0e00000 next (null) prev (null) mm ffff8800b61150c0 prot 8000000000000027 anon_vma (null) vm_ops ffffffffa0091240 pgoff 0 file ffff8800b638ef80 private_data (null) flags: 0x380000fb(read|write|shared|mayread|maywrite|mayexec|mayshare|softdirty|mixedmap|hugepage) ------------[ cut here ]------------ kernel BUG at mm/huge_memory.c:2014! [..] RIP: 0010:__split_huge_pud+0x12a/0x180 [..] Call Trace: unmap_page_range+0x245/0xa40 ? __vma_adjust+0x301/0x990 unmap_vmas+0x4c/0xa0 unmap_region+0xae/0x120 ? __vma_rb_erase+0x11a/0x230 do_munmap+0x276/0x410 vm_munmap+0x6a/0xa0 SyS_munmap+0x1d/0x30 Link: http://lkml.kernel.org/r/151130418681.4029.7118245855057952010.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: dee410792419 ("/dev/dax, core: file operations and dax-mmap") Signed-off-by: Dan Williams Reported-by: Jeff Moyer Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/dax/dax.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c index 40be3747724d..473b44c008dd 100644 --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c @@ -453,9 +453,21 @@ static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr, return rc; } +static int dax_dev_split(struct vm_area_struct *vma, unsigned long addr) +{ + struct file *filp = vma->vm_file; + struct dax_dev *dax_dev = filp->private_data; + struct dax_region *dax_region = dax_dev->region; + + if (!IS_ALIGNED(addr, dax_region->align)) + return -EINVAL; + return 0; +} + static const struct vm_operations_struct dax_dev_vm_ops = { .fault = dax_dev_fault, .pmd_fault = dax_dev_pmd_fault, + .split = dax_dev_split, }; static int dax_mmap(struct file *filp, struct vm_area_struct *vma) -- cgit v1.2.3 From 53dfce305929bc3c7f4018b7b18027b74284802c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 23 Feb 2018 14:05:54 -0800 Subject: v4l2: disable filesystem-dax mapping support commit b70131de648c2b997d22f4653934438013f407a1 upstream. V4L2 memory registrations are incompatible with filesystem-dax that needs the ability to revoke dma access to a mapping at will, or otherwise allow the kernel to wait for completion of DMA. The filesystem-dax implementation breaks the traditional solution of truncate of active file backed mappings since there is no page-cache page we can orphan to sustain ongoing DMA. If v4l2 wants to support long lived DMA mappings it needs to arrange to hold a file lease or use some other mechanism so that the kernel can coordinate revoking DMA access when the filesystem needs to truncate mappings. Link: http://lkml.kernel.org/r/151068940499.7446.12846708245365671207.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: 3565fce3a659 ("mm, x86: get_user_pages() for dax mappings") Signed-off-by: Dan Williams Reported-by: Jan Kara Reviewed-by: Jan Kara Cc: Mauro Carvalho Chehab Cc: Christoph Hellwig Cc: Doug Ledford Cc: Hal Rosenstock Cc: Inki Dae Cc: Jason Gunthorpe Cc: Jeff Moyer Cc: Joonyoung Shim Cc: Kyungmin Park Cc: Mel Gorman Cc: Ross Zwisler Cc: Sean Hefty Cc: Seung-Woo Kim Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/videobuf-dma-sg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index 1db0af6c7f94..b6189a4958c5 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c @@ -185,12 +185,13 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n", data, size, dma->nr_pages); - err = get_user_pages(data & PAGE_MASK, dma->nr_pages, + err = get_user_pages_longterm(data & PAGE_MASK, dma->nr_pages, flags, dma->pages, NULL); if (err != dma->nr_pages) { dma->nr_pages = (err >= 0) ? err : 0; - dprintk(1, "get_user_pages: err=%d [%d]\n", err, dma->nr_pages); + dprintk(1, "get_user_pages_longterm: err=%d [%d]\n", err, + dma->nr_pages); return err < 0 ? err : -EINVAL; } return 0; -- cgit v1.2.3 From 00a6e639b58d23c0b6e36bb44b117afd2e245f52 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 23 Feb 2018 14:06:00 -0800 Subject: IB/core: disable memory registration of filesystem-dax vmas commit 5f1d43de54164dcfb9bfa542fcc92c1e1a1b6c1d upstream. Until there is a solution to the dma-to-dax vs truncate problem it is not safe to allow RDMA to create long standing memory registrations against filesytem-dax vmas. Link: http://lkml.kernel.org/r/151068941011.7446.7766030590347262502.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: 3565fce3a659 ("mm, x86: get_user_pages() for dax mappings") Signed-off-by: Dan Williams Reported-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Acked-by: Jason Gunthorpe Acked-by: Doug Ledford Cc: Sean Hefty Cc: Hal Rosenstock Cc: Jeff Moyer Cc: Ross Zwisler Cc: Inki Dae Cc: Jan Kara Cc: Joonyoung Shim Cc: Kyungmin Park Cc: Mauro Carvalho Chehab Cc: Mel Gorman Cc: Seung-Woo Kim Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/umem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index c22fde6207d1..8e973a2993a6 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -193,7 +193,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, sg_list_start = umem->sg_head.sgl; while (npages) { - ret = get_user_pages(cur_base, + ret = get_user_pages_longterm(cur_base, min_t(unsigned long, npages, PAGE_SIZE / sizeof (struct page *)), gup_flags, page_list, vma_list); -- cgit v1.2.3 From 807e3365895ca847749864c482d95c0ec1c89461 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 23 Feb 2018 14:06:05 -0800 Subject: libnvdimm, dax: fix 1GB-aligned namespaces vs physical misalignment commit 41fce90f26333c4fa82e8e43b9ace86c4e8a0120 upstream. The following namespace configuration attempt: # ndctl create-namespace -e namespace0.0 -m devdax -a 1G -f libndctl: ndctl_dax_enable: dax0.1: failed to enable Error: namespace0.0: failed to enable failed to reconfigure namespace: No such device or address ...fails when the backing memory range is not physically aligned to 1G: # cat /proc/iomem | grep Persistent 210000000-30fffffff : Persistent Memory (legacy) In the above example the 4G persistent memory range starts and ends on a 256MB boundary. We handle this case correctly when needing to handle cases that violate section alignment (128MB) collisions against "System RAM", and we simply need to extend that padding/truncation for the 1GB alignment use case. Cc: Fixes: 315c562536c4 ("libnvdimm, pfn: add 'align' attribute...") Reported-and-tested-by: Jane Chu Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/pfn_devs.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 42abdd2391c9..d6aa59ca68b9 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -563,6 +563,12 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, return altmap; } +static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys) +{ + return min_t(u64, PHYS_SECTION_ALIGN_DOWN(phys), + ALIGN_DOWN(phys, nd_pfn->align)); +} + static int nd_pfn_init(struct nd_pfn *nd_pfn) { u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; @@ -618,13 +624,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) start = nsio->res.start; size = PHYS_SECTION_ALIGN_UP(start + size) - start; if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, - IORES_DESC_NONE) == REGION_MIXED) { + IORES_DESC_NONE) == REGION_MIXED + || !IS_ALIGNED(start + resource_size(&nsio->res), + nd_pfn->align)) { size = resource_size(&nsio->res); - end_trunc = start + size - PHYS_SECTION_ALIGN_DOWN(start + size); + end_trunc = start + size - phys_pmem_align_down(nd_pfn, + start + size); } if (start_pad + end_trunc) - dev_info(&nd_pfn->dev, "%s section collision, truncate %d bytes\n", + dev_info(&nd_pfn->dev, "%s alignment collision, truncate %d bytes\n", dev_name(&ndns->dev), start_pad + end_trunc); /* -- cgit v1.2.3 From b4e0649eeb65c556d01de986a589da2ffd5c2029 Mon Sep 17 00:00:00 2001 From: Ben Gardner Date: Wed, 14 Feb 2018 09:29:52 -0600 Subject: i2c: designware: must wait for enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fba4adbbf670577e605f9ad306629db6031cd48b upstream. One I2C bus on my Atom E3845 board has been broken since 4.9. It has two devices, both declared by ACPI and with built-in drivers. There are two back-to-back transactions originating from the kernel, one targeting each device. The first transaction works, the second one locks up the I2C controller. The controller never recovers. These kernel logs show up whenever an I2C transaction is attempted after this failure. i2c-designware-pci 0000:00:18.3: timeout in disabling adapter i2c-designware-pci 0000:00:18.3: timeout waiting for bus ready Waiting for the I2C controller status to indicate that it is enabled before programming it fixes the issue. I have tested this patch on 4.14 and 4.15. Fixes: commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only if necessary") Cc: linux-stable #4.13+ Signed-off-by: Ben Gardner Acked-by: Jarkko Nikula Reviewed-by: José Roberto de Souza Signed-off-by: Wolfram Sang Signed-off-by: Ben Gardner [Jarkko: Backported to v4.9..v4.12 before i2c-designware-core.c was renamed to i2c-designware-master.c] Signed-off-by: Jarkko Nikula Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-designware-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 809f4d4e93a0..340e037b3224 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -507,7 +507,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) i2c_dw_disable_int(dev); /* Enable the adapter */ - __i2c_dw_enable(dev, true); + __i2c_dw_enable_and_wait(dev, true); /* Clear and enable interrupts */ dw_readl(dev, DW_IC_CLR_INTR); -- cgit v1.2.3 From 051337a8993a5481046209ec167eb6e821b6d922 Mon Sep 17 00:00:00 2001 From: Andreas Platschek Date: Thu, 14 Dec 2017 12:50:51 +0100 Subject: dmaengine: fsl-edma: disable clks on all error paths [ Upstream commit 2610acf46b9ed528ec2cacd717bc9d354e452b73 ] Previously enabled clks are only disabled if clk_prepare_enable() fails. However, there are other error paths were the previously enabled clocks are not disabled. To fix the problem, fsl_disable_clocks() now takes the number of clocks that shall be disabled + unprepared. For existing calls were all clocks were already successfully prepared + enabled, DMAMUX_NR is passed to disable + unprepare all clocks. In error paths were only some clocks were successfully prepared + enabled the loop counter is passed, in order to disable + unprepare all successfully prepared + enabled clocks. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Andreas Platschek Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/dma/fsl-edma.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 6775f2c74e25..c7568869284e 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -863,11 +863,11 @@ static void fsl_edma_irq_exit( } } -static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma) +static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks) { int i; - for (i = 0; i < DMAMUX_NR; i++) + for (i = 0; i < nr_clocks; i++) clk_disable_unprepare(fsl_edma->muxclk[i]); } @@ -904,25 +904,25 @@ static int fsl_edma_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(fsl_edma->muxbase[i])) + if (IS_ERR(fsl_edma->muxbase[i])) { + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); return PTR_ERR(fsl_edma->muxbase[i]); + } sprintf(clkname, "dmamux%d", i); fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname); if (IS_ERR(fsl_edma->muxclk[i])) { dev_err(&pdev->dev, "Missing DMAMUX block clock.\n"); + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); return PTR_ERR(fsl_edma->muxclk[i]); } ret = clk_prepare_enable(fsl_edma->muxclk[i]); - if (ret) { - /* disable only clks which were enabled on error */ - for (; i >= 0; i--) - clk_disable_unprepare(fsl_edma->muxclk[i]); - - dev_err(&pdev->dev, "DMAMUX clk block failed.\n"); - return ret; - } + if (ret) + /* on error: disable all previously enabled clks */ + fsl_disable_clocks(fsl_edma, i); } @@ -976,7 +976,7 @@ static int fsl_edma_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Can't register Freescale eDMA engine. (%d)\n", ret); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return ret; } @@ -985,7 +985,7 @@ static int fsl_edma_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Can't register Freescale eDMA of_dma. (%d)\n", ret); dma_async_device_unregister(&fsl_edma->dma_dev); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return ret; } @@ -1015,7 +1015,7 @@ static int fsl_edma_remove(struct platform_device *pdev) fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); of_dma_controller_free(np); dma_async_device_unregister(&fsl_edma->dma_dev); - fsl_disable_clocks(fsl_edma); + fsl_disable_clocks(fsl_edma, DMAMUX_NR); return 0; } -- cgit v1.2.3 From d4ea6118d3e36ea87b02607aea8f173b4c69f808 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 14 Dec 2017 11:20:14 -0700 Subject: nvme: check hw sectors before setting chunk sectors [ Upstream commit 249159c5f15812140fa216f9997d799ac0023a1f ] Some devices with IDs matching the "stripe" quirk don't actually have this quirk, and don't have an MDTS value. When MDTS is not set, the driver sets the max sectors to UINT_MAX, which is not a power of 2, hitting a BUG_ON from blk_queue_chunk_sectors. This patch skips setting chunk sectors for such devices. Signed-off-by: Keith Busch Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- 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 719ee5fb2626..ad9d82eb2aed 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1204,7 +1204,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } - if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) + if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && + is_power_of_2(ctrl->max_hw_sectors)) blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); blk_queue_virt_boundary(q, ctrl->page_size - 1); if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) -- cgit v1.2.3 From 83c5a93514c7404c94d1de94a4c8aa5d5684fc95 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Thu, 14 Dec 2017 16:56:14 +0100 Subject: net: usb: qmi_wwan: add Telit ME910 PID 0x1101 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit c647c0d62c82eb3ddf78a0d8b3d58819d9f552aa ] This patch adds support for Telit ME910 PID 0x1101. Signed-off-by: Daniele Palmas Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index e1e5e8438457..930deb332404 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -914,6 +914,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ + {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ -- cgit v1.2.3 From dd1e39f4b3a81706571f03807381a21949655898 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 5 Dec 2017 11:51:40 +0100 Subject: mtd: nand: gpmi: Fix failure when a erased page has a bitflip at BBM [ Upstream commit fdf2e821052958a114618a95ab18a300d0b080cb ] When erased subpages are read then the BCH decoder returns STATUS_ERASED if they are all empty, or STATUS_UNCORRECTABLE if there are bitflips. When there are bitflips, we have to set these bits again to show the upper layers a completely erased page. When a bitflip happens in the exact byte where the bad block marker is, then this byte is swapped with another byte in block_mark_swapping(). The correction code then detects a bitflip in another subpage and no longer corrects the bitflip where it really happens. Correct this behaviour by calling block_mark_swapping() after the bitflips have been corrected. In our case UBIFS failed with this bug because it expects erased pages to be really empty: UBIFS error (pid 187): ubifs_scan: corrupt empty space at LEB 36:118735 UBIFS error (pid 187): ubifs_scanned_corruption: corruption at LEB 36:118735 UBIFS error (pid 187): ubifs_scanned_corruption: first 8192 bytes from LEB 36:118735 UBIFS error (pid 187): ubifs_scan: LEB 36 scanning failed UBIFS error (pid 187): do_commit: commit failed, error -117 Signed-off-by: Sascha Hauer Reviewed-by: Richard Weinberger Acked-by: Boris Brezillon Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 6c062b8251d2..427039b77668 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1059,9 +1059,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, return ret; } - /* handle the block mark swapping */ - block_mark_swapping(this, payload_virt, auxiliary_virt); - /* Loop over status bytes, accumulating ECC status. */ status = auxiliary_virt + nfc_geo->auxiliary_status_offset; @@ -1150,6 +1147,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, max_bitflips = max_t(unsigned int, max_bitflips, *status); } + /* handle the block mark swapping */ + block_mark_swapping(this, buf, auxiliary_virt); + if (oob_required) { /* * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() -- cgit v1.2.3 From e88872ef990c8c0692963d916c9585b9b65254c6 Mon Sep 17 00:00:00 2001 From: Albert Hsieh Date: Mon, 20 Nov 2017 11:26:26 +0800 Subject: mtd: nand: brcmnand: Zero bitflip is not an error [ Upstream commit e44b9a9c135727f3410e029910275f40681dc8bc ] A negative return value of brcmstb_nand_verify_erased_page() indicates a real bitflip error of an erased page, and other return values (>= 0) show the corrected bitflip number. Zero return value means no bitflip, but the current driver code treats it as an error, and eventually leads to falsely reported ECC error. Fixes: 02b88eea9f9c ("mtd: brcmnand: Add check for erased page bitflip") Signed-off-by: Albert Hsieh Acked-by: Boris Brezillon Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/brcmnand/brcmnand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 1a4a790054e4..ef9a6b22c9fa 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1763,7 +1763,7 @@ try_dmaread: err = brcmstb_nand_verify_erased_page(mtd, chip, buf, addr); /* erased page bitflips corrected */ - if (err > 0) + if (err >= 0) return err; } -- cgit v1.2.3 From 396927052bad2f8228c98d3eab34c097823fd089 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 16 Dec 2017 00:52:39 +0300 Subject: net: phy: xgene: disable clk on error paths [ Upstream commit ab14436065c8066c265540312742390d6d07ddd2 ] There are several error paths in xgene_mdio_probe(), where clk is left undisabled. The patch fixes them. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/mdio-xgene.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index 92af182951be..8eb077b677f6 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c @@ -197,8 +197,11 @@ static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata) } ret = xgene_enet_ecc_init(pdata); - if (ret) + if (ret) { + if (pdata->dev->of_node) + clk_disable_unprepare(pdata->clk); return ret; + } xgene_gmac_reset(pdata); return 0; @@ -364,8 +367,10 @@ static int xgene_mdio_probe(struct platform_device *pdev) return ret; mdio_bus = mdiobus_alloc(); - if (!mdio_bus) - return -ENOMEM; + if (!mdio_bus) { + ret = -ENOMEM; + goto out_clk; + } mdio_bus->name = "APM X-Gene MDIO bus"; @@ -394,7 +399,7 @@ static int xgene_mdio_probe(struct platform_device *pdev) mdio_bus->phy_mask = ~0; ret = mdiobus_register(mdio_bus); if (ret) - goto out; + goto out_mdiobus; acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, acpi_register_phy, NULL, mdio_bus, NULL); @@ -402,16 +407,20 @@ static int xgene_mdio_probe(struct platform_device *pdev) } if (ret) - goto out; + goto out_mdiobus; pdata->mdio_bus = mdio_bus; xgene_mdio_status = true; return 0; -out: +out_mdiobus: mdiobus_free(mdio_bus); +out_clk: + if (dev->of_node) + clk_disable_unprepare(pdata->clk); + return ret; } -- cgit v1.2.3 From 5330add6da101da85ef4d1dcf31bf2e1b3252fc8 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Fri, 24 Nov 2017 03:56:26 +0100 Subject: drm/nouveau/pci: do a msi rearm on init [ Upstream commit a121027d2747168df0aac0c3da35509eea39f61c ] On my GP107 when I load nouveau after unloading it, for some reason the GPU stopped sending or the CPU stopped receiving interrupts if MSI was enabled. Doing a rearm once before getting any interrupts fixes this. Signed-off-by: Karol Herbst Reviewed-by: Thierry Reding Signed-off-by: Ben Skeggs Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index a4cb82495cee..245c946ea661 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev) return ret; pci->irq = pdev->irq; + + /* Ensure MSI interrupts are armed, for the case where there are + * already interrupts pending (for whatever reason) at load time. + */ + if (pci->msi) + pci->func->msi_rearm(pci); + return ret; } -- cgit v1.2.3 From ad176934842636d8b1d23298fb90d10a97e4c6f7 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Tue, 12 Dec 2017 17:26:36 +0800 Subject: mac80211_hwsim: Fix a possible sleep-in-atomic bug in hwsim_get_radio_nl [ Upstream commit 162bd5e5fd921785077b5862d8f2ffabe2fe11e5 ] The driver may sleep under a spinlock. The function call path is: hwsim_get_radio_nl (acquire the spinlock) nlmsg_new(GFP_KERNEL) --> may sleep To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mac80211_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4b462dc21c41..61e85eac706a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3154,7 +3154,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) continue; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!skb) { res = -ENOMEM; goto out_err; -- cgit v1.2.3 From 90f7d14cef9bd30214dd7e56fc3c7a468cef6228 Mon Sep 17 00:00:00 2001 From: Radu Pirea Date: Fri, 15 Dec 2017 17:40:17 +0200 Subject: spi: atmel: fixed spin_lock usage inside atmel_spi_remove [ Upstream commit 66e900a3d225575c8b48b59ae1fe74bb6e5a65cc ] The only part of atmel_spi_remove which needs to be atomic is hardware reset. atmel_spi_stop_dma calls dma_terminate_all and this needs interrupts enabled. atmel_spi_release_dma calls dma_release_channel and dma_release_channel locks a mutex inside of spin_lock. So the call of these functions can't be inside a spin_lock. Reported-by: Jia-Ju Bai Signed-off-by: Radu Pirea Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-atmel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8feac599e9ab..44be6b593b30 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1669,12 +1669,12 @@ static int atmel_spi_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); /* reset the hardware and block queue progress */ - spin_lock_irq(&as->lock); if (as->use_dma) { atmel_spi_stop_dma(as); atmel_spi_release_dma(as); } + spin_lock_irq(&as->lock); spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_readl(as, SR); -- cgit v1.2.3 From 757677d0da516f9f60b7a855ecbf10b73263e006 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 18 Dec 2017 17:00:17 +0800 Subject: net: mediatek: setup proper state for disabled GMAC on the default [ Upstream commit 7352e252b5bf40d59342494a70354a2d436fd0cd ] The current solution would setup fixed and force link of 1Gbps to the both GMAC on the default. However, The GMAC should always be put to link down state when the GMAC is disabled on certain target boards. Otherwise, the driver possibly receives unexpected data from the floating hardware connection through the unused GMAC. Although the driver had been added certain protection in RX path to get rid of such kind of unexpected data sent to the upper stack. Signed-off-by: Sean Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 4832223f1500..20de37a414fe 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -1842,11 +1842,12 @@ static int mtk_hw_init(struct mtk_eth *eth) /* set GE2 TUNE */ regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); - /* GE1, Force 1000M/FD, FC ON */ - mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); - - /* GE2, Force 1000M/FD, FC ON */ - mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1)); + /* Set linkdown as the default for each GMAC. Its own MCR would be set + * up with the more appropriate value when mtk_phy_link_adjust call is + * being invoked. + */ + for (i = 0; i < MTK_MAC_COUNT; i++) + mtk_w32(eth, 0, MTK_MAC_MCR(i)); /* Enable RX VLan Offloading */ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -- cgit v1.2.3 From 95e094a709eabaede6c53272b2d90925c55c02e0 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Fri, 15 Dec 2017 20:20:06 +0300 Subject: net: arc_emac: fix arc_emac_rx() error paths [ Upstream commit e688822d035b494071ecbadcccbd6f3325fb0f59 ] arc_emac_rx() has some issues found by code review. In case netdev_alloc_skb_ip_align() or dma_map_single() failure rx fifo entry will not be returned to EMAC. In case dma_map_single() failure previously allocated skb became lost to driver. At the same time address of newly allocated skb will not be provided to EMAC. Signed-off-by: Alexander Kochetkov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/arc/emac_main.c | 53 +++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index be865b4dada2..aba4853e6b70 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c @@ -210,39 +210,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget) continue; } - pktlen = info & LEN_MASK; - stats->rx_packets++; - stats->rx_bytes += pktlen; - skb = rx_buff->skb; - skb_put(skb, pktlen); - skb->dev = ndev; - skb->protocol = eth_type_trans(skb, ndev); - - dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), - dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); - - /* Prepare the BD for next cycle */ - rx_buff->skb = netdev_alloc_skb_ip_align(ndev, - EMAC_BUFFER_SIZE); - if (unlikely(!rx_buff->skb)) { + /* Prepare the BD for next cycle. netif_receive_skb() + * only if new skb was allocated and mapped to avoid holes + * in the RX fifo. + */ + skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE); + if (unlikely(!skb)) { + if (net_ratelimit()) + netdev_err(ndev, "cannot allocate skb\n"); + /* Return ownership to EMAC */ + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); stats->rx_errors++; - /* Because receive_skb is below, increment rx_dropped */ stats->rx_dropped++; continue; } - /* receive_skb only if new skb was allocated to avoid holes */ - netif_receive_skb(skb); - - addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, + addr = dma_map_single(&ndev->dev, (void *)skb->data, EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(&ndev->dev, addr)) { if (net_ratelimit()) - netdev_err(ndev, "cannot dma map\n"); - dev_kfree_skb(rx_buff->skb); + netdev_err(ndev, "cannot map dma buffer\n"); + dev_kfree_skb(skb); + /* Return ownership to EMAC */ + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); stats->rx_errors++; + stats->rx_dropped++; continue; } + + /* unmap previosly mapped skb */ + dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); + + pktlen = info & LEN_MASK; + stats->rx_packets++; + stats->rx_bytes += pktlen; + skb_put(rx_buff->skb, pktlen); + rx_buff->skb->dev = ndev; + rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev); + + netif_receive_skb(rx_buff->skb); + + rx_buff->skb = skb; dma_unmap_addr_set(rx_buff, addr, addr); dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE); -- cgit v1.2.3 From 9d0858e71219ca4657ebeff7eea92067fbaf9b77 Mon Sep 17 00:00:00 2001 From: Fredrik Hallenberg Date: Mon, 18 Dec 2017 23:33:59 +0100 Subject: net: stmmac: Fix TX timestamp calculation [ Upstream commit 200922c93f008e03ddc804c6dacdf26ca1ba86d7 ] When using GMAC4 the value written in PTP_SSIR should be shifted however the shifted value is also used in subsequent calculations which results in a bad timestamp value. Signed-off-by: Fredrik Hallenberg Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 10d6059b2f26..f4074e25fb71 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -38,6 +38,7 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, { u32 value = readl(ioaddr + PTP_TCR); unsigned long data; + u32 reg_value; /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second * formula = (1/ptp_clock) * 1000000000 @@ -54,10 +55,11 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, data &= PTP_SSIR_SSINC_MASK; + reg_value = data; if (gmac4) - data = data << GMAC4_PTP_SSIR_SSINC_SHIFT; + reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT; - writel(data, ioaddr + PTP_SSIR); + writel(reg_value, ioaddr + PTP_SSIR); return data; } -- cgit v1.2.3 From 6358cb4c5b273cd8ddcd7c850084fae721566523 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Tue, 19 Dec 2017 13:32:48 -0500 Subject: scsi: storvsc: Fix scsi_cmd error assignments in storvsc_handle_error [ Upstream commit d1b8b2391c24751e44f618fcf86fb55d9a9247fd ] When an I/O is returned with an srb_status of SRB_STATUS_INVALID_LUN which has zero good_bytes it must be assigned an error. Otherwise the I/O will be continuously requeued and will cause a deadlock in the case where disks are being hot added and removed. sd_probe_async will wait forever for its I/O to complete while holding scsi_sd_probe_domain. Also returning the default error of DID_TARGET_FAILURE causes multipath to not retry the I/O resulting in applications receiving I/O errors before a failover can occur. Signed-off-by: Cathy Avery Signed-off-by: Long Li Reviewed-by: Stephen Hemminger Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/storvsc_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 2bf96d33428a..0dd1984e381e 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -915,10 +915,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, case TEST_UNIT_READY: break; default: - set_host_byte(scmnd, DID_TARGET_FAILURE); + set_host_byte(scmnd, DID_ERROR); } break; case SRB_STATUS_INVALID_LUN: + set_host_byte(scmnd, DID_NO_CONNECT); do_work = true; process_err_fn = storvsc_remove_lun; break; -- cgit v1.2.3 From 3d6becbc8063bda30a84527039fac9cf449a1e56 Mon Sep 17 00:00:00 2001 From: Siva Reddy Kallam Date: Fri, 22 Dec 2017 16:05:28 +0530 Subject: tg3: Add workaround to restrict 5762 MRRS to 2048 [ Upstream commit 4419bb1cedcda0272e1dc410345c5a1d1da0e367 ] One of AMD based server with 5762 hangs with jumbo frame traffic. This AMD platform has southbridge limitation which is restricting MRRS to 4000. As a work around, driver to restricts the MRRS to 2048 for this particular 5762 NX1 card. Signed-off-by: Siva Reddy Kallam Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/tg3.c | 10 ++++++++++ drivers/net/ethernet/broadcom/tg3.h | 4 ++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bb22d325e965..3943c5c1281c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -10049,6 +10049,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) tw32(GRC_MODE, tp->grc_mode | val); + /* On one of the AMD platform, MRRS is restricted to 4000 because of + * south bridge limitation. As a workaround, Driver is setting MRRS + * to 2048 instead of default 4096. + */ + if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && + tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) { + val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK; + tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048); + } + /* Setup the timer prescalar register. Clock is always 66Mhz. */ val = tr32(GRC_MISC_CFG); val &= ~0xff; diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 3b5e98ecba00..6e51b793615c 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -95,6 +95,7 @@ #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a +#define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0 #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a @@ -280,6 +281,9 @@ #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ /* 0xa8 --> 0xb8 unused */ +#define TG3PCI_DEV_STATUS_CTRL 0x000000b4 +#define MAX_READ_REQ_SIZE_2048 0x00004000 +#define MAX_READ_REQ_MASK 0x00007000 #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 #define DUAL_MAC_CTRL_CH_MASK 0x00000003 #define DUAL_MAC_CTRL_ID 0x00000004 -- cgit v1.2.3 From 78cc448e0882abffdc0c50309127d39bc2523146 Mon Sep 17 00:00:00 2001 From: Siva Reddy Kallam Date: Fri, 22 Dec 2017 16:05:29 +0530 Subject: tg3: Enable PHY reset in MTU change path for 5720 [ Upstream commit e60ee41aaf898584205a6af5c996860d0fe6a836 ] A customer noticed RX path hang when MTU is changed on the fly while running heavy traffic with NCSI enabled for 5717 and 5719. Since 5720 belongs to same ASIC family, we observed same issue and same fix could solve this problem for 5720. Signed-off-by: Siva Reddy Kallam Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/tg3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 3943c5c1281c..795a133fb074 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14238,7 +14238,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) */ if (tg3_asic_rev(tp) == ASIC_REV_57766 || tg3_asic_rev(tp) == ASIC_REV_5717 || - tg3_asic_rev(tp) == ASIC_REV_5719) + tg3_asic_rev(tp) == ASIC_REV_5719 || + tg3_asic_rev(tp) == ASIC_REV_5720) reset_phy = true; err = tg3_restart_hw(tp, reset_phy); -- cgit v1.2.3 From af60c3822a721f9c2bf511ed1234e59ee4135010 Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Fri, 22 Dec 2017 13:01:39 -0200 Subject: bnx2x: Improve reliability in case of nested PCI errors [ Upstream commit f7084059a9cb9e56a186e1677b1dcffd76c2cd24 ] While in recovery process of PCI error (called EEH on PowerPC arch), another PCI transaction could be corrupted causing a situation of nested PCI errors. Also, this scenario could be reproduced with error injection mechanisms (for debug purposes). We observe that in case of nested PCI errors, bnx2x might attempt to initialize its shmem and cause a kernel crash due to bad addresses read from MCP. Multiple different stack traces were observed depending on the point the second PCI error happens. This patch avoids the crashes by: * failing PCI recovery in case of nested errors (since multiple PCI errors in a row are not expected to lead to a functional adapter anyway), and by, * preventing access to adapter FW when MCP is failed (we mark it as failed when shmem cannot get initialized properly). Reported-by: Abdul Haleem Signed-off-by: Guilherme G. Piccoli Acked-by: Shahed Shaikh Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 ++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 0a5ee1d973ac..596f88b693ef 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3034,7 +3034,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) del_timer_sync(&bp->timer); - if (IS_PF(bp)) { + if (IS_PF(bp) && !BP_NOMCP(bp)) { /* Set ALWAYS_ALIVE bit in shmem */ bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; bnx2x_drv_pulse(bp); @@ -3120,7 +3120,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) bp->cnic_loaded = false; /* Clear driver version indication in shmem */ - if (IS_PF(bp)) + if (IS_PF(bp) && !BP_NOMCP(bp)) bnx2x_update_mng_version(bp); /* Check if there are pending parity attentions. If there are - set diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 5d958b5bb8b1..554c4086b3c6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp) do { bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + + /* If we read all 0xFFs, means we are in PCI error state and + * should bail out to avoid crashes on adapter's FW reads. + */ + if (bp->common.shmem_base == 0xFFFFFFFF) { + bp->flags |= NO_MCP_FLAG; + return -ENODEV; + } + if (bp->common.shmem_base) { val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); if (val & SHR_MEM_VALIDITY_MB) @@ -14312,7 +14321,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) BNX2X_ERR("IO slot reset --> driver unload\n"); /* MCP should have been reset; Need to wait for validity */ - bnx2x_init_shmem(bp); + if (bnx2x_init_shmem(bp)) { + rtnl_unlock(); + return PCI_ERS_RESULT_DISCONNECT; + } if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { u32 v; -- cgit v1.2.3 From 86b9fa2190907f4f550d9d6bf490c5f89ca33836 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Tue, 12 Dec 2017 11:10:44 +0100 Subject: led: core: Fix brightness setting when setting delay_off=0 [ Upstream commit 2b83ff96f51d0b039c4561b9f95c824d7bddb85c ] With the current code, the following sequence won't work : echo timer > trigger echo 0 > delay_off * at this point we call ** led_delay_off_store ** led_blink_set --- drivers/leds/led-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 3bce44893021..d70d4a5273b8 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - del_timer_sync(&led_cdev->blink_timer); + led_stop_software_blink(led_cdev); led_cdev->flags &= ~LED_BLINK_ONESHOT; led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; -- cgit v1.2.3 From 64fb18c837c79d6c98985e57ae2b6a8420a616b2 Mon Sep 17 00:00:00 2001 From: Nitzan Carmi Date: Tue, 26 Dec 2017 11:20:20 +0200 Subject: IB/mlx5: Fix mlx5_ib_alloc_mr error flow [ Upstream commit 45e6ae7ef21b907dacb18da62d5787d74a31d860 ] ibmr.device is being set only after ib_alloc_mr() is (successfully) complete. Therefore, in case mlx5_core_create_mkey() return with error, the error flow calls mlx5_free_priv_descs() which uses ibmr.device (which doesn't exist yet), causing a NULL dereference oops. To fix this, the IB device should be set in the mr struct earlier stage (e.g. prior to calling mlx5_core_create_mkey()). Fixes: 8a187ee52b04 ("IB/mlx5: Support the new memory registration API") Signed-off-by: Max Gurtovoy Signed-off-by: Nitzan Carmi Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/mr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 0a260a06876d..c7d5786d366b 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1648,6 +1648,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, MLX5_SET(mkc, mkc, access_mode, mr->access_mode); MLX5_SET(mkc, mkc, umr_en, 1); + mr->ibmr.device = pd->device; err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); if (err) goto err_destroy_psv; -- cgit v1.2.3 From 336c28a1228f11a6a4a3c6cc267cc45d7ce94daa Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 6 Dec 2017 10:30:39 +0100 Subject: s390/dasd: fix wrongly assigned configuration data [ Upstream commit 8a9bd4f8ebc6800bfc0596e28631ff6809a2f615 ] We store per path and per device configuration data to identify the path or device correctly. The per path configuration data might get mixed up if the original request gets into error recovery and is started with a random path mask. This would lead to a wrong identification of a path in case of a CUIR event for example. Fix by copying the path mask from the original request to the error recovery request in case it is a path verification request. Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/s390/block/dasd_3990_erp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 8305ab688d57..a20dc2940d2d 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2755,6 +2755,16 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) erp = dasd_3990_erp_handle_match_erp(cqr, erp); } + + /* + * For path verification work we need to stick with the path that was + * originally chosen so that the per path configuration data is + * assigned correctly. + */ + if (test_bit(DASD_CQR_VERIFY_PATH, &erp->flags) && cqr->lpm) { + erp->lpm = cqr->lpm; + } + if (device->features & DASD_FEATURE_ERPLOG) { /* print current erp_chain */ dev_err(&device->cdev->dev, -- cgit v1.2.3 From fb426a4888216e9fadc75f7fc7f5a560c885aa0d Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Sun, 31 Dec 2017 15:33:14 +0200 Subject: IB/mlx4: Fix mlx4_ib_alloc_mr error flow [ Upstream commit 5a371cf87e145b86efd32007e46146e78c1eff6d ] ibmr.device is being set only after ib_alloc_mr() is successfully complete. Therefore, in case imlx4_mr_enable() returns with error, the error flow unwinder calls to mlx4_free_priv_pages(), which uses ibmr.device. Such usage causes to NULL dereference oops and to fix it, the IB device should be set in the mr struct earlier stage (e.g. prior to calling mlx4_free_priv_pages()). Fixes: 1b2cd0fc673c ("IB/mlx4: Support the new memory registration API") Signed-off-by: Nitzan Carmi Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx4/mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 5d73989d9771..ae41623e0f13 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -406,7 +406,6 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, goto err_free_mr; mr->max_pages = max_num_sg; - err = mlx4_mr_enable(dev->dev, &mr->mmr); if (err) goto err_free_pl; @@ -417,6 +416,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, return &mr->ibmr; err_free_pl: + mr->ibmr.device = pd->device; mlx4_free_priv_pages(mr); err_free_mr: (void) mlx4_mr_free(dev->dev, &mr->mmr); -- cgit v1.2.3 From ab43aaa00d52d644957a8e1e9b89d94ee304a6c8 Mon Sep 17 00:00:00 2001 From: Erez Shitrit Date: Sun, 31 Dec 2017 15:33:15 +0200 Subject: IB/ipoib: Fix race condition in neigh creation [ Upstream commit 16ba3defb8bd01a9464ba4820a487f5b196b455b ] When using enhanced mode for IPoIB, two threads may execute xmit in parallel to two different TX queues while the target is the same. In this case, both of them will add the same neighbor to the path's neigh link list and we might see the following message: list_add double add: new=ffff88024767a348, prev=ffff88024767a348... WARNING: lib/list_debug.c:31__list_add_valid+0x4e/0x70 ipoib_start_xmit+0x477/0x680 [ib_ipoib] dev_hard_start_xmit+0xb9/0x3e0 sch_direct_xmit+0xf9/0x250 __qdisc_run+0x176/0x5d0 __dev_queue_xmit+0x1f5/0xb10 __dev_queue_xmit+0x55/0xb10 Analysis: Two SKB are scheduled to be transmitted from two cores. In ipoib_start_xmit, both gets NULL when calling ipoib_neigh_get. Two calls to neigh_add_path are made. One thread takes the spin-lock and calls ipoib_neigh_alloc which creates the neigh structure, then (after the __path_find) the neigh is added to the path's neigh link list. When the second thread enters the critical section it also calls ipoib_neigh_alloc but in this case it gets the already allocated ipoib_neigh structure, which is already linked to the path's neigh link list and adds it again to the list. Which beside of triggering the list, it creates a loop in the linked list. This loop leads to endless loop inside path_rec_completion. Solution: Check list_empty(&neigh->list) before adding to the list. Add a similar fix in "ipoib_multicast.c::ipoib_mcast_send" Fixes: b63b70d87741 ('IPoIB: Use a private hash table for path lookup in xmit path') Signed-off-by: Erez Shitrit Reviewed-by: Alex Vesker Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 25 ++++++++++++++++++------- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 5 ++++- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 183db0cd849e..e37e918cb935 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -919,8 +919,8 @@ static int path_rec_start(struct net_device *dev, return 0; } -static void neigh_add_path(struct sk_buff *skb, u8 *daddr, - struct net_device *dev) +static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr, + struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; @@ -933,7 +933,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, spin_unlock_irqrestore(&priv->lock, flags); ++dev->stats.tx_dropped; dev_kfree_skb_any(skb); - return; + return NULL; + } + + /* To avoid race condition, make sure that the + * neigh will be added only once. + */ + if (unlikely(!list_empty(&neigh->list))) { + spin_unlock_irqrestore(&priv->lock, flags); + return neigh; } path = __path_find(dev, daddr + 4); @@ -971,7 +979,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, spin_unlock_irqrestore(&priv->lock, flags); ipoib_send(dev, skb, path->ah, IPOIB_QPN(daddr)); ipoib_neigh_put(neigh); - return; + return NULL; } } else { neigh->ah = NULL; @@ -988,7 +996,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, spin_unlock_irqrestore(&priv->lock, flags); ipoib_neigh_put(neigh); - return; + return NULL; err_path: ipoib_neigh_free(neigh); @@ -998,6 +1006,8 @@ err_drop: spin_unlock_irqrestore(&priv->lock, flags); ipoib_neigh_put(neigh); + + return NULL; } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, @@ -1103,8 +1113,9 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) case htons(ETH_P_TIPC): neigh = ipoib_neigh_get(dev, phdr->hwaddr); if (unlikely(!neigh)) { - neigh_add_path(skb, phdr->hwaddr, dev); - return NETDEV_TX_OK; + neigh = neigh_add_path(skb, phdr->hwaddr, dev); + if (likely(!neigh)) + return NETDEV_TX_OK; } break; case htons(ETH_P_ARP): diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index fddff403d5d2..6b6826f3e446 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -818,7 +818,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) spin_lock_irqsave(&priv->lock, flags); if (!neigh) { neigh = ipoib_neigh_alloc(daddr, dev); - if (neigh) { + /* Make sure that the neigh will be added only + * once to mcast list. + */ + if (neigh && list_empty(&neigh->list)) { kref_get(&mcast->ah->ref); neigh->ah = mcast->ah; list_add_tail(&neigh->list, &mcast->neigh_list); -- cgit v1.2.3 From 88f72bd9f99fc2315acfde7a15a1a8eecb154bcb Mon Sep 17 00:00:00 2001 From: Gao Feng Date: Tue, 26 Dec 2017 21:44:32 +0800 Subject: macvlan: Fix one possible double free [ Upstream commit d02fd6e7d2933ede6478a15f9e4ce8a93845824e ] Because the macvlan_uninit would free the macvlan port, so there is one double free case in macvlan_common_newlink. When the macvlan port is just created, then register_netdevice or netdev_upper_dev_link failed and they would invoke macvlan_uninit. Then it would reach the macvlan_port_destroy which triggers the double free. Signed-off-by: Gao Feng Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/macvlan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 6d55049cd3dc..e8ad4d060da7 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1377,9 +1377,14 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, return 0; unregister_netdev: + /* macvlan_uninit would free the macvlan port */ unregister_netdevice(dev); + return err; destroy_macvlan_port: - if (create) + /* the macvlan port may be freed by macvlan_uninit when fail to register. + * so we destroy the macvlan port only when it's valid. + */ + if (create && macvlan_port_get_rtnl(dev)) macvlan_port_destroy(port->dev); return err; } -- cgit v1.2.3 From 125ca9316b2bdc4c6a1b07751211e1b56683ad89 Mon Sep 17 00:00:00 2001 From: Tushar Dave Date: Wed, 6 Dec 2017 02:26:29 +0530 Subject: e1000: fix disabling already-disabled warning [ Upstream commit 0b76aae741abb9d16d2c0e67f8b1e766576f897d ] This patch adds check so that driver does not disable already disabled device. [ 44.637743] advantechwdt: Unexpected close, not stopping watchdog! [ 44.997548] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input6 [ 45.013419] e1000 0000:00:03.0: disabling already-disabled device [ 45.013447] ------------[ cut here ]------------ [ 45.014868] WARNING: CPU: 1 PID: 71 at drivers/pci/pci.c:1641 pci_disable_device+0xa1/0x105: pci_disable_device at drivers/pci/pci.c:1640 [ 45.016171] CPU: 1 PID: 71 Comm: rcu_perf_shutdo Not tainted 4.14.0-01330-g3c07399 #1 [ 45.017197] task: ffff88011bee9e40 task.stack: ffffc90000860000 [ 45.017987] RIP: 0010:pci_disable_device+0xa1/0x105: pci_disable_device at drivers/pci/pci.c:1640 [ 45.018603] RSP: 0000:ffffc90000863e30 EFLAGS: 00010286 [ 45.019282] RAX: 0000000000000035 RBX: ffff88013a230008 RCX: 0000000000000000 [ 45.020182] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000203 [ 45.021084] RBP: ffff88013a3f31e8 R08: 0000000000000001 R09: 0000000000000000 [ 45.021986] R10: ffffffff827ec29c R11: 0000000000000002 R12: 0000000000000001 [ 45.022946] R13: ffff88013a230008 R14: ffff880117802b20 R15: ffffc90000863e8f [ 45.023842] FS: 0000000000000000(0000) GS:ffff88013fd00000(0000) knlGS:0000000000000000 [ 45.024863] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 45.025583] CR2: ffffc900006d4000 CR3: 000000000220f000 CR4: 00000000000006a0 [ 45.026478] Call Trace: [ 45.026811] __e1000_shutdown+0x1d4/0x1e2: __e1000_shutdown at drivers/net/ethernet/intel/e1000/e1000_main.c:5162 [ 45.027344] ? rcu_perf_cleanup+0x2a1/0x2a1: rcu_perf_shutdown at kernel/rcu/rcuperf.c:627 [ 45.027883] e1000_shutdown+0x14/0x3a: e1000_shutdown at drivers/net/ethernet/intel/e1000/e1000_main.c:5235 [ 45.028351] device_shutdown+0x110/0x1aa: device_shutdown at drivers/base/core.c:2807 [ 45.028858] kernel_power_off+0x31/0x64: kernel_power_off at kernel/reboot.c:260 [ 45.029343] rcu_perf_shutdown+0x9b/0xa7: rcu_perf_shutdown at kernel/rcu/rcuperf.c:637 [ 45.029852] ? __wake_up_common_lock+0xa2/0xa2: autoremove_wake_function at kernel/sched/wait.c:376 [ 45.030414] kthread+0x126/0x12e: kthread at kernel/kthread.c:233 [ 45.030834] ? __kthread_bind_mask+0x8e/0x8e: kthread at kernel/kthread.c:190 [ 45.031399] ? ret_from_fork+0x1f/0x30: ret_from_fork at arch/x86/entry/entry_64.S:443 [ 45.031883] ? kernel_init+0xa/0xf5: kernel_init at init/main.c:997 [ 45.032325] ret_from_fork+0x1f/0x30: ret_from_fork at arch/x86/entry/entry_64.S:443 [ 45.032777] Code: 00 48 85 ed 75 07 48 8b ab a8 00 00 00 48 8d bb 98 00 00 00 e8 aa d1 11 00 48 89 ea 48 89 c6 48 c7 c7 d8 e4 0b 82 e8 55 7d da ff <0f> ff b9 01 00 00 00 31 d2 be 01 00 00 00 48 c7 c7 f0 b1 61 82 [ 45.035222] ---[ end trace c257137b1b1976ef ]--- [ 45.037838] ACPI: Preparing to enter system sleep state S5 Signed-off-by: Tushar Dave Tested-by: Fengguang Wu Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000/e1000.h | 3 ++- drivers/net/ethernet/intel/e1000/e1000_main.c | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index d7bdea79e9fa..8fd2458060a0 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -331,7 +331,8 @@ struct e1000_adapter { enum e1000_state_t { __E1000_TESTING, __E1000_RESETTING, - __E1000_DOWN + __E1000_DOWN, + __E1000_DISABLED }; #undef pr_fmt diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index f42129d09e2c..dd112aa5cebb 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -940,7 +940,7 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter, static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; - struct e1000_adapter *adapter; + struct e1000_adapter *adapter = NULL; struct e1000_hw *hw; static int cards_found; @@ -950,6 +950,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u16 tmp = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; int bars, need_ioport; + bool disable_dev = false; /* do not allocate ioport bars when not needed */ need_ioport = e1000_is_need_ioport(pdev); @@ -1250,11 +1251,13 @@ err_mdio_ioremap: iounmap(hw->ce4100_gbe_mdio_base_virt); iounmap(hw->hw_addr); err_ioremap: + disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags); free_netdev(netdev); err_alloc_etherdev: pci_release_selected_regions(pdev, bars); err_pci_reg: - pci_disable_device(pdev); + if (!adapter || disable_dev) + pci_disable_device(pdev); return err; } @@ -1272,6 +1275,7 @@ static void e1000_remove(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + bool disable_dev; e1000_down_and_stop(adapter); e1000_release_manageability(adapter); @@ -1290,9 +1294,11 @@ static void e1000_remove(struct pci_dev *pdev) iounmap(hw->flash_address); pci_release_selected_regions(pdev, adapter->bars); + disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags); free_netdev(netdev); - pci_disable_device(pdev); + if (disable_dev) + pci_disable_device(pdev); } /** @@ -5166,7 +5172,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) if (netif_running(netdev)) e1000_free_irq(adapter); - pci_disable_device(pdev); + if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags)) + pci_disable_device(pdev); return 0; } @@ -5210,6 +5217,10 @@ static int e1000_resume(struct pci_dev *pdev) pr_err("Cannot enable PCI device from suspend\n"); return err; } + + /* flush memory to make sure state is correct */ + smp_mb__before_atomic(); + clear_bit(__E1000_DISABLED, &adapter->flags); pci_set_master(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); @@ -5284,7 +5295,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, if (netif_running(netdev)) e1000_down(adapter); - pci_disable_device(pdev); + + if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags)) + pci_disable_device(pdev); /* Request a slot slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -5312,6 +5325,10 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) pr_err("Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } + + /* flush memory to make sure state is correct */ + smp_mb__before_atomic(); + clear_bit(__E1000_DISABLED, &adapter->flags); pci_set_master(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); -- cgit v1.2.3 From b4b73c1224de87d677dd5dc6fae8bc9e5b4849b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?= Date: Fri, 29 Dec 2017 17:02:17 +0800 Subject: NET: usb: qmi_wwan: add support for YUGA CLM920-NC5 PID 0x9625 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit bd30ffc414e55194ed6149fad69a145550cb7c18 ] This patch adds support for PID 0x9625 of YUGA CLM920-NC5. YUGA CLM920-NC5 needs to enable QMI_WWAN_QUIRK_DTR before QMI operation. qmicli -d /dev/cdc-wdm0 -p --dms-get-revision [/dev/cdc-wdm0] Device revision retrieved: Revision: 'CLM920_NC5-V1 1 [Oct 23 2016 19:00:00]' Signed-off-by: SZ Lin (林上智) Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 930deb332404..a30d6a6dbd95 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -805,6 +805,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, + {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ -- cgit v1.2.3 From 3a26db8cf2e952016dd470d02cbf2fa7f886ff29 Mon Sep 17 00:00:00 2001 From: Xiongwei Song Date: Tue, 2 Jan 2018 21:24:55 +0800 Subject: drm/ttm: check the return value of kzalloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 19d859a7205bc59ffc38303eb25ae394f61d21dc ] In the function ttm_page_alloc_init, kzalloc call is made for variable _manager, we need to check its return value, it may return NULL. Signed-off-by: Xiongwei Song Reviewed-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index ddd6badd0eee..c756b2b7f5dc 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -818,6 +818,8 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) pr_info("Initializing pool allocator\n"); _manager = kzalloc(sizeof(*_manager), GFP_KERNEL); + if (!_manager) + return -ENOMEM; ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc"); -- cgit v1.2.3 From cd80cb0be131daee2f9fd7862de52fa430f01370 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 8 Dec 2017 10:55:04 -0800 Subject: i40e/i40evf: Account for frags split over multiple descriptors in check linearize [ Upstream commit 248de22e638f10bd5bfc7624a357f940f66ba137 ] The original code for __i40e_chk_linearize didn't take into account the fact that if a fragment is 16K in size or larger it has to be split over 2 descriptors and the smaller of those 2 descriptors will be on the trailing edge of the transmit. As a result we can get into situations where we didn't catch requests that could result in a Tx hang. This patch takes care of that by subtracting the length of all but the trailing edge of the stale fragment before we test for sum. By doing this we can guarantee that we have all cases covered, including the case of a fragment that spans multiple descriptors. We don't need to worry about checking the inner portions of this since 12K is the maximum aligned DMA size and that is larger than any MSS will ever be since the MTU limit for jumbos is something on the order of 9K. Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 26 +++++++++++++++++++++++--- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 26 +++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index c5430394fac9..28b640fa2e35 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2670,10 +2670,30 @@ bool __i40e_chk_linearize(struct sk_buff *skb) /* Walk through fragments adding latest fragment, testing it, and * then removing stale fragments from the sum. */ - stale = &skb_shinfo(skb)->frags[0]; - for (;;) { + for (stale = &skb_shinfo(skb)->frags[0];; stale++) { + int stale_size = skb_frag_size(stale); + sum += skb_frag_size(frag++); + /* The stale fragment may present us with a smaller + * descriptor than the actual fragment size. To account + * for that we need to remove all the data on the front and + * figure out what the remainder would be in the last + * descriptor associated with the fragment. + */ + if (stale_size > I40E_MAX_DATA_PER_TXD) { + int align_pad = -(stale->page_offset) & + (I40E_MAX_READ_REQ_SIZE - 1); + + sum -= align_pad; + stale_size -= align_pad; + + do { + sum -= I40E_MAX_DATA_PER_TXD_ALIGNED; + stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED; + } while (stale_size > I40E_MAX_DATA_PER_TXD); + } + /* if sum is negative we failed to make sufficient progress */ if (sum < 0) return true; @@ -2681,7 +2701,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb) if (!nr_frags--) break; - sum -= skb_frag_size(stale++); + sum -= stale_size; } return false; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index c03800d1000a..90ebc5ac16fd 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1872,10 +1872,30 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) /* Walk through fragments adding latest fragment, testing it, and * then removing stale fragments from the sum. */ - stale = &skb_shinfo(skb)->frags[0]; - for (;;) { + for (stale = &skb_shinfo(skb)->frags[0];; stale++) { + int stale_size = skb_frag_size(stale); + sum += skb_frag_size(frag++); + /* The stale fragment may present us with a smaller + * descriptor than the actual fragment size. To account + * for that we need to remove all the data on the front and + * figure out what the remainder would be in the last + * descriptor associated with the fragment. + */ + if (stale_size > I40E_MAX_DATA_PER_TXD) { + int align_pad = -(stale->page_offset) & + (I40E_MAX_READ_REQ_SIZE - 1); + + sum -= align_pad; + stale_size -= align_pad; + + do { + sum -= I40E_MAX_DATA_PER_TXD_ALIGNED; + stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED; + } while (stale_size > I40E_MAX_DATA_PER_TXD); + } + /* if sum is negative we failed to make sufficient progress */ if (sum < 0) return true; @@ -1883,7 +1903,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) if (!nr_frags--) break; - sum -= skb_frag_size(stale++); + sum -= stale_size; } return false; -- cgit v1.2.3 From 9137deb6cf4829194c9a01b272a17ff3fd1ddfe8 Mon Sep 17 00:00:00 2001 From: Luu An Phu Date: Tue, 2 Jan 2018 10:44:18 +0700 Subject: can: flex_can: Correct the checking for frame length in flexcan_start_xmit() [ Upstream commit 13454c14550065fcc1705d6bd4ee6d40e057099f ] The flexcan_start_xmit() function compares the frame length with data register length to write frame content into data[0] and data[1] register. Data register length is 4 bytes and frame maximum length is 8 bytes. Fix the check that compares frame length with 3. Because the register length is 4. Signed-off-by: Luu An Phu Reviewed-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/flexcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 16f7cadda5c3..47f43bdecd51 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -493,7 +493,7 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) data = be32_to_cpup((__be32 *)&cf->data[0]); flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]); } - if (cf->can_dlc > 3) { + if (cf->can_dlc > 4) { data = be32_to_cpup((__be32 *)&cf->data[4]); flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]); } -- cgit v1.2.3 From 0fd874142d3091d3116f5015753ca4fe4c078a06 Mon Sep 17 00:00:00 2001 From: Venkat Duvvuru Date: Thu, 4 Jan 2018 18:46:55 -0500 Subject: bnxt_en: Fix the 'Invalid VF' id check in bnxt_vf_ndo_prep routine. [ Upstream commit 78f300049335ae81a5cc6b4b232481dc5e1f9d41 ] In bnxt_vf_ndo_prep (which is called by bnxt_get_vf_config ndo), there is a check for "Invalid VF id". Currently, the check is done against max_vfs. However, the user doesn't always create max_vfs. So, the check should be against the created number of VFs. The number of bnxt_vf_info structures that are allocated in bnxt_alloc_vf_resources routine is the "number of requested VFs". So, if an "invalid VF id" falls between the requested number of VFs and the max_vfs, the driver will be dereferencing an invalid pointer. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Signed-off-by: Venkat Devvuru Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 60e2af8678bd..393cce3bf2fc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -68,7 +68,7 @@ static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id) netdev_err(bp->dev, "vf ndo called though sriov is disabled\n"); return -EINVAL; } - if (vf_id >= bp->pf.max_vfs) { + if (vf_id >= bp->pf.active_vfs) { netdev_err(bp->dev, "Invalid VF id %d\n", vf_id); return -EINVAL; } -- cgit v1.2.3 From cded2e6f1660449e34c8bd6740614ee35e6ebf23 Mon Sep 17 00:00:00 2001 From: Eduardo Otubo Date: Fri, 5 Jan 2018 09:42:16 +0100 Subject: xen-netfront: enable device after manual module load [ Upstream commit b707fda2df4070785d0fa8a278aa13944c5f51f8 ] When loading the module after unloading it, the network interface would not be enabled and thus wouldn't have a backend counterpart and unable to be used by the guest. The guest would face errors like: [root@guest ~]# ethtool -i eth0 Cannot get driver information: No such device [root@guest ~]# ifconfig eth0 eth0: error fetching interface information: Device not found This patch initializes the state of the netfront device whenever it is loaded manually, this state would communicate the netback to create its device and establish the connection between them. Signed-off-by: Eduardo Otubo Reviewed-by: Boris Ostrovsky Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netfront.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 1a9dadf7b3cc..b09c81e882b4 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1345,6 +1345,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) netif_carrier_off(netdev); + xenbus_switch_state(dev, XenbusStateInitialising); return netdev; exit: -- cgit v1.2.3 From 7086ec8f0e63792ed25398d165a9f603b64e9853 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 6 Jan 2018 09:00:09 +0100 Subject: mdio-sun4i: Fix a memory leak [ Upstream commit 56c0290202ab94a2f2780c449395d4ae8495fab4 ] If the probing of the regulator is deferred, the memory allocated by 'mdiobus_alloc_size()' will be leaking. It should be freed before the next call to 'sun4i_mdio_probe()' which will reallocate it. Fixes: 4bdcb1dd9feb ("net: Add MDIO bus driver for the Allwinner EMAC") Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/mdio-sun4i.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index 135296508a7e..6425ce04d3f9 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c @@ -118,8 +118,10 @@ static int sun4i_mdio_probe(struct platform_device *pdev) data->regulator = devm_regulator_get(&pdev->dev, "phy"); if (IS_ERR(data->regulator)) { - if (PTR_ERR(data->regulator) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(data->regulator) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_out_free_mdiobus; + } dev_info(&pdev->dev, "no regulator found\n"); data->regulator = NULL; -- cgit v1.2.3 From beaa7d1cea2debe0882c51639d463d3eb987804a Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Tue, 9 Jan 2018 12:10:21 +0000 Subject: xen/gntdev: Fix off-by-one error when unmapping with holes [ Upstream commit 951a010233625b77cde3430b4b8785a9a22968d1 ] If the requested range has a hole, the calculation of the number of pages to unmap is off by one. Fix it. Signed-off-by: Ross Lagerwall Reviewed-by: Boris Ostrovsky Signed-off-by: Boris Ostrovsky Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/xen/gntdev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 79b8ab4c6663..54c4c4183fbe 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -378,10 +378,8 @@ static int unmap_grant_pages(struct grant_map *map, int offset, int pages) } range = 0; while (range < pages) { - if (map->unmap_ops[offset+range].handle == -1) { - range--; + if (map->unmap_ops[offset+range].handle == -1) break; - } range++; } err = __unmap_grant_pages(map, offset, range); -- cgit v1.2.3 From c65c0dfb27914e141be8193d509fcd4e6387d13c Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Tue, 9 Jan 2018 12:10:22 +0000 Subject: xen/gntdev: Fix partial gntdev_mmap() cleanup [ Upstream commit cf2acf66ad43abb39735568f55e1f85f9844e990 ] When cleaning up after a partially successful gntdev_mmap(), unmap the successfully mapped grant pages otherwise Xen will kill the domain if in debug mode (Attempt to implicitly unmap a granted PTE) or Linux will kill the process and emit "BUG: Bad page map in process" if Xen is in release mode. This is only needed when use_ptemod is true because gntdev_put_map() will unmap grant pages itself when use_ptemod is false. Signed-off-by: Ross Lagerwall Reviewed-by: Boris Ostrovsky Signed-off-by: Boris Ostrovsky Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/xen/gntdev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 54c4c4183fbe..910b5d40c6e9 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -1077,8 +1077,10 @@ unlock_out: out_unlock_put: mutex_unlock(&priv->lock); out_put_map: - if (use_ptemod) + if (use_ptemod) { map->vma = NULL; + unmap_grant_pages(map, 0, map->count); + } gntdev_put_map(priv, map); return err; } -- cgit v1.2.3 From 3eb222174ee8b6280e552f71ed68f890bbbdc437 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 9 Jan 2018 11:02:33 +0800 Subject: net: gianfar_ptp: move set_fipers() to spinlock protecting area [ Upstream commit 11d827a993a969c3c6ec56758ff63a44ba19b466 ] set_fipers() calling should be protected by spinlock in case that any interrupt breaks related registers setting and the function we expect. This patch is to move set_fipers() to spinlock protecting area in ptp_gianfar_adjtime(). Signed-off-by: Yangbo Lu Acked-by: Richard Cochran Reviewed-by: Fabio Estevam Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/gianfar_ptp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 57798814160d..ec4b6997f24a 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -314,11 +314,10 @@ static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta) now = tmr_cnt_read(etsects); now += delta; tmr_cnt_write(etsects, now); + set_fipers(etsects); spin_unlock_irqrestore(&etsects->lock, flags); - set_fipers(etsects); - return 0; } -- cgit v1.2.3 From 9be164624e90d1d1b03200c7a749d9c72ad26f23 Mon Sep 17 00:00:00 2001 From: Jeremy Boone Date: Thu, 8 Feb 2018 12:29:09 -0800 Subject: tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus commit 6d24cd186d9fead3722108dec1b1c993354645ff upstream. Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. In all the driver _recv() functions, we need to use a u32 to unmarshal the response size, otherwise a bit flip of the 31st bit would cause the expected variable to go negative, which would then try to read a huge amount of data. Also sanity check that the expected amount of data is large enough for the TPM header. Signed-off-by: Jeremy Boone Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/st33zp24/st33zp24.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 6f060c76217b..7205e6da16cd 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -458,7 +458,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, size_t count) { int size = 0; - int expected; + u32 expected; if (!chip) return -EBUSY; @@ -475,7 +475,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, } expected = be32_to_cpu(*(__be32 *)(buf + 2)); - if (expected > count) { + if (expected > count || expected < TPM_HEADER_SIZE) { size = -EIO; goto out; } -- cgit v1.2.3 From e785c9e50fd7da8a547a968add753bac49054789 Mon Sep 17 00:00:00 2001 From: Jeremy Boone Date: Thu, 8 Feb 2018 12:30:01 -0800 Subject: tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus commit 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed upstream. Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. In all the driver _recv() functions, we need to use a u32 to unmarshal the response size, otherwise a bit flip of the 31st bit would cause the expected variable to go negative, which would then try to read a huge amount of data. Also sanity check that the expected amount of data is large enough for the TPM header. Signed-off-by: Jeremy Boone Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_i2c_infineon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 62ee44e57ddc..da69ddea56cf 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -437,7 +437,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count) { int size = 0; - int expected, status; + int status; + u32 expected; if (count < TPM_HEADER_SIZE) { size = -EIO; @@ -452,7 +453,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count) } expected = be32_to_cpu(*(__be32 *)(buf + 2)); - if ((size_t) expected > count) { + if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) { size = -EIO; goto out; } -- cgit v1.2.3 From 15dcd3aa1542a1f00df25dd741200c720b870793 Mon Sep 17 00:00:00 2001 From: Jeremy Boone Date: Thu, 8 Feb 2018 12:31:16 -0800 Subject: tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus commit f9d4d9b5a5ef2f017bc344fb65a58a902517173b upstream. Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. In all the driver _recv() functions, we need to use a u32 to unmarshal the response size, otherwise a bit flip of the 31st bit would cause the expected variable to go negative, which would then try to read a huge amount of data. Also sanity check that the expected amount of data is large enough for the TPM header. Signed-off-by: Jeremy Boone Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_i2c_nuvoton.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index c6428771841f..caa86b19c76d 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) struct device *dev = chip->dev.parent; struct i2c_client *client = to_i2c_client(dev); s32 rc; - int expected, status, burst_count, retries, size = 0; + int status; + int burst_count; + int retries; + int size = 0; + u32 expected; if (count < TPM_HEADER_SIZE) { i2c_nuvoton_ready(chip); /* return to idle */ @@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) * to machine native */ expected = be32_to_cpu(*(__be32 *) (buf + 2)); - if (expected > count) { + if (expected > count || expected < size) { dev_err(dev, "%s() expected > count\n", __func__); size = -EIO; continue; -- cgit v1.2.3 From 922f22e680e2ed1277b53f8e183265b71b5dfcf3 Mon Sep 17 00:00:00 2001 From: Jeremy Boone Date: Thu, 8 Feb 2018 12:32:06 -0800 Subject: tpm_tis: fix potential buffer overruns caused by bit glitches on the bus commit 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 upstream. Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. In all the driver _recv() functions, we need to use a u32 to unmarshal the response size, otherwise a bit flip of the 31st bit would cause the expected variable to go negative, which would then try to read a huge amount of data. Also sanity check that the expected amount of data is large enough for the TPM header. Signed-off-by: Jeremy Boone Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Tested-by: Jarkko Sakkinen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_tis_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 4d24ec3d7cd6..caf7b18895f2 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -208,7 +208,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int size = 0; - int expected, status; + int status; + u32 expected; if (count < TPM_HEADER_SIZE) { size = -EIO; @@ -223,7 +224,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) } expected = be32_to_cpu(*(__be32 *) (buf + 2)); - if (expected > count) { + if (expected > count || expected < TPM_HEADER_SIZE) { size = -EIO; goto out; } -- cgit v1.2.3 From e6b9e04f575faba84448eb8d67461a9acae45eae Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 7 Sep 2017 15:30:45 +0200 Subject: tpm: constify transmit data pointers commit c37fbc09bd4977736f6bc4050c6f099c587052a7 upstream. Making cmd_getticks 'const' introduced a couple of harmless warnings: drivers/char/tpm/tpm_tis_core.c: In function 'probe_itpm': drivers/char/tpm/tpm_tis_core.c:469:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] rc = tpm_tis_send_data(chip, cmd_getticks, len); drivers/char/tpm/tpm_tis_core.c:477:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] rc = tpm_tis_send_data(chip, cmd_getticks, len); drivers/char/tpm/tpm_tis_core.c:255:12: note: expected 'u8 * {aka unsigned char *}' but argument is of type 'const u8 * {aka const unsigned char *}' static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) This changes the related functions to all take 'const' pointers so that gcc can see this as being correct. I had to slightly modify the logic around tpm_tis_spi_transfer() for this to work without introducing ugly casts. Cc: stable@vger.kernel.org Fixes: 5e35bd8e06b9 ("tpm_tis: make array cmd_getticks static const to shink object code size") Signed-off-by: Arnd Bergmann Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_tis.c | 2 +- drivers/char/tpm/tpm_tis_core.c | 4 ++-- drivers/char/tpm/tpm_tis_core.h | 4 ++-- drivers/char/tpm/tpm_tis_spi.c | 25 +++++++++++-------------- 4 files changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 8022bea27fed..06173d2e316f 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -98,7 +98,7 @@ static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, } static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, - u8 *value) + const u8 *value) { struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index caf7b18895f2..f9aa47ec7af7 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -257,7 +257,7 @@ out: * tpm.c can skip polling for the data to be available as the interrupt is * waited for here */ -static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) +static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int rc, status, burstcnt; @@ -346,7 +346,7 @@ static void disable_interrupts(struct tpm_chip *chip) * tpm.c can skip polling for the data to be available as the interrupt is * waited for here */ -static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len) +static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int rc; diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 9191aabbf9c2..e1c2193f2ed3 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -98,7 +98,7 @@ struct tpm_tis_phy_ops { int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, u8 *result); int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, - u8 *value); + const u8 *value); int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result); int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result); int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src); @@ -128,7 +128,7 @@ static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr, } static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr, - u16 len, u8 *value) + u16 len, const u8 *value) { return data->phy_ops->write_bytes(data, addr, len, value); } diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c index 3b97b14c3417..1a09a7491019 100644 --- a/drivers/char/tpm/tpm_tis_spi.c +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -58,7 +58,7 @@ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *da } static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, - u8 *buffer, u8 direction) + u8 *in, const u8 *out) { struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); int ret = 0; @@ -72,7 +72,7 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, while (len) { transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE); - phy->tx_buf[0] = direction | (transfer_len - 1); + phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1); phy->tx_buf[1] = 0xd4; phy->tx_buf[2] = addr >> 8; phy->tx_buf[3] = addr; @@ -113,14 +113,8 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, spi_xfer.cs_change = 0; spi_xfer.len = transfer_len; spi_xfer.delay_usecs = 5; - - if (direction) { - spi_xfer.tx_buf = NULL; - spi_xfer.rx_buf = buffer; - } else { - spi_xfer.tx_buf = buffer; - spi_xfer.rx_buf = NULL; - } + spi_xfer.tx_buf = out; + spi_xfer.rx_buf = in; spi_message_init(&m); spi_message_add_tail(&spi_xfer, &m); @@ -129,7 +123,10 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, goto exit; len -= transfer_len; - buffer += transfer_len; + if (in) + in += transfer_len; + if (out) + out += transfer_len; } exit: @@ -140,13 +137,13 @@ exit: static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, u8 *result) { - return tpm_tis_spi_transfer(data, addr, len, result, 0x80); + return tpm_tis_spi_transfer(data, addr, len, result, NULL); } static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, - u16 len, u8 *value) + u16 len, const u8 *value) { - return tpm_tis_spi_transfer(data, addr, len, value, 0); + return tpm_tis_spi_transfer(data, addr, len, NULL, value); } static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) -- cgit v1.2.3 From eb75717b1898c0ded2e1eaf0360008e31ad24c97 Mon Sep 17 00:00:00 2001 From: Alexander Steffen Date: Mon, 11 Sep 2017 12:26:52 +0200 Subject: tpm_tis_spi: Use DMA-safe memory for SPI transfers commit 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 upstream. The buffers used as tx_buf/rx_buf in a SPI transfer need to be DMA-safe. This cannot be guaranteed for the buffers passed to tpm_tis_spi_read_bytes and tpm_tis_spi_write_bytes. Therefore, we need to use our own DMA-safe buffer and copy the data to/from it. The buffer needs to be allocated separately, to ensure that it is cacheline-aligned and not shared with other data, so that DMA can work correctly. Fixes: 0edbfea537d1 ("tpm/tpm_tis_spi: Add support for spi phy") Cc: stable@vger.kernel.org Reviewed-by: Jarkko Sakkinen Signed-off-by: Alexander Steffen Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_tis_spi.c | 45 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c index 1a09a7491019..01eccb193b5a 100644 --- a/drivers/char/tpm/tpm_tis_spi.c +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -47,9 +47,7 @@ struct tpm_tis_spi_phy { struct tpm_tis_data priv; struct spi_device *spi_device; - - u8 tx_buf[4]; - u8 rx_buf[4]; + u8 *iobuf; }; static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) @@ -72,14 +70,14 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, while (len) { transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE); - phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1); - phy->tx_buf[1] = 0xd4; - phy->tx_buf[2] = addr >> 8; - phy->tx_buf[3] = addr; + phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1); + phy->iobuf[1] = 0xd4; + phy->iobuf[2] = addr >> 8; + phy->iobuf[3] = addr; memset(&spi_xfer, 0, sizeof(spi_xfer)); - spi_xfer.tx_buf = phy->tx_buf; - spi_xfer.rx_buf = phy->rx_buf; + spi_xfer.tx_buf = phy->iobuf; + spi_xfer.rx_buf = phy->iobuf; spi_xfer.len = 4; spi_xfer.cs_change = 1; @@ -89,9 +87,9 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, if (ret < 0) goto exit; - if ((phy->rx_buf[3] & 0x01) == 0) { + if ((phy->iobuf[3] & 0x01) == 0) { // handle SPI wait states - phy->tx_buf[0] = 0; + phy->iobuf[0] = 0; for (i = 0; i < TPM_RETRY; i++) { spi_xfer.len = 1; @@ -100,7 +98,7 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, ret = spi_sync_locked(phy->spi_device, &m); if (ret < 0) goto exit; - if (phy->rx_buf[0] & 0x01) + if (phy->iobuf[0] & 0x01) break; } @@ -113,8 +111,14 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, spi_xfer.cs_change = 0; spi_xfer.len = transfer_len; spi_xfer.delay_usecs = 5; - spi_xfer.tx_buf = out; - spi_xfer.rx_buf = in; + + if (in) { + spi_xfer.tx_buf = NULL; + } else if (out) { + spi_xfer.rx_buf = NULL; + memcpy(phy->iobuf, out, transfer_len); + out += transfer_len; + } spi_message_init(&m); spi_message_add_tail(&spi_xfer, &m); @@ -122,11 +126,12 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, if (ret < 0) goto exit; - len -= transfer_len; - if (in) + if (in) { + memcpy(in, phy->iobuf, transfer_len); in += transfer_len; - if (out) - out += transfer_len; + } + + len -= transfer_len; } exit: @@ -192,6 +197,10 @@ static int tpm_tis_spi_probe(struct spi_device *dev) phy->spi_device = dev; + phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); + if (!phy->iobuf) + return -ENOMEM; + return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops, NULL); } -- cgit v1.2.3 From 89f0fb9698810841c1a02fa8d4a80e2eb654daff Mon Sep 17 00:00:00 2001 From: Alexander Steffen Date: Fri, 8 Sep 2017 17:21:32 +0200 Subject: tpm-dev-common: Reject too short writes commit ee70bc1e7b63ac8023c9ff9475d8741e397316e7 upstream. tpm_transmit() does not offer an explicit interface to indicate the number of valid bytes in the communication buffer. Instead, it relies on the commandSize field in the TPM header that is encoded within the buffer. Therefore, ensure that a) enough data has been written to the buffer, so that the commandSize field is present and b) the commandSize field does not announce more data than has been written to the buffer. This should have been fixed with CVE-2011-1161 long ago, but apparently a correct version of that patch never made it into the kernel. Cc: stable@vger.kernel.org Signed-off-by: Alexander Steffen Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm-dev.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index 912ad30be585..65b824954bdc 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -136,6 +136,12 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, return -EFAULT; } + if (in_size < 6 || + in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) { + mutex_unlock(&priv->buffer_mutex); + return -EINVAL; + } + /* atomic tpm command send and result receive. We only hold the ops * lock during this period so that the tpm can be unregistered even if * the char dev is held open. -- cgit v1.2.3 From 144b6353ae503c055dd8bda0a03f42798d62aaa4 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 23 Feb 2018 09:38:28 +0530 Subject: cpufreq: s3c24xx: Fix broken s3c_cpufreq_init() commit 0373ca74831b0f93cd4cdbf7ad3aec3c33a479a5 upstream. commit a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()" accidentally broke cpufreq on s3c2410 and s3c2412. These two platforms don't have a CPU frequency table and used to skip calling cpufreq_table_validate_and_show() for them. But with the above commit, we started calling it unconditionally and that will eventually fail as the frequency table pointer is NULL. Fix this by calling cpufreq_table_validate_and_show() conditionally again. Fixes: a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()" Cc: 3.13+ # v3.13+ Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/s3c24xx-cpufreq.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 7b596fa38ad2..6bebc1f9f55a 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -351,7 +351,13 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) static int s3c_cpufreq_init(struct cpufreq_policy *policy) { policy->clk = clk_arm; - return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); + + policy->cpuinfo.transition_latency = cpu_cur.info->latency; + + if (ftab) + return cpufreq_table_validate_and_show(policy, ftab); + + return 0; } static int __init s3c_cpufreq_initclks(void) -- cgit v1.2.3 From 9bcc9ac1cfd280e8795eb6b9fe3120a5682af939 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 10 Feb 2018 06:14:10 -0500 Subject: media: m88ds3103: don't call a non-initalized function commit b9c97c67fd19262c002d94ced2bfb513083e161e upstream. If m88d3103 chip ID is not recognized, the device is not initialized. However, it returns from probe without any error, causing this OOPS: [ 7.689289] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 7.689297] pgd = 7b0bd7a7 [ 7.689302] [00000000] *pgd=00000000 [ 7.689318] Internal error: Oops: 80000005 [#1] SMP ARM [ 7.689322] Modules linked in: dvb_usb_dvbsky(+) m88ds3103 dvb_usb_v2 dvb_core videobuf2_vmalloc videobuf2_memops videobuf2_core crc32_arm_ce videodev media [ 7.689358] CPU: 3 PID: 197 Comm: systemd-udevd Not tainted 4.15.0-mcc+ #23 [ 7.689361] Hardware name: BCM2835 [ 7.689367] PC is at 0x0 [ 7.689382] LR is at m88ds3103_attach+0x194/0x1d0 [m88ds3103] [ 7.689386] pc : [<00000000>] lr : [] psr: 60000013 [ 7.689391] sp : ed8e5c20 ip : ed8c1e00 fp : ed8945c0 [ 7.689395] r10: ed894000 r9 : ed894378 r8 : eda736c0 [ 7.689400] r7 : ed894070 r6 : ed8e5c44 r5 : bf0bb040 r4 : eda77600 [ 7.689405] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : eda77600 [ 7.689412] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 7.689417] Control: 10c5383d Table: 2d8e806a DAC: 00000051 [ 7.689423] Process systemd-udevd (pid: 197, stack limit = 0xe9dbfb63) [ 7.689428] Stack: (0xed8e5c20 to 0xed8e6000) [ 7.689439] 5c20: ed853a80 eda73640 ed894000 ed8942c0 ed853a80 bf0b9e98 ed894070 bf0b9f10 [ 7.689449] 5c40: 00000000 00000000 bf08c17c c08dfc50 00000000 00000000 00000000 00000000 [ 7.689459] 5c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689468] 5c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689479] 5ca0: 00000000 00000000 ed8945c0 ed8942c0 ed894000 ed894830 bf0b9e98 00000000 [ 7.689490] 5cc0: ed894378 bf0a3cb4 bf0bc3b0 0000533b ed920540 00000000 00000034 bf0a6434 [ 7.689500] 5ce0: ee952070 ed826600 bf0a7038 bf0a2dd8 00000001 bf0a6768 bf0a2f90 ed8943c0 [ 7.689511] 5d00: 00000000 c08eca68 ed826620 ed826620 00000000 ee952070 bf0bc034 ee952000 [ 7.689521] 5d20: ed826600 bf0bb080 ffffffed c0aa9e9c c0aa9dac ed826620 c16edf6c c168c2c8 [ 7.689531] 5d40: c16edf70 00000000 bf0bc034 0000000d 00000000 c08e268c bf0bb080 ed826600 [ 7.689541] 5d60: bf0bc034 ed826654 ed826620 bf0bc034 c164c8bc 00000000 00000001 00000000 [ 7.689553] 5d80: 00000028 c08e2948 00000000 bf0bc034 c08e2848 c08e0778 ee9f0a58 ed88bab4 [ 7.689563] 5da0: bf0bc034 ed90ba80 c168c1f0 c08e1934 bf0bb3bc c17045ac bf0bc034 c164c8bc [ 7.689574] 5dc0: bf0bc034 bf0bb3bc ed91f564 c08e34ec bf0bc000 c164c8bc bf0bc034 c0aa8dc4 [ 7.689584] 5de0: ffffe000 00000000 bf0bf000 ed91f600 ed91f564 c03021e4 00000001 00000000 [ 7.689595] 5e00: c166e040 8040003f ed853a80 bf0bc448 00000000 c1678174 ed853a80 f0f22000 [ 7.689605] 5e20: f0f21fff 8040003f 014000c0 ed91e700 ed91e700 c16d8e68 00000001 ed91e6c0 [ 7.689615] 5e40: bf0bc400 00000001 bf0bc400 ed91f564 00000001 00000000 00000028 c03c9a24 [ 7.689625] 5e60: 00000001 c03c8c94 ed8e5f50 ed8e5f50 00000001 bf0bc400 ed91f540 c03c8cb0 [ 7.689637] 5e80: bf0bc40c 00007fff bf0bc400 c03c60b0 00000000 bf0bc448 00000028 c0e09684 [ 7.689647] 5ea0: 00000002 bf0bc530 c1234bf8 bf0bc5dc bf0bc514 c10ebbe8 ffffe000 bf000000 [ 7.689657] 5ec0: 00011538 00000000 ed8e5f48 00000000 00000000 00000000 00000000 00000000 [ 7.689666] 5ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689676] 5f00: 00000000 00000000 7fffffff 00000000 00000013 b6e55a18 0000017b c0309104 [ 7.689686] 5f20: ed8e4000 00000000 00510af0 c03c9430 7fffffff 00000000 00000003 00000000 [ 7.689697] 5f40: 00000000 f0f0f000 00011538 00000000 f0f107b0 f0f0f000 00011538 f0f1fdb8 [ 7.689707] 5f60: f0f1fbe8 f0f1b974 00004000 000041e0 bf0bc3d0 00000001 00000000 000024c4 [ 7.689717] 5f80: 0000002d 0000002e 00000019 00000000 00000010 00000000 16894000 00000000 [ 7.689727] 5fa0: 00000000 c0308f20 16894000 00000000 00000013 b6e55a18 00000000 b6e5652c [ 7.689737] 5fc0: 16894000 00000000 00000000 0000017b 00020000 00508110 00000000 00510af0 [ 7.689748] 5fe0: bef68948 bef68938 b6e4d3d0 b6d32590 60000010 00000013 00000000 00000000 [ 7.689790] [] (m88ds3103_attach [m88ds3103]) from [] (dvbsky_s960c_attach+0x78/0x280 [dvb_usb_dvbsky]) [ 7.689821] [] (dvbsky_s960c_attach [dvb_usb_dvbsky]) from [] (dvb_usbv2_probe+0xa3c/0x1024 [dvb_usb_v2]) [ 7.689849] [] (dvb_usbv2_probe [dvb_usb_v2]) from [] (usb_probe_interface+0xf0/0x2a8) [ 7.689869] [] (usb_probe_interface) from [] (driver_probe_device+0x2f8/0x4b4) [ 7.689881] [] (driver_probe_device) from [] (__driver_attach+0x100/0x11c) [ 7.689895] [] (__driver_attach) from [] (bus_for_each_dev+0x4c/0x9c) [ 7.689909] [] (bus_for_each_dev) from [] (bus_add_driver+0x1c0/0x264) [ 7.689919] [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [ 7.689931] [] (driver_register) from [] (usb_register_driver+0x70/0x134) [ 7.689946] [] (usb_register_driver) from [] (do_one_initcall+0x44/0x168) [ 7.689963] [] (do_one_initcall) from [] (do_init_module+0x64/0x1f4) [ 7.689979] [] (do_init_module) from [] (load_module+0x20a0/0x25c8) [ 7.689993] [] (load_module) from [] (SyS_finit_module+0xb4/0xec) [ 7.690007] [] (SyS_finit_module) from [] (ret_fast_syscall+0x0/0x54) [ 7.690018] Code: bad PC value This may happen on normal circumstances, if, for some reason, the demod hangs and start returning an invalid chip ID: [ 10.394395] m88ds3103 3-0068: Unknown device. Chip_id=00 So, change the logic to cause probe to fail with -ENODEV, preventing the OOPS. Detected while testing DVB MMAP patches on Raspberry Pi 3 with DVBSky S960CI. Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/m88ds3103.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index e0fe5bc9dbce..31f16105184c 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan) * New users must use I2C client binding directly! */ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, - struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter) + struct i2c_adapter *i2c, + struct i2c_adapter **tuner_i2c_adapter) { struct i2c_client *client; struct i2c_board_info board_info; - struct m88ds3103_platform_data pdata; + struct m88ds3103_platform_data pdata = {}; pdata.clk = cfg->clock; pdata.i2c_wr_max = cfg->i2c_wr_max; @@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client, case M88DS3103_CHIP_ID: break; default: + ret = -ENODEV; + dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id); goto err_kfree; } -- cgit v1.2.3 From 6213c714a580c34751f9501725369fc5e0fe71e5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 2 Oct 2017 15:08:40 +0100 Subject: PCI/ASPM: Deal with missing root ports in link state handling commit ee8bdfb6568d86bb93f55f8d99c4c643e77304ee upstream. Even though it is unconventional, some PCIe host implementations omit the root ports entirely, and simply consist of a host bridge (which is not modeled as a device in the PCI hierarchy) and a link. When the downstream device is an endpoint, our current code does not seem to mind this unusual configuration. However, when PCIe switches are involved, the ASPM code assumes that any downstream switch port has a parent, and blindly dereferences the bus->parent->self field of the pci_dev struct to chain the downstream link state to the link state of the root port. Given that the root port is missing, the link is not modeled at all, and nor is the link state, and attempting to access it results in a NULL pointer dereference and a crash. Avoid this by allowing the link state chain to terminate at the downstream port if no root port exists. Signed-off-by: Ard Biesheuvel Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pcie/aspm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index b0916b126923..6643a7bc381c 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -526,10 +526,14 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev) /* * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe - * hierarchies. + * hierarchies. Note that some PCIe host implementations omit + * the root ports entirely, in which case a downstream port on + * a switch may become the root of the link state chain for all + * its subordinate endpoints. */ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT || - pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) { + pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE || + !pdev->bus->parent->self) { link->root = link; } else { struct pcie_link_state *parent; -- cgit v1.2.3 From b6f93a1341fb166ea861aa37eeac492af3de837a Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 20 Jun 2017 19:14:30 -0400 Subject: dm io: fix duplicate bio completion due to missing ref count commit feb7695fe9fb83084aa29de0094774f4c9d4c9fc upstream. If only a subset of the devices associated with multiple regions support a given special operation (eg. DISCARD) then the dec_count() that is used to set error for the region must increment the io->count. Otherwise, when the dec_count() is called it can cause the dm-io caller's bio to be completed multiple times. As was reported against the dm-mirror target that had mirror legs with a mix of discard capabilities. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=196077 Reported-by: Zhang Yi Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-io.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 0bf1a12e35fe..ee6045d6c0bb 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -302,6 +302,7 @@ static void do_region(int op, int op_flags, unsigned region, special_cmd_max_sectors = q->limits.max_write_same_sectors; if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_SAME) && special_cmd_max_sectors == 0) { + atomic_inc(&io->count); dec_count(io, region, -EOPNOTSUPP); return; } -- cgit v1.2.3 From eb2593fbd643f68a557b62141106788242183954 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 3 Feb 2018 09:19:30 +1100 Subject: md: only allow remove_and_add_spares when no sync_thread running. commit 39772f0a7be3b3dc26c74ea13fe7847fd1522c8b upstream. The locking protocols in md assume that a device will never be removed from an array during resync/recovery/reshape. When that isn't happening, rcu or reconfig_mutex is needed to protect an rdev pointer while taking a refcount. When it is happening, that protection isn't needed. Unfortunately there are cases were remove_and_add_spares() is called when recovery might be happening: is state_store(), slot_store() and hot_remove_disk(). In each case, this is just an optimization, to try to expedite removal from the personality so the device can be removed from the array. If resync etc is happening, we just have to wait for md_check_recover to find a suitable time to call remove_and_add_spares(). This optimization and not essential so it doesn't matter if it fails. So change remove_and_add_spares() to abort early if resync/recovery/reshape is happening, unless it is called from md_check_recovery() as part of a newly started recovery. The parameter "this" is only NULL when called from md_check_recovery() so when it is NULL, there is no need to abort. As this can result in a NULL dereference, the fix is suitable for -stable. cc: yuyufen Cc: Tomasz Majchrzak Fixes: 8430e7e0af9a ("md: disconnect device from personality before trying to remove it.") Cc: stable@ver.kernel.org (v4.8+) Signed-off-by: NeilBrown Signed-off-by: Shaohua Li Signed-off-by: Greg Kroah-Hartman --- drivers/md/md.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 8ebf1b97e1d2..27d8bb21e04f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8224,6 +8224,10 @@ static int remove_and_add_spares(struct mddev *mddev, int removed = 0; bool remove_some = false; + if (this && test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) + /* Mustn't remove devices when resync thread is running */ + return 0; + rdev_for_each(rdev, mddev) { if ((this == NULL || rdev == this) && rdev->raid_disk >= 0 && -- cgit v1.2.3 From 188633598e26c2ee25d0e2efb0a2f061c5666db5 Mon Sep 17 00:00:00 2001 From: Denis Du Date: Sat, 24 Feb 2018 16:51:42 -0500 Subject: hdlc_ppp: carrier detect ok, don't turn off negotiation [ Upstream commit b6c3bad1ba83af1062a7ff6986d9edc4f3d7fc8e ] Sometimes when physical lines have a just good noise to make the protocol handshaking fail, but the carrier detect still good. Then after remove of the noise, nobody will trigger this protocol to be start again to cause the link to never come back. The fix is when the carrier is still on, not terminate the protocol handshaking. Signed-off-by: Denis Du Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/hdlc_ppp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index 47fdb87d3567..8a9aced850be 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -574,7 +574,10 @@ static void ppp_timer(unsigned long arg) ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0, 0, NULL); proto->restart_counter--; - } else + } else if (netif_carrier_ok(proto->dev)) + ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0, + 0, NULL); + else ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0, 0, NULL); break; -- cgit v1.2.3 From 3741c8fad871b77ccc31f2255047ac0e71b8cb15 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 2 Mar 2018 18:41:16 +0100 Subject: ppp: prevent unregistered channels from connecting to PPP units [ Upstream commit 77f840e3e5f09c6d7d727e85e6e08276dd813d11 ] PPP units don't hold any reference on the channels connected to it. It is the channel's responsibility to ensure that it disconnects from its unit before being destroyed. In practice, this is ensured by ppp_unregister_channel() disconnecting the channel from the unit before dropping a reference on the channel. However, it is possible for an unregistered channel to connect to a PPP unit: register a channel with ppp_register_net_channel(), attach a /dev/ppp file to it with ioctl(PPPIOCATTCHAN), unregister the channel with ppp_unregister_channel() and finally connect the /dev/ppp file to a PPP unit with ioctl(PPPIOCCONNECT). Once in this situation, the channel is only held by the /dev/ppp file, which can be released at anytime and free the channel without letting the parent PPP unit know. Then the ppp structure ends up with dangling pointers in its ->channels list. Prevent this scenario by forbidding unregistered channels from connecting to PPP units. This maintains the code logic by keeping ppp_unregister_channel() responsible from disconnecting the channel if necessary and avoids modification on the reference counting mechanism. This issue seems to predate git history (successfully reproduced on Linux 2.6.26 and earlier PPP commits are unrelated). Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ppp/ppp_generic.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index fc4c2ccc3d22..114457921890 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -3157,6 +3157,15 @@ ppp_connect_channel(struct channel *pch, int unit) goto outl; ppp_lock(ppp); + spin_lock_bh(&pch->downl); + if (!pch->chan) { + /* Don't connect unregistered channels */ + spin_unlock_bh(&pch->downl); + ppp_unlock(ppp); + ret = -ENOTCONN; + goto outl; + } + spin_unlock_bh(&pch->downl); if (pch->file.hdrlen > ppp->file.hdrlen) ppp->file.hdrlen = pch->file.hdrlen; hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */ -- cgit v1.2.3 From 804e337023e644c5d3ac5d23a9a9c2904e1331e3 Mon Sep 17 00:00:00 2001 From: Shalom Toledo Date: Thu, 1 Mar 2018 11:37:05 +0100 Subject: mlxsw: spectrum_switchdev: Check success of FDB add operation [ Upstream commit 0a8a1bf17e3af34f1f8d2368916a6327f8b3bfd5 ] Until now, we assumed that in case of error when adding FDB entries, the write operation will fail, but this is not the case. Instead, we need to check that the number of entries reported in the response is equal to the number of entries specified in the request. Fixes: 56ade8fe3fe1 ("mlxsw: spectrum: Add initial support for Spectrum ASIC") Reported-by: Ido Schimmel Signed-off-by: Shalom Toledo Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- .../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 1e2c8eca3af1..bea9ae31a769 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -809,6 +809,7 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port, bool dynamic) { char *sfd_pl; + u8 num_rec; int err; sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL); @@ -818,9 +819,16 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port, mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0); mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic), mac, fid, action, local_port); + num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); - kfree(sfd_pl); + if (err) + goto out; + + if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl)) + err = -EBUSY; +out: + kfree(sfd_pl); return err; } @@ -845,6 +853,7 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id, bool adding, bool dynamic) { char *sfd_pl; + u8 num_rec; int err; sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL); @@ -855,9 +864,16 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id, mlxsw_reg_sfd_uc_lag_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic), mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP, lag_vid, lag_id); + num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); - kfree(sfd_pl); + if (err) + goto out; + + if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl)) + err = -EBUSY; +out: + kfree(sfd_pl); return err; } @@ -891,6 +907,7 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr, u16 fid, u16 mid, bool adding) { char *sfd_pl; + u8 num_rec; int err; sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL); @@ -900,7 +917,15 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr, mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0); mlxsw_reg_sfd_mc_pack(sfd_pl, 0, addr, fid, MLXSW_REG_SFD_REC_ACTION_NOP, mid); + num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); + if (err) + goto out; + + if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl)) + err = -EBUSY; + +out: kfree(sfd_pl); return err; } -- cgit v1.2.3 From 19d32133abf960fb49ebb423390f6d8b238423eb Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 8 Feb 2018 21:01:48 +0100 Subject: net: phy: fix phy_start to consider PHY_IGNORE_INTERRUPT [ Upstream commit 08f5138512180a479ce6b9d23b825c9f4cd3be77 ] This condition wasn't adjusted when PHY_IGNORE_INTERRUPT (-2) was added long ago. In case of PHY_IGNORE_INTERRUPT the MAC interrupt indicates also PHY state changes and we should do what the symbol says. Fixes: 84a527a41f38 ("net: phylib: fix interrupts re-enablement in phy_start") Signed-off-by: Heiner Kallweit Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 6e12401b5102..e2d9ca60e467 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -925,7 +925,7 @@ void phy_start(struct phy_device *phydev) break; case PHY_HALTED: /* make sure interrupts are re-enabled for the PHY */ - if (phydev->irq != PHY_POLL) { + if (phy_interrupt_is_valid(phydev)) { err = phy_enable_interrupts(phydev); if (err < 0) break; -- cgit v1.2.3 From 8d072588de679ef1593f67d8d4de7184111efa4f Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Fri, 9 Feb 2018 11:03:49 +0100 Subject: s390/qeth: fix underestimated count of buffer elements [ Upstream commit 89271c65edd599207dd982007900506283c90ae3 ] For a memory range/skb where the last byte falls onto a page boundary (ie. 'end' is of the form xxx...xxx001), the PFN_UP() part of the calculation currently doesn't round up to the next PFN due to an off-by-one error. Thus qeth believes that the skb occupies one page less than it actually does, and may select a IO buffer that doesn't have enough spare buffer elements to fit all of the skb's data. HW detects this as a malformed buffer descriptor, and raises an exception which then triggers device recovery. Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count") Signed-off-by: Ursula Braun Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 9b5fc502f6a1..2fe218101c46 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -849,7 +849,7 @@ struct qeth_trap_id { */ static inline int qeth_get_elements_for_range(addr_t start, addr_t end) { - return PFN_UP(end - 1) - PFN_DOWN(start); + return PFN_UP(end) - PFN_DOWN(start); } static inline int qeth_get_micros(void) -- cgit v1.2.3 From 3c0718711177865020e89a714f062b6403ff78e5 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Fri, 9 Feb 2018 11:03:50 +0100 Subject: s390/qeth: fix SETIP command handling [ Upstream commit 1c5b2216fbb973a9410e0b06389740b5c1289171 ] send_control_data() applies some special handling to SETIP v4 IPA commands. But current code parses *all* command types for the SETIP command code. Limit the command code check to IPA commands. Fixes: 5b54e16f1a54 ("qeth: do not spin for SETIP ip assist command") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core.h | 5 +++++ drivers/s390/net/qeth_core_main.c | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 2fe218101c46..403712bf1ddf 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -592,6 +592,11 @@ struct qeth_cmd_buffer { void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *); }; +static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob) +{ + return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); +} + /** * definition of a qeth channel, used for read and write */ diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index df8f74cb1406..ca514e475096 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2050,7 +2050,7 @@ int qeth_send_control_data(struct qeth_card *card, int len, unsigned long flags; struct qeth_reply *reply = NULL; unsigned long timeout, event_timeout; - struct qeth_ipa_cmd *cmd; + struct qeth_ipa_cmd *cmd = NULL; QETH_CARD_TEXT(card, 2, "sendctl"); @@ -2077,10 +2077,13 @@ int qeth_send_control_data(struct qeth_card *card, int len, while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ; qeth_prepare_control_data(card, len, iob); - if (IS_IPA(iob->data)) + if (IS_IPA(iob->data)) { + cmd = __ipa_cmd(iob); event_timeout = QETH_IPA_TIMEOUT; - else + } else { event_timeout = QETH_TIMEOUT; + } + timeout = jiffies + event_timeout; QETH_CARD_TEXT(card, 6, "noirqpnd"); @@ -2105,9 +2108,8 @@ int qeth_send_control_data(struct qeth_card *card, int len, /* we have only one long running ipassist, since we can ensure process context of this command we can sleep */ - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - if ((cmd->hdr.command == IPA_CMD_SETIP) && - (cmd->hdr.prot_version == QETH_PROT_IPV4)) { + if (cmd && cmd->hdr.command == IPA_CMD_SETIP && + cmd->hdr.prot_version == QETH_PROT_IPV4) { if (!wait_event_timeout(reply->wait_q, atomic_read(&reply->received), event_timeout)) goto time_err; -- cgit v1.2.3 From 797658d05e40486104312a28abf1ac37e6479e14 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 27 Feb 2018 18:58:12 +0100 Subject: s390/qeth: fix overestimated count of buffer elements [ Upstream commit 12472af89632beb1ed8dea29d4efe208ca05b06a ] qeth_get_elements_for_range() doesn't know how to handle a 0-length range (ie. start == end), and returns 1 when it should return 0. Such ranges occur on TSO skbs, where the L2/L3/L4 headers (and thus all of the skb's linear data) are skipped when mapping the skb into regular buffer elements. This overestimation may cause several performance-related issues: 1. sub-optimal IO buffer selection, where the next buffer gets selected even though the skb would actually still fit into the current buffer. 2. forced linearization, if the element count for a non-linear skb exceeds QETH_MAX_BUFFER_ELEMENTS. Rather than modifying qeth_get_elements_for_range() and adding overhead to every caller, fix up those callers that are in risk of passing a 0-length range. Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 10 ++++++---- drivers/s390/net/qeth_l3_main.c | 11 ++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index ca514e475096..fb0ba3c48e3d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3854,10 +3854,12 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags); int qeth_get_elements_no(struct qeth_card *card, struct sk_buff *skb, int extra_elems, int data_offset) { - int elements = qeth_get_elements_for_range( - (addr_t)skb->data + data_offset, - (addr_t)skb->data + skb_headlen(skb)) + - qeth_get_elements_for_frags(skb); + addr_t end = (addr_t)skb->data + skb_headlen(skb); + int elements = qeth_get_elements_for_frags(skb); + addr_t start = (addr_t)skb->data + data_offset; + + if (start != end) + elements += qeth_get_elements_for_range(start, end); if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { QETH_DBF_MESSAGE(2, "Invalid size of IP packet " diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 1487f8a0c575..34400ff018af 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2784,11 +2784,12 @@ static void qeth_tso_fill_header(struct qeth_card *card, static int qeth_l3_get_elements_no_tso(struct qeth_card *card, struct sk_buff *skb, int extra_elems) { - addr_t tcpdptr = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb); - int elements = qeth_get_elements_for_range( - tcpdptr, - (addr_t)skb->data + skb_headlen(skb)) + - qeth_get_elements_for_frags(skb); + addr_t start = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb); + addr_t end = (addr_t)skb->data + skb_headlen(skb); + int elements = qeth_get_elements_for_frags(skb); + + if (start != end) + elements += qeth_get_elements_for_range(start, end); if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { QETH_DBF_MESSAGE(2, -- cgit v1.2.3 From 1537f144ac065b571c4d2c1969a389e138f06150 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 27 Feb 2018 18:58:13 +0100 Subject: s390/qeth: fix IP removal on offline cards [ Upstream commit 98d823ab1fbdcb13abc25b420f9bb71bade42056 ] If the HW is not reachable, then none of the IPs in qeth's internal table has been registered with the HW yet. So when deleting such an IP, there's no need to stage it for deregistration - just drop it from the table. This fixes the "add-delete-add" scenario on an offline card, where the the second "add" merely increments the IP's use count. But as the IP is still set to DISP_ADDR_DELETE from the previous "delete" step, l3_recover_ip() won't register it with the HW when the card goes online. Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_l3_main.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 34400ff018af..e91693de86bb 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -259,12 +259,8 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) if (addr->in_progress) return -EINPROGRESS; - if (!qeth_card_hw_is_reachable(card)) { - addr->disp_flag = QETH_DISP_ADDR_DELETE; - return 0; - } - - rc = qeth_l3_deregister_addr_entry(card, addr); + if (qeth_card_hw_is_reachable(card)) + rc = qeth_l3_deregister_addr_entry(card, addr); hash_del(&addr->hnode); kfree(addr); @@ -406,11 +402,7 @@ static void qeth_l3_recover_ip(struct qeth_card *card) spin_lock_bh(&card->ip_lock); hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) { - if (addr->disp_flag == QETH_DISP_ADDR_DELETE) { - qeth_l3_deregister_addr_entry(card, addr); - hash_del(&addr->hnode); - kfree(addr); - } else if (addr->disp_flag == QETH_DISP_ADDR_ADD) { + if (addr->disp_flag == QETH_DISP_ADDR_ADD) { if (addr->proto == QETH_PROT_IPV4) { addr->in_progress = 1; spin_unlock_bh(&card->ip_lock); -- cgit v1.2.3 From 2a3db8370ae36bb884512e35bd559e07bf4148df Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 27 Feb 2018 18:58:14 +0100 Subject: s390/qeth: fix double-free on IP add/remove race [ Upstream commit 14d066c3531a87f727968cacd85bd95c75f59843 ] Registering an IPv4 address with the HW takes quite a while, so we temporarily drop the ip_htable lock. Any concurrent add/remove of the same IP adjusts the IP's use count, and (on remove) is then blocked by addr->in_progress. After the register call has completed, we check the use count for concurrently attempted add/remove calls - and possibly straight-away deregister the IP again. This happens via l3_delete_ip(), which 1) looks up the queried IP in the htable (getting a reference to the *same* queried object), 2) deregisters the IP from the HW, and 3) frees the IP object. The caller in l3_add_ip() then does a second free on the same object. For this case, skip all the extra checks and lookups in l3_delete_ip() and just deregister & free the IP object ourselves. Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_l3_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e91693de86bb..d7505a114d1d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -323,7 +323,8 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) (rc == IPA_RC_LAN_OFFLINE)) { addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; if (addr->ref_counter < 1) { - qeth_l3_delete_ip(card, addr); + qeth_l3_deregister_addr_entry(card, addr); + hash_del(&addr->hnode); kfree(addr); } } else { -- cgit v1.2.3 From 058db71dd8d68973e3add8b5a355036ddc13b460 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 27 Feb 2018 18:58:16 +0100 Subject: s390/qeth: fix IP address lookup for L3 devices [ Upstream commit c5c48c58b259bb8f0482398370ee539d7a12df3e ] Current code ("qeth_l3_ip_from_hash()") matches a queried address object against objects in the IP table by IP address, Mask/Prefix Length and MAC address ("qeth_l3_ipaddrs_is_equal()"). But what callers actually require is either a) "is this IP address registered" (ie. match by IP address only), before adding a new address. b) or "is this address object registered" (ie. match all relevant attributes), before deleting an address. Right now 1. the ADD path is too strict in its lookup, and eg. doesn't detect conflicts between an existing NORMAL address and a new VIPA address (because the NORMAL address will have mask != 0, while VIPA has a mask == 0), 2. the DELETE path is not strict enough, and eg. allows del_rxip() to delete a VIPA address as long as the IP address matches. Fix all this by adding helpers (_addr_match_ip() and _addr_match_all()) that do the appropriate checking. Note that the ADD path for NORMAL addresses is special, as qeth keeps track of how many times such an address is in use (and there is no immediate way of returning errors to the caller). So when a requested NORMAL address _fully_ matches an existing one, it's not considered a conflict and we merely increment the refcount. Fixes: 5f78e29ceebf ("qeth: optimize IP handling in rx_mode callback") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_l3.h | 34 ++++++++++++++- drivers/s390/net/qeth_l3_main.c | 91 +++++++++++++++++++---------------------- 2 files changed, 74 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index eedf9b01a496..573569474e44 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -39,8 +39,40 @@ struct qeth_ipaddr { unsigned int pfxlen; } a6; } u; - }; + +static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1, + struct qeth_ipaddr *a2) +{ + if (a1->proto != a2->proto) + return false; + if (a1->proto == QETH_PROT_IPV6) + return ipv6_addr_equal(&a1->u.a6.addr, &a2->u.a6.addr); + return a1->u.a4.addr == a2->u.a4.addr; +} + +static inline bool qeth_l3_addr_match_all(struct qeth_ipaddr *a1, + struct qeth_ipaddr *a2) +{ + /* Assumes that the pair was obtained via qeth_l3_addr_find_by_ip(), + * so 'proto' and 'addr' match for sure. + * + * For ucast: + * - 'mac' is always 0. + * - 'mask'/'pfxlen' for RXIP/VIPA is always 0. For NORMAL, matching + * values are required to avoid mixups in takeover eligibility. + * + * For mcast, + * - 'mac' is mapped from the IP, and thus always matches. + * - 'mask'/'pfxlen' is always 0. + */ + if (a1->type != a2->type) + return false; + if (a1->proto == QETH_PROT_IPV6) + return a1->u.a6.pfxlen == a2->u.a6.pfxlen; + return a1->u.a4.mask == a2->u.a4.mask; +} + static inline u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr) { u64 ret = 0; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index d7505a114d1d..a668e6b71a29 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -154,6 +154,24 @@ int qeth_l3_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto, return -EINVAL; } +static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card, + struct qeth_ipaddr *query) +{ + u64 key = qeth_l3_ipaddr_hash(query); + struct qeth_ipaddr *addr; + + if (query->is_multicast) { + hash_for_each_possible(card->ip_mc_htable, addr, hnode, key) + if (qeth_l3_addr_match_ip(addr, query)) + return addr; + } else { + hash_for_each_possible(card->ip_htable, addr, hnode, key) + if (qeth_l3_addr_match_ip(addr, query)) + return addr; + } + return NULL; +} + static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len) { int i, j; @@ -207,34 +225,6 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, return rc; } -inline int -qeth_l3_ipaddrs_is_equal(struct qeth_ipaddr *addr1, struct qeth_ipaddr *addr2) -{ - return addr1->proto == addr2->proto && - !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) && - !memcmp(&addr1->mac, &addr2->mac, sizeof(addr1->mac)); -} - -static struct qeth_ipaddr * -qeth_l3_ip_from_hash(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) -{ - struct qeth_ipaddr *addr; - - if (tmp_addr->is_multicast) { - hash_for_each_possible(card->ip_mc_htable, addr, - hnode, qeth_l3_ipaddr_hash(tmp_addr)) - if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr)) - return addr; - } else { - hash_for_each_possible(card->ip_htable, addr, - hnode, qeth_l3_ipaddr_hash(tmp_addr)) - if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr)) - return addr; - } - - return NULL; -} - int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) { int rc = 0; @@ -249,8 +239,8 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8); } - addr = qeth_l3_ip_from_hash(card, tmp_addr); - if (!addr) + addr = qeth_l3_find_addr_by_ip(card, tmp_addr); + if (!addr || !qeth_l3_addr_match_all(addr, tmp_addr)) return -ENOENT; addr->ref_counter--; @@ -272,6 +262,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) { int rc = 0; struct qeth_ipaddr *addr; + char buf[40]; QETH_CARD_TEXT(card, 4, "addip"); @@ -282,8 +273,20 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8); } - addr = qeth_l3_ip_from_hash(card, tmp_addr); - if (!addr) { + addr = qeth_l3_find_addr_by_ip(card, tmp_addr); + if (addr) { + if (tmp_addr->type != QETH_IP_TYPE_NORMAL) + return -EADDRINUSE; + if (qeth_l3_addr_match_all(addr, tmp_addr)) { + addr->ref_counter++; + return 0; + } + qeth_l3_ipaddr_to_string(tmp_addr->proto, (u8 *)&tmp_addr->u, + buf); + dev_warn(&card->gdev->dev, + "Registering IP address %s failed\n", buf); + return -EADDRINUSE; + } else { addr = qeth_l3_get_addr_buffer(tmp_addr->proto); if (!addr) return -ENOMEM; @@ -331,11 +334,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) hash_del(&addr->hnode); kfree(addr); } - } else { - if (addr->type == QETH_IP_TYPE_NORMAL) - addr->ref_counter++; } - return rc; } @@ -719,12 +718,7 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, return -ENOMEM; spin_lock_bh(&card->ip_lock); - - if (qeth_l3_ip_from_hash(card, ipaddr)) - rc = -EEXIST; - else - qeth_l3_add_ip(card, ipaddr); - + rc = qeth_l3_add_ip(card, ipaddr); spin_unlock_bh(&card->ip_lock); kfree(ipaddr); @@ -787,12 +781,7 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, return -ENOMEM; spin_lock_bh(&card->ip_lock); - - if (qeth_l3_ip_from_hash(card, ipaddr)) - rc = -EEXIST; - else - qeth_l3_add_ip(card, ipaddr); - + rc = qeth_l3_add_ip(card, ipaddr); spin_unlock_bh(&card->ip_lock); kfree(ipaddr); @@ -1437,8 +1426,9 @@ qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev) memcpy(tmp->mac, buf, sizeof(tmp->mac)); tmp->is_multicast = 1; - ipm = qeth_l3_ip_from_hash(card, tmp); + ipm = qeth_l3_find_addr_by_ip(card, tmp); if (ipm) { + /* for mcast, by-IP match means full match */ ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING; } else { ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); @@ -1521,8 +1511,9 @@ qeth_l3_add_mc6_to_hash(struct qeth_card *card, struct inet6_dev *in6_dev) sizeof(struct in6_addr)); tmp->is_multicast = 1; - ipm = qeth_l3_ip_from_hash(card, tmp); + ipm = qeth_l3_find_addr_by_ip(card, tmp); if (ipm) { + /* for mcast, by-IP match means full match */ ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING; continue; } -- cgit v1.2.3 From f3d26ce9ce34c5d34a23db6ecd00e23dec82febc Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 27 Feb 2018 18:58:17 +0100 Subject: s390/qeth: fix IPA command submission race [ Upstream commit d22ffb5a712f9211ffd104c38fc17cbfb1b5e2b0 ] If multiple IPA commands are build & sent out concurrently, fill_ipacmd_header() may assign a seqno value to a command that's different from what send_control_data() later assigns to this command's reply. This is due to other commands passing through send_control_data(), and incrementing card->seqno.ipa along the way. So one IPA command has no reply that's waiting for its seqno, while some other IPA command has multiple reply objects waiting for it. Only one of those waiting replies wins, and the other(s) times out and triggers a recovery via send_ipa_cmd(). Fix this by making sure that the same seqno value is assigned to a command and its reply object. Do so immediately before submitting the command & while holding the irq_pending "lock", to produce nicely ascending seqnos. As a side effect, *all* IPA commands now use a reply object that's waiting for its actual seqno. Previously, early IPA commands that were submitted while the card was still DOWN used the "catch-all" IDX seqno. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fb0ba3c48e3d..cc28dda322b5 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2064,25 +2064,26 @@ int qeth_send_control_data(struct qeth_card *card, int len, } reply->callback = reply_cb; reply->param = reply_param; - if (card->state == CARD_STATE_DOWN) - reply->seqno = QETH_IDX_COMMAND_SEQNO; - else - reply->seqno = card->seqno.ipa++; + init_waitqueue_head(&reply->wait_q); - spin_lock_irqsave(&card->lock, flags); - list_add_tail(&reply->list, &card->cmd_waiter_list); - spin_unlock_irqrestore(&card->lock, flags); QETH_DBF_HEX(CTRL, 2, iob->data, QETH_DBF_CTRL_LEN); while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ; - qeth_prepare_control_data(card, len, iob); if (IS_IPA(iob->data)) { cmd = __ipa_cmd(iob); + cmd->hdr.seqno = card->seqno.ipa++; + reply->seqno = cmd->hdr.seqno; event_timeout = QETH_IPA_TIMEOUT; } else { + reply->seqno = QETH_IDX_COMMAND_SEQNO; event_timeout = QETH_TIMEOUT; } + qeth_prepare_control_data(card, len, iob); + + spin_lock_irqsave(&card->lock, flags); + list_add_tail(&reply->list, &card->cmd_waiter_list); + spin_unlock_irqrestore(&card->lock, flags); timeout = jiffies + event_timeout; @@ -2873,7 +2874,7 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card, memset(cmd, 0, sizeof(struct qeth_ipa_cmd)); cmd->hdr.command = command; cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST; - cmd->hdr.seqno = card->seqno.ipa; + /* cmd->hdr.seqno is set by qeth_send_control_data() */ cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type); cmd->hdr.rel_adapter_no = (__u8) card->info.portno; if (card->options.layer2) -- cgit v1.2.3 From e126e3eaa219534530bedadb21d16482d538e344 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Wed, 7 Mar 2018 14:49:09 +0200 Subject: RDMA/ucma: Limit possible option size commit 6a21dfc0d0db7b7e0acedce67ca533a6eb19283c upstream. Users of ucma are supposed to provide size of option level, in most paths it is supposed to be equal to u8 or u16, but it is not the case for the IB path record, where it can be multiple of struct ib_path_rec_data. This patch takes simplest possible approach and prevents providing values more than possible to allocate. Reported-by: syzbot+a38b0e9f694c379ca7ce@syzkaller.appspotmail.com Fixes: 7ce86409adcd ("RDMA/ucma: Allow user space to set service type") Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 9520154f1d7c..dcca8c400646 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1275,6 +1275,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx); + if (unlikely(cmd.optval > KMALLOC_MAX_SIZE)) + return -EINVAL; + optval = memdup_user((void __user *) (unsigned long) cmd.optval, cmd.optlen); if (IS_ERR(optval)) { -- cgit v1.2.3 From b063d53d7a1d209da183d72ac0fda85a449d5810 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Wed, 7 Mar 2018 18:49:16 +0200 Subject: RDMA/ucma: Check that user doesn't overflow QP state commit a5880b84430316e3e1c1f5d23aa32ec6000cc717 upstream. The QP state is limited and declared in enum ib_qp_state, but ucma user was able to supply any possible (u32) value. Reported-by: syzbot+0df1ab766f8924b1edba@syzkaller.appspotmail.com Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index dcca8c400646..6840d3c5cd64 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1139,6 +1139,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; + if (cmd.qp_state > IB_QPS_ERR) + return -EINVAL; + ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); -- cgit v1.2.3 From 1bb454527e18b04437c41b2b4dfe31678fb4146d Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Wed, 7 Mar 2018 15:29:09 +0200 Subject: RDMA/mlx5: Fix integer overflow while resizing CQ commit 28e9091e3119933c38933cb8fc48d5618eb784c8 upstream. The user can provide very large cqe_size which will cause to integer overflow as it can be seen in the following UBSAN warning: ======================================================================= UBSAN: Undefined behaviour in drivers/infiniband/hw/mlx5/cq.c:1192:53 signed integer overflow: 64870 * 65536 cannot be represented in type 'int' CPU: 0 PID: 267 Comm: syzkaller605279 Not tainted 4.15.0+ #90 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 Call Trace: dump_stack+0xde/0x164 ? dma_virt_map_sg+0x22c/0x22c ubsan_epilogue+0xe/0x81 handle_overflow+0x1f3/0x251 ? __ubsan_handle_negate_overflow+0x19b/0x19b ? lock_acquire+0x440/0x440 mlx5_ib_resize_cq+0x17e7/0x1e40 ? cyc2ns_read_end+0x10/0x10 ? native_read_msr_safe+0x6c/0x9b ? cyc2ns_read_end+0x10/0x10 ? mlx5_ib_modify_cq+0x220/0x220 ? sched_clock_cpu+0x18/0x200 ? lookup_get_idr_uobject+0x200/0x200 ? rdma_lookup_get_uobject+0x145/0x2f0 ib_uverbs_resize_cq+0x207/0x3e0 ? ib_uverbs_ex_create_cq+0x250/0x250 ib_uverbs_write+0x7f9/0xef0 ? cyc2ns_read_end+0x10/0x10 ? print_irqtrace_events+0x280/0x280 ? ib_uverbs_ex_create_cq+0x250/0x250 ? uverbs_devnode+0x110/0x110 ? sched_clock_cpu+0x18/0x200 ? do_raw_spin_trylock+0x100/0x100 ? __lru_cache_add+0x16e/0x290 __vfs_write+0x10d/0x700 ? uverbs_devnode+0x110/0x110 ? kernel_read+0x170/0x170 ? sched_clock_cpu+0x18/0x200 ? security_file_permission+0x93/0x260 vfs_write+0x1b0/0x550 SyS_write+0xc7/0x1a0 ? SyS_read+0x1a0/0x1a0 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x1e/0x8b RIP: 0033:0x433549 RSP: 002b:00007ffe63bd1ea8 EFLAGS: 00000217 ======================================================================= Cc: syzkaller Cc: # 3.13 Fixes: bde51583f49b ("IB/mlx5: Add support for resize CQ") Reported-by: Noa Osherovich Reviewed-by: Yishai Hadas Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/cq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index fcd04b881ec1..9cdcff77b9a8 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -1117,7 +1117,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, if (ucmd.reserved0 || ucmd.reserved1) return -EINVAL; - umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size, + /* check multiplication overflow */ + if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1) + return -EINVAL; + + umem = ib_umem_get(context, ucmd.buf_addr, + (size_t)ucmd.cqe_size * entries, IB_ACCESS_LOCAL_WRITE, 1); if (IS_ERR(umem)) { err = PTR_ERR(umem); -- cgit v1.2.3 From 84e1a8afc7dba0bca8986faba01032e46eae82f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Sun, 31 Dec 2017 23:34:54 +0100 Subject: drm/i915: Try EDID bitbanging on HDMI after failed read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 90024a5951029685acc5396258f1b0de9b23cf4a upstream. The ACK/NACK implementation as found in e.g. the G965 has the falling clock edge and the release of the data line after the ACK for the received byte happen at the same time. This is conformant with the I2C specification, which allows a zero hold time, see footnote [3]: "A device must internally provide a hold time of at least 300 ns for the SDA signal (with respect to the V IH(min) of the SCL signal) to bridge the undefined region of the falling edge of SCL." Some HDMI-to-VGA converters apparently fail to adhere to this requirement and latch SDA at the falling clock edge, so instead of an ACK sometimes a NACK is read and the slave (i.e. the EDID ROM) ends the transfer. The bitbanging releases the data line for the ACK only 1/4 bit time after the falling clock edge, so a slave will see the correct value no matter if it samples at the rising or the falling clock edge or in the center. Fallback to bitbanging is already done for the CRT connector. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92685 Signed-off-by: Stefan Brüns Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/a39f080b-81a5-4c93-b3f7-7cb0a58daca3@rwthex-w2-a.rwth-ad.de (cherry picked from commit cfb926e148e99acc02351d72e8b85e32b5f786ef) Signed-off-by: Rodrigo Vivi Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_hdmi.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 13c306173f27..0c935dede9f4 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1452,12 +1452,20 @@ intel_hdmi_set_edid(struct drm_connector *connector) struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct edid *edid; bool connected = false; + struct i2c_adapter *i2c; intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); + + edid = drm_get_edid(connector, i2c); + + if (!edid && !intel_gmbus_is_forced_bit(i2c)) { + DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n"); + intel_gmbus_force_bit(i2c, true); + edid = drm_get_edid(connector, i2c); + intel_gmbus_force_bit(i2c, false); + } intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); -- cgit v1.2.3 From 8f16e7d01b5f4f149d3cd7d5bf38a3e53792acf6 Mon Sep 17 00:00:00 2001 From: "himanshu.madhani@cavium.com" Date: Mon, 12 Feb 2018 10:28:14 -0800 Subject: scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS commit 1514839b366417934e2f1328edb50ed1e8a719f5 upstream. This patch fixes NULL pointer crash due to active timer running for abort IOCB. From crash dump analysis it was discoverd that get_next_timer_interrupt() encountered a corrupted entry on the timer list. #9 [ffff95e1f6f0fd40] page_fault at ffffffff914fe8f8 [exception RIP: get_next_timer_interrupt+440] RIP: ffffffff90ea3088 RSP: ffff95e1f6f0fdf0 RFLAGS: 00010013 RAX: ffff95e1f6451028 RBX: 000218e2389e5f40 RCX: 00000001232ad600 RDX: 0000000000000001 RSI: ffff95e1f6f0fdf0 RDI: 0000000001232ad6 RBP: ffff95e1f6f0fe40 R8: ffff95e1f6451188 R9: 0000000000000001 R10: 0000000000000016 R11: 0000000000000016 R12: 00000001232ad5f6 R13: ffff95e1f6450000 R14: ffff95e1f6f0fdf8 R15: ffff95e1f6f0fe10 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 Looking at the assembly of get_next_timer_interrupt(), address came from %r8 (ffff95e1f6451188) which is pointing to list_head with single entry at ffff95e5ff621178. 0xffffffff90ea307a : mov (%r8),%rdx 0xffffffff90ea307d : cmp %r8,%rdx 0xffffffff90ea3080 : je 0xffffffff90ea30a7 0xffffffff90ea3082 : nopw 0x0(%rax,%rax,1) 0xffffffff90ea3088 : testb $0x1,0x18(%rdx) crash> rd ffff95e1f6451188 10 ffff95e1f6451188: ffff95e5ff621178 ffff95e5ff621178 x.b.....x.b..... ffff95e1f6451198: ffff95e1f6451198 ffff95e1f6451198 ..E.......E..... ffff95e1f64511a8: ffff95e1f64511a8 ffff95e1f64511a8 ..E.......E..... ffff95e1f64511b8: ffff95e77cf509a0 ffff95e77cf509a0 ...|.......|.... ffff95e1f64511c8: ffff95e1f64511c8 ffff95e1f64511c8 ..E.......E..... crash> rd ffff95e5ff621178 10 ffff95e5ff621178: 0000000000000001 ffff95e15936aa00 ..........6Y.... ffff95e5ff621188: 0000000000000000 00000000ffffffff ................ ffff95e5ff621198: 00000000000000a0 0000000000000010 ................ ffff95e5ff6211a8: ffff95e5ff621198 000000000000000c ..b............. ffff95e5ff6211b8: 00000f5800000000 ffff95e751f8d720 ....X... ..Q.... ffff95e5ff621178 belongs to freed mempool object at ffff95e5ff621080. CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE ffff95dc7fd74d00 mnt_cache 384 19785 24948 594 16k SLAB MEMORY NODE TOTAL ALLOCATED FREE ffffdc5dabfd8800 ffff95e5ff620000 1 42 29 13 FREE / [ALLOCATED] ffff95e5ff621080 (cpu 6 cache) Examining the contents of that memory reveals a pointer to a constant string in the driver, "abort\0", which is set by qla24xx_async_abort_cmd(). crash> rd ffffffffc059277c 20 ffffffffc059277c: 6e490074726f6261 0074707572726574 abort.Interrupt. ffffffffc059278c: 00676e696c6c6f50 6920726576697244 Polling.Driver i ffffffffc059279c: 646f6d207325206e 6974736554000a65 n %s mode..Testi ffffffffc05927ac: 636976656420676e 786c252074612065 ng device at %lx ffffffffc05927bc: 6b63656843000a2e 646f727020676e69 ...Checking prod ffffffffc05927cc: 6f20444920746375 0a2e706968632066 uct ID of chip.. ffffffffc05927dc: 5120646e756f4600 204130303232414c .Found QLA2200A ffffffffc05927ec: 43000a2e70696843 20676e696b636568 Chip...Checking ffffffffc05927fc: 65786f626c69616d 6c636e69000a2e73 mailboxes...incl ffffffffc059280c: 756e696c2f656475 616d2d616d642f78 ude/linux/dma-ma crash> struct -ox srb_iocb struct srb_iocb { union { struct {...} logio; struct {...} els_logo; struct {...} tmf; struct {...} fxiocb; struct {...} abt; struct ct_arg ctarg; struct {...} mbx; struct {...} nack; [0x0 ] } u; [0xb8] struct timer_list timer; [0x108] void (*timeout)(void *); } SIZE: 0x110 crash> ! bc ibase=16 obase=10 B8+40 F8 The object is a srb_t, and at offset 0xf8 within that structure (i.e. ffff95e5ff621080 + f8 -> ffff95e5ff621178) is a struct timer_list. Cc: #4.4+ Fixes: 4440e46d5db7 ("[SCSI] qla2xxx: Add IOCB Abort command asynchronous handling.") Signed-off-by: Himanshu Madhani Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 8f12f6baa6b8..4441a559f139 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -369,6 +369,7 @@ qla24xx_abort_sp_done(void *data, void *ptr, int res) srb_t *sp = (srb_t *)ptr; struct srb_iocb *abt = &sp->u.iocb_cmd; + del_timer(&sp->u.iocb_cmd.timer); complete(&abt->u.abt.comp); } -- cgit v1.2.3 From e9ca26c52280da324f5b4511ace7eb074f616920 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 16 Jan 2018 16:53:24 +0100 Subject: drm/i915: Always call to intel_display_set_init_power() in resume_early. commit d13a8479f3584613b6aacbb793eae64578b8f69a upstream. intel_power_domains_init_hw() calls set_init_power, but when using runtime power management this call is skipped. This prevents hw readout from taking place. Signed-off-by: Maarten Lankhorst Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104172 Link: https://patchwork.freedesktop.org/patch/msgid/20180116155324.75120-1-maarten.lankhorst@linux.intel.com Fixes: bc87229f323e ("drm/i915/skl: enable PC9/10 power states during suspend-to-idle") Cc: Nivedita Swaminathan Cc: Imre Deak Cc: Patrik Jakobsson Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: # v4.5+ Reviewed-by: Imre Deak (cherry picked from commit ac25dfed15d470d7f23dd817e965b54aa3f94a1e) Signed-off-by: Rodrigo Vivi Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_drv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7513e7678263..bae62cf934cf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1703,6 +1703,8 @@ static int i915_drm_resume_early(struct drm_device *dev) if (IS_BROXTON(dev_priv) || !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload)) intel_power_domains_init_hw(dev_priv, true); + else + intel_display_set_init_power(dev_priv, true); enable_rpm_wakeref_asserts(dev_priv); -- cgit v1.2.3 From d006d9047c483f1cb0963cd4794d46eb2ff3fd07 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 14 Feb 2018 06:41:25 +0100 Subject: drm: Allow determining if current task is output poll worker commit 25c058ccaf2ebbc3e250ec1e199e161f91fe27d4 upstream. Introduce a helper to determine if the current task is an output poll worker. This allows us to fix a long-standing deadlock in several DRM drivers wherein the ->runtime_suspend callback waits for the output poll worker to finish and the worker in turn calls a ->detect callback which waits for runtime suspend to finish. The ->detect callback is invoked from multiple call sites and waiting for runtime suspend to finish is the correct thing to do except if it's executing in the context of the worker. v2: Expand kerneldoc to specifically mention deadlock between output poll worker and autosuspend worker as use case. (Lyude) Cc: Dave Airlie Cc: Ben Skeggs Cc: Alex Deucher Reviewed-by: Lyude Paul Signed-off-by: Lukas Wunner Link: https://patchwork.freedesktop.org/patch/msgid/3549ce32e7f1467102e70d3e9cbf70c46bfe108e.1518593424.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_probe_helper.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 276474d13763..d7822bef1986 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -460,6 +460,26 @@ out: schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); } +/** + * drm_kms_helper_is_poll_worker - is %current task an output poll worker? + * + * Determine if %current task is an output poll worker. This can be used + * to select distinct code paths for output polling versus other contexts. + * + * One use case is to avoid a deadlock between the output poll worker and + * the autosuspend worker wherein the latter waits for polling to finish + * upon calling drm_kms_helper_poll_disable(), while the former waits for + * runtime suspend to finish upon calling pm_runtime_get_sync() in a + * connector ->detect hook. + */ +bool drm_kms_helper_is_poll_worker(void) +{ + struct work_struct *work = current_work(); + + return work && work->func == output_poll_execute; +} +EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); + /** * drm_kms_helper_poll_disable - disable output polling * @dev: drm_device -- cgit v1.2.3 From 24f82eef049e4caba0fbf6831dbc1dd255d97967 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 11 Feb 2018 10:38:28 +0100 Subject: drm/nouveau: Fix deadlock on runtime suspend commit d61a5c1063515e855bedb1b81e20e50b0ac3541e upstream. nouveau's ->runtime_suspend hook calls drm_kms_helper_poll_disable(), which waits for the output poll worker to finish if it's running. The output poll worker meanwhile calls pm_runtime_get_sync() in nouveau_connector_detect() which waits for the ongoing suspend to finish, causing a deadlock. Fix by not acquiring a runtime PM ref if nouveau_connector_detect() is called in the output poll worker's context. This is safe because the poll worker is only enabled while runtime active and we know that ->runtime_suspend waits for it to finish. Other contexts calling nouveau_connector_detect() do require a runtime PM ref, these comprise: status_store() drm sysfs interface ->fill_modes drm callback drm_fb_helper_probe_connector_modes() drm_mode_getconnector() nouveau_connector_hotplug() nouveau_display_hpd_work() nv17_tv_set_property() Stack trace for posterity: INFO: task kworker/0:1:58 blocked for more than 120 seconds. Workqueue: events output_poll_execute [drm_kms_helper] Call Trace: schedule+0x28/0x80 rpm_resume+0x107/0x6e0 __pm_runtime_resume+0x47/0x70 nouveau_connector_detect+0x7e/0x4a0 [nouveau] nouveau_connector_detect_lvds+0x132/0x180 [nouveau] drm_helper_probe_detect_ctx+0x85/0xd0 [drm_kms_helper] output_poll_execute+0x11e/0x1c0 [drm_kms_helper] process_one_work+0x184/0x380 worker_thread+0x2e/0x390 INFO: task kworker/0:2:252 blocked for more than 120 seconds. Workqueue: pm pm_runtime_work Call Trace: schedule+0x28/0x80 schedule_timeout+0x1e3/0x370 wait_for_completion+0x123/0x190 flush_work+0x142/0x1c0 nouveau_pmops_runtime_suspend+0x7e/0xd0 [nouveau] pci_pm_runtime_suspend+0x5c/0x180 vga_switcheroo_runtime_suspend+0x1e/0xa0 __rpm_callback+0xc1/0x200 rpm_callback+0x1f/0x70 rpm_suspend+0x13c/0x640 pm_runtime_work+0x6e/0x90 process_one_work+0x184/0x380 worker_thread+0x2e/0x390 Bugzilla: https://bugs.archlinux.org/task/53497 Bugzilla: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870523 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388#c33 Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)") Cc: stable@vger.kernel.org # v3.12+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker Cc: Ben Skeggs Cc: Dave Airlie Reviewed-by: Lyude Paul Signed-off-by: Lukas Wunner Link: https://patchwork.freedesktop.org/patch/msgid/b7d2cbb609a80f59ccabfdf479b9d5907c603ea1.1518338789.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nouveau_connector.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index c1084088f9e4..56c288f78d8a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -271,9 +271,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) nv_connector->edid = NULL; } - ret = pm_runtime_get_sync(connector->dev->dev); - if (ret < 0 && ret != -EACCES) - return conn_status; + /* Outputs are only polled while runtime active, so acquiring a + * runtime PM ref here is unnecessary (and would deadlock upon + * runtime suspend because it waits for polling to finish). + */ + if (!drm_kms_helper_is_poll_worker()) { + ret = pm_runtime_get_sync(connector->dev->dev); + if (ret < 0 && ret != -EACCES) + return conn_status; + } nv_encoder = nouveau_connector_ddc_detect(connector); if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { @@ -348,8 +354,10 @@ detect_analog: out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return conn_status; } -- cgit v1.2.3 From bacc51c36ebdc39013c12d02cc9090e387c768ac Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 11 Feb 2018 10:38:28 +0100 Subject: drm/radeon: Fix deadlock on runtime suspend commit 15734feff2bdac24aa3266c437cffa42851990e3 upstream. radeon's ->runtime_suspend hook calls drm_kms_helper_poll_disable(), which waits for the output poll worker to finish if it's running. The output poll worker meanwhile calls pm_runtime_get_sync() in radeon's ->detect hooks, which waits for the ongoing suspend to finish, causing a deadlock. Fix by not acquiring a runtime PM ref if the ->detect hooks are called in the output poll worker's context. This is safe because the poll worker is only enabled while runtime active and we know that ->runtime_suspend waits for it to finish. Stack trace for posterity: INFO: task kworker/0:3:31847 blocked for more than 120 seconds Workqueue: events output_poll_execute [drm_kms_helper] Call Trace: schedule+0x3c/0x90 rpm_resume+0x1e2/0x690 __pm_runtime_resume+0x3f/0x60 radeon_lvds_detect+0x39/0xf0 [radeon] output_poll_execute+0xda/0x1e0 [drm_kms_helper] process_one_work+0x14b/0x440 worker_thread+0x48/0x4a0 INFO: task kworker/2:0:10493 blocked for more than 120 seconds. Workqueue: pm pm_runtime_work Call Trace: schedule+0x3c/0x90 schedule_timeout+0x1b3/0x240 wait_for_common+0xc2/0x180 wait_for_completion+0x1d/0x20 flush_work+0xfc/0x1a0 __cancel_work_timer+0xa5/0x1d0 cancel_delayed_work_sync+0x13/0x20 drm_kms_helper_poll_disable+0x1f/0x30 [drm_kms_helper] radeon_pmops_runtime_suspend+0x3d/0xa0 [radeon] pci_pm_runtime_suspend+0x61/0x1a0 vga_switcheroo_runtime_suspend+0x21/0x70 __rpm_callback+0x32/0x70 rpm_callback+0x24/0x80 rpm_suspend+0x12b/0x640 pm_runtime_work+0x6f/0xb0 process_one_work+0x14b/0x440 worker_thread+0x48/0x4a0 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94147 Fixes: 10ebc0bc0934 ("drm/radeon: add runtime PM support (v2)") Cc: stable@vger.kernel.org # v3.13+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct Cc: stable@vger.kernel.org # v3.13+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker Cc: Ismo Toijala Cc: Alex Deucher Cc: Dave Airlie Reviewed-by: Lyude Paul Signed-off-by: Lukas Wunner Link: https://patchwork.freedesktop.org/patch/msgid/64ea02c44f91dda19bc563902b97bbc699040392.1518338789.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_connectors.c | 74 ++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 27affbde058c..af0d7fd5706b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -897,9 +897,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -922,8 +924,12 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) /* check acpi lid status ??? */ radeon_connector_update_scratch_regs(connector, ret); - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } + return ret; } @@ -1037,9 +1043,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } encoder = radeon_best_single_encoder(connector); if (!encoder) @@ -1106,8 +1114,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force) radeon_connector_update_scratch_regs(connector, ret); out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } @@ -1171,9 +1181,11 @@ radeon_tv_detect(struct drm_connector *connector, bool force) if (!radeon_connector->dac_load_detect) return ret; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } encoder = radeon_best_single_encoder(connector); if (!encoder) @@ -1185,8 +1197,12 @@ radeon_tv_detect(struct drm_connector *connector, bool force) if (ret == connector_status_connected) ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); radeon_connector_update_scratch_regs(connector, ret); - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } + return ret; } @@ -1249,9 +1265,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; bool dret = false, broken_edid = false; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (radeon_connector->detected_hpd_without_ddc) { force = true; @@ -1434,8 +1452,10 @@ out: } exit: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } @@ -1686,9 +1706,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_dig_connector->is_mst) return connector_status_disconnected; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (!force && radeon_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1775,8 +1797,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) } out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } -- cgit v1.2.3 From 3a7c3cab42a05d8a1428eb0186a8757b50e85202 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 11 Feb 2018 10:38:28 +0100 Subject: drm/amdgpu: Fix deadlock on runtime suspend commit aa0aad57909eb321746325951d66af88a83bc956 upstream. amdgpu's ->runtime_suspend hook calls drm_kms_helper_poll_disable(), which waits for the output poll worker to finish if it's running. The output poll worker meanwhile calls pm_runtime_get_sync() in amdgpu's ->detect hooks, which waits for the ongoing suspend to finish, causing a deadlock. Fix by not acquiring a runtime PM ref if the ->detect hooks are called in the output poll worker's context. This is safe because the poll worker is only enabled while runtime active and we know that ->runtime_suspend waits for it to finish. Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") Cc: stable@vger.kernel.org # v4.2+: 27d4ee03078a: workqueue: Allow retrieval of current task's work struct Cc: stable@vger.kernel.org # v4.2+: 25c058ccaf2e: drm: Allow determining if current task is output poll worker Cc: Alex Deucher Tested-by: Mike Lothian Reviewed-by: Lyude Paul Signed-off-by: Lukas Wunner Link: https://patchwork.freedesktop.org/patch/msgid/4c9bf72aacae1eef062bd134cd112e0770a7f121.1518338789.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 58 +++++++++++++++++--------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 086aa5c9c634..c82b04b24bf9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -739,9 +739,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (encoder) { struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); @@ -760,8 +762,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) /* check acpi lid status ??? */ amdgpu_connector_update_scratch_regs(connector, ret); - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } + return ret; } @@ -871,9 +877,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } encoder = amdgpu_connector_best_single_encoder(connector); if (!encoder) @@ -927,8 +935,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) amdgpu_connector_update_scratch_regs(connector, ret); out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } @@ -991,9 +1001,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; bool dret = false, broken_edid = false; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1118,8 +1130,10 @@ out: amdgpu_connector_update_scratch_regs(connector, ret); exit: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } @@ -1362,9 +1376,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); int r; - r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) - return connector_status_disconnected; + if (!drm_kms_helper_is_poll_worker()) { + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1432,8 +1448,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) amdgpu_connector_update_scratch_regs(connector, ret); out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + if (!drm_kms_helper_is_poll_worker()) { + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + } return ret; } -- cgit v1.2.3 From 5bf82a32ac88ce9dcf118159fb3743dff29f096f Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 27 Feb 2018 18:20:53 +0800 Subject: drm/amdgpu: Notify sbios device ready before send request commit 1bced75f4ab04bec55aecb57d99435dc6d0ae5a0 upstream. it is required if a platform supports PCIe root complex core voltage reduction. After receiving this notification, SBIOS can apply default PCIe root complex power policy. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 5796539a0bcb..648ecf69bad5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, size_t size; u32 retry = 3; + if (amdgpu_acpi_pcie_notify_device_ready(adev)) + return -EINVAL; + /* Get the device handle */ handle = ACPI_HANDLE(&adev->pdev->dev); if (!handle) -- cgit v1.2.3 From a32168f9ba6e5e1f02548696528530808c7cb78b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 1 Mar 2018 11:03:27 -0500 Subject: drm/radeon: fix KV harvesting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0b58d90f89545e021d188c289fa142e5ff9e708b upstream. Always set the graphics values to the max for the asic type. E.g., some 1 RB chips are actually 1 RB chips, others are actually harvested 2 RB chips. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=99353 Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/cik.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index edee6a5f4da9..b99f3e59011c 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3244,35 +3244,8 @@ static void cik_gpu_init(struct radeon_device *rdev) case CHIP_KAVERI: rdev->config.cik.max_shader_engines = 1; rdev->config.cik.max_tile_pipes = 4; - if ((rdev->pdev->device == 0x1304) || - (rdev->pdev->device == 0x1305) || - (rdev->pdev->device == 0x130C) || - (rdev->pdev->device == 0x130F) || - (rdev->pdev->device == 0x1310) || - (rdev->pdev->device == 0x1311) || - (rdev->pdev->device == 0x131C)) { - rdev->config.cik.max_cu_per_sh = 8; - rdev->config.cik.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x1309) || - (rdev->pdev->device == 0x130A) || - (rdev->pdev->device == 0x130D) || - (rdev->pdev->device == 0x1313) || - (rdev->pdev->device == 0x131D)) { - rdev->config.cik.max_cu_per_sh = 6; - rdev->config.cik.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x1306) || - (rdev->pdev->device == 0x1307) || - (rdev->pdev->device == 0x130B) || - (rdev->pdev->device == 0x130E) || - (rdev->pdev->device == 0x1315) || - (rdev->pdev->device == 0x1318) || - (rdev->pdev->device == 0x131B)) { - rdev->config.cik.max_cu_per_sh = 4; - rdev->config.cik.max_backends_per_se = 1; - } else { - rdev->config.cik.max_cu_per_sh = 3; - rdev->config.cik.max_backends_per_se = 1; - } + rdev->config.cik.max_cu_per_sh = 8; + rdev->config.cik.max_backends_per_se = 2; rdev->config.cik.max_sh_per_se = 1; rdev->config.cik.max_texture_channel_caches = 4; rdev->config.cik.max_gprs = 256; -- cgit v1.2.3 From 74d5d735a75b5d018c8275d899b023f1fab26598 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 1 Mar 2018 11:05:31 -0500 Subject: drm/amdgpu: fix KV harvesting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 545b0bcde7fbd3ee408fa842ea0731451dc4bd0a upstream. Always set the graphics values to the max for the asic type. E.g., some 1 RB chips are actually 1 RB chips, others are actually harvested 2 RB chips. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=99353 Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 71116da9e782..e040a896179c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -4475,34 +4475,8 @@ static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev) case CHIP_KAVERI: adev->gfx.config.max_shader_engines = 1; adev->gfx.config.max_tile_pipes = 4; - if ((adev->pdev->device == 0x1304) || - (adev->pdev->device == 0x1305) || - (adev->pdev->device == 0x130C) || - (adev->pdev->device == 0x130F) || - (adev->pdev->device == 0x1310) || - (adev->pdev->device == 0x1311) || - (adev->pdev->device == 0x131C)) { - adev->gfx.config.max_cu_per_sh = 8; - adev->gfx.config.max_backends_per_se = 2; - } else if ((adev->pdev->device == 0x1309) || - (adev->pdev->device == 0x130A) || - (adev->pdev->device == 0x130D) || - (adev->pdev->device == 0x1313) || - (adev->pdev->device == 0x131D)) { - adev->gfx.config.max_cu_per_sh = 6; - adev->gfx.config.max_backends_per_se = 2; - } else if ((adev->pdev->device == 0x1306) || - (adev->pdev->device == 0x1307) || - (adev->pdev->device == 0x130B) || - (adev->pdev->device == 0x130E) || - (adev->pdev->device == 0x1315) || - (adev->pdev->device == 0x131B)) { - adev->gfx.config.max_cu_per_sh = 4; - adev->gfx.config.max_backends_per_se = 1; - } else { - adev->gfx.config.max_cu_per_sh = 3; - adev->gfx.config.max_backends_per_se = 1; - } + adev->gfx.config.max_cu_per_sh = 8; + adev->gfx.config.max_backends_per_se = 2; adev->gfx.config.max_sh_per_se = 1; adev->gfx.config.max_texture_channel_caches = 4; adev->gfx.config.max_gprs = 256; -- cgit v1.2.3 From 957cfa6f9bdec9fde07d034f94a44b708e3bf09b Mon Sep 17 00:00:00 2001 From: James Zhu Date: Tue, 6 Mar 2018 14:43:50 -0500 Subject: drm/amdgpu:Correct max uvd handles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0e5ee33d2a54e4c55fe92857f23e1cbb0440d6de upstream. Max uvd handles should use adev->uvd.max_handles instead of AMDGPU_MAX_UVD_HANDLES here. Signed-off-by: James Zhu Reviewed-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index e3281cacc586..b7715d6a0252 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -277,7 +277,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) if (atomic_read(&adev->uvd.handles[i])) break; - if (i == AMDGPU_MAX_UVD_HANDLES) + if (i == adev->uvd.max_handles) return 0; cancel_delayed_work_sync(&adev->uvd.idle_work); -- cgit v1.2.3 From eea86015a5400f94ab8858e1cc7d90ea3639c447 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Tue, 6 Mar 2018 14:52:35 -0500 Subject: drm/amdgpu:Always save uvd vcpu_bo in VM Mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f8bee6135e167f5b35b7789c74c2956dad14d0d5 upstream. When UVD is in VM mode, there is not uvd handle exchanged, uvd.handles are always 0. So vcpu_bo always need save, Otherwise amdgpu driver will fail during suspend/resume. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105021 Signed-off-by: James Zhu Reviewed-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index b7715d6a0252..5caf517eec9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -273,12 +273,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) if (adev->uvd.vcpu_bo == NULL) return 0; - for (i = 0; i < adev->uvd.max_handles; ++i) - if (atomic_read(&adev->uvd.handles[i])) - break; + /* only valid for physical mode */ + if (adev->asic_type < CHIP_POLARIS10) { + for (i = 0; i < adev->uvd.max_handles; ++i) + if (atomic_read(&adev->uvd.handles[i])) + break; - if (i == adev->uvd.max_handles) - return 0; + if (i == adev->uvd.max_handles) + return 0; + } cancel_delayed_work_sync(&adev->uvd.idle_work); -- cgit v1.2.3 From 236ff4dd7cf973076ab46ff62bb6d0087d0f7ed1 Mon Sep 17 00:00:00 2001 From: Zhang Bo Date: Mon, 5 Feb 2018 14:56:21 -0800 Subject: Input: matrix_keypad - fix race when disabling interrupts commit ea4f7bd2aca9f68470e9aac0fc9432fd180b1fe7 upstream. If matrix_keypad_stop() is executing and the keypad interrupt is triggered, disable_row_irqs() may be called by both matrix_keypad_interrupt() and matrix_keypad_stop() at the same time, causing interrupts to be disabled twice and the keypad being "stuck" after resuming. Take lock when setting keypad->stopped to ensure that ISR will not race with matrix_keypad_stop() disabling interrupts. Signed-off-by: Zhang Bo Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/matrix_keypad.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 7f12b6579f82..795fa353de7c 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -216,8 +216,10 @@ static void matrix_keypad_stop(struct input_dev *dev) { struct matrix_keypad *keypad = input_get_drvdata(dev); + spin_lock_irq(&keypad->lock); keypad->stopped = true; - mb(); + spin_unlock_irq(&keypad->lock); + flush_work(&keypad->work.work); /* * matrix_keypad_scan() will leave IRQs enabled; -- cgit v1.2.3 From c0fac97933c1da286e770e1cf5d4419191401fdc Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Fri, 9 Mar 2018 08:36:36 -0700 Subject: loop: Fix lost writes caused by missing flag commit 1d037577c323e5090ce281e96bc313ab2eee5be2 upstream. The following commit: commit aa4d86163e4e ("block: loop: switch to VFS ITER_BVEC") replaced __do_lo_send_write(), which used ITER_KVEC iterators, with lo_write_bvec() which uses ITER_BVEC iterators. In this change, though, the WRITE flag was lost: - iov_iter_kvec(&from, ITER_KVEC | WRITE, &kvec, 1, len); + iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len); This flag is necessary for the DAX case because we make decisions based on whether or not the iterator is a READ or a WRITE in dax_iomap_actor() and in dax_iomap_rw(). We end up going through this path in configurations where we combine a PMEM device with 4k sectors, a loopback device and DAX. The consequence of this missed flag is that what we intend as a write actually turns into a read in the DAX code, so no data is ever written. The very simplest test case is to create a loopback device and try and write a small string to it, then hexdump a few bytes of the device to see if the write took. Without this patch you read back all zeros, with this you read back the string you wrote. For XFS this causes us to fail or panic during the following xfstests: xfs/074 xfs/078 xfs/216 xfs/217 xfs/250 For ext4 we have a similar issue where writes never happen, but we don't currently have any xfstests that use loopback and show this issue. Fix this by restoring the WRITE flag argument to iov_iter_bvec(). This causes the xfstests to all pass. Cc: Al Viro Cc: stable@vger.kernel.org Fixes: commit aa4d86163e4e ("block: loop: switch to VFS ITER_BVEC") Reviewed-by: Christoph Hellwig Reviewed-by: Ming Lei Signed-off-by: Ross Zwisler Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 402254d26247..68bfcef24701 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -263,7 +263,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) struct iov_iter i; ssize_t bw; - iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len); + iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len); file_start_write(file); bw = vfs_iter_write(file, &i, ppos); -- cgit v1.2.3 From 4c5579483bd56aab3e009c8dac047b2051947299 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Fri, 23 Feb 2018 19:41:30 +0800 Subject: virtio_ring: fix num_free handling in error case commit e82df670235138575b37ff0ec24412a471efd97f upstream. The vq->vq.num_free hasn't been changed when error happens, so it shouldn't be changed when handling the error. Fixes: 780bc7903a32 ("virtio_ring: Support DMA APIs") Cc: Andy Lutomirski Cc: Michael S. Tsirkin Cc: stable@vger.kernel.org Signed-off-by: Tiwei Bie Signed-off-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/virtio/virtio_ring.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 489bfc61cf30..8977f40ea441 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -423,8 +423,6 @@ unmap_release: i = vq->vring.desc[i].next; } - vq->vq.num_free += total_sg; - if (indirect) kfree(desc); -- cgit v1.2.3 From e749262f1dcdf70687a432df29a6d70b6b0246a7 Mon Sep 17 00:00:00 2001 From: Sergey Gorenko Date: Sun, 25 Feb 2018 13:39:48 +0200 Subject: IB/mlx5: Fix incorrect size of klms in the memory region commit da343b6d90e11132f1e917d865d88ee35d6e6d00 upstream. The value of mr->ndescs greater than mr->max_descs is set in the function mlx5_ib_sg_to_klms() if sg_nents is greater than mr->max_descs. This is an invalid value and it causes the following error when registering mr: mlx5_0:dump_cqe:276:(pid 193): dump error cqe 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000030: 00 00 00 00 0f 00 78 06 25 00 00 8b 08 1e 8f d3 Cc: # 4.5 Fixes: b005d3164713 ("mlx5: Add arbitrary sg list support") Signed-off-by: Sergey Gorenko Tested-by: Laurence Oberman Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index c7d5786d366b..7e466f031e30 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1821,7 +1821,6 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, mr->ibmr.iova = sg_dma_address(sg) + sg_offset; mr->ibmr.length = 0; - mr->ndescs = sg_nents; for_each_sg(sgl, sg, sg_nents, i) { if (unlikely(i >= mr->max_descs)) @@ -1833,6 +1832,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, sg_offset = 0; } + mr->ndescs = i; if (sg_offset_p) *sg_offset_p = sg_offset; -- cgit v1.2.3 From 35d9c9eac24fefeb01a8d74959785bd249f3aeb7 Mon Sep 17 00:00:00 2001 From: Tang Junhui Date: Mon, 5 Mar 2018 13:41:54 -0800 Subject: bcache: fix crashes in duplicate cache device register commit cc40daf91bdddbba72a4a8cd0860640e06668309 upstream. Kernel crashed when register a duplicate cache device, the call trace is bellow: [ 417.643790] CPU: 1 PID: 16886 Comm: bcache-register Tainted: G W OE 4.15.5-amd64-preempt-sysrq-20171018 #2 [ 417.643861] Hardware name: LENOVO 20ERCTO1WW/20ERCTO1WW, BIOS N1DET41W (1.15 ) 12/31/2015 [ 417.643870] RIP: 0010:bdevname+0x13/0x1e [ 417.643876] RSP: 0018:ffffa3aa9138fd38 EFLAGS: 00010282 [ 417.643884] RAX: 0000000000000000 RBX: ffff8c8f2f2f8000 RCX: ffffd6701f8 c7edf [ 417.643890] RDX: ffffa3aa9138fd88 RSI: ffffa3aa9138fd88 RDI: 00000000000 00000 [ 417.643895] RBP: ffffa3aa9138fde0 R08: ffffa3aa9138fae8 R09: 00000000000 1850e [ 417.643901] R10: ffff8c8eed34b271 R11: ffff8c8eed34b250 R12: 00000000000 00000 [ 417.643906] R13: ffffd6701f78f940 R14: ffff8c8f38f80000 R15: ffff8c8ea7d 90000 [ 417.643913] FS: 00007fde7e66f500(0000) GS:ffff8c8f61440000(0000) knlGS: 0000000000000000 [ 417.643919] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 417.643925] CR2: 0000000000000314 CR3: 00000007e6fa0001 CR4: 00000000003 606e0 [ 417.643931] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 00000000000 00000 [ 417.643938] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 00000000000 00400 [ 417.643946] Call Trace: [ 417.643978] register_bcache+0x1117/0x1270 [bcache] [ 417.643994] ? slab_pre_alloc_hook+0x15/0x3c [ 417.644001] ? slab_post_alloc_hook.isra.44+0xa/0x1a [ 417.644013] ? kernfs_fop_write+0xf6/0x138 [ 417.644020] kernfs_fop_write+0xf6/0x138 [ 417.644031] __vfs_write+0x31/0xcc [ 417.644043] ? current_kernel_time64+0x10/0x36 [ 417.644115] ? __audit_syscall_entry+0xbf/0xe3 [ 417.644124] vfs_write+0xa5/0xe2 [ 417.644133] SyS_write+0x5c/0x9f [ 417.644144] do_syscall_64+0x72/0x81 [ 417.644161] entry_SYSCALL_64_after_hwframe+0x3d/0xa2 [ 417.644169] RIP: 0033:0x7fde7e1c1974 [ 417.644175] RSP: 002b:00007fff13009a38 EFLAGS: 00000246 ORIG_RAX: 0000000 000000001 [ 417.644183] RAX: ffffffffffffffda RBX: 0000000001658280 RCX: 00007fde7e1c 1974 [ 417.644188] RDX: 000000000000000a RSI: 0000000001658280 RDI: 000000000000 0001 [ 417.644193] RBP: 000000000000000a R08: 0000000000000003 R09: 000000000000 0077 [ 417.644198] R10: 000000000000089e R11: 0000000000000246 R12: 000000000000 0001 [ 417.644203] R13: 000000000000000a R14: 7fffffffffffffff R15: 000000000000 0000 [ 417.644213] Code: c7 c2 83 6f ee 98 be 20 00 00 00 48 89 df e8 6c 27 3b 0 0 48 89 d8 5b c3 0f 1f 44 00 00 48 8b 47 70 48 89 f2 48 8b bf 80 00 00 00 <8 b> b0 14 03 00 00 e9 73 ff ff ff 0f 1f 44 00 00 48 8b 47 40 39 [ 417.644302] RIP: bdevname+0x13/0x1e RSP: ffffa3aa9138fd38 [ 417.644306] CR2: 0000000000000314 When registering duplicate cache device in register_cache(), after failure on calling register_cache_set(), bch_cache_release() will be called, then bdev will be freed, so bdevname(bdev, name) caused kernel crash. Since bch_cache_release() will free bdev, so in this patch we make sure bdev being freed if register_cache() fail, and do not free bdev again in register_bcache() when register_cache() fail. Signed-off-by: Tang Junhui Reported-by: Marc MERLIN Tested-by: Michael Lyle Reviewed-by: Michael Lyle Cc: Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/md/bcache/super.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 28ce342348a9..62f9f743c365 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1182,7 +1182,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, return; err: - pr_notice("error opening %s: %s", bdevname(bdev, name), err); + pr_notice("error %s: %s", bdevname(bdev, name), err); bcache_device_stop(&dc->disk); } @@ -1853,6 +1853,8 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, const char *err = NULL; /* must be set for any error case */ int ret = 0; + bdevname(bdev, name); + memcpy(&ca->sb, sb, sizeof(struct cache_sb)); ca->bdev = bdev; ca->bdev->bd_holder = ca; @@ -1863,11 +1865,12 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, ca->sb_bio.bi_io_vec[0].bv_page = sb_page; get_page(sb_page); - if (blk_queue_discard(bdev_get_queue(ca->bdev))) + if (blk_queue_discard(bdev_get_queue(bdev))) ca->discard = CACHE_DISCARD(&ca->sb); ret = cache_alloc(ca); if (ret != 0) { + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); if (ret == -ENOMEM) err = "cache_alloc(): -ENOMEM"; else @@ -1890,14 +1893,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, goto out; } - pr_info("registered cache device %s", bdevname(bdev, name)); + pr_info("registered cache device %s", name); out: kobject_put(&ca->kobj); err: if (err) - pr_notice("error opening %s: %s", bdevname(bdev, name), err); + pr_notice("error %s: %s", name, err); return ret; } @@ -1986,6 +1989,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, if (err) goto err_close; + err = "failed to register device"; if (SB_IS_BDEV(sb)) { struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); if (!dc) @@ -2000,7 +2004,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, goto err_close; if (register_cache(sb, sb_page, bdev, ca) != 0) - goto err_close; + goto err; } out: if (sb_page) @@ -2013,7 +2017,7 @@ out: err_close: blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); err: - pr_info("error opening %s: %s", path, err); + pr_info("error %s: %s", path, err); ret = -EINVAL; goto out; } -- cgit v1.2.3 From d4f80945828c025e43273cc094f09fb6fe353dbf Mon Sep 17 00:00:00 2001 From: Michael Lyle Date: Mon, 5 Mar 2018 13:41:55 -0800 Subject: bcache: don't attach backing with duplicate UUID commit 86755b7a96faed57f910f9e6b8061e019ac1ec08 upstream. This can happen e.g. during disk cloning. This is an incomplete fix: it does not catch duplicate UUIDs earlier when things are still unattached. It does not unregister the device. Further changes to cope better with this are planned but conflict with Coly's ongoing improvements to handling device errors. In the meantime, one can manually stop the device after this has happened. Attempts to attach a duplicate device result in: [ 136.372404] loop: module loaded [ 136.424461] bcache: register_bdev() registered backing device loop0 [ 136.424464] bcache: bch_cached_dev_attach() Tried to attach loop0 but duplicate UUID already attached My test procedure is: dd if=/dev/sdb1 of=imgfile bs=1024 count=262144 losetup -f imgfile Signed-off-by: Michael Lyle Reviewed-by: Tang Junhui Cc: Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/md/bcache/super.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 62f9f743c365..c61341c84d2d 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -937,6 +937,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) uint32_t rtime = cpu_to_le32(get_seconds()); struct uuid_entry *u; char buf[BDEVNAME_SIZE]; + struct cached_dev *exist_dc, *t; bdevname(dc->bdev, buf); @@ -960,6 +961,16 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) return -EINVAL; } + /* Check whether already attached */ + list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { + if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { + pr_err("Tried to attach %s but duplicate UUID already attached", + buf); + + return -EINVAL; + } + } + u = uuid_find(c, dc->sb.uuid); if (u && -- cgit v1.2.3 From 3f55635c749e6fce40e1d7f547398c1269edb68f Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Mon, 23 Oct 2017 16:46:16 -0600 Subject: watchdog: hpwdt: SMBIOS check commit c42cbe41727a138905a28f8e0b00c147be77ee93 upstream. This corrects: commit cce78da76601 ("watchdog: hpwdt: Add check for UEFI bits") The test on HPE SMBIOS extension type 219 record "Misc Features" bits for UEFI support is incorrect. The definition of the Misc Features bits in the HPE SMBIOS OEM Extensions specification (and related firmware) was changed to use a different pair of bits to represent UEFI supported. Howerver, a corresponding change to Linux was missed. Current code/platform work because the iCRU test is working. But purpose of cce78da766 is to ensure correct functionality on future systems where iCRU isn't supported. Signed-off-by: Jerry Hoemann Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/hpwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 70c7194e2810..fed1aed85ea6 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -700,7 +700,7 @@ static void dmi_find_icru(const struct dmi_header *dm, void *dummy) smbios_proliant_ptr = (struct smbios_proliant_info *) dm; if (smbios_proliant_ptr->misc_features & 0x01) is_icru = 1; - if (smbios_proliant_ptr->misc_features & 0x408) + if (smbios_proliant_ptr->misc_features & 0x1400) is_uefi = 1; } } -- cgit v1.2.3 From c387231337fbc4633bd7f42fca8d05e9ee5c18a8 Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Mon, 23 Oct 2017 16:46:17 -0600 Subject: watchdog: hpwdt: Check source of NMI commit 838534e50e2e5c1e644e30ab6cb28da88eb31368 upstream. Do not claim the NMI (i.e. return NMI_DONE) if the source of the NMI isn't the iLO watchdog or debug. Signed-off-by: Jerry Hoemann Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/hpwdt.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index fed1aed85ea6..9a001c14819a 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -52,6 +52,7 @@ static char expect_release; static unsigned long hpwdt_is_open; static void __iomem *pci_mem_addr; /* the PCI-memory address */ +static unsigned long __iomem *hpwdt_nmistat; static unsigned long __iomem *hpwdt_timer_reg; static unsigned long __iomem *hpwdt_timer_con; @@ -474,6 +475,11 @@ static int hpwdt_time_left(void) return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); } +static int hpwdt_my_nmi(void) +{ + return ioread8(hpwdt_nmistat) & 0x6; +} + #ifdef CONFIG_HPWDT_NMI_DECODING /* * NMI Handler @@ -486,6 +492,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) if (!hpwdt_nmi_decoding) return NMI_DONE; + if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) + return NMI_DONE; + spin_lock_irqsave(&rom_lock, rom_pl); if (!die_nmi_called && !is_icru && !is_uefi) asminline_call(&cmn_regs, cru_rom_addr); @@ -842,6 +851,7 @@ static int hpwdt_init_one(struct pci_dev *dev, retval = -ENOMEM; goto error_pci_iomap; } + hpwdt_nmistat = pci_mem_addr + 0x6e; hpwdt_timer_reg = pci_mem_addr + 0x70; hpwdt_timer_con = pci_mem_addr + 0x72; -- cgit v1.2.3 From 6cda76dc3f86d5dc6839cd894a9465a13eb91501 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Dec 2017 22:02:37 +0100 Subject: watchdog: hpwdt: fix unused variable warning commit aeebc6ba88ba3758ad95467ff6191fabf2074c13 upstream. The new hpwdt_my_nmi() function is used conditionally, which produces a harmless warning in some configurations: drivers/watchdog/hpwdt.c:478:12: error: 'hpwdt_my_nmi' defined but not used [-Werror=unused-function] This moves it inside of the #ifdef that protects its caller, to silence the warning. Fixes: 621174a92851 ("watchdog: hpwdt: Check source of NMI") Signed-off-by: Arnd Bergmann Reviewed-by: Jerry Hoemann Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/hpwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 9a001c14819a..7f6cb3a93c54 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -475,12 +475,12 @@ static int hpwdt_time_left(void) return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); } +#ifdef CONFIG_HPWDT_NMI_DECODING static int hpwdt_my_nmi(void) { return ioread8(hpwdt_nmistat) & 0x6; } -#ifdef CONFIG_HPWDT_NMI_DECODING /* * NMI Handler */ -- cgit v1.2.3 From 25d576732bc52416497734610b9324b3ceaf17ce Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Sun, 25 Feb 2018 20:22:20 -0700 Subject: watchdog: hpwdt: Remove legacy NMI sourcing. commit 2b3d89b402b085b08498e896c65267a145bed486 upstream. Gen8 and prior Proliant systems supported the "CRU" interface to firmware. This interfaces allows linux to "call back" into firmware to source the cause of an NMI. This feature isn't fully utilized as the actual source of the NMI isn't printed, the driver only indicates that the source couldn't be determined when the call fails. With the advent of Gen9, iCRU replaces the CRU. The call back feature is no longer available in firmware. To be compatible and not attempt to call back into firmware on system not supporting CRU, the SMBIOS table is consulted to determine if it is safe to make the call back or not. This results in about half of the driver code being devoted to either making CRU calls or determing if it is safe to make CRU calls. As noted, the driver isn't really using the results of the CRU calls. Furthermore, as a consequence of the Spectre security issue, the BIOS/EFI calls are being wrapped into Spectre-disabling section. Removing the call back in hpwdt_pretimeout assists in this effort. As the CRU sourcing of the NMI isn't required for handling the NMI and there are security concerns with making the call back, remove the legacy (pre Gen9) NMI sourcing and the DMI code to determine if the system had the CRU interface. Signed-off-by: Jerry Hoemann Acked-by: Ingo Molnar Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/hpwdt.c | 501 +---------------------------------------------- 1 file changed, 9 insertions(+), 492 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 7f6cb3a93c54..b0a158073abd 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -28,16 +28,7 @@ #include #include #include -#ifdef CONFIG_HPWDT_NMI_DECODING -#include -#include -#include -#include -#include -#include -#endif /* CONFIG_HPWDT_NMI_DECODING */ #include -#include #define HPWDT_VERSION "1.4.0" #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) @@ -48,6 +39,9 @@ static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; +#ifdef CONFIG_HPWDT_NMI_DECODING +static unsigned int allow_kdump = 1; +#endif static char expect_release; static unsigned long hpwdt_is_open; @@ -63,373 +57,6 @@ static const struct pci_device_id hpwdt_devices[] = { }; MODULE_DEVICE_TABLE(pci, hpwdt_devices); -#ifdef CONFIG_HPWDT_NMI_DECODING -#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ -#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 -#define PCI_BIOS32_PARAGRAPH_LEN 16 -#define PCI_ROM_BASE1 0x000F0000 -#define ROM_SIZE 0x10000 - -struct bios32_service_dir { - u32 signature; - u32 entry_point; - u8 revision; - u8 length; - u8 checksum; - u8 reserved[5]; -}; - -/* type 212 */ -struct smbios_cru64_info { - u8 type; - u8 byte_length; - u16 handle; - u32 signature; - u64 physical_address; - u32 double_length; - u32 double_offset; -}; -#define SMBIOS_CRU64_INFORMATION 212 - -/* type 219 */ -struct smbios_proliant_info { - u8 type; - u8 byte_length; - u16 handle; - u32 power_features; - u32 omega_features; - u32 reserved; - u32 misc_features; -}; -#define SMBIOS_ICRU_INFORMATION 219 - - -struct cmn_registers { - union { - struct { - u8 ral; - u8 rah; - u16 rea2; - }; - u32 reax; - } u1; - union { - struct { - u8 rbl; - u8 rbh; - u8 reb2l; - u8 reb2h; - }; - u32 rebx; - } u2; - union { - struct { - u8 rcl; - u8 rch; - u16 rec2; - }; - u32 recx; - } u3; - union { - struct { - u8 rdl; - u8 rdh; - u16 red2; - }; - u32 redx; - } u4; - - u32 resi; - u32 redi; - u16 rds; - u16 res; - u32 reflags; -} __attribute__((packed)); - -static unsigned int hpwdt_nmi_decoding; -static unsigned int allow_kdump = 1; -static unsigned int is_icru; -static unsigned int is_uefi; -static DEFINE_SPINLOCK(rom_lock); -static void *cru_rom_addr; -static struct cmn_registers cmn_regs; - -extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, - unsigned long *pRomEntry); - -#ifdef CONFIG_X86_32 -/* --32 Bit Bios------------------------------------------------------------ */ - -#define HPWDT_ARCH 32 - -asm(".text \n\t" - ".align 4 \n\t" - ".globl asminline_call \n" - "asminline_call: \n\t" - "pushl %ebp \n\t" - "movl %esp, %ebp \n\t" - "pusha \n\t" - "pushf \n\t" - "push %es \n\t" - "push %ds \n\t" - "pop %es \n\t" - "movl 8(%ebp),%eax \n\t" - "movl 4(%eax),%ebx \n\t" - "movl 8(%eax),%ecx \n\t" - "movl 12(%eax),%edx \n\t" - "movl 16(%eax),%esi \n\t" - "movl 20(%eax),%edi \n\t" - "movl (%eax),%eax \n\t" - "push %cs \n\t" - "call *12(%ebp) \n\t" - "pushf \n\t" - "pushl %eax \n\t" - "movl 8(%ebp),%eax \n\t" - "movl %ebx,4(%eax) \n\t" - "movl %ecx,8(%eax) \n\t" - "movl %edx,12(%eax) \n\t" - "movl %esi,16(%eax) \n\t" - "movl %edi,20(%eax) \n\t" - "movw %ds,24(%eax) \n\t" - "movw %es,26(%eax) \n\t" - "popl %ebx \n\t" - "movl %ebx,(%eax) \n\t" - "popl %ebx \n\t" - "movl %ebx,28(%eax) \n\t" - "pop %es \n\t" - "popf \n\t" - "popa \n\t" - "leave \n\t" - "ret \n\t" - ".previous"); - - -/* - * cru_detect - * - * Routine Description: - * This function uses the 32-bit BIOS Service Directory record to - * search for a $CRU record. - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int cru_detect(unsigned long map_entry, - unsigned long map_offset) -{ - void *bios32_map; - unsigned long *bios32_entrypoint; - unsigned long cru_physical_address; - unsigned long cru_length; - unsigned long physical_bios_base = 0; - unsigned long physical_bios_offset = 0; - int retval = -ENODEV; - - bios32_map = ioremap(map_entry, (2 * PAGE_SIZE)); - - if (bios32_map == NULL) - return -ENODEV; - - bios32_entrypoint = bios32_map + map_offset; - - cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; - - set_memory_x((unsigned long)bios32_map, 2); - asminline_call(&cmn_regs, bios32_entrypoint); - - if (cmn_regs.u1.ral != 0) { - pr_warn("Call succeeded but with an error: 0x%x\n", - cmn_regs.u1.ral); - } else { - physical_bios_base = cmn_regs.u2.rebx; - physical_bios_offset = cmn_regs.u4.redx; - cru_length = cmn_regs.u3.recx; - cru_physical_address = - physical_bios_base + physical_bios_offset; - - /* If the values look OK, then map it in. */ - if ((physical_bios_base + physical_bios_offset)) { - cru_rom_addr = - ioremap(cru_physical_address, cru_length); - if (cru_rom_addr) { - set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, - (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT); - retval = 0; - } - } - - pr_debug("CRU Base Address: 0x%lx\n", physical_bios_base); - pr_debug("CRU Offset Address: 0x%lx\n", physical_bios_offset); - pr_debug("CRU Length: 0x%lx\n", cru_length); - pr_debug("CRU Mapped Address: %p\n", &cru_rom_addr); - } - iounmap(bios32_map); - return retval; -} - -/* - * bios_checksum - */ -static int bios_checksum(const char __iomem *ptr, int len) -{ - char sum = 0; - int i; - - /* - * calculate checksum of size bytes. This should add up - * to zero if we have a valid header. - */ - for (i = 0; i < len; i++) - sum += ptr[i]; - - return ((sum == 0) && (len > 0)); -} - -/* - * bios32_present - * - * Routine Description: - * This function finds the 32-bit BIOS Service Directory - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int bios32_present(const char __iomem *p) -{ - struct bios32_service_dir *bios_32_ptr; - int length; - unsigned long map_entry, map_offset; - - bios_32_ptr = (struct bios32_service_dir *) p; - - /* - * Search for signature by checking equal to the swizzled value - * instead of calling another routine to perform a strcmp. - */ - if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) { - length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN; - if (bios_checksum(p, length)) { - /* - * According to the spec, we're looking for the - * first 4KB-aligned address below the entrypoint - * listed in the header. The Service Directory code - * is guaranteed to occupy no more than 2 4KB pages. - */ - map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1); - map_offset = bios_32_ptr->entry_point - map_entry; - - return cru_detect(map_entry, map_offset); - } - } - return -ENODEV; -} - -static int detect_cru_service(void) -{ - char __iomem *p, *q; - int rc = -1; - - /* - * Search from 0x0f0000 through 0x0fffff, inclusive. - */ - p = ioremap(PCI_ROM_BASE1, ROM_SIZE); - if (p == NULL) - return -ENOMEM; - - for (q = p; q < p + ROM_SIZE; q += 16) { - rc = bios32_present(q); - if (!rc) - break; - } - iounmap(p); - return rc; -} -/* ------------------------------------------------------------------------- */ -#endif /* CONFIG_X86_32 */ -#ifdef CONFIG_X86_64 -/* --64 Bit Bios------------------------------------------------------------ */ - -#define HPWDT_ARCH 64 - -asm(".text \n\t" - ".align 4 \n\t" - ".globl asminline_call \n\t" - ".type asminline_call, @function \n\t" - "asminline_call: \n\t" - FRAME_BEGIN - "pushq %rax \n\t" - "pushq %rbx \n\t" - "pushq %rdx \n\t" - "pushq %r12 \n\t" - "pushq %r9 \n\t" - "movq %rsi, %r12 \n\t" - "movq %rdi, %r9 \n\t" - "movl 4(%r9),%ebx \n\t" - "movl 8(%r9),%ecx \n\t" - "movl 12(%r9),%edx \n\t" - "movl 16(%r9),%esi \n\t" - "movl 20(%r9),%edi \n\t" - "movl (%r9),%eax \n\t" - "call *%r12 \n\t" - "pushfq \n\t" - "popq %r12 \n\t" - "movl %eax, (%r9) \n\t" - "movl %ebx, 4(%r9) \n\t" - "movl %ecx, 8(%r9) \n\t" - "movl %edx, 12(%r9) \n\t" - "movl %esi, 16(%r9) \n\t" - "movl %edi, 20(%r9) \n\t" - "movq %r12, %rax \n\t" - "movl %eax, 28(%r9) \n\t" - "popq %r9 \n\t" - "popq %r12 \n\t" - "popq %rdx \n\t" - "popq %rbx \n\t" - "popq %rax \n\t" - FRAME_END - "ret \n\t" - ".previous"); - -/* - * dmi_find_cru - * - * Routine Description: - * This function checks whether or not a SMBIOS/DMI record is - * the 64bit CRU info or not - */ -static void dmi_find_cru(const struct dmi_header *dm, void *dummy) -{ - struct smbios_cru64_info *smbios_cru64_ptr; - unsigned long cru_physical_address; - - if (dm->type == SMBIOS_CRU64_INFORMATION) { - smbios_cru64_ptr = (struct smbios_cru64_info *) dm; - if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) { - cru_physical_address = - smbios_cru64_ptr->physical_address + - smbios_cru64_ptr->double_offset; - cru_rom_addr = ioremap(cru_physical_address, - smbios_cru64_ptr->double_length); - set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, - smbios_cru64_ptr->double_length >> PAGE_SHIFT); - } - } -} - -static int detect_cru_service(void) -{ - cru_rom_addr = NULL; - - dmi_walk(dmi_find_cru, NULL); - - /* if cru_rom_addr has been set then we found a CRU service */ - return ((cru_rom_addr != NULL) ? 0 : -ENODEV); -} -/* ------------------------------------------------------------------------- */ -#endif /* CONFIG_X86_64 */ -#endif /* CONFIG_HPWDT_NMI_DECODING */ /* * Watchdog operations @@ -486,30 +113,12 @@ static int hpwdt_my_nmi(void) */ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) { - unsigned long rom_pl; - static int die_nmi_called; - - if (!hpwdt_nmi_decoding) - return NMI_DONE; - if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) return NMI_DONE; - spin_lock_irqsave(&rom_lock, rom_pl); - if (!die_nmi_called && !is_icru && !is_uefi) - asminline_call(&cmn_regs, cru_rom_addr); - die_nmi_called = 1; - spin_unlock_irqrestore(&rom_lock, rom_pl); - if (allow_kdump) hpwdt_stop(); - if (!is_icru && !is_uefi) { - if (cmn_regs.u1.ral == 0) { - nmi_panic(regs, "An NMI occurred, but unable to determine source.\n"); - return NMI_HANDLED; - } - } nmi_panic(regs, "An NMI occurred. Depending on your system the reason " "for the NMI is logged in any one of the following " "resources:\n" @@ -675,84 +284,11 @@ static struct miscdevice hpwdt_miscdev = { * Init & Exit */ -#ifdef CONFIG_HPWDT_NMI_DECODING -#ifdef CONFIG_X86_LOCAL_APIC -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) -{ - /* - * If nmi_watchdog is turned off then we can turn on - * our nmi decoding capability. - */ - hpwdt_nmi_decoding = 1; -} -#else -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) -{ - dev_warn(&dev->dev, "NMI decoding is disabled. " - "Your kernel does not support a NMI Watchdog.\n"); -} -#endif /* CONFIG_X86_LOCAL_APIC */ - -/* - * dmi_find_icru - * - * Routine Description: - * This function checks whether or not we are on an iCRU-based server. - * This check is independent of architecture and needs to be made for - * any ProLiant system. - */ -static void dmi_find_icru(const struct dmi_header *dm, void *dummy) -{ - struct smbios_proliant_info *smbios_proliant_ptr; - - if (dm->type == SMBIOS_ICRU_INFORMATION) { - smbios_proliant_ptr = (struct smbios_proliant_info *) dm; - if (smbios_proliant_ptr->misc_features & 0x01) - is_icru = 1; - if (smbios_proliant_ptr->misc_features & 0x1400) - is_uefi = 1; - } -} static int hpwdt_init_nmi_decoding(struct pci_dev *dev) { +#ifdef CONFIG_HPWDT_NMI_DECODING int retval; - - /* - * On typical CRU-based systems we need to map that service in - * the BIOS. For 32 bit Operating Systems we need to go through - * the 32 Bit BIOS Service Directory. For 64 bit Operating - * Systems we get that service through SMBIOS. - * - * On systems that support the new iCRU service all we need to - * do is call dmi_walk to get the supported flag value and skip - * the old cru detect code. - */ - dmi_walk(dmi_find_icru, NULL); - if (!is_icru && !is_uefi) { - - /* - * We need to map the ROM to get the CRU service. - * For 32 bit Operating Systems we need to go through the 32 Bit - * BIOS Service Directory - * For 64 bit Operating Systems we get that service through SMBIOS. - */ - retval = detect_cru_service(); - if (retval < 0) { - dev_warn(&dev->dev, - "Unable to detect the %d Bit CRU Service.\n", - HPWDT_ARCH); - return retval; - } - - /* - * We know this is the only CRU call we need to make so lets keep as - * few instructions as possible once the NMI comes in. - */ - cmn_regs.u1.rah = 0x0D; - cmn_regs.u1.ral = 0x02; - } - /* * Only one function can register for NMI_UNKNOWN */ @@ -780,44 +316,25 @@ error: dev_warn(&dev->dev, "Unable to register a die notifier (err=%d).\n", retval); - if (cru_rom_addr) - iounmap(cru_rom_addr); return retval; +#endif /* CONFIG_HPWDT_NMI_DECODING */ + return 0; } static void hpwdt_exit_nmi_decoding(void) { +#ifdef CONFIG_HPWDT_NMI_DECODING unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); unregister_nmi_handler(NMI_SERR, "hpwdt"); unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); - if (cru_rom_addr) - iounmap(cru_rom_addr); -} -#else /* !CONFIG_HPWDT_NMI_DECODING */ -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) -{ -} - -static int hpwdt_init_nmi_decoding(struct pci_dev *dev) -{ - return 0; +#endif } -static void hpwdt_exit_nmi_decoding(void) -{ -} -#endif /* CONFIG_HPWDT_NMI_DECODING */ - static int hpwdt_init_one(struct pci_dev *dev, const struct pci_device_id *ent) { int retval; - /* - * Check if we can do NMI decoding or not - */ - hpwdt_check_nmi_decoding(dev); - /* * First let's find out if we are on an iLO2+ server. We will * not run on a legacy ASM box. @@ -922,6 +439,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" #ifdef CONFIG_HPWDT_NMI_DECODING module_param(allow_kdump, int, 0); MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); -#endif /* !CONFIG_HPWDT_NMI_DECODING */ +#endif /* CONFIG_HPWDT_NMI_DECODING */ module_pci_driver(hpwdt_driver); -- cgit v1.2.3 From c9763bfc7d27dca13d4b6ac93207b98cbd46dda8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 13 Feb 2017 15:45:59 -0800 Subject: Input: tca8418_keypad - remove double read of key event register commit 9dd46c02532a6bed6240101ecf4bbc407f8c6adf upstream. There is no need to tread the same register twice in a row. Fixes: ea4348c8462a ("Input: tca8418_keypad - hide gcc-4.9 -Wmaybe-un ...") Signed-off-by: Dmitry Torokhov Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/tca8418_keypad.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 3048ef3e3e16..a5e8998047fe 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -189,8 +189,6 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keymap[code], state); - /* Read for next loop */ - error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); } while (1); input_sync(input); -- cgit v1.2.3 From b323768e610b3108bd8ad48329f420d91e7b336b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 4 May 2017 12:20:17 -0300 Subject: tc358743: fix register i2c_rd/wr function fix commit f2c61f98e0b5f8b53b8fb860e5dcdd661bde7d0b upstream. The below mentioned fix contains a small but severe bug, fix it to make the driver work again. Fixes: 3538aa6ecfb2 ("[media] tc358743: fix register i2c_rd/wr functions") Cc: Hans Verkuil Cc: Mauro Carvalho Chehab Signed-off-by: Philipp Zabel Acked-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/tc358743.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 26d999c812c9..0f572bff64f5 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -222,7 +222,7 @@ static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val) static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg, u8 mask, u8 val) { - i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2); + i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 1) & mask) | val, 1); } static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) -- cgit v1.2.3 From cde0b3af90c7edc198956a45a66e5fc92bd04b6c Mon Sep 17 00:00:00 2001 From: Clay McClure Date: Thu, 21 Sep 2017 19:01:34 -0700 Subject: ubi: Fix race condition between ubi volume creation and udev commit a51a0c8d213594bc094cb8e54aad0cb6d7f7b9a6 upstream. Similar to commit 714fb87e8bc0 ("ubi: Fix race condition between ubi device creation and udev"), we should make the volume active before registering it. Signed-off-by: Clay McClure Cc: Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/vmt.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 7ac78c13dd1c..1bcb25bc35ef 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -265,6 +265,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) vol->last_eb_bytes = vol->usable_leb_size; } + /* Make volume "available" before it becomes accessible via sysfs */ + spin_lock(&ubi->volumes_lock); + ubi->volumes[vol_id] = vol; + ubi->vol_count += 1; + spin_unlock(&ubi->volumes_lock); + /* Register character device for the volume */ cdev_init(&vol->cdev, &ubi_vol_cdev_operations); vol->cdev.owner = THIS_MODULE; @@ -304,11 +310,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (err) goto out_sysfs; - spin_lock(&ubi->volumes_lock); - ubi->volumes[vol_id] = vol; - ubi->vol_count += 1; - spin_unlock(&ubi->volumes_lock); - ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED); self_check_volumes(ubi); return err; @@ -328,6 +329,10 @@ out_sysfs: out_cdev: cdev_del(&vol->cdev); out_mapping: + spin_lock(&ubi->volumes_lock); + ubi->volumes[vol_id] = NULL; + ubi->vol_count -= 1; + spin_unlock(&ubi->volumes_lock); if (do_free) ubi_eba_destroy_table(eba_tbl); out_acc: -- cgit v1.2.3 From 05d42c517250653f53e296e3d59d0b0db1a87296 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 4 Dec 2017 14:45:10 -0800 Subject: scsi: qla2xxx: Replace fcport alloc with qla2x00_alloc_fcport commit 063b36d6b0ad74c748d536f5cb47bac2f850a0fa upstream. Current code manually allocate an fcport structure that is not properly initialize. Replace kzalloc with qla2x00_alloc_fcport, so that all fields are initialized. Also set set scan flag to port found Cc: Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 59059ffbb98c..11f45cb99892 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -5789,7 +5789,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, fc_port_t *fcport; int rc; - fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); + fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); if (!fcport) { ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f, "qla_target(%d): Allocation of tmp FC port failed", -- cgit v1.2.3 From 4afade73b70a47b17718133d0421c03b6ec8d10b Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 15 Feb 2018 13:02:27 +0100 Subject: serial: sh-sci: prevent lockup on full TTY buffers commit 7842055bfce4bf0170d0f61df8b2add8399697be upstream. When the TTY buffers fill up to the configured maximum, a system lockup occurs: [ 598.820128] INFO: rcu_preempt detected stalls on CPUs/tasks: [ 598.825796] 0-...!: (1 GPs behind) idle=5a6/2/0 softirq=1974/1974 fqs=1 [ 598.832577] (detected by 3, t=62517 jiffies, g=296, c=295, q=126) [ 598.838755] Task dump for CPU 0: [ 598.841977] swapper/0 R running task 0 0 0 0x00000022 [ 598.849023] Call trace: [ 598.851476] __switch_to+0x98/0xb0 [ 598.854870] (null) This can be prevented by doing a dummy read of the RX data register. This issue affects both HSCIF and SCIF ports. Reported for R-Car H3 ES2.0; reproduced and fixed on H3 ES1.1. Probably affects other R-Car platforms as well. Reported-by: Yoshihiro Shimoda Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Cc: stable Tested-by: Nguyen Viet Dung Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 15eaea53b3df..a55c94dfefd2 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -935,6 +935,8 @@ static void sci_receive_chars(struct uart_port *port) /* Tell the rest of the system the news. New characters! */ tty_flip_buffer_push(tport); } else { + /* TTY buffers full; read from RX reg to prevent lockup */ + serial_port_in(port, SCxRDR); serial_port_in(port, SCxSR); /* dummy read */ sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); } -- cgit v1.2.3 From 85afaf5e2e7c354a60d06ad6ffbd10f5d28bf0e9 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Mon, 29 Jan 2018 12:39:15 +0100 Subject: tty/serial: atmel: add new version check for usart commit fd63a8903a2c40425a9811c3371dd4d0f42c0ad3 upstream. On our at91sam9260 based board the usart0 and usart1 ports report their versions (ATMEL_US_VERSION) as 0x10302. This version is not included in the current checks in the driver. Signed-off-by: Jonas Danielsson Acked-by: Richard Genoud Acked-by: Nicolas Ferre Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4d079cdaa7a3..addb287cacea 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1780,6 +1780,7 @@ static void atmel_get_ip_name(struct uart_port *port) switch (version) { case 0x302: case 0x10213: + case 0x10302: dev_dbg(port->dev, "This version is usart\n"); atmel_port->has_frac_baudrate = true; atmel_port->has_hw_timer = true; -- cgit v1.2.3 From 438fd54e0527633facedaf195db2755cca28bffd Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 6 Mar 2018 15:04:24 +0100 Subject: uas: fix comparison for error code commit 9a513c905bb95bef79d96feb08621c1ec8d8c4bb upstream. A typo broke the comparison. Fixes: cbeef22fd611 ("usb: uas: unconditionally bring back host after reset") Signed-off-by: Oliver Neukum CC: stable@kernel.org Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 6891e9092775..a96dcc660d0f 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -1076,7 +1076,7 @@ static int uas_post_reset(struct usb_interface *intf) return 0; err = uas_configure_endpoints(devinfo); - if (err && err != ENODEV) + if (err && err != -ENODEV) shost_printk(KERN_ERR, shost, "%s: alloc streams error %d after reset", __func__, err); -- cgit v1.2.3 From 137cb4fd3f57dc39666c68f0e0b948ac83480201 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Thu, 15 Feb 2018 15:13:42 -0500 Subject: staging: comedi: fix comedi_nsamples_left. commit a42ae5905140c324362fe5036ae1dbb16e4d359c upstream. A rounding error was causing comedi_nsamples_left to return the wrong value when nsamples was not a multiple of the scan length. Cc: # v4.4+ Signed-off-by: Frank Mori Hess Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index a5bf2cc165c0..1736248bc5b8 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -484,8 +484,7 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s, struct comedi_cmd *cmd = &async->cmd; if (cmd->stop_src == TRIG_COUNT) { - unsigned int nscans = nsamples / cmd->scan_end_arg; - unsigned int scans_left = __comedi_nscans_left(s, nscans); + unsigned int scans_left = __comedi_nscans_left(s, cmd->stop_arg); unsigned int scan_pos = comedi_bytes_to_samples(s, async->scan_progress); unsigned long long samples_left = 0; -- cgit v1.2.3 From 1d47c874cd72dec1fabff5ecdb766d364467ff56 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Fri, 16 Feb 2018 11:02:01 -0800 Subject: staging: android: ashmem: Fix lockdep issue during llseek commit cb57469c9573f6018cd1302953dd45d6e05aba7b upstream. ashmem_mutex create a chain of dependencies like so: (1) mmap syscall -> mmap_sem -> (acquired) ashmem_mmap ashmem_mutex (try to acquire) (block) (2) llseek syscall -> ashmem_llseek -> ashmem_mutex -> (acquired) inode_lock -> inode->i_rwsem (try to acquire) (block) (3) getdents -> iterate_dir -> inode_lock -> inode->i_rwsem (acquired) copy_to_user -> mmap_sem (try to acquire) There is a lock ordering created between mmap_sem and inode->i_rwsem causing a lockdep splat [2] during a syzcaller test, this patch fixes the issue by unlocking the mutex earlier. Functionally that's Ok since we don't need to protect vfs_llseek. [1] https://patchwork.kernel.org/patch/10185031/ [2] https://lkml.org/lkml/2018/1/10/48 Acked-by: Todd Kjos Cc: Arve Hjonnevag Cc: stable@vger.kernel.org Reported-by: syzbot+8ec30bb7bf1a981a2012@syzkaller.appspotmail.com Signed-off-by: Joel Fernandes Acked-by: Greg Hackmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index d08324998933..db100154f85c 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -343,24 +343,23 @@ static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin) mutex_lock(&ashmem_mutex); if (asma->size == 0) { - ret = -EINVAL; - goto out; + mutex_unlock(&ashmem_mutex); + return -EINVAL; } if (!asma->file) { - ret = -EBADF; - goto out; + mutex_unlock(&ashmem_mutex); + return -EBADF; } + mutex_unlock(&ashmem_mutex); + ret = vfs_llseek(asma->file, offset, origin); if (ret < 0) - goto out; + return ret; /** Copy f_pos from backing file, since f_ops->llseek() sets it */ file->f_pos = asma->file->f_pos; - -out: - mutex_unlock(&ashmem_mutex); return ret; } -- cgit v1.2.3 From 3fad4ea9283da98cd02d7b30e7a5e96e0a414ae1 Mon Sep 17 00:00:00 2001 From: Teijo Kinnunen Date: Thu, 1 Mar 2018 19:34:29 +0200 Subject: USB: storage: Add JMicron bridge 152d:2567 to unusual_devs.h commit 5126a504b63d82785eaece3a9c30c660b313785a upstream. This USB-SATA controller seems to be similar with JMicron bridge 152d:2566 already on the list. Adding it here fixes "Invalid field in cdb" errors. Signed-off-by: Teijo Kinnunen Cc: stable@vger.kernel.org Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b605115eb47a..ca3a5d430ae1 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -2137,6 +2137,13 @@ UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BROKEN_FUA ), +/* Reported by Teijo Kinnunen */ +UNUSUAL_DEV( 0x152d, 0x2567, 0x0117, 0x0117, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + /* Reported-by George Cherian */ UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999, "JMicron", -- cgit v1.2.3 From b7661e9af851da7f5cba97749591080f78dacbca Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 22 Feb 2018 17:39:17 +0000 Subject: usbip: vudc: fix null pointer dereference on udc->lock commit df3334c223a033f562645712e832ca4cbb326bbf upstream. Currently the driver attempts to spin lock on udc->lock before a NULL pointer check is performed on udc, hence there is a potential null pointer dereference on udc->lock. Fix this by moving the null check on udc before the lock occurs. Fixes: ea6873a45a22 ("usbip: vudc: Add SysFS infrastructure for VUDC") Signed-off-by: Colin Ian King Acked-by: Shuah Khan Reviewed-by: Krzysztof Opasiak Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vudc_sysfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c index 0f98f2c7475f..7efa374a4970 100644 --- a/drivers/usb/usbip/vudc_sysfs.c +++ b/drivers/usb/usbip/vudc_sysfs.c @@ -117,10 +117,14 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, if (rv != 0) return -EINVAL; + if (!udc) { + dev_err(dev, "no device"); + return -ENODEV; + } spin_lock_irqsave(&udc->lock, flags); /* Don't export what we don't have */ - if (!udc || !udc->driver || !udc->pullup) { - dev_err(dev, "no device or gadget not bound"); + if (!udc->driver || !udc->pullup) { + dev_err(dev, "gadget not bound"); ret = -ENODEV; goto unlock; } -- cgit v1.2.3 From b2708e1e30e02ef4170266d20d90774cce4419e8 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Tue, 6 Mar 2018 09:38:49 +0100 Subject: usb: quirks: add control message delay for 1b1c:1b20 commit cb88a0588717ba6c756cb5972d75766b273a6817 upstream. Corsair Strafe RGB keyboard does not respond to usb control messages sometimes and hence generates timeouts. Commit de3af5bf259d ("usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard") tried to fix those timeouts by adding USB_QUIRK_DELAY_INIT. Unfortunately, even with this quirk timeouts of usb_control_msg() can still be seen, but with a lower frequency (approx. 1 out of 15): [ 29.103520] usb 1-8: string descriptor 0 read error: -110 [ 34.363097] usb 1-8: can't set config #1, error -110 Adding further delays to different locations where usb control messages are issued just moves the timeouts to other locations, e.g.: [ 35.400533] usbhid 1-8:1.0: can't add hid device: -110 [ 35.401014] usbhid: probe of 1-8:1.0 failed with error -110 The only way to reliably avoid those issues is having a pause after each usb control message. In approx. 200 boot cycles no more timeouts were seen. Addionaly, keep USB_QUIRK_DELAY_INIT as it turned out to be necessary to have the delay in hub_port_connect() after hub_port_init(). The overall boot time seems not to be influenced by these additional delays, even on fast machines and lightweight distributions. Fixes: de3af5bf259d ("usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard") Cc: stable@vger.kernel.org Signed-off-by: Danilo Krummrich Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 4 ++++ drivers/usb/core/quirks.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 4c388451f31f..9cb66475c211 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -148,6 +148,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); + /* Linger a bit, prior to the next control message. */ + if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) + msleep(200); + kfree(dr); return ret; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 774c97bb1c08..4f1c6f8d4352 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -229,7 +229,8 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, /* Corsair Strafe RGB */ - { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT | + USB_QUIRK_DELAY_CTRL_MSG }, /* Corsair K70 LUX */ { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, -- cgit v1.2.3 From 63f3bac3bedcf415d789ff3ae8fb1361e4ab104e Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Fri, 9 Mar 2018 00:21:14 -0600 Subject: usb: usbmon: Read text within supplied buffer size commit a5f596830e27e15f7a0ecd6be55e433d776986d8 upstream. This change fixes buffer overflows and silent data corruption with the usbmon device driver text file read operations. Signed-off-by: Fredrik Noring Signed-off-by: Pete Zaitcev Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_text.c | 126 ++++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index e59334b09c41..f8ac59e0158d 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -83,6 +83,8 @@ struct mon_reader_text { wait_queue_head_t wait; int printf_size; + size_t printf_offset; + size_t printf_togo; char *printf_buf; struct mutex printf_lock; @@ -374,75 +376,103 @@ err_alloc: return rc; } -/* - * For simplicity, we read one record in one system call and throw out - * what does not fit. This means that the following does not work: - * dd if=/dbg/usbmon/0t bs=10 - * Also, we do not allow seeks and do not bother advancing the offset. - */ +static ssize_t mon_text_copy_to_user(struct mon_reader_text *rp, + char __user * const buf, const size_t nbytes) +{ + const size_t togo = min(nbytes, rp->printf_togo); + + if (copy_to_user(buf, &rp->printf_buf[rp->printf_offset], togo)) + return -EFAULT; + rp->printf_togo -= togo; + rp->printf_offset += togo; + return togo; +} + +/* ppos is not advanced since the llseek operation is not permitted. */ static ssize_t mon_text_read_t(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) + size_t nbytes, loff_t *ppos) { struct mon_reader_text *rp = file->private_data; struct mon_event_text *ep; struct mon_text_ptr ptr; + ssize_t ret; - ep = mon_text_read_wait(rp, file); - if (IS_ERR(ep)) - return PTR_ERR(ep); mutex_lock(&rp->printf_lock); - ptr.cnt = 0; - ptr.pbuf = rp->printf_buf; - ptr.limit = rp->printf_size; - - mon_text_read_head_t(rp, &ptr, ep); - mon_text_read_statset(rp, &ptr, ep); - ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, - " %d", ep->length); - mon_text_read_data(rp, &ptr, ep); - - if (copy_to_user(buf, rp->printf_buf, ptr.cnt)) - ptr.cnt = -EFAULT; + + if (rp->printf_togo == 0) { + + ep = mon_text_read_wait(rp, file); + if (IS_ERR(ep)) { + mutex_unlock(&rp->printf_lock); + return PTR_ERR(ep); + } + ptr.cnt = 0; + ptr.pbuf = rp->printf_buf; + ptr.limit = rp->printf_size; + + mon_text_read_head_t(rp, &ptr, ep); + mon_text_read_statset(rp, &ptr, ep); + ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, + " %d", ep->length); + mon_text_read_data(rp, &ptr, ep); + + rp->printf_togo = ptr.cnt; + rp->printf_offset = 0; + + kmem_cache_free(rp->e_slab, ep); + } + + ret = mon_text_copy_to_user(rp, buf, nbytes); mutex_unlock(&rp->printf_lock); - kmem_cache_free(rp->e_slab, ep); - return ptr.cnt; + return ret; } +/* ppos is not advanced since the llseek operation is not permitted. */ static ssize_t mon_text_read_u(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) + size_t nbytes, loff_t *ppos) { struct mon_reader_text *rp = file->private_data; struct mon_event_text *ep; struct mon_text_ptr ptr; + ssize_t ret; - ep = mon_text_read_wait(rp, file); - if (IS_ERR(ep)) - return PTR_ERR(ep); mutex_lock(&rp->printf_lock); - ptr.cnt = 0; - ptr.pbuf = rp->printf_buf; - ptr.limit = rp->printf_size; - mon_text_read_head_u(rp, &ptr, ep); - if (ep->type == 'E') { - mon_text_read_statset(rp, &ptr, ep); - } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { - mon_text_read_isostat(rp, &ptr, ep); - mon_text_read_isodesc(rp, &ptr, ep); - } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) { - mon_text_read_intstat(rp, &ptr, ep); - } else { - mon_text_read_statset(rp, &ptr, ep); + if (rp->printf_togo == 0) { + + ep = mon_text_read_wait(rp, file); + if (IS_ERR(ep)) { + mutex_unlock(&rp->printf_lock); + return PTR_ERR(ep); + } + ptr.cnt = 0; + ptr.pbuf = rp->printf_buf; + ptr.limit = rp->printf_size; + + mon_text_read_head_u(rp, &ptr, ep); + if (ep->type == 'E') { + mon_text_read_statset(rp, &ptr, ep); + } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { + mon_text_read_isostat(rp, &ptr, ep); + mon_text_read_isodesc(rp, &ptr, ep); + } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) { + mon_text_read_intstat(rp, &ptr, ep); + } else { + mon_text_read_statset(rp, &ptr, ep); + } + ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, + " %d", ep->length); + mon_text_read_data(rp, &ptr, ep); + + rp->printf_togo = ptr.cnt; + rp->printf_offset = 0; + + kmem_cache_free(rp->e_slab, ep); } - ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, - " %d", ep->length); - mon_text_read_data(rp, &ptr, ep); - if (copy_to_user(buf, rp->printf_buf, ptr.cnt)) - ptr.cnt = -EFAULT; + ret = mon_text_copy_to_user(rp, buf, nbytes); mutex_unlock(&rp->printf_lock); - kmem_cache_free(rp->e_slab, ep); - return ptr.cnt; + return ret; } static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp, -- cgit v1.2.3 From dddf4650cf649d741a83d6cac148718171ab60d6 Mon Sep 17 00:00:00 2001 From: Xinyong Date: Fri, 2 Mar 2018 19:20:07 +0800 Subject: usb: gadget: f_fs: Fix use-after-free in ffs_fs_kill_sb() commit 1a087f032111a88e826877449dfb93ceb22b78b9 upstream. When I debug a kernel crash issue in funcitonfs, found ffs_data.ref overflowed, While functionfs is unmounting, ffs_data is put twice. Commit 43938613c6fd ("drivers, usb: convert ffs_data.ref from atomic_t to refcount_t") can avoid refcount overflow, but that is risk some situations. So no need put ffs data in ffs_fs_kill_sb, already put in ffs_data_closed. The issue can be reproduced in Mediatek mt6763 SoC, ffs for ADB device. KASAN enabled configuration reports use-after-free errro. BUG: KASAN: use-after-free in refcount_dec_and_test+0x14/0xe0 at addr ffffffc0579386a0 Read of size 4 by task umount/4650 ==================================================== BUG kmalloc-512 (Tainted: P W O ): kasan: bad access detected ----------------------------------------------------------------------------- INFO: Allocated in ffs_fs_mount+0x194/0x844 age=22856 cpu=2 pid=566 alloc_debug_processing+0x1ac/0x1e8 ___slab_alloc.constprop.63+0x640/0x648 __slab_alloc.isra.57.constprop.62+0x24/0x34 kmem_cache_alloc_trace+0x1a8/0x2bc ffs_fs_mount+0x194/0x844 mount_fs+0x6c/0x1d0 vfs_kern_mount+0x50/0x1b4 do_mount+0x258/0x1034 INFO: Freed in ffs_data_put+0x25c/0x320 age=0 cpu=3 pid=4650 free_debug_processing+0x22c/0x434 __slab_free+0x2d8/0x3a0 kfree+0x254/0x264 ffs_data_put+0x25c/0x320 ffs_data_closed+0x124/0x15c ffs_fs_kill_sb+0xb8/0x110 deactivate_locked_super+0x6c/0x98 deactivate_super+0xb0/0xbc INFO: Object 0xffffffc057938600 @offset=1536 fp=0x (null) ...... Call trace: [] dump_backtrace+0x0/0x250 [] show_stack+0x14/0x1c [] dump_stack+0xa0/0xc8 [] print_trailer+0x158/0x260 [] object_err+0x3c/0x40 [] kasan_report_error+0x2a8/0x754 [] kasan_report+0x5c/0x60 [] __asan_load4+0x70/0x88 [] refcount_dec_and_test+0x14/0xe0 [] ffs_data_put+0x80/0x320 [] ffs_fs_kill_sb+0xc8/0x110 [] deactivate_locked_super+0x6c/0x98 [] deactivate_super+0xb0/0xbc [] cleanup_mnt+0x64/0xec [] __cleanup_mnt+0x10/0x18 [] task_work_run+0xcc/0x124 [] do_notify_resume+0x60/0x70 [] work_pending+0x10/0x14 Cc: stable@vger.kernel.org Signed-off-by: Xinyong Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_fs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 48f52138bb1a..071346973dd6 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1522,7 +1522,6 @@ ffs_fs_kill_sb(struct super_block *sb) if (sb->s_fs_info) { ffs_release_dev(sb->s_fs_info); ffs_data_closed(sb->s_fs_info); - ffs_data_put(sb->s_fs_info); } } -- cgit v1.2.3 From 46d16d6e758b3ff34ad8641e1b4e736ffd9a44ac Mon Sep 17 00:00:00 2001 From: Nikola Ciprich Date: Tue, 13 Feb 2018 15:04:46 +0100 Subject: serial: 8250_pci: Add Brainboxes UC-260 4 port serial device commit 9f2068f35729948bde84d87a40d135015911345d upstream. Add PCI ids for two variants of Brainboxes UC-260 quad port PCI serial cards. Suggested-by: Andy Shevchenko Signed-off-by: Nikola Ciprich Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index b80ea872b039..e82b3473b6b8 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5099,6 +5099,17 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ pbn_b2_4_115200 }, + /* + * BrainBoxes UC-260 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D21, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, + pbn_b2_4_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0E34, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, + pbn_b2_4_115200 }, /* * Perle PCI-RAS cards */ -- cgit v1.2.3 From fbe1ad9742d3e20e403fa09083d815e20fbf0e9b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sat, 3 Feb 2018 12:27:23 +0100 Subject: serial: core: mark port as initialized in autoconfig commit 714569064adee3c114a2a6490735b94abe269068 upstream. This is a followup on 44117a1d1732 ("serial: core: mark port as initialized after successful IRQ change"). Nikola has been using autoconfig via setserial and reported a crash similar to what I fixed in the earlier mentioned commit. Here I do the same fixup for the autoconfig. I wasn't sure that this is the right approach. Nikola confirmed that it fixes his crash. Fixes: b3b576461864 ("tty: serial_core: convert uart_open to use tty_port_open") Link: http://lkml.kernel.org/r/20180131072000.GD1853@localhost.localdomain Reported-by: Nikola Ciprich Tested-by: Nikola Ciprich Cc: Signed-off-by: Sebastian Andrzej Siewior Tested-by: Nikola Ciprich Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 23973a8124fc..6cbd46c565f8 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1135,6 +1135,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) uport->ops->config_port(uport, flags); ret = uart_startup(tty, state, 1); + if (ret == 0) + tty_port_set_initialized(port, true); if (ret > 0) ret = 0; } -- cgit v1.2.3 From bd0d673023edfeaedf57b68e39e7795cdcee4e45 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Tue, 13 Feb 2018 17:09:08 +0800 Subject: earlycon: add reg-offset to physical address before mapping commit 1f66dd36bb18437397ea0d7882c52f7e3c476e15 upstream. It will get the wrong virtual address because port->mapbase is not added the correct reg-offset yet. We have to update it before earlycon_map() is called Signed-off-by: Greentime Hu Acked-by: Arnd Bergmann Cc: Peter Hurley Cc: stable@vger.kernel.org Fixes: 088da2a17619 ("of: earlycon: Initialize port fields from DT properties") Acked-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/earlycon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index c3651540e1ba..3b31fd8863eb 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -253,11 +253,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match, } port->mapbase = addr; port->uartclk = BASE_BAUD * 16; - port->membase = earlycon_map(port->mapbase, SZ_4K); val = of_get_flat_dt_prop(node, "reg-offset", NULL); if (val) port->mapbase += be32_to_cpu(*val); + port->membase = earlycon_map(port->mapbase, SZ_4K); + val = of_get_flat_dt_prop(node, "reg-shift", NULL); if (val) port->regshift = be32_to_cpu(*val); -- cgit v1.2.3 From 0e2bc507f242e10c544243b53d8613133cd741d9 Mon Sep 17 00:00:00 2001 From: Koen Vandeputte Date: Wed, 7 Mar 2018 10:46:39 -0600 Subject: PCI: dwc: Fix enumeration end when reaching root subordinate commit fc110ebdd014dd1368c98e7685b47789c31fab42 upstream. The subordinate value indicates the highest bus number which can be reached downstream though a certain device. Commit a20c7f36bd3d ("PCI: Do not allocate more buses than available in parent") ensures that downstream devices cannot assign busnumbers higher than the upstream device subordinate number, which was indeed illogical. By default, dw_pcie_setup_rc() inits the Root Complex subordinate to a value of 0x01. Due to this combined with above commit, enumeration stops digging deeper downstream as soon as bus num 0x01 has been assigned, which is always the case for a bridge device. This results in all devices behind a bridge bus remaining undetected, as these would be connected to bus 0x02 or higher. Fix this by initializing the RC to a subordinate value of 0xff, which is not altering hardware behaviour in any way, but informs probing function pci_scan_bridge() later on which reads this value back from register. The following nasty errors during boot are also fixed by this: pci_bus 0000:02: busn_res: can not insert [bus 02-ff] under [bus 01] (conflicts with (null) [bus 01]) ... pci_bus 0000:03: [bus 03] partially hidden behind bridge 0000:01 [bus 01] ... pci_bus 0000:04: [bus 04] partially hidden behind bridge 0000:01 [bus 01] ... pci_bus 0000:05: [bus 05] partially hidden behind bridge 0000:01 [bus 01] pci_bus 0000:02: busn_res: [bus 02-ff] end is updated to 05 pci_bus 0000:02: busn_res: can not insert [bus 02-05] under [bus 01] (conflicts with (null) [bus 01]) pci_bus 0000:02: [bus 02-05] partially hidden behind bridge 0000:01 [bus 01] Fixes: a20c7f36bd3d ("PCI: Do not allocate more buses than available in parent") Tested-by: Niklas Cassel Tested-by: Fabio Estevam Tested-by: Sebastian Reichel Signed-off-by: Koen Vandeputte Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg Acked-by: Lucas Stach Cc: stable@vger.kernel.org # v4.15+ Cc: Binghui Wang Cc: Jesper Nilsson Cc: Jianguo Sun Cc: Jingoo Han Cc: Kishon Vijay Abraham I Cc: Lucas Stach Cc: Mika Westerberg Cc: Minghuan Lian Cc: Mingkai Hu Cc: Murali Karicheri Cc: Pratyush Anand Cc: Richard Zhu Cc: Roy Zang Cc: Shawn Guo Cc: Stanimir Varbanov Cc: Thomas Petazzoni Cc: Xiaowei Song Cc: Zhou Wang [fabio: adapted to the file location of 4.9 kernel] Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pcie-designware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index af8f6e92e885..b3a87159e457 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -861,7 +861,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) /* setup bus numbers */ val = dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS); val &= 0xff000000; - val |= 0x00010100; + val |= 0x00ff0100; dw_pcie_writel_rc(pp, PCI_PRIMARY_BUS, val); /* setup command register */ -- cgit v1.2.3 From 3ec4b846a5dda7fe983015e6310c3d551b029329 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Fri, 17 Feb 2017 12:51:19 -0800 Subject: Input: tsc2007 - check for presence and power down tsc2007 during probe [ Upstream commit 934df23171e7c5b71d937104d4957891c39748ff ] 1. check if chip is really present and don't succeed if it isn't. 2. if it succeeds, power down the chip until accessed Signed-off-by: H. Nikolaus Schaller Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/tsc2007.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 5d0cd51c6f41..a4b7b4c3d27b 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -455,6 +455,14 @@ static int tsc2007_probe(struct i2c_client *client, tsc2007_stop(ts); + /* power down the chip (TSC2007_SETUP does not ACK on I2C) */ + err = tsc2007_xfer(ts, PWRDOWN); + if (err < 0) { + dev_err(&client->dev, + "Failed to setup chip: %d\n", err); + return err; /* usually, chip does not respond */ + } + err = input_register_device(input_dev); if (err) { dev_err(&client->dev, -- cgit v1.2.3 From 74cf9ab7d1de72a022519991a9b27ea1510c4c9f Mon Sep 17 00:00:00 2001 From: Varsha Rao Date: Sat, 25 Feb 2017 17:53:58 +0530 Subject: staging: speakup: Replace BUG_ON() with WARN_ON(). [ Upstream commit d351c2db5420bb17dcd2d9aac7ddb5f64c6d04b3 ] BUG_ON() is replaced with WARN_ON() and EINVAL is returned, when WARN_ON() is true. This fixes the following checkpatch issue: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON(). Signed-off-by: Varsha Rao Reviewed-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/kobjects.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index e744aa9730ff..dea018cba094 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -834,7 +834,9 @@ static ssize_t message_show(struct kobject *kobj, struct msg_group_t *group = spk_find_msg_group(attr->attr.name); unsigned long flags; - BUG_ON(!group); + if (WARN_ON(!group)) + return -EINVAL; + spin_lock_irqsave(&speakup_info.spinlock, flags); retval = message_show_helper(buf, group->start, group->end); spin_unlock_irqrestore(&speakup_info.spinlock, flags); @@ -846,7 +848,9 @@ static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr, { struct msg_group_t *group = spk_find_msg_group(attr->attr.name); - BUG_ON(!group); + if (WARN_ON(!group)) + return -EINVAL; + return message_store_helper(buf, count, group); } -- cgit v1.2.3 From 8f6cd2d0c0f37b272833d88604ce7f82fd05b167 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 28 Feb 2017 11:47:33 +0000 Subject: staging: wilc1000: add check for kmalloc allocation failure. [ Upstream commit 6cc0c259d034c6ab48f4e12f505213988e73d380 ] Add a sanity check that wid.val has been allocated, fixes a null pointer deference on stamac when calling ether_add_copy. Detected by CoverityScan, CID#1369537 ("Dereference null return value") Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6ab7443eabde..6326375b76ab 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1930,6 +1930,8 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wid.type = WID_STR; wid.size = ETH_ALEN; wid.val = kmalloc(wid.size, GFP_KERNEL); + if (!wid.val) + return -ENOMEM; stamac = wid.val; memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN); -- cgit v1.2.3 From 953468bda711fe7ab68235a9a4ae3ca67698736f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valtteri=20Heikkil=C3=A4?= Date: Tue, 14 Feb 2017 23:14:32 +0000 Subject: HID: reject input outside logical range only if null state is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 3f3752705dbd50b66b66ad7b4d54fe33d2f746ed ] This patch fixes an issue in drivers/hid/hid-input.c where USB HID control null state flag is not checked upon rejecting inputs outside logical minimum-maximum range. The check should be made according to USB HID specification 1.11, section 6.2.2.5, p.31. The fix will resolve issues with some game controllers, such as: https://bugzilla.kernel.org/show_bug.cgi?id=68621 [tk@the-tk.com: shortened and fixed spelling in commit message] Signed-off-by: Valtteri Heikkilä Signed-off-by: Tomasz Kramkowski Acked-By: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-input.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index fb9ace1cef8b..76f2527fbc60 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1156,6 +1156,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct * don't specify logical min and max. */ if ((field->flags & HID_MAIN_ITEM_VARIABLE) && + (field->flags & HID_MAIN_ITEM_NULL_STATE) && (field->logical_minimum < field->logical_maximum) && (value < field->logical_minimum || value > field->logical_maximum)) { -- cgit v1.2.3 From 23c475fa7124f1174d417cd378e6b4d363856081 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Mon, 27 Feb 2017 17:33:30 -0300 Subject: drm: qxl: Don't alloc fbdev if emulation is not supported [ Upstream commit 861078381ba56b56808113736000d9e7ead349c8 ] If fbdev emulation is disabled, the QXL shutdown path will try to clean a framebuffer that wasn't initialized, hitting the Oops below. The problem is that even when FBDEV_EMULATION is disabled we allocate the qfbdev strutucture, but we don't initialize it. The fix is to stop allocating the memory, since it won't be used. This allows the existing verification in the cleanup hook to do it's job preventing the oops. Now that we don't allocate the unused fbdev structure, we need to be careful when dereferencing it in the PM suspend hook. [ 24.284684] BUG: unable to handle kernel NULL pointer dereference at 00000000000002e0 [ 24.285627] IP: mutex_lock+0x18/0x30 [ 24.286049] PGD 78cdf067 [ 24.286050] PUD 7940f067 [ 24.286344] PMD 0 [ 24.286649] [ 24.287072] Oops: 0002 [#1] SMP [ 24.287422] Modules linked in: qxl [ 24.287806] CPU: 0 PID: 2328 Comm: bash Not tainted 4.10.0-rc5+ #97 [ 24.288515] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014 [ 24.289681] task: ffff88007c4c0000 task.stack: ffffc90001b58000 [ 24.290354] RIP: 0010:mutex_lock+0x18/0x30 [ 24.290812] RSP: 0018:ffffc90001b5bcb0 EFLAGS: 00010246 [ 24.291401] RAX: 0000000000000000 RBX: 00000000000002e0 RCX: 0000000000000000 [ 24.292209] RDX: ffff88007c4c0000 RSI: 0000000000000001 RDI: 00000000000002e0 [ 24.292987] RBP: ffffc90001b5bcb8 R08: fffffffffffffffe R09: 0000000000000001 [ 24.293797] R10: ffff880078d80b80 R11: 0000000000011400 R12: 0000000000000000 [ 24.294601] R13: 00000000000002e0 R14: ffffffffa0009c28 R15: 0000000000000060 [ 24.295439] FS: 00007f30e3acbb40(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 [ 24.296364] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 24.296997] CR2: 00000000000002e0 CR3: 0000000078c7b000 CR4: 00000000000006f0 [ 24.297813] Call Trace: [ 24.298097] drm_framebuffer_cleanup+0x1f/0x70 [ 24.298612] qxl_fbdev_fini+0x68/0x90 [qxl] [ 24.299074] qxl_modeset_fini+0xd/0x30 [qxl] [ 24.299562] qxl_pci_remove+0x22/0x50 [qxl] [ 24.300025] pci_device_remove+0x34/0xb0 [ 24.300507] device_release_driver_internal+0x150/0x200 [ 24.301082] device_release_driver+0xd/0x10 [ 24.301587] unbind_store+0x108/0x150 [ 24.301993] drv_attr_store+0x20/0x30 [ 24.302402] sysfs_kf_write+0x32/0x40 [ 24.302827] kernfs_fop_write+0x108/0x190 [ 24.303269] __vfs_write+0x23/0x120 [ 24.303678] ? security_file_permission+0x36/0xb0 [ 24.304193] ? rw_verify_area+0x49/0xb0 [ 24.304636] vfs_write+0xb0/0x190 [ 24.305004] SyS_write+0x41/0xa0 [ 24.305362] entry_SYSCALL_64_fastpath+0x1a/0xa9 [ 24.305887] RIP: 0033:0x7f30e31d9620 [ 24.306285] RSP: 002b:00007ffc54b47e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 24.307128] RAX: ffffffffffffffda RBX: 00007f30e3497600 RCX: 00007f30e31d9620 [ 24.307928] RDX: 000000000000000d RSI: 0000000000da2008 RDI: 0000000000000001 [ 24.308727] RBP: 000000000070bc60 R08: 00007f30e3498760 R09: 00007f30e3acbb40 [ 24.309504] R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000001 [ 24.310295] R13: 0000000000000000 R14: 0000000000000000 R15: 00007ffc54b47f34 [ 24.311095] Code: 0e 01 e9 7b fe ff ff 66 90 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 89 fb e8 83 e8 ff ff 65 48 8b 14 25 40 c4 00 00 31 c0 <3e> 48 0f b1 13 48 85 c0 74 08 48 89 df e8 66 fd ff ff 5b 5d c3 [ 24.313182] RIP: mutex_lock+0x18/0x30 RSP: ffffc90001b5bcb0 [ 24.313811] CR2: 00000000000002e0 [ 24.314208] ---[ end trace 29669c1593cae14b ]--- Signed-off-by: Gabriel Krisman Bertazi Link: http://patchwork.freedesktop.org/patch/msgid/20170227203330.18542-1-krisman@collabora.co.uk Signed-off-by: Gerd Hoffmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/qxl/qxl_fb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 2cd879a4ae15..cdbb6e625f05 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -387,9 +387,11 @@ static const struct drm_fb_helper_funcs qxl_fb_helper_funcs = { int qxl_fbdev_init(struct qxl_device *qdev) { + int ret = 0; + +#ifdef CONFIG_DRM_FBDEV_EMULATION struct qxl_fbdev *qfbdev; int bpp_sel = 32; /* TODO: parameter from somewhere? */ - int ret; qfbdev = kzalloc(sizeof(struct qxl_fbdev), GFP_KERNEL); if (!qfbdev) @@ -423,6 +425,8 @@ fini: drm_fb_helper_fini(&qfbdev->helper); free: kfree(qfbdev); +#endif + return ret; } @@ -438,6 +442,9 @@ void qxl_fbdev_fini(struct qxl_device *qdev) void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state) { + if (!qdev->mode_info.qfbdev) + return; + drm_fb_helper_set_suspend(&qdev->mode_info.qfbdev->helper, state); } -- cgit v1.2.3 From 7c4b9440c5c3490fb702ff3029f3e54ee9a2be91 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 17 Feb 2017 11:13:25 +0800 Subject: drm/sun4i: Fix up error path cleanup for master bind function [ Upstream commit 9d56defb44b15427f4342c543a70fb7886fc06f5 ] The master bind function calls numerous drm functions which initialize underlying structures. It also tries to bind the various components of the display pipeline, some of which may add additional drm objects. This patch adds proper cleanup functions in the error path of the master bind function. This requires the patch "drm/sun4i: Move drm_mode_config_cleanup call to main driver", which splits out drm_mode_config_cleanup from sun4i_framebuffer_free so we can call it separately. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/sun4i/sun4i_drv.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 1feec34ca9dd..9e77fc034e0a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -145,7 +145,7 @@ static int sun4i_drv_bind(struct device *dev) ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); - goto free_drm; + goto cleanup_mode_config; } /* Create our layers */ @@ -153,7 +153,7 @@ static int sun4i_drv_bind(struct device *dev) if (IS_ERR(drv->layers)) { dev_err(drm->dev, "Couldn't create the planes\n"); ret = PTR_ERR(drv->layers); - goto free_drm; + goto cleanup_mode_config; } /* Create our CRTC */ @@ -161,7 +161,7 @@ static int sun4i_drv_bind(struct device *dev) if (!drv->crtc) { dev_err(drm->dev, "Couldn't create the CRTC\n"); ret = -EINVAL; - goto free_drm; + goto cleanup_mode_config; } drm->irq_enabled = true; @@ -173,7 +173,7 @@ static int sun4i_drv_bind(struct device *dev) if (IS_ERR(drv->fbdev)) { dev_err(drm->dev, "Couldn't create our framebuffer\n"); ret = PTR_ERR(drv->fbdev); - goto free_drm; + goto cleanup_mode_config; } /* Enable connectors polling */ @@ -181,10 +181,16 @@ static int sun4i_drv_bind(struct device *dev) ret = drm_dev_register(drm, 0); if (ret) - goto free_drm; + goto finish_poll; return 0; +finish_poll: + drm_kms_helper_poll_fini(drm); + sun4i_framebuffer_free(drm); +cleanup_mode_config: + drm_mode_config_cleanup(drm); + drm_vblank_cleanup(drm); free_drm: drm_dev_unref(drm); return ret; -- cgit v1.2.3 From c1315eea94ea76395918d6f5e9285de82ca023f7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 23 Feb 2017 16:05:34 +0800 Subject: drm/sun4i: Set drm_crtc.port to the underlying TCON's output port node [ Upstream commit 7544860733d158e3edbf309f27e79e258c8f66bd ] The way drm_of_find_possible_crtcs works is it tries to match the remote-endpoint of the given node's various endpoints to all the crtc's .port field. Thus we need to set drm_crtc.port to the output port node of the underlying TCON. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 4a192210574f..caba0311c86c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -136,5 +137,9 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm) drm_crtc_helper_add(&scrtc->crtc, &sun4i_crtc_helper_funcs); + /* Set crtc.port to output port node of the tcon */ + scrtc->crtc.port = of_graph_get_port_by_id(drv->tcon->dev->of_node, + 1); + return scrtc; } -- cgit v1.2.3 From 5d2db0dbb1939cbd08c02e225795459fdfccc948 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 8 Mar 2017 13:52:06 +0200 Subject: ath10k: fix a warning during channel switch with multiple vaps [ Upstream commit c73f8c00330f59ce9b1ace9ff698aca83390d358 ] Doing a channel switch via hostapd_cli seems to update the new channel context for each VAP's appropriately as below in 'ath10k_mac_update_vif_chan', hence we can safely suppress the warning that shows up during this operation and dump the warning only if no vaps are available for channel switch hostapd_cli -i wlan0 chan_switch 5 5200 OK ath10k_pci : mac chanctx switch n_vifs 3 mode 1 ath10k_pci : mac chanctx switch vdev_id 2 freq 5180->5200 width 0->0 ath10k_pci : mac chanctx switch vdev_id 1 freq 5180->5200 width 0->0 ath10k_pci : mac chanctx switch vdev_id 0 freq 5180->5200 width 0->0 Call Trace: WARNING: backports-20161201-3.14.77-9ab3068/drivers/net/wireless/ath/ath10k/mac.c:7126 [] (warn_slowpath_null) from [] (ath10k_reconfig_complete+0xe4/0x25c [ath10k_core]) [] (ath10k_reconfig_complete [ath10k_core]) [] (ath10k_mac_vif_ap_csa_work+0x214/0x370 [ath10k_core]) [] (ath10k_mac_op_change_chanctx+0x108/0x128 [ath10k_core]) [] (ieee80211_recalc_chanctx_min_def+0x30c/0x430 [mac80211]) [] (ieee80211_recalc_smps_chanctx+0x2ec/0x840 [mac80211]) [] (ieee80211_vif_use_reserved_context+0x7c/0xf8 [mac80211]) [] (ieee80211_vif_use_reserved_context [mac80211]) [] (ieee80211_csa_finalize_work+0x5c/0x88 [mac80211]) Fixes: d7bf4b4aba05 ("ath10k: fix ar->rx_channel updating logic") Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 17ab8efdac35..696b90270615 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -7070,7 +7070,7 @@ ath10k_mac_update_rx_channel(struct ath10k *ar, lockdep_assert_held(&ar->data_lock); WARN_ON(ctx && vifs); - WARN_ON(vifs && n_vifs != 1); + WARN_ON(vifs && !n_vifs); /* FIXME: Sort of an optimization and a workaround. Peers and vifs are * on a linked list now. Doing a lookup peer -> vif -> chanctx for each -- cgit v1.2.3 From 4d2c5e9a5a4d64d416ff30a0f29994b6341b22b6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 9 Mar 2017 18:05:24 +0800 Subject: drm/sun4i: Fix TCON clock and regmap initialization sequence [ Upstream commit 4c7f16d14a33a9cfb4af9cb780d8a73bcca64a92 ] The TCON driver calls sun4i_tcon_init_regmap and sun4i_tcon_init_clocks in its bind function. The former creates a regmap and writes to several register to clear its configuration to a known default. The latter initializes various clocks. This includes enabling the bus clock for register access and creating the dotclock. In order for the first step's writes to work, the bus clock must be enabled which is done in the second step. but the dotclock's ops use the regmap created in the first step. Rearrange the function calls such that the clocks are initialized before the regmap, and split out the dot clock creation to after the regmap is initialized. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index c6afb2448655..f2975a1525be 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -336,12 +336,11 @@ static int sun4i_tcon_init_clocks(struct device *dev, } } - return sun4i_dclk_create(dev, tcon); + return 0; } static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) { - sun4i_dclk_free(tcon); clk_disable_unprepare(tcon->clk); } @@ -506,22 +505,28 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, return ret; } + ret = sun4i_tcon_init_clocks(dev, tcon); + if (ret) { + dev_err(dev, "Couldn't init our TCON clocks\n"); + goto err_assert_reset; + } + ret = sun4i_tcon_init_regmap(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON regmap\n"); - goto err_assert_reset; + goto err_free_clocks; } - ret = sun4i_tcon_init_clocks(dev, tcon); + ret = sun4i_dclk_create(dev, tcon); if (ret) { - dev_err(dev, "Couldn't init our TCON clocks\n"); - goto err_assert_reset; + dev_err(dev, "Couldn't create our TCON dot clock\n"); + goto err_free_clocks; } ret = sun4i_tcon_init_irq(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON interrupts\n"); - goto err_free_clocks; + goto err_free_dotclock; } ret = sun4i_rgb_init(drm); @@ -530,6 +535,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, return 0; +err_free_dotclock: + sun4i_dclk_free(tcon); err_free_clocks: sun4i_tcon_free_clocks(tcon); err_assert_reset: @@ -542,6 +549,7 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master, { struct sun4i_tcon *tcon = dev_get_drvdata(dev); + sun4i_dclk_free(tcon); sun4i_tcon_free_clocks(tcon); } -- cgit v1.2.3 From bae359c00b391644ebf813ee3dfb17549e09b5ef Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 26 Jan 2017 14:07:47 -0500 Subject: PCI/MSI: Stop disabling MSI/MSI-X in pci_device_shutdown() [ Upstream commit fda78d7a0ead144f4b2cdb582dcba47911f4952c ] The pci_bus_type .shutdown method, pci_device_shutdown(), is called from device_shutdown() in the kernel restart and shutdown paths. Previously, pci_device_shutdown() called pci_msi_shutdown() and pci_msix_shutdown(). This disables MSI and MSI-X, which causes the device to fall back to raising interrupts via INTx. But the driver is still bound to the device, it doesn't know about this change, and it likely doesn't have an INTx handler, so these INTx interrupts cause "nobody cared" warnings like this: irq 16: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.2-1.el7_UNSUPPORTED.x86_64 #1 Hardware name: Hewlett-Packard HP Z820 Workstation/158B, BIOS J63 v03.90 06/ ... The MSI disabling code was added by d52877c7b1af ("pci/irq: let pci_device_shutdown to call pci_msi_shutdown v2") because a driver left MSI enabled and kdump failed because the kexeced kernel wasn't prepared to receive the MSI interrupts. Subsequent commits 1851617cd2da ("PCI/MSI: Disable MSI at enumeration even if kernel doesn't support MSI") and e80e7edc55ba ("PCI/MSI: Initialize MSI capability for all architectures") changed the kexeced kernel to disable all MSIs itself so it no longer depends on the crashed kernel to clean up after itself. Stop disabling MSI/MSI-X in pci_device_shutdown(). This resolves the "nobody cared" unhandled IRQ issue above. It also allows PCI serial devices, which may rely on the MSI interrupts, to continue outputting messages during reboot/shutdown. [bhelgaas: changelog, drop pci_msi_shutdown() and pci_msix_shutdown() calls altogether] Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=187351 Signed-off-by: Prarit Bhargava Signed-off-by: Bjorn Helgaas CC: Alex Williamson CC: David Arcari CC: Myron Stowe CC: Lukas Wunner CC: Keith Busch CC: Mika Westerberg Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 802997e2ddcc..d81ad841dc0c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -463,8 +463,6 @@ static void pci_device_shutdown(struct device *dev) if (drv && drv->shutdown) drv->shutdown(pci_dev); - pci_msi_shutdown(pci_dev); - pci_msix_shutdown(pci_dev); /* * If this is a kexec reboot, turn off Bus Master bit on the -- cgit v1.2.3 From 6297c56c5e7fe3dd1ade273774f3ffc8451b6d71 Mon Sep 17 00:00:00 2001 From: Aaron Salter Date: Fri, 2 Dec 2016 12:33:02 -0800 Subject: i40e: Acquire NVM lock before reads on all devices [ Upstream commit 96a39aed25e6559b160786117df124084feb9080 ] Acquire NVM lock before reads on all devices. Previously, locks were only used for X722 and later. Fixes an issue where simultaneous X710 NVM accesses were interfering with each other. Change-ID: If570bb7acf958cef58725ec2a2011cead6f80638 Signed-off-by: Aaron Salter Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index 954efe3118db..abe290bfc638 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -292,14 +292,14 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, { enum i40e_status_code ret_code = 0; - if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) { - ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); - if (!ret_code) { + ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); + if (!ret_code) { + if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) { ret_code = i40e_read_nvm_word_aq(hw, offset, data); - i40e_release_nvm(hw); + } else { + ret_code = i40e_read_nvm_word_srctl(hw, offset, data); } - } else { - ret_code = i40e_read_nvm_word_srctl(hw, offset, data); + i40e_release_nvm(hw); } return ret_code; } -- cgit v1.2.3 From daf88438c5a30b24b784a3b7cb95a780d733dc12 Mon Sep 17 00:00:00 2001 From: Lihong Yang Date: Mon, 30 Jan 2017 12:29:32 -0800 Subject: i40e: fix ethtool to get EEPROM data from X722 interface [ Upstream commit c271dd6c391b535226cf1a81aaad9f33cb5899d3 ] Currently ethtool -e will error out with a X722 interface as its EEPROM has a scope limit at offset 0x5B9FFF. This patch fixes the issue by setting the EEPROM length to the scope limit to avoid NVM read failure beyond that. Change-ID: I0b7d4dd6c7f2a57cace438af5dffa0f44c229372 Signed-off-by: Lihong Yang Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 92bc8846f1ba..f4569461dcb8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1135,6 +1135,11 @@ static int i40e_get_eeprom_len(struct net_device *netdev) struct i40e_hw *hw = &np->vsi->back->hw; u32 val; +#define X722_EEPROM_SCOPE_LIMIT 0x5B9FFF + if (hw->mac.type == I40E_MAC_X722) { + val = X722_EEPROM_SCOPE_LIMIT + 1; + return val; + } val = (rd32(hw, I40E_GLPCI_LBARCTRL) & I40E_GLPCI_LBARCTRL_FL_SIZE_MASK) >> I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT; -- cgit v1.2.3 From c82b5831a27319b7f3793bdd17145b3551963d21 Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Wed, 15 Mar 2017 13:27:16 -0700 Subject: drivers: net: xgene: Fix hardware checksum setting [ Upstream commit e026e700d940a1ea3d3bc84d92ac668b1f015462 ] This patch fixes the hardware checksum settings by properly program the classifier. Otherwise, packet may be received with checksum error on X-Gene1 SoC. Signed-off-by: Quan Nguyen Signed-off-by: Iyappan Subramanian Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 1 + drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 5390ae89136c..71611bd6384b 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -560,6 +560,7 @@ static void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata, xgene_enet_rd_csr(pdata, CLE_BYPASS_REG0_0_ADDR, &cb); cb |= CFG_CLE_BYPASS_EN0; CFG_CLE_IP_PROTOCOL0_SET(&cb, 3); + CFG_CLE_IP_HDR_LEN_SET(&cb, 0); xgene_enet_wr_csr(pdata, CLE_BYPASS_REG0_0_ADDR, cb); xgene_enet_rd_csr(pdata, CLE_BYPASS_REG1_0_ADDR, &cb); diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index 06e598c8bc16..c82faf1a88b8 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h @@ -163,6 +163,7 @@ enum xgene_enet_rm { #define CFG_RXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 26, 3) #define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2) +#define CFG_CLE_IP_HDR_LEN_SET(dst, val) xgene_set_bits(dst, val, 8, 5) #define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12) #define CFG_CLE_FPSEL0_SET(dst, val) xgene_set_bits(dst, val, 16, 4) #define CFG_MACMODE_SET(dst, val) xgene_set_bits(dst, val, 18, 2) -- cgit v1.2.3 From 054221c210227e3b8b325c1459443518eeea2cd1 Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Wed, 15 Mar 2017 13:27:15 -0700 Subject: drivers: net: phy: xgene: Fix mdio write [ Upstream commit 4b72436dc3dd2457056b22d6f147777368c869fa ] This patches fixes a typo in the argument to xgene_enet_wr_mdio_csr(). Signed-off-by: Quan Nguyen Signed-off-by: Iyappan Subramanian Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/mdio-xgene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index 8eb077b677f6..39be3b82608f 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c @@ -232,7 +232,7 @@ static int xgene_xfi_mdio_write(struct mii_bus *bus, int phy_id, val = SET_VAL(HSTPHYADX, phy_id) | SET_VAL(HSTREGADX, reg) | SET_VAL(HSTMIIMWRDAT, data); - xgene_enet_wr_mdio_csr(addr, MIIM_FIELD_ADDR, data); + xgene_enet_wr_mdio_csr(addr, MIIM_FIELD_ADDR, val); val = HSTLDCMD | SET_VAL(HSTMIIMCMD, MIIM_CMD_LEGACY_WRITE); xgene_enet_wr_mdio_csr(addr, MIIM_COMMAND_ADDR, val); -- cgit v1.2.3 From 67622b81288413e28fca6d94338c66a0b08797a5 Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Wed, 15 Mar 2017 13:27:17 -0700 Subject: drivers: net: xgene: Fix wrong logical operation [ Upstream commit 11623fce0f9afef30c45e3f2120b063de3809a8f ] This patch fixes the wrong logical OR operation by changing it to bit-wise OR operation. Fixes: 3bb502f83080 ("drivers: net: xgene: fix statistics counters race condition") Signed-off-by: Iyappan Subramanian Signed-off-by: Quan Nguyen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 8158d4698734..de1546a63a7f 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -537,9 +537,9 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, buf_pool->rx_skb[skb_index] = NULL; /* checking for error */ - status = (GET_VAL(ELERR, le64_to_cpu(raw_desc->m0)) << LERR_LEN) || + status = (GET_VAL(ELERR, le64_to_cpu(raw_desc->m0)) << LERR_LEN) | GET_VAL(LERR, le64_to_cpu(raw_desc->m0)); - if (unlikely(status > 2)) { + if (unlikely(status)) { dev_kfree_skb_any(skb); xgene_enet_parse_error(rx_ring, netdev_priv(rx_ring->ndev), status); -- cgit v1.2.3 From 671eeac5358a15b9bb69d146ef5a3d4d54eb7b5b Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Wed, 15 Mar 2017 13:27:18 -0700 Subject: drivers: net: xgene: Fix Rx checksum validation logic [ Upstream commit 0a0400c3094b5d5cedd479ddbf1329de74c09c4b ] This patch fixes Rx checksum validation logic and adds NETIF_F_RXCSUM flag. Signed-off-by: Iyappan Subramanian Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index de1546a63a7f..651f308cdc60 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -505,14 +505,24 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } -static void xgene_enet_skip_csum(struct sk_buff *skb) +static void xgene_enet_rx_csum(struct sk_buff *skb) { + struct net_device *ndev = skb->dev; struct iphdr *iph = ip_hdr(skb); - if (!ip_is_fragment(iph) || - (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - } + if (!(ndev->features & NETIF_F_RXCSUM)) + return; + + if (skb->protocol != htons(ETH_P_IP)) + return; + + if (ip_is_fragment(iph)) + return; + + if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP) + return; + + skb->ip_summed = CHECKSUM_UNNECESSARY; } static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, @@ -555,10 +565,7 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, ndev); - if (likely((ndev->features & NETIF_F_IP_CSUM) && - skb->protocol == htons(ETH_P_IP))) { - xgene_enet_skip_csum(skb); - } + xgene_enet_rx_csum(skb); rx_ring->rx_packets++; rx_ring->rx_bytes += datalen; @@ -1725,7 +1732,7 @@ static int xgene_enet_probe(struct platform_device *pdev) xgene_enet_setup_ops(pdata); if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) { - ndev->features |= NETIF_F_TSO; + ndev->features |= NETIF_F_TSO | NETIF_F_RXCSUM; spin_lock_init(&pdata->mss_lock); } ndev->hw_features = ndev->features; -- cgit v1.2.3 From 80ec67573b9508bce7f10a80f01b78fb7c9cb1c2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 15 Mar 2017 20:40:25 +0000 Subject: drm: Defer disabling the vblank IRQ until the next interrupt (for instant-off) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 608b20506941969ea30d8c08dc9ae02bb87dbf7d ] On vblank instant-off systems, we can get into a situation where the cost of enabling and disabling the vblank IRQ around a drmWaitVblank query dominates. And with the advent of even deeper hardware sleep state, touching registers becomes ever more expensive. However, we know that if the user wants the current vblank counter, they are also very likely to immediately queue a vblank wait and so we can keep the interrupt around and only turn it off if we have no further vblank requests queued within the interrupt interval. After vblank event delivery, this patch adds a shadow of one vblank where the interrupt is kept alive for the user to query and queue another vblank event. Similarly, if the user is using blocking drmWaitVblanks, the interrupt will be disabled on the IRQ following the wait completion. However, if the user is simply querying the current vblank counter and timestamp, the interrupt will be disabled after every IRQ and the user will enabled it again on the first query following the IRQ. v2: Mario Kleiner - After testing this, one more thing that would make sense is to move the disable block at the end of drm_handle_vblank() instead of at the top. Turns out that if high precision timestaming is disabled or doesn't work for some reason (as can be simulated by echo 0 > /sys/module/drm/parameters/timestamp_precision_usec), then with your delayed disable code at its current place, the vblank counter won't increment anymore at all for instant queries, ie. with your other "instant query" patches. Clients which repeatedly query the counter and wait for it to progress will simply hang, spinning in an endless query loop. There's that comment in vblank_disable_and_save: "* Skip this step if there isn't any high precision timestamp * available. In that case we can't account for this and just * hope for the best. */ With the disable happening after leading edge of vblank (== hw counter increment already happened) but before the vblank counter/timestamp handling in drm_handle_vblank, that step is needed to keep the counter progressing, so skipping it is bad. Now without high precision timestamping support, a kms driver must not set dev->vblank_disable_immediate = true, as this would cause problems for clients, so this shouldn't matter, but it would be good to still make this robust against a future kms driver which might have unreliable high precision timestamping, e.g., high precision timestamping that intermittently doesn't work. v3: Patch before coffee needs extra coffee. Testcase: igt/kms_vblank Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Michel Dänzer Cc: Laurent Pinchart Cc: Dave Airlie , Cc: Mario Kleiner Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170315204027.20160-1-chris@chris-wilson.co.uk Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_irq.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 48a6167f5e7b..00c815a7c414 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1202,9 +1202,9 @@ static void drm_vblank_put(struct drm_device *dev, unsigned int pipe) if (atomic_dec_and_test(&vblank->refcount)) { if (drm_vblank_offdelay == 0) return; - else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0) + else if (drm_vblank_offdelay < 0) vblank_disable_fn((unsigned long)vblank); - else + else if (!dev->vblank_disable_immediate) mod_timer(&vblank->disable_timer, jiffies + ((drm_vblank_offdelay * HZ)/1000)); } @@ -1819,6 +1819,16 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) wake_up(&vblank->queue); drm_handle_vblank_events(dev, pipe); + /* With instant-off, we defer disabling the interrupt until after + * we finish processing the following vblank. The disable has to + * be last (after drm_handle_vblank_events) so that the timestamp + * is always accurate. + */ + if (dev->vblank_disable_immediate && + drm_vblank_offdelay > 0 && + !atomic_read(&vblank->refcount)) + vblank_disable_fn((unsigned long)vblank); + spin_unlock_irqrestore(&dev->event_lock, irqflags); return true; -- cgit v1.2.3 From 6a528ebdf3ce081204854cea4b33aea37539b9c4 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 22 Feb 2017 21:03:11 +0530 Subject: ath10k: disallow DFS simulation if DFS channel is not enabled [ Upstream commit ca07baab0b1e627ae1d4a55d190fb1c9d32a3445 ] If DFS is not enabled in hostapd (ieee80211h=0) DFS channels shall not be available for use even though the hardware may have the capability to support DFS. With this configuration (DFS disabled in hostapd) trying to bring up ath10k device in DFS channel for AP mode fails and trying to simulate DFS in ath10k debugfs results in a warning in cfg80211 complaining invalid channel and this should be avoided in the driver itself rather than false propogating RADAR detection to mac80211/cfg80211. Fix this by checking for the first vif 'is_started' state(should work for client mode as well) as all the vifs shall be configured for the same channel sys/kernel/debug/ieee80211/phy1/ath10k# echo 1 > dfs_simulate_radar WARNING: at net/wireless/chan.c:265 cfg80211_radar_event+0x24/0x60 Workqueue: phy0 ieee80211_dfs_radar_detected_work [mac80211] [] (warn_slowpath_null) from [] (cfg80211_radar_event+0x24/0x60 [cfg80211]) [] (cfg80211_radar_event [cfg80211]) from [] (ieee80211_dfs_radar_detected_work+0x94/0xa0 [mac80211]) [] (ieee80211_dfs_radar_detected_work [mac80211]) from [] (process_one_work+0x20c/0x32c) WARNING: at net/wireless/nl80211.c:2488 nl80211_get_mpath+0x13c/0x4cc Workqueue: phy0 ieee80211_dfs_radar_detected_work [mac80211] [] (warn_slowpath_null) from [] (cfg80211_radar_event+0x24/0x60 [cfg80211]) [] (cfg80211_radar_event [cfg80211]) from [] (ieee80211_dfs_radar_detected_work+0x94/0xa0 [mac80211]) [] (ieee80211_dfs_radar_detected_work [mac80211]) from [] (process_one_work+0x20c/0x32c) Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/debug.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 82a4c67f3672..6aa2b93497dd 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1942,6 +1942,15 @@ static ssize_t ath10k_write_simulate_radar(struct file *file, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; + struct ath10k_vif *arvif; + + /* Just check for for the first vif alone, as all the vifs will be + * sharing the same channel and if the channel is disabled, all the + * vifs will share the same 'is_started' state. + */ + arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list); + if (!arvif->is_started) + return -EINVAL; ieee80211_radar_detected(ar->hw); -- cgit v1.2.3 From 84b63638ca812f02f9fc79ee358146f9f8d310ab Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 8 Mar 2017 18:03:32 +0530 Subject: ath10k: fix fetching channel during potential radar detection [ Upstream commit a28f6f27a88f047f03f04b9246ca260ebc91455e ] Fetch target operating channel during potential radar detection when the interface is just brought up, but no channel is assigned from userspace. In this scenario rx_channel may not be having a valid pointer hence fetch the target operating channel to avoid warnings as below which can be triggered by the commands with DFS testing over longer run comamnds: iw wlan1 set type mesh ifconfig wlan1 up (valid tgt_oper_chan only) iw wlan1 cac trigger freq 5260 HT20 (valid rx_channel, tgt_oper_chan) iw wlan1 cac trigger freq 5280 HT20 iw wlan1 cac trigger freq 5300 HT20 Once the CAC expires, current channel context will be removed and we are only left with the fallback option of using 'target operating channel' Firmware and driver log: ath: phy1: DFS: radar found on freq=5300: id=1, pri=1125, count=5, count_false=4 ath: phy1: DFS: radar found on freq=5260: id=5, pri=3151, count=6, count_false=11 ath: phy1: DFS: radar found on freq=5280: id=1, pri=1351, count=6, count_false=4 ath: phy1: DFS: radar found on freq=5300: id=1, pri=1125, count=5, count_false=4 ath10k_pci 0001:01:00.0: failed to derive channel for radar pulse, treating as radar ath10k_pci 0001:01:00.0: failed to derive channel for radar pulse, treating as radar Call trace: WARNING: CPU: 1 PID: 2145 at backports-20161201-3.14.77-9ab3068/net/wireless/chan.c:265 cfg80211_set_dfs_state+0x3c/0x88 [cfg80211]() Workqueue: phy1 ieee80211_dfs_radar_detected_work [mac80211] [] (warn_slowpath_null) from [] (cfg80211_set_dfs_state+0x3c/0x88 [cfg80211]) [] (cfg80211_set_dfs_state [cfg80211]) from [] (cfg80211_radar_event+0xc4/0x140 [cfg80211]) [] (cfg80211_radar_event [cfg80211]) from [] (ieee80211_dfs_radar_detected_work+0xa8/0xb4 [mac80211]) [] (ieee80211_dfs_radar_detected_work [mac80211]) from [] (process_one_work+0x298/0x4a4) Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/wmi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 54df425bb0fc..e518b640aad0 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3638,6 +3638,11 @@ static void ath10k_dfs_radar_report(struct ath10k *ar, spin_lock_bh(&ar->data_lock); ch = ar->rx_channel; + + /* fetch target operating channel during channel change */ + if (!ch) + ch = ar->tgt_oper_chan; + spin_unlock_bh(&ar->data_lock); if (!ch) { -- cgit v1.2.3 From e6e868c7504502cda721c0a814d3eac2594760f0 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 14 Mar 2017 12:05:07 +0100 Subject: usb: misc: lvs: fix race condition in disconnect handling [ Upstream commit c4ba329cabca7c839ab48fb58b5bcc2582951a48 ] There is a small window during which the an URB may remain active after disconnect has returned. If in that case already freed memory may be accessed and executed. The fix is to poison the URB befotre the work is flushed. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/lvstest.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index d3d124753266..bd6e06ef88ac 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c @@ -433,6 +433,7 @@ static void lvs_rh_disconnect(struct usb_interface *intf) struct lvs_rh *lvs = usb_get_intfdata(intf); sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); + usb_poison_urb(lvs->urb); /* used in scheduled work */ flush_work(&lvs->rh_work); usb_free_urb(lvs->urb); } -- cgit v1.2.3 From 09bcb120a27be242f35432ddb671ba11786d8790 Mon Sep 17 00:00:00 2001 From: Steve Lin Date: Thu, 16 Mar 2017 11:48:58 -0400 Subject: net: ethernet: bgmac: Allow MAC address to be specified in DTB [ Upstream commit 2f771399a3a2c371c140ff33544a583c6fbc5fd9 ] Allows the BCMA version of the bgmac driver to obtain MAC address from the device tree. If no MAC address is specified there, then the previous behavior (obtaining MAC address from SPROM) is used. Signed-off-by: Steve Lin Reviewed-by: Florian Fainelli Acked-by: Jon Mason Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 39 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a51876..1ee11b600645 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "bgmac.h" static inline bool bgmac_is_bcm4707_family(struct bcma_device *core) @@ -96,7 +97,7 @@ static int bgmac_probe(struct bcma_device *core) struct ssb_sprom *sprom = &core->bus->sprom; struct mii_bus *mii_bus; struct bgmac *bgmac; - u8 *mac; + const u8 *mac = NULL; int err; bgmac = kzalloc(sizeof(*bgmac), GFP_KERNEL); @@ -110,21 +111,27 @@ static int bgmac_probe(struct bcma_device *core) bcma_set_drvdata(core, bgmac); - switch (core->core_unit) { - case 0: - mac = sprom->et0mac; - break; - case 1: - mac = sprom->et1mac; - break; - case 2: - mac = sprom->et2mac; - break; - default: - dev_err(bgmac->dev, "Unsupported core_unit %d\n", - core->core_unit); - err = -ENOTSUPP; - goto err; + if (bgmac->dev->of_node) + mac = of_get_mac_address(bgmac->dev->of_node); + + /* If no MAC address assigned via device tree, check SPROM */ + if (!mac) { + switch (core->core_unit) { + case 0: + mac = sprom->et0mac; + break; + case 1: + mac = sprom->et1mac; + break; + case 2: + mac = sprom->et2mac; + break; + default: + dev_err(bgmac->dev, "Unsupported core_unit %d\n", + core->core_unit); + err = -ENOTSUPP; + goto err; + } } ether_addr_copy(bgmac->mac_addr, mac); -- cgit v1.2.3 From a124c8751f2288ef328fba9544634af9a4021d9f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 20 Mar 2017 18:30:59 +0100 Subject: omapfb: dss: Handle return errors in dss_init_ports() [ Upstream commit 0348aaa34412e24ebe622a2b1b013e68d6ae5412 ] dss_init_ports() is not handling return errors from dpi_init_port() and sdi_init_port(). It is also always returning 0 currently which results in part of error handling code in dss_bind() being unused. Fix dss_init_ports() to handle return errors from dpi_init_port() and sdi_init_port(). Signed-off-by: Arvind Yadav Cc: tomi.valkeinen@ti.com [b.zolnierkie: fail early on errors, minor fixups] Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/omap2/omapfb/dss/dss.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c index 47d7f69ad9ad..48c6500c24e1 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c @@ -941,11 +941,13 @@ static int dss_init_features(struct platform_device *pdev) return 0; } +static void dss_uninit_ports(struct platform_device *pdev); + static int dss_init_ports(struct platform_device *pdev) { struct device_node *parent = pdev->dev.of_node; struct device_node *port; - int r; + int r, ret = 0; if (parent == NULL) return 0; @@ -972,17 +974,21 @@ static int dss_init_ports(struct platform_device *pdev) switch (port_type) { case OMAP_DISPLAY_TYPE_DPI: - dpi_init_port(pdev, port); + ret = dpi_init_port(pdev, port); break; case OMAP_DISPLAY_TYPE_SDI: - sdi_init_port(pdev, port); + ret = sdi_init_port(pdev, port); break; default: break; } - } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); + } while (!ret && + (port = omapdss_of_get_next_port(parent, port)) != NULL); - return 0; + if (ret) + dss_uninit_ports(pdev); + + return ret; } static void dss_uninit_ports(struct platform_device *pdev) -- cgit v1.2.3 From 3582c4b4df1d7f2ff219b6367976e31d7dfbada1 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Tue, 14 Mar 2017 13:29:13 +0000 Subject: HID: clamp input to logical range if no null state [ Upstream commit c3883fe06488a483658ba5d849b70e49bee15e7c ] This patch fixes an issue in drivers/hid/hid-input.c where values outside of the logical range are not clamped when "null state" bit of the input control is not set. This was discussed on the lists [1] and this change stems from the fact due to the ambiguity of the HID specification it might be appropriate to follow Microsoft's own interpretation of the specification. As noted in Microsoft's documentation [2] in the section titled "Required HID usages for digitizers" it is noted that values reported outside the logical range "will be considered as invalid data and the value will be changed to the nearest boundary value (logical min/max)." This patch fixes an issue where the (1292:4745) Innomedia INNEX GENESIS/ATARI reports out of range values for its X and Y axis of the DPad which, due to the null state bit being unset, are forwarded to userspace as is. Now these values will get clamped to the logical range before being forwarded to userspace. This device was also used to test this patch. This patch expands on commit 3f3752705dbd ("HID: reject input outside logical range only if null state is set"). [1]: http://lkml.kernel.org/r/20170307131036.GA853@gaia.local [2]: https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp Signed-off-by: Tomasz Kramkowski Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-input.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 76f2527fbc60..40233315d5f5 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1149,19 +1149,26 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct /* * Ignore out-of-range values as per HID specification, - * section 5.10 and 6.2.25. + * section 5.10 and 6.2.25, when NULL state bit is present. + * When it's not, clamp the value to match Microsoft's input + * driver as mentioned in "Required HID usages for digitizers": + * https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp * * The logical_minimum < logical_maximum check is done so that we * don't unintentionally discard values sent by devices which * don't specify logical min and max. */ if ((field->flags & HID_MAIN_ITEM_VARIABLE) && - (field->flags & HID_MAIN_ITEM_NULL_STATE) && - (field->logical_minimum < field->logical_maximum) && - (value < field->logical_minimum || - value > field->logical_maximum)) { - dbg_hid("Ignoring out-of-range value %x\n", value); - return; + (field->logical_minimum < field->logical_maximum)) { + if (field->flags & HID_MAIN_ITEM_NULL_STATE && + (value < field->logical_minimum || + value > field->logical_maximum)) { + dbg_hid("Ignoring out-of-range value %x\n", value); + return; + } + value = clamp(value, + field->logical_minimum, + field->logical_maximum); } /* -- cgit v1.2.3 From 82ca25fbd07c8572526ef6e584c09a4260b610c3 Mon Sep 17 00:00:00 2001 From: "Mintz, Yuval" Date: Sun, 19 Mar 2017 13:08:20 +0200 Subject: qed: Always publish VF link from leading hwfn [ Upstream commit e50728effe1126eae39445ba144078b1305b7047 ] The link information exists only on the leading hwfn, but some of its derivatives [e.g., min/max rate] need to be configured for each hwfn. When re-basing the VF link view, use the leading hwfn information as basis for all existing hwfns to allow said configurations to stick. Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_sriov.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index d2d6621fe0e5..48bc5c151336 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -3573,6 +3573,7 @@ static int qed_get_vf_config(struct qed_dev *cdev, void qed_inform_vf_link_state(struct qed_hwfn *hwfn) { + struct qed_hwfn *lead_hwfn = QED_LEADING_HWFN(hwfn->cdev); struct qed_mcp_link_capabilities caps; struct qed_mcp_link_params params; struct qed_mcp_link_state link; @@ -3589,9 +3590,15 @@ void qed_inform_vf_link_state(struct qed_hwfn *hwfn) if (!vf_info) continue; - memcpy(¶ms, qed_mcp_get_link_params(hwfn), sizeof(params)); - memcpy(&link, qed_mcp_get_link_state(hwfn), sizeof(link)); - memcpy(&caps, qed_mcp_get_link_capabilities(hwfn), + /* Only hwfn0 is actually interested in the link speed. + * But since only it would receive an MFW indication of link, + * need to take configuration from it - otherwise things like + * rate limiting for hwfn1 VF would not work. + */ + memcpy(¶ms, qed_mcp_get_link_params(lead_hwfn), + sizeof(params)); + memcpy(&link, qed_mcp_get_link_state(lead_hwfn), sizeof(link)); + memcpy(&caps, qed_mcp_get_link_capabilities(lead_hwfn), sizeof(caps)); /* Modify link according to the VF's configured link state */ -- cgit v1.2.3 From 84f876e346377a3ff16775781879981d8eb1aaf6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Mar 2017 13:44:21 +0100 Subject: zd1211rw: fix NULL-deref at probe [ Upstream commit ca260ece6a57dc7d751e0685f51fa2c55d851873 ] Make sure to check the number of endpoints to avoid dereferencing a NULL-pointer or accessing memory beyond the endpoint array should a malicious device lack the expected endpoints. Fixes: a1030e92c150 ("[PATCH] zd1211rw: Convert installer CDROM device into WLAN device") Cc: Daniel Drake Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/zydas/zd1211rw/zd_usb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index c5effd6c6be9..01ca1d57b3d9 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -1278,6 +1278,9 @@ static int eject_installer(struct usb_interface *intf) u8 bulk_out_ep; int r; + if (iface_desc->desc.bNumEndpoints < 2) + return -ENODEV; + /* Find bulk out endpoint */ for (r = 1; r >= 0; r--) { endpoint = &iface_desc->endpoint[r].desc; -- cgit v1.2.3 From 6ba32c648a9fc27993330632e84c4cbdceef5d57 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 16 Jan 2017 14:28:39 -0600 Subject: of: fix of_device_get_modalias returned length when truncating buffers [ Upstream commit bcf54d5385abaea9c8026aae6f4eeb348671a52d ] If the length of the modalias is greater than the buffer size, then the modalias is truncated. However the untruncated length is returned which will cause an error. Fix this to return the truncated length. If an error in the case was desired, then then we should just return -ENOMEM. The reality is no device will ever have 4KB of compatible strings to hit this case. Signed-off-by: Rob Herring Cc: Frank Rowand Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/of/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/device.c b/drivers/of/device.c index f7a970120055..3cda60c036f9 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -223,7 +223,7 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) str[i] = '_'; } - return tsize; + return repend; } EXPORT_SYMBOL_GPL(of_device_get_modalias); -- cgit v1.2.3 From 078c1a50e189829e0279764f245970a3d2b461fd Mon Sep 17 00:00:00 2001 From: Anton Sviridenko Date: Thu, 9 Mar 2017 10:46:18 -0300 Subject: solo6x10: release vb2 buffers in solo_stop_streaming() [ Upstream commit 6e4c8480bd2eb95309ad3c875e11d2cad98f9188 ] Fixes warning that appears in dmesg after closing V4L2 userspace application that plays video from the display device (first device from V4L2 device nodes provided by solo, usually /dev/video0 when no other V4L2 devices are present). Encoder device nodes are not affected. Can be reproduced by starting and closing ffplay -f video4linux2 /dev/video0 [ 8130.281251] ------------[ cut here ]------------ [ 8130.281256] WARNING: CPU: 1 PID: 20414 at drivers/media/v4l2-core/videobuf2-core.c:1651 __vb2_queue_cancel+0x14b/0x230 [ 8130.281257] Modules linked in: ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat solo6x10 x86_pkg_temp_thermal vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) [ 8130.281264] CPU: 1 PID: 20414 Comm: ffplay Tainted: G O 4.10.0-gentoo #1 [ 8130.281264] Hardware name: ASUS All Series/B85M-E, BIOS 2301 03/30/2015 [ 8130.281265] Call Trace: [ 8130.281267] dump_stack+0x4f/0x72 [ 8130.281270] __warn+0xc7/0xf0 [ 8130.281271] warn_slowpath_null+0x18/0x20 [ 8130.281272] __vb2_queue_cancel+0x14b/0x230 [ 8130.281273] vb2_core_streamoff+0x23/0x90 [ 8130.281275] vb2_streamoff+0x24/0x50 [ 8130.281276] vb2_ioctl_streamoff+0x3d/0x50 [ 8130.281278] v4l_streamoff+0x15/0x20 [ 8130.281279] __video_do_ioctl+0x25e/0x2f0 [ 8130.281280] video_usercopy+0x279/0x520 [ 8130.281282] ? v4l_enum_fmt+0x1330/0x1330 [ 8130.281285] ? unmap_region+0xdf/0x110 [ 8130.281285] video_ioctl2+0x10/0x20 [ 8130.281286] v4l2_ioctl+0xce/0xe0 [ 8130.281289] do_vfs_ioctl+0x8b/0x5b0 [ 8130.281290] ? __fget+0x72/0xa0 [ 8130.281291] SyS_ioctl+0x74/0x80 [ 8130.281294] entry_SYSCALL_64_fastpath+0x13/0x94 [ 8130.281295] RIP: 0033:0x7ff86fee6b27 [ 8130.281296] RSP: 002b:00007ffe467f6a08 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 8130.281297] RAX: ffffffffffffffda RBX: 00000000d1a4d788 RCX: 00007ff86fee6b27 [ 8130.281297] RDX: 00007ffe467f6a14 RSI: 0000000040045613 RDI: 0000000000000006 [ 8130.281298] RBP: 000000000373f8d0 R08: 00000000ffffffff R09: 00007ff860001140 [ 8130.281298] R10: 0000000000000243 R11: 0000000000000246 R12: 0000000000000000 [ 8130.281299] R13: 00000000000000a0 R14: 00007ffe467f6530 R15: 0000000001f32228 [ 8130.281300] ---[ end trace 00695dc96be646e7 ]--- Signed-off-by: Anton Sviridenko Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/pci/solo6x10/solo6x10-v4l2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c index b4be47969b6b..e17d6b945c07 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c @@ -341,6 +341,17 @@ static void solo_stop_streaming(struct vb2_queue *q) struct solo_dev *solo_dev = vb2_get_drv_priv(q); solo_stop_thread(solo_dev); + + spin_lock(&solo_dev->slock); + while (!list_empty(&solo_dev->vidq_active)) { + struct solo_vb2_buf *buf = list_entry( + solo_dev->vidq_active.next, + struct solo_vb2_buf, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + } + spin_unlock(&solo_dev->slock); INIT_LIST_HEAD(&solo_dev->vidq_active); } -- cgit v1.2.3 From 3dda4b42a8f971d3d3896f14ca5f7185a29ae067 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Tue, 28 Feb 2017 16:14:56 -0800 Subject: scsi: fnic: Fix for "Number of Active IOs" in fnicstats becoming negative [ Upstream commit 7ef539c88d7d394410d547c9f082d477093a2a22 ] Fixing the IO stats update (Active IOs and IO completion) to prevent "Number of Active IOs" from becoming negative in the fnistats output. Signed-off-by: Satish Kharat Signed-off-by: Sesidhar Baddela Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/fnic/fnic_scsi.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 44dd372aa7d3..c056b8111ad2 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1127,12 +1127,6 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, else CMD_ABTS_STATUS(sc) = hdr_status; - atomic64_dec(&fnic_stats->io_stats.active_ios); - if (atomic64_read(&fnic->io_cmpl_skip)) - atomic64_dec(&fnic->io_cmpl_skip); - else - atomic64_inc(&fnic_stats->io_stats.io_completions); - if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) atomic64_inc(&misc_stats->no_icmnd_itmf_cmpls); @@ -1173,6 +1167,11 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); sc->scsi_done(sc); + atomic64_dec(&fnic_stats->io_stats.active_ios); + if (atomic64_read(&fnic->io_cmpl_skip)) + atomic64_dec(&fnic->io_cmpl_skip); + else + atomic64_inc(&fnic_stats->io_stats.io_completions); } } @@ -1962,6 +1961,11 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) /* Call SCSI completion function to complete the IO */ sc->result = (DID_ABORT << 16); sc->scsi_done(sc); + atomic64_dec(&fnic_stats->io_stats.active_ios); + if (atomic64_read(&fnic->io_cmpl_skip)) + atomic64_dec(&fnic->io_cmpl_skip); + else + atomic64_inc(&fnic_stats->io_stats.io_completions); } fnic_abort_cmd_end: -- cgit v1.2.3 From 2f1b0a81b1b39e8eb2a79b667fc17bf76f24b788 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 15 Mar 2017 16:58:36 -0500 Subject: scsi: ipr: Fix missed EH wakeup [ Upstream commit 66a0d59cdd12546ddf01d229de28b07ccf6d637f ] Following a command abort or device reset, ipr's EH handlers wait for the commands getting aborted to get sent back from the adapter prior to returning from the EH handler. This fixes up some cases where the completion handler was not getting called, which would have resulted in the EH thread waiting until it timed out, greatly extending EH time. Signed-off-by: Brian King Reviewed-by: Wendy Xiong Tested-by: Wendy Xiong Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ipr.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 532474109624..c5bc41d97f84 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -836,8 +836,10 @@ static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd) qc->err_mask |= AC_ERR_OTHER; sata_port->ioasa.status |= ATA_BUSY; - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); ata_qc_complete(qc); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } /** @@ -5947,8 +5949,10 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) res->in_erp = 0; } scsi_dma_unmap(ipr_cmd->scsi_cmd); - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } /** @@ -6338,8 +6342,10 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, } scsi_dma_unmap(ipr_cmd->scsi_cmd); - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } /** @@ -6365,8 +6371,10 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) scsi_dma_unmap(scsi_cmd); spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); } else { spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); -- cgit v1.2.3 From bc88d1bee232c2a514877dd078ed2fd42cde959f Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 15 Jun 2016 19:29:50 -0300 Subject: media: i2c/soc_camera: fix ov6650 sensor getting wrong clock [ Upstream commit 54449af0e0b2ea43a8166611c95b730c850c3184 ] After changes to v4l2_clk API introduced in v4.1 by commits a37462b919 '[media] V4L: remove clock name from v4l2_clk API' and 4f528afcfb '[media] V4L: add CCF support to the v4l2_clk API', ov6650 sensor stopped responding because v4l2_clk_get(), still called with depreciated V4L2 clock name "mclk", started to return respective CCF clock instead of the V4l2 one registered by soc_camera. Fix it by calling v4l2_clk_get() with NULL clock name. Created and tested on Amstrad Delta against Linux-4.7-rc3 with omap1_camera fixes. Signed-off-by: Janusz Krzysztofik Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/soc_camera/ov6650.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index 4bf2995e1cb8..8f85910eda5d 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -1033,7 +1033,7 @@ static int ov6650_probe(struct i2c_client *client, priv->code = MEDIA_BUS_FMT_YUYV8_2X8; priv->colorspace = V4L2_COLORSPACE_JPEG; - priv->clk = v4l2_clk_get(&client->dev, "mclk"); + priv->clk = v4l2_clk_get(&client->dev, NULL); if (IS_ERR(priv->clk)) { ret = PTR_ERR(priv->clk); goto eclkget; -- cgit v1.2.3 From 997de25b0aa87077afd340d4f7aae9903ac8fb6d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 23 Mar 2017 13:33:12 -0700 Subject: Input: qt1070 - add OF device ID table [ Upstream commit cf5cd9d4480a87da78768718cac194a71079b5cb ] The driver doesn't have a struct of_device_id table but supported devices are registered via Device Trees. This is working on the assumption that a I2C device registered via OF will always match a legacy I2C device ID and that the MODALIAS reported will always be of the form i2c:. But this could change in the future so the correct approach is to have an OF device ID table if the devices are registered via OF. The compatible strings don't have a vendor prefix because that's how it's used currently, and changing this will be a Device Tree ABI break. Signed-off-by: Javier Martinez Canillas Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/qt1070.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index 5a5778729e37..76bb51309a78 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c @@ -274,9 +274,18 @@ static const struct i2c_device_id qt1070_id[] = { }; MODULE_DEVICE_TABLE(i2c, qt1070_id); +#ifdef CONFIG_OF +static const struct of_device_id qt1070_of_match[] = { + { .compatible = "qt1070", }, + { }, +}; +MODULE_DEVICE_TABLE(of, qt1070_of_match); +#endif + static struct i2c_driver qt1070_driver = { .driver = { .name = "qt1070", + .of_match_table = of_match_ptr(qt1070_of_match), .pm = &qt1070_pm_ops, }, .id_table = qt1070_id, -- cgit v1.2.3 From fd15bade786ee8d2db6fe45b5b7784a1ec9ca2b7 Mon Sep 17 00:00:00 2001 From: Long Li Date: Thu, 23 Mar 2017 14:58:10 -0700 Subject: PCI: hv: Properly handle PCI bus remove [ Upstream commit d3a78d8bf759d8848339dcc367c4c1678b57a08b ] hv_pci_devices_present() is called in hv_pci_remove() when we remove a PCI device from the host, e.g., by disabling SR-IOV on a device. In hv_pci_remove(), the bus is already removed before the call, so we don't need to rescan the bus in the workqueue scheduled from hv_pci_devices_present(). By introducing bus state hv_pcibus_removed, we can avoid this situation. Reported-by: Xiaofeng Wang Signed-off-by: Long Li Signed-off-by: Bjorn Helgaas Acked-by: K. Y. Srinivasan Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-hyperv.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index dafb4cdb2b7f..43aa630f419a 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -351,6 +351,7 @@ enum hv_pcibus_state { hv_pcibus_init = 0, hv_pcibus_probed, hv_pcibus_installed, + hv_pcibus_removed, hv_pcibus_maximum }; @@ -1489,13 +1490,24 @@ static void pci_devices_present_work(struct work_struct *work) put_pcichild(hpdev, hv_pcidev_ref_initial); } - /* Tell the core to rescan bus because there may have been changes. */ - if (hbus->state == hv_pcibus_installed) { + switch(hbus->state) { + case hv_pcibus_installed: + /* + * Tell the core to rescan bus + * because there may have been changes. + */ pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); pci_unlock_rescan_remove(); - } else { + break; + + case hv_pcibus_init: + case hv_pcibus_probed: survey_child_resources(hbus); + break; + + default: + break; } up(&hbus->enum_sem); @@ -2170,6 +2182,7 @@ static int hv_pci_probe(struct hv_device *hdev, hbus = kzalloc(sizeof(*hbus), GFP_KERNEL); if (!hbus) return -ENOMEM; + hbus->state = hv_pcibus_init; /* * The PCI bus "domain" is what is called "segment" in ACPI and @@ -2312,6 +2325,7 @@ static int hv_pci_remove(struct hv_device *hdev) pci_stop_root_bus(hbus->pci_bus); pci_remove_root_bus(hbus->pci_bus); pci_unlock_rescan_remove(); + hbus->state = hv_pcibus_removed; } ret = hv_send_resources_released(hdev); -- cgit v1.2.3 From 422fcc97747961709f9faa97b5d1f3f4305b67b8 Mon Sep 17 00:00:00 2001 From: Long Li Date: Thu, 23 Mar 2017 14:58:32 -0700 Subject: PCI: hv: Lock PCI bus on device eject [ Upstream commit 414428c5da1c71986727c2fa5cdf1ed071e398d7 ] A PCI_EJECT message can arrive at the same time we are calling pci_scan_child_bus() in the workqueue for the previous PCI_BUS_RELATIONS message or in create_root_hv_pci_bus(). In this case we could potentially modify the bus from multiple places. Properly lock the bus access. Thanks Dexuan Cui for pointing out the race condition in create_root_hv_pci_bus(). Reported-by: Xiaofeng Wang Signed-off-by: Long Li Signed-off-by: Bjorn Helgaas Acked-by: K. Y. Srinivasan Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-hyperv.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 43aa630f419a..d392a55ec0a9 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -1206,9 +1206,11 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus) hbus->pci_bus->msi = &hbus->msi_chip; hbus->pci_bus->msi->dev = &hbus->hdev->device; + pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); pci_bus_assign_resources(hbus->pci_bus); pci_bus_add_devices(hbus->pci_bus); + pci_unlock_rescan_remove(); hbus->state = hv_pcibus_installed; return 0; } @@ -1597,8 +1599,10 @@ static void hv_eject_device_work(struct work_struct *work) pdev = pci_get_domain_bus_and_slot(hpdev->hbus->sysdata.domain, 0, wslot); if (pdev) { + pci_lock_rescan_remove(); pci_stop_and_remove_bus_device(pdev); pci_dev_put(pdev); + pci_unlock_rescan_remove(); } memset(&ctxt, 0, sizeof(ctxt)); -- cgit v1.2.3 From 84353d9d99cf6793f6f28e948f2973681d63806c Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 22 Mar 2017 09:18:26 +0900 Subject: spi: omap2-mcspi: poll OMAP2_MCSPI_CHSTAT_RXS for PIO transfer [ Upstream commit 812613591cb652344186c4cd912304ed02138566 ] When running the spi-loopback-test with slower clock rate like 10 KHz, the test for 251 bytes transfer was failed. This failure triggered an spi-omap2-mcspi's error message "DMA RX last word empty". This message means that PIO for reading the remaining bytes due to the DMA transfer length reduction is failed. This problem can be fixed by polling OMAP2_MCSPI_CHSTAT_RXS bit in channel status register to wait until the receive buffer register is filled. Cc: Mark Brown Signed-off-by: Akinobu Mita Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-omap2-mcspi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index d5157b2222ce..a47cf638460a 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -454,6 +454,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, int elements = 0; int word_len, element_count; struct omap2_mcspi_cs *cs = spi->controller_state; + void __iomem *chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; + mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; count = xfer->len; @@ -549,8 +551,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, if (l & OMAP2_MCSPI_CHCONF_TURBO) { elements--; - if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) - & OMAP2_MCSPI_CHSTAT_RXS)) { + if (!mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_RXS)) { u32 w; w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); @@ -568,8 +570,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, return count; } } - if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) - & OMAP2_MCSPI_CHSTAT_RXS)) { + if (!mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_RXS)) { u32 w; w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); -- cgit v1.2.3 From 61ed2d27b87fe5b01fa867492e75495b96a41456 Mon Sep 17 00:00:00 2001 From: Jiada Wang Date: Thu, 16 Mar 2017 23:12:09 -0700 Subject: dmaengine: imx-sdma: add 1ms delay to ensure SDMA channel is stopped [ Upstream commit 7f3ff14b7eb1ffad132117f08a1973b48e653d43 ] sdma_disable_channel() cannot ensure dma is stopped to access module's FIFOs. There is chance SDMA core is running and accessing BD when disable of corresponding channel, this may cause sometimes even after call of .sdma_disable_channel(), SDMA core still be running and accessing module's FIFOs. According to NXP R&D team a delay of one BD SDMA cost time (maximum is 1ms) should be added after disable of the channel bit, to ensure SDMA core has really been stopped after SDMA clients call .device_terminate_all. This patch introduces adds a new function sdma_disable_channel_with_delay() which simply adds 1ms delay after call sdma_disable_channel(), and set it as .device_terminate_all. Signed-off-by: Jiada Wang Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/dma/imx-sdma.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d1651a50c349..21726a270fc4 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -937,6 +937,21 @@ static int sdma_disable_channel(struct dma_chan *chan) return 0; } +static int sdma_disable_channel_with_delay(struct dma_chan *chan) +{ + sdma_disable_channel(chan); + + /* + * According to NXP R&D team a delay of one BD SDMA cost time + * (maximum is 1ms) should be added after disable of the channel + * bit, to ensure SDMA core has really been stopped after SDMA + * clients call .device_terminate_all. + */ + mdelay(1); + + return 0; +} + static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac) { struct sdma_engine *sdma = sdmac->sdma; @@ -1828,7 +1843,7 @@ static int sdma_probe(struct platform_device *pdev) sdma->dma_device.device_prep_slave_sg = sdma_prep_slave_sg; sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; sdma->dma_device.device_config = sdma_config; - sdma->dma_device.device_terminate_all = sdma_disable_channel; + sdma->dma_device.device_terminate_all = sdma_disable_channel_with_delay; sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -- cgit v1.2.3 From c582696e096064d43d953fd576712d95fcab6702 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 3 Aug 2016 14:16:15 +0300 Subject: usb: dwc3: make sure UX_EXIT_PX is cleared [ Upstream commit 1966b8657d058ecb95031809b607bf3fd1e01c10 ] This bit is only supposed to be used with known buggy PHYs, however some platforms might erroneously set it. In order to avoid it, let's make sure this bit is always cleared. If some PHY needs this, we will need to add a quirk flag. Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fea446900cad..a0c2b8b6edd0 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -463,6 +463,12 @@ static int dwc3_phy_setup(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + /* + * Make sure UX_EXIT_PX is cleared as that causes issues with some + * PHYs. Also, this bit is not supposed to be used in normal operation. + */ + reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX; + /* * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY * to '0' during coreConsultant configuration. So default value diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 884c43714456..bc3678e9dcb1 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -223,6 +223,7 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) #define DWC3_GUSB3PIPECTL_DISRXDETINP3 (1 << 28) +#define DWC3_GUSB3PIPECTL_UX_EXIT_PX (1 << 27) #define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24) #define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19) #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7) -- cgit v1.2.3 From 55b22830b97ecccafc58df9a0f9824ece3add663 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 21 Feb 2017 15:55:41 -0800 Subject: i40e/i40evf: Fix use after free in Rx cleanup path [ Upstream commit 741b8b832a57402380be79d7d11a59eaf57fff3b ] We need to reset skb back to NULL when we have freed it in the Rx cleanup path. I found one spot where this wasn't occurring so this patch fixes it. Change-ID: Iaca68934200732cd4a63eb0bd83b539c95f8c4dd Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 28b640fa2e35..2e12ccf73dba 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1820,6 +1820,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) */ if (unlikely(i40e_test_staterr(rx_desc, BIT(I40E_RXD_QW1_ERROR_SHIFT)))) { dev_kfree_skb_any(skb); + skb = NULL; continue; } diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 90ebc5ac16fd..7bfed441c466 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1262,6 +1262,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) */ if (unlikely(i40e_test_staterr(rx_desc, BIT(I40E_RXD_QW1_ERROR_SHIFT)))) { dev_kfree_skb_any(skb); + skb = NULL; continue; } -- cgit v1.2.3 From 13cc05b621bfde13f6afa5ccbc8e5bd88f26399b Mon Sep 17 00:00:00 2001 From: Jitendra Bhivare Date: Fri, 24 Mar 2017 14:11:40 +0530 Subject: scsi: be2iscsi: Check tag in beiscsi_mccq_compl_wait [ Upstream commit eb419229be58dc6d4a3a814116a265908e088c39 ] scsi host12: BS_1377 : mgmt_invalidate_connection Failed for cid=256 BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] __list_add+0xf/0xc0 PGD 0 Oops: 0000 [#1] SMP Modules linked in: ... CPU: 9 PID: 1542 Comm: iscsid Tainted: G ------------ T 3.10.0-514.el7.x86_64 #1 Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 09/12/2016 task: ffff88076f310fb0 ti: ffff88076bba8000 task.ti: ffff88076bba8000 RIP: 0010:[] [] __list_add+0xf/0xc0 RSP: 0018:ffff88076bbab8e8 EFLAGS: 00010046 RAX: 0000000000000246 RBX: ffff88076bbab990 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff880468badf58 RDI: ffff88076bbab990 RBP: ffff88076bbab900 R08: 0000000000000246 R09: 00000000000020de R10: 0000000000000000 R11: ffff88076bbab5be R12: 0000000000000000 R13: ffff880468badf58 R14: 000000000001adb0 R15: ffff88076f310fb0 FS: 00007f377124a880(0000) GS:ffff88046fa40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 0000000771318000 CR4: 00000000001407e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Stack: ffff88076bbab990 ffff880468badf50 0000000000000001 ffff88076bbab938 ffffffff810b128b 0000000000000246 00000000cf9b7040 ffff880468bac7a0 0000000000000000 ffff880468bac7a0 ffff88076bbab9d0 ffffffffa05a6ea3 Call Trace: [] prepare_to_wait+0x7b/0x90 [] beiscsi_mccq_compl_wait+0x153/0x330 [be2iscsi] [] ? wake_up_atomic_t+0x30/0x30 [] beiscsi_ep_disconnect+0x91/0x2d0 [be2iscsi] [] iscsi_if_ep_disconnect.isra.14+0x5a/0x70 [scsi_transport_iscsi] [] iscsi_if_recv_msg+0x113b/0x14a0 [scsi_transport_iscsi] [] ? __kmalloc_node_track_caller+0x58/0x290 [] iscsi_if_rx+0x8e/0x1f0 [scsi_transport_iscsi] [] netlink_unicast+0xed/0x1b0 [] netlink_sendmsg+0x31e/0x690 [] ? netlink_rcv_wake+0x44/0x60 [] ? netlink_recvmsg+0x1e3/0x450 beiscsi_mccq_compl_wait gets called even when MCC tag allocation failed for mgmt_invalidate_connection. mcc_wait is not initialized for tag 0 so causes crash in prepare_to_wait. Signed-off-by: Jitendra Bhivare Reviewed-by: Tomas Henzl Reviewed-by: Chris Leech Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/be2iscsi/be_cmds.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index be65da2988fb..838edbba8aec 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -246,6 +246,12 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, { int rc = 0; + if (!tag || tag > MAX_MCC_CMD) { + __beiscsi_log(phba, KERN_ERR, + "BC_%d : invalid tag %u\n", tag); + return -EINVAL; + } + if (beiscsi_hba_in_error(phba)) { clear_bit(MCC_TAG_STATE_RUNNING, &phba->ctrl.ptag_state[tag].tag_state); -- cgit v1.2.3 From 3a8649e6c5b28b4bb72ce94a9b1967ffdd70481d Mon Sep 17 00:00:00 2001 From: Shikhar Dogra Date: Mon, 27 Mar 2017 16:16:44 -0700 Subject: driver: (adm1275) set the m,b and R coefficients correctly for power [ Upstream commit 6faecba0b3da7b617bf72bef422bf0d3bb6dfe7d ] Seems like coefficient values for m, b and R under power have been put in the wrong order. Rearranging them properly to get correct values of coefficients for power. For specs, please refer to table 7 (page 35) on http://www.analog.com/media/en/technical-documentation/data-sheets/ADM1075.pdf Fixes: 904b296f308d ("hwmon: (adm1275) Introduce configuration data structure for coeffcients") Signed-off-by: Shikhar Dogra Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/pmbus/adm1275.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 3baa4f4a8c5e..d659a02647d4 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -101,8 +101,8 @@ static const struct coefficients adm1075_coefficients[] = { [0] = { 27169, 0, -1 }, /* voltage */ [1] = { 806, 20475, -1 }, /* current, irange25 */ [2] = { 404, 20475, -1 }, /* current, irange50 */ - [3] = { 0, -1, 8549 }, /* power, irange25 */ - [4] = { 0, -1, 4279 }, /* power, irange50 */ + [3] = { 8549, 0, -1 }, /* power, irange25 */ + [4] = { 4279, 0, -1 }, /* power, irange50 */ }; static const struct coefficients adm1275_coefficients[] = { -- cgit v1.2.3 From 851eb3187617dcaacf6162626dd750850d5abef1 Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Mon, 27 Mar 2017 11:37:35 -0700 Subject: bonding: make speed, duplex setting consistent with link state [ Upstream commit c4adfc822bf5d8e97660b6114b5a8892530ce8cb ] bond_update_speed_duplex() retrieves speed and duplex settings. There is a possibility of failure in retrieving these values but caller has to assume it's always successful. This leads to having inconsistent slave link settings. If these (speed, duplex) values cannot be retrieved, then keeping the link UP causes problems. The updated bond_update_speed_duplex() returns 0 on success if it retrieves sane values for speed and duplex. On failure it returns 1 and marks the link down. Signed-off-by: Mahesh Bandewar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 63d61c084815..6b4b43319ffa 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -371,9 +371,10 @@ down: /* Get link speed and duplex from the slave's base driver * using ethtool. If for some reason the call fails or the * values are invalid, set speed and duplex to -1, - * and return. + * and return. Return 1 if speed or duplex settings are + * UNKNOWN; 0 otherwise. */ -static void bond_update_speed_duplex(struct slave *slave) +static int bond_update_speed_duplex(struct slave *slave) { struct net_device *slave_dev = slave->dev; struct ethtool_link_ksettings ecmd; @@ -383,24 +384,27 @@ static void bond_update_speed_duplex(struct slave *slave) slave->duplex = DUPLEX_UNKNOWN; res = __ethtool_get_link_ksettings(slave_dev, &ecmd); - if (res < 0) - return; - - if (ecmd.base.speed == 0 || ecmd.base.speed == ((__u32)-1)) - return; - + if (res < 0) { + slave->link = BOND_LINK_DOWN; + return 1; + } + if (ecmd.base.speed == 0 || ecmd.base.speed == ((__u32)-1)) { + slave->link = BOND_LINK_DOWN; + return 1; + } switch (ecmd.base.duplex) { case DUPLEX_FULL: case DUPLEX_HALF: break; default: - return; + slave->link = BOND_LINK_DOWN; + return 1; } slave->speed = ecmd.base.speed; slave->duplex = ecmd.base.duplex; - return; + return 0; } const char *bond_slave_link_status(s8 link) -- cgit v1.2.3 From e2afbcdeb61503683b16cf90b98da187f33c6d39 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 27 Mar 2017 16:54:12 -0700 Subject: regulator: core: Limit propagation of parent voltage count and list [ Upstream commit fd086045559d90cd7854818b4c60a7119eda6231 ] Commit 26988efe11b1 ("regulator: core: Allow to get voltage count and list from parent") introduces the propagation of the parent voltage count and list for regulators that don't provide this information themselves. The goal is to support simple switch regulators, however as a side effect normal continuous regulators can leak details of their supplies and provide consumers with inconsistent information. Limit the propagation of the voltage count and list to switch regulators. Fixes: 26988efe11b1 ("regulator: core: Allow to get voltage count and list from parent") Signed-off-by: Matthias Kaehlcke Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9403245503de..178fcda12cec 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2465,7 +2465,7 @@ static int _regulator_list_voltage(struct regulator *regulator, ret = ops->list_voltage(rdev, selector); if (lock) mutex_unlock(&rdev->mutex); - } else if (rdev->supply) { + } else if (rdev->is_switch && rdev->supply) { ret = _regulator_list_voltage(rdev->supply, selector, lock); } else { return -EINVAL; @@ -2523,7 +2523,7 @@ int regulator_count_voltages(struct regulator *regulator) if (rdev->desc->n_voltages) return rdev->desc->n_voltages; - if (!rdev->supply) + if (!rdev->is_switch || !rdev->supply) return -EINVAL; return regulator_count_voltages(rdev->supply); @@ -4049,6 +4049,11 @@ regulator_register(const struct regulator_desc *regulator_desc, mutex_unlock(®ulator_list_mutex); } + if (!rdev->desc->ops->get_voltage && + !rdev->desc->ops->list_voltage && + !rdev->desc->fixed_uV) + rdev->is_switch = true; + ret = device_register(&rdev->dev); if (ret != 0) { put_device(&rdev->dev); -- cgit v1.2.3 From 508126005146f7a8d0c44c2acd02f0fce1665ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Tue, 14 Feb 2017 09:37:12 +0100 Subject: drm/ttm: never add BO that failed to validate to the LRU list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit c2c139cf435b18939204800fa72c53a7207bdd68 ] Fixes a potential race condition in amdgpu that looks as follows: Task 1: attempt ttm_bo_init, but ttm_bo_validate fails Task 1: add BO to global list anyway Task 2: grabs hold of the BO, waits on its reservation lock Task 1: releases its reference of the BO; never gives up the reservation lock The patch "drm/amdgpu: fix a potential deadlock in amdgpu_bo_create_restricted()" attempts to fix that by releasing the reservation lock in amdgpu code; unfortunately, it introduces a use-after-free when this race _doesn't_ happen. This patch should fix the race properly by never adding the BO to the global list in the first place. Cc: zhoucm1 Signed-off-by: Nicolai Hähnle Tested-by: Samuel Pitoiset Reviewed-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/ttm/ttm_bo.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d09276ec7e90..52a2a1a75682 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1209,18 +1209,20 @@ int ttm_bo_init(struct ttm_bo_device *bdev, if (likely(!ret)) ret = ttm_bo_validate(bo, placement, interruptible, false); - if (!resv) { + if (!resv) ttm_bo_unreserve(bo); - } else if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { + if (unlikely(ret)) { + ttm_bo_unref(&bo); + return ret; + } + + if (resv && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { spin_lock(&bo->glob->lru_lock); ttm_bo_add_to_lru(bo); spin_unlock(&bo->glob->lru_lock); } - if (unlikely(ret)) - ttm_bo_unref(&bo); - return ret; } EXPORT_SYMBOL(ttm_bo_init); -- cgit v1.2.3 From 8c989a6803e4e235cd50d789a7ebe6fad10f747d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Mar 2017 10:45:44 -0700 Subject: bonding: refine bond_fold_stats() wrap detection [ Upstream commit 142c6594acbcc32391af9c15f8cd65c6c177698f ] Some device drivers reset their stats at down/up events, possibly fooling bonding stats, since they operate with relative deltas. It is nearly not possible to fix drivers, since some of them compute the tx/rx counters based on per rx/tx queue stats, and the queues can be reconfigured (ethtool -L) between the down/up sequence. Lets avoid accumulating 'negative' values that render bonding stats useless. It is better to lose small deltas, assuming the bonding stats are fetched at a reasonable frequency. Fixes: 5f0c5f73e5ef ("bonding: make global bonding stats more reliable") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6b4b43319ffa..c3f3096b24ae 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3331,12 +3331,17 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res, for (i = 0; i < sizeof(*_res) / sizeof(u64); i++) { u64 nv = new[i]; u64 ov = old[i]; + s64 delta = nv - ov; /* detects if this particular field is 32bit only */ if (((nv | ov) >> 32) == 0) - res[i] += (u32)nv - (u32)ov; - else - res[i] += nv - ov; + delta = (s64)(s32)((u32)nv - (u32)ov); + + /* filter anomalies, some drivers reset their stats + * at down/up events. + */ + if (delta > 0) + res[i] += delta; } } -- cgit v1.2.3 From aad6ccac0e4fddcfd1b04a2cbd95b550c59da23e Mon Sep 17 00:00:00 2001 From: Manish Jaggi Date: Thu, 30 Mar 2017 18:47:14 -0500 Subject: PCI: Apply Cavium ACS quirk only to CN81xx/CN83xx/CN88xx devices [ Upstream commit b77d537d00d08fcf0bf641cd3491dd7df0ad1475 ] Only apply the Cavium ACS quirk to devices with ID in the range 0xa000-0xa0ff. These are the on-chip PCI devices for CN81xx/CN83xx/CN88xx. Fixes: b404bcfbf035 ("PCI: Add ACS quirk for all Cavium devices") Reported-by: Alex Williamson Signed-off-by: Manish Jaggi Acked-by: David Daney Acked-by: Alex Williamson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0c9edc9d7c44..4c9fb8b323e8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4104,6 +4104,9 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) */ acs_flags &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_SV | PCI_ACS_UF); + if (!((dev->device >= 0xa000) && (dev->device <= 0xa0ff))) + return -ENOTTY; + return acs_flags ? 0 : 1; } -- cgit v1.2.3 From 399a4f3c2b3f0c1812a04a4a9994ced8d1704c3d Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Thu, 23 Mar 2017 14:28:21 -0700 Subject: drm/vmwgfx: Fixes to vmwgfx_fb [ Upstream commit aa74f0687cfe998e59b20d6454f45e8aa4403c45 ] 1. When unsetting a mode, num_connector should be set to zero 2. The pixel_format field needs to be initialized as newer DRM internal functions checks this field 3. Take the drm_modeset_lock_all() because vmw_fb_kms_detach() can change current mode Signed-off-by: Sinclair Yeh Reviewed-by: Thomas Hellstrom Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index d2d93959b119..aec6e9eef489 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -433,7 +433,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, set.y = 0; set.mode = NULL; set.fb = NULL; - set.num_connectors = 1; + set.num_connectors = 0; set.connectors = &par->con; ret = drm_mode_set_config_internal(&set); if (ret) { @@ -821,7 +821,9 @@ int vmw_fb_off(struct vmw_private *vmw_priv) flush_delayed_work(&par->local_work); mutex_lock(&par->bo_mutex); + drm_modeset_lock_all(vmw_priv->dev); (void) vmw_fb_kms_detach(par, true, false); + drm_modeset_unlock_all(vmw_priv->dev); mutex_unlock(&par->bo_mutex); return 0; -- cgit v1.2.3 From 441f5af65244dd6585f1c364f1f4fbd00aacb64b Mon Sep 17 00:00:00 2001 From: Felix Manlunas Date: Wed, 29 Mar 2017 17:56:43 -0700 Subject: vxlan: vxlan dev should inherit lowerdev's gso_max_size [ Upstream commit d6acfeb17d030bb3907e77c048b0e7783ad8e5a9 ] vxlan dev currently ignores lowerdev's gso_max_size, which adversely affects TSO performance of liquidio if it's the lowerdev. Egress TCP packets' skb->len often exceed liquidio's advertised gso_max_size. This may happen on other NIC drivers. Fix it by assigning lowerdev's gso_max_size to that of vxlan dev. Might as well do likewise for gso_max_segs. Single flow TSO throughput of liquidio as lowerdev (using iperf3): Before the patch: 139 Mbps After the patch : 8.68 Gbps Percent increase: 6,144 % Signed-off-by: Felix Manlunas Signed-off-by: Satanand Burla Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 983e941bdf29..50570d779b01 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2912,6 +2912,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, return -EINVAL; } + if (lowerdev) { + dev->gso_max_size = lowerdev->gso_max_size; + dev->gso_max_segs = lowerdev->gso_max_segs; + } + if (conf->mtu) { err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false); if (err) -- cgit v1.2.3 From c95acb7bbefb4267c8df48b963d977262268de0a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 26 Oct 2016 11:00:12 +0200 Subject: NFC: nfcmrvl: Include unaligned.h instead of access_ok.h [ Upstream commit d916d923724d59cde99ee588f15eec59dd863bbd ] Including linux/unaligned/access_ok.h causes the allmodconfig build on ia64 (and maybe others) to fail with the following warnings: include/linux/unaligned/access_ok.h:7:19: error: redefinition of 'get_unaligned_le16' include/linux/unaligned/access_ok.h:12:19: error: redefinition of 'get_unaligned_le32' include/linux/unaligned/access_ok.h:17:19: error: redefinition of 'get_unaligned_le64' include/linux/unaligned/access_ok.h:22:19: error: redefinition of 'get_unaligned_be16' include/linux/unaligned/access_ok.h:27:19: error: redefinition of 'get_unaligned_be32' include/linux/unaligned/access_ok.h:32:19: error: redefinition of 'get_unaligned_be64' include/linux/unaligned/access_ok.h:37:20: error: redefinition of 'put_unaligned_le16' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_le32' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_le64' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be16' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be32' include/linux/unaligned/access_ok.h:42:20: error: redefinition of 'put_unaligned_be64' Fix these by including asm/unaligned.h instead and leave it up to the architecture to decide how to implement unaligned accesses. Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support") Reported-by: kbuild test robot Link: https://lkml.org/lkml/2016/10/22/247 Cc: Vincent Cuissard Signed-off-by: Tobias Klauser Signed-off-by: Samuel Ortiz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/nfcmrvl/fw_dnld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index af62c4c854f3..b4f31dad40d6 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include -- cgit v1.2.3 From 8f2c9f6c575969c7d5336cae0c73f7f45ffbfd73 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 Mar 2017 08:22:37 +0300 Subject: NFC: nfcmrvl: double free on error path [ Upstream commit ca42fb9e52d155547e6cf18cf26bce3e1a6af4ea ] The nci_spi_send() function calls kfree_skb(skb) on both error and success so this extra kfree_skb() is a double free. Fixes: caf6e49bf6d0 ("NFC: nfcmrvl: add spi driver") Signed-off-by: Dan Carpenter Signed-off-by: Samuel Ortiz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/nfcmrvl/spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c index a7faa0bcc01e..fc8e78a29d77 100644 --- a/drivers/nfc/nfcmrvl/spi.c +++ b/drivers/nfc/nfcmrvl/spi.c @@ -96,10 +96,9 @@ static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv, /* Send the SPI packet */ err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion, skb); - if (err != 0) { + if (err) nfc_err(priv->dev, "spi_send failed %d", err); - kfree_skb(skb); - } + return err; } -- cgit v1.2.3 From 14c63f375b9a94cb39f9b8a669a9d6e530e6bfa9 Mon Sep 17 00:00:00 2001 From: Andrey Rusalin Date: Wed, 28 Dec 2016 20:10:57 +0300 Subject: NFC: pn533: change order of free_irq and dev unregistration [ Upstream commit 068a496c4525c638ffab56449d905b88ef97fe32 ] Change order of free_irq and dev unregistration. It fixes situation when device already unregistered and an interrupt happens and nobody can handle it. Signed-off-by: Andrey Rusalin Signed-off-by: Samuel Ortiz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/pn533/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1dc89248e58e..11d78b43cf76 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -242,10 +242,10 @@ static int pn533_i2c_remove(struct i2c_client *client) dev_dbg(&client->dev, "%s\n", __func__); - pn533_unregister_device(phy->priv); - free_irq(client->irq, phy); + pn533_unregister_device(phy->priv); + return 0; } -- cgit v1.2.3 From 9c1e8b472b48421e8a698bd63cda283960ef5279 Mon Sep 17 00:00:00 2001 From: lipeng Date: Sat, 1 Apr 2017 12:03:39 +0100 Subject: net: hns: Correct HNS RSS key set function [ Upstream commit 64ec10dc2ab8ef5bc6e76b1d4bc8203c08a6da1e ] This patch fixes below ethtool configuration error: localhost:~ # ethtool -X eth0 hkey XX:XX:XX... Cannot set Rx flow hash configuration: Operation not supported Signed-off-by: lipeng Reviewed-by: Yisen Zhuang Signed-off-by: Salil Mehta Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 23 ++++++++++++++--------- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 9 ++++----- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index 2d0cb609adc3..b7c8433a7a37 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -773,8 +773,9 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 *indir, u8 *key, memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE); /* update the current hash->queue mappings from the shadow RSS table */ - memcpy(indir, ppe_cb->rss_indir_table, - HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir)); + if (indir) + memcpy(indir, ppe_cb->rss_indir_table, + HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir)); return 0; } @@ -785,15 +786,19 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const u32 *indir, struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle); /* set the RSS Hash Key if specififed by the user */ - if (key) - hns_ppe_set_rss_key(ppe_cb, (u32 *)key); + if (key) { + memcpy(ppe_cb->rss_key, key, HNS_PPEV2_RSS_KEY_SIZE); + hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key); + } - /* update the shadow RSS table with user specified qids */ - memcpy(ppe_cb->rss_indir_table, indir, - HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir)); + if (indir) { + /* update the shadow RSS table with user specified qids */ + memcpy(ppe_cb->rss_indir_table, indir, + HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir)); - /* now update the hardware */ - hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table); + /* now update the hardware */ + hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table); + } return 0; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 87d5c94b2810..8490cba230bd 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -1243,6 +1243,7 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; + int ret; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, @@ -1252,12 +1253,10 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, ops = priv->ae_handle->dev->ops; - /* currently hfunc can only be Toeplitz hash */ - if (key || - (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) { + netdev_err(netdev, "Invalid hfunc!\n"); return -EOPNOTSUPP; - if (!indir) - return 0; + } return ops->set_rss(priv->ae_handle, indir, key, hfunc); } -- cgit v1.2.3 From 6e09b864df341b5c9321593514f173d8a049952b Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 2 Apr 2017 20:20:47 +0200 Subject: net/faraday: Add missing include of of.h [ Upstream commit d39004ab136ebb6949a7dda9d24376f3d6209295 ] Breaking the include loop netdevice.h, dsa.h, devlink.h broke this driver, it depends on includes brought in by these headers. Adding linux/of.h fixes it. Fixes: ed0e39e97d34 ("net: break include loop netdevice.h, dsa.h, devlink.h") Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/faraday/ftgmac100.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 262587240c86..0437149f5939 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From d45d7c94f8acb226a626840b378d2a5bba3758c4 Mon Sep 17 00:00:00 2001 From: Michal Kalderon Date: Mon, 3 Apr 2017 12:21:10 +0300 Subject: qed: Fix TM block ILT allocation [ Upstream commit 44531ba45dbf3c23cc7ae0934ec9b33ef340ac56 ] When configuring the HW timers block we should set the number of CIDs up until the last CID that require timers, instead of only those CIDs whose protocol needs timers support. Today, the protocols that require HW timers' support have their CIDs before any other protocol, but that would change in future [when we add iWARP support]. Signed-off-by: Michal Kalderon Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 32 ++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index ed014bdbbabd..457e30427535 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c @@ -271,16 +271,34 @@ struct qed_tm_iids { u32 per_vf_tids; }; -static void qed_cxt_tm_iids(struct qed_cxt_mngr *p_mngr, +static void qed_cxt_tm_iids(struct qed_hwfn *p_hwfn, + struct qed_cxt_mngr *p_mngr, struct qed_tm_iids *iids) { - u32 i, j; - - for (i = 0; i < MAX_CONN_TYPES; i++) { + bool tm_vf_required = false; + bool tm_required = false; + int i, j; + + /* Timers is a special case -> we don't count how many cids require + * timers but what's the max cid that will be used by the timer block. + * therefore we traverse in reverse order, and once we hit a protocol + * that requires the timers memory, we'll sum all the protocols up + * to that one. + */ + for (i = MAX_CONN_TYPES - 1; i >= 0; i--) { struct qed_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[i]; - if (tm_cid_proto(i)) { + if (tm_cid_proto(i) || tm_required) { + if (p_cfg->cid_count) + tm_required = true; + iids->pf_cids += p_cfg->cid_count; + } + + if (tm_cid_proto(i) || tm_vf_required) { + if (p_cfg->cids_per_vf) + tm_vf_required = true; + iids->per_vf_cids += p_cfg->cids_per_vf; } } @@ -696,7 +714,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn) /* TM PF */ p_cli = &p_mngr->clients[ILT_CLI_TM]; - qed_cxt_tm_iids(p_mngr, &tm_iids); + qed_cxt_tm_iids(p_hwfn, p_mngr, &tm_iids); total = tm_iids.pf_cids + tm_iids.pf_tids_total; if (total) { p_blk = &p_cli->pf_blks[0]; @@ -1591,7 +1609,7 @@ static void qed_tm_init_pf(struct qed_hwfn *p_hwfn) u8 i; memset(&tm_iids, 0, sizeof(tm_iids)); - qed_cxt_tm_iids(p_mngr, &tm_iids); + qed_cxt_tm_iids(p_hwfn, p_mngr, &tm_iids); /* @@@TBD No pre-scan for now */ -- cgit v1.2.3 From a24c058d89cb18c861c2dcad92f808bb40fdd03e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 10 Feb 2017 13:30:35 +0200 Subject: drm: rcar-du: Handle event when disabling CRTCs [ Upstream commit 6dd47cfd03a058d08b8caffb06194aa0eb109cf1 ] The driver currently handles vblank events only when updating planes on a CRTC. The atomic update API however allows requesting an event when disabling a CRTC. This currently leads to event objects being leaked in the kernel and to events not being sent out. Fix it. Signed-off-by: Laurent Pinchart Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 3322b157106d..1c4d95dea887 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -512,6 +512,13 @@ static void rcar_du_crtc_disable(struct drm_crtc *crtc) rcar_du_crtc_stop(rcrtc); rcar_du_crtc_put(rcrtc); + spin_lock_irq(&crtc->dev->event_lock); + if (crtc->state->event) { + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + } + spin_unlock_irq(&crtc->dev->event_lock); + rcrtc->outputs = 0; } -- cgit v1.2.3 From f530c1f0025213f9942297e7ddc6f1b838b7deba Mon Sep 17 00:00:00 2001 From: Easwar Hariharan Date: Mon, 20 Mar 2017 17:25:42 -0700 Subject: IB/hfi1: Check for QSFP presence before attempting reads [ Upstream commit fb897ad315643e5dc1092a115b3cec914b66df9d ] Attempting to read the status of a QSFP cable creates noise in the logs and misses out on setting an appropriate Offline/Disabled Reason if the cable is not plugged in. Check for this prior to attempting the read and attendant retries. Fixes: 673b975f1fba ("IB/hfi1: Add QSFP sanity pre-check") Reviewed-by: Dennis Dalessandro Signed-off-by: Easwar Hariharan Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/hfi1/chip.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 4682909b021b..3be62ef154d1 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -9489,8 +9489,11 @@ static int test_qsfp_read(struct hfi1_pportdata *ppd) int ret; u8 status; - /* report success if not a QSFP */ - if (ppd->port_type != PORT_TYPE_QSFP) + /* + * Report success if not a QSFP or, if it is a QSFP, but the cable is + * not present + */ + if (ppd->port_type != PORT_TYPE_QSFP || !qsfp_mod_present(ppd)) return 0; /* read byte 2, the status byte */ -- cgit v1.2.3 From 1f7b46d22802e7adefd2c4f3d13773cb8cb35b92 Mon Sep 17 00:00:00 2001 From: Phil Turnbull Date: Wed, 23 Nov 2016 13:33:58 -0500 Subject: fm10k: correctly check if interface is removed [ Upstream commit 540fca35e38d15777b310f450f63f056e63039f5 ] FM10K_REMOVED expects a hardware address, not a 'struct fm10k_hw'. Fixes: 5cb8db4a4cbc ("fm10k: Add support for VF") Signed-off-by: Phil Turnbull Tested-by: Krishneil Singh Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c index 5241e0873397..7041d83d48bf 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c @@ -942,7 +942,7 @@ static void fm10k_self_test(struct net_device *dev, memset(data, 0, sizeof(*data) * FM10K_TEST_LEN); - if (FM10K_REMOVED(hw)) { + if (FM10K_REMOVED(hw->hw_addr)) { netif_err(interface, drv, dev, "Interface removed - test blocked\n"); eth_test->flags |= ETH_TEST_FL_FAILED; -- cgit v1.2.3 From d4894a600657ccf2d58ebf9af37a69b0a756f773 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Wed, 5 Apr 2017 13:01:02 -0500 Subject: EDAC, altera: Fix peripheral warnings for Cyclone5 [ Upstream commit 25b223ddfe2a557307c05fe673e09d94ae950877 ] The peripherals' RAS functionality only exist on the Arria10 SoCFPGA. The Cyclone5 initialization generates EDAC warnings when the peripherals aren't found in the device tree. Fix by checking for Arria10 in the init functions. Signed-off-by: Thor Thayer Cc: linux-edac Link: http://lkml.kernel.org/r/1491415262-5018-1-git-send-email-thor.thayer@linux.intel.com Signed-off-by: Borislav Petkov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/edac/altera_edac.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 58d3e2b39b5b..61262a7a5c3a 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1020,13 +1020,23 @@ out: return ret; } +static int socfpga_is_a10(void) +{ + return of_machine_is_compatible("altr,socfpga-arria10"); +} + static int validate_parent_available(struct device_node *np); static const struct of_device_id altr_edac_a10_device_of_match[]; static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat) { int irq; - struct device_node *child, *np = of_find_compatible_node(NULL, NULL, - "altr,socfpga-a10-ecc-manager"); + struct device_node *child, *np; + + if (!socfpga_is_a10()) + return -ENODEV; + + np = of_find_compatible_node(NULL, NULL, + "altr,socfpga-a10-ecc-manager"); if (!np) { edac_printk(KERN_ERR, EDAC_DEVICE, "ECC Manager not found\n"); return -ENODEV; @@ -1542,8 +1552,12 @@ static const struct edac_device_prv_data a10_sdmmceccb_data = { static int __init socfpga_init_sdmmc_ecc(void) { int rc = -ENODEV; - struct device_node *child = of_find_compatible_node(NULL, NULL, - "altr,socfpga-sdmmc-ecc"); + struct device_node *child; + + if (!socfpga_is_a10()) + return -ENODEV; + + child = of_find_compatible_node(NULL, NULL, "altr,socfpga-sdmmc-ecc"); if (!child) { edac_printk(KERN_WARNING, EDAC_DEVICE, "SDMMC node not found\n"); return -ENODEV; -- cgit v1.2.3 From 7cd70b3f8ce3ee9ff06bebbbdeb87e38f26ec1aa Mon Sep 17 00:00:00 2001 From: Mauricio Faria de Oliveira Date: Wed, 5 Apr 2017 12:18:19 -0300 Subject: scsi: ses: don't get power status of SES device slot on probe [ Upstream commit 75106523f39751390b5789b36ee1d213b3af1945 ] The commit 08024885a2a3 ("ses: Add power_status to SES device slot") introduced the 'power_status' attribute to enclosure components and the associated callbacks. There are 2 callbacks available to get the power status of a device: 1) ses_get_power_status() for 'struct enclosure_component_callbacks' 2) get_component_power_status() for the sysfs device attribute (these are available for kernel-space and user-space, respectively.) However, despite both methods being available to get power status on demand, that commit also introduced a call to get power status in ses_enclosure_data_process(). This dramatically increased the total probe time for SCSI devices on larger configurations, because ses_enclosure_data_process() is called several times during the SCSI devices probe and loops over the component devices (but that is another problem, another patch). That results in a tremendous continuous hammering of SCSI Receive Diagnostics commands to the enclosure-services device, which does delay the total probe time for the SCSI devices __significantly__: Originally, ~34 minutes on a system attached to ~170 disks: [ 9214.490703] mpt3sas version 13.100.00.00 loaded ... [11256.580231] scsi 17:0:177:0: qdepth(16), tagged(1), simple(0), ordered(0), scsi_level(6), cmd_que(1) With this patch, it decreased to ~2.5 minutes -- a 13.6x faster [ 1002.992533] mpt3sas version 13.100.00.00 loaded ... [ 1151.978831] scsi 11:0:177:0: qdepth(16), tagged(1), simple(0), ordered(0), scsi_level(6), cmd_que(1) Back to the commit discussion.. on the ses_get_power_status() call introduced in ses_enclosure_data_process(): impact of removing it. That may possibly be in place to initialize the power status value on device probe. However, those 2 functions available to retrieve that value _do_ automatically refresh/update it. So the potential benefit would be a direct access of the 'power_status' field which does not use the callbacks... But the only reader of 'struct enclosure_component::power_status' is the get_component_power_status() callback for sysfs attribute, and it _does_ check for and call the .get_power_status callback, (which indeed is defined and implemented by that commit), so the power status value is, again, automatically updated. So, the remaining potential for a direct/non-callback access to the power_status attribute would be out-of-tree modules -- well, for those, if they are for whatever reason interested in values that are set during device probe and not up-to-date by the time they need it.. well, that would be curious. Well, to handle that more properly, set the initial power state value to '-1' (i.e., uninitialized) instead of '1' (power 'on'), and check for it in that callback which may do an direct access to the field value _if_ a callback function is not defined. Signed-off-by: Mauricio Faria de Oliveira Fixes: 08024885a2a3 ("ses: Add power_status to SES device slot") Reviewed-by: Dan Williams Reviewed-by: Song Liu Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/enclosure.c | 7 ++++++- drivers/scsi/ses.c | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index cc91f7b3d90c..eb29113e0bac 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -148,7 +148,7 @@ enclosure_register(struct device *dev, const char *name, int components, for (i = 0; i < components; i++) { edev->component[i].number = -1; edev->component[i].slot = -1; - edev->component[i].power_status = 1; + edev->component[i].power_status = -1; } mutex_lock(&container_list_lock); @@ -600,6 +600,11 @@ static ssize_t get_component_power_status(struct device *cdev, if (edev->cb->get_power_status) edev->cb->get_power_status(edev, ecomp); + + /* If still uninitialized, the callback failed or does not exist. */ + if (ecomp->power_status == -1) + return (edev->cb->get_power_status) ? -EIO : -ENOTTY; + return snprintf(buf, 40, "%s\n", ecomp->power_status ? "on" : "off"); } diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 50adabbb5808..f1cdf32d7514 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -548,7 +548,6 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, ecomp = &edev->component[components++]; if (!IS_ERR(ecomp)) { - ses_get_power_status(edev, ecomp); if (addl_desc_ptr) ses_process_descriptor( ecomp, -- cgit v1.2.3 From b07b26448103a94bd6353a38af0e039488201c23 Mon Sep 17 00:00:00 2001 From: "Mintz, Yuval" Date: Wed, 5 Apr 2017 21:20:11 +0300 Subject: qed: Correct MSI-x for storage [ Upstream commit 2f78227874754b1e10cd348fd6e7693b0dabb3f6 ] When qedr is enabled, qed would try dividing the msi-x vectors between L2 and RoCE, starting with L2 and providing it with sufficient vectors for its queues. Problem is qed would also do that for storage partitions, and as those don't need queues it would lead qed to award those partitions with 0 msi-x vectors, causing them to believe theye're using INTa and preventing them from operating. Fixes: 51ff17251c9c ("qed: Add support for RoCE hw init") Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 333c7442e48a..dba3fbe4800e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -711,7 +711,8 @@ static int qed_slowpath_setup_int(struct qed_dev *cdev, cdev->int_params.fp_msix_cnt = cdev->int_params.out.num_vectors - cdev->num_hwfns; - if (!IS_ENABLED(CONFIG_QED_RDMA)) + if (!IS_ENABLED(CONFIG_QED_RDMA) || + QED_LEADING_HWFN(cdev)->hw_info.personality != QED_PCI_ETH_ROCE) return 0; for_each_hwfn(cdev, i) -- cgit v1.2.3 From 79a6866647f91c27af165aa1223d305b2c118e44 Mon Sep 17 00:00:00 2001 From: Nate Watterson Date: Fri, 7 Apr 2017 01:36:20 -0400 Subject: iommu/iova: Fix underflow bug in __alloc_and_insert_iova_range [ Upstream commit 5016bdb796b3726eec043ca0ce3be981f712c756 ] Normally, calling alloc_iova() using an iova_domain with insufficient pfns remaining between start_pfn and dma_limit will fail and return a NULL pointer. Unexpectedly, if such a "full" iova_domain contains an iova with pfn_lo == 0, the alloc_iova() call will instead succeed and return an iova containing invalid pfns. This is caused by an underflow bug in __alloc_and_insert_iova_range() that occurs after walking the "full" iova tree when the search ends at the iova with pfn_lo == 0 and limit_pfn is then adjusted to be just below that (-1). This (now huge) limit_pfn gives the impression that a vast amount of space is available between it and start_pfn and thus a new iova is allocated with the invalid pfn_hi value, 0xFFF.... . To rememdy this, a check is introduced to ensure that adjustments to limit_pfn will not underflow. This issue has been observed in the wild, and is easily reproduced with the following sample code. struct iova_domain *iovad = kzalloc(sizeof(*iovad), GFP_KERNEL); struct iova *rsvd_iova, *good_iova, *bad_iova; unsigned long limit_pfn = 3; unsigned long start_pfn = 1; unsigned long va_size = 2; init_iova_domain(iovad, SZ_4K, start_pfn, limit_pfn); rsvd_iova = reserve_iova(iovad, 0, 0); good_iova = alloc_iova(iovad, va_size, limit_pfn, true); bad_iova = alloc_iova(iovad, va_size, limit_pfn, true); Prior to the patch, this yielded: *rsvd_iova == {0, 0} /* Expected */ *good_iova == {2, 3} /* Expected */ *bad_iova == {-2, -1} /* Oh no... */ After the patch, bad_iova is NULL as expected since inadequate space remains between limit_pfn and start_pfn after allocating good_iova. Signed-off-by: Nate Watterson Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/iova.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index e23001bfcfee..f106fd9782bf 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -138,7 +138,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, break; /* found a free slot */ } adjust_limit_pfn: - limit_pfn = curr_iova->pfn_lo - 1; + limit_pfn = curr_iova->pfn_lo ? (curr_iova->pfn_lo - 1) : 0; move_left: prev = curr; curr = rb_prev(curr); -- cgit v1.2.3 From b8c231ebced08cc005e164ad841cc6395596189e Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Fri, 7 Apr 2017 17:03:24 +0200 Subject: video: ARM CLCD: fix dma allocation size [ Upstream commit 9a1c779e6b06855e41099caa6f15b3b584dfa88c ] This patch forces the frambuffer size to be aligned on kernel pages. During the board startup, the splash screed did appear; the "ts_test" program or our application were not able to start. The following error message was reported: error: failed to map framebuffer device to memory. LinuxFB: driver cannot connect The issue was discovered, on the LPC32xx platform, during the migration of the LCD definition from the board file to the device tree. Signed-off-by: Liam Beguin Signed-off-by: Sylvain Lemieux Cc: Vladimir Zapolskiy Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/amba-clcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index ec2671d98abc..89880b70cc28 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -892,8 +892,8 @@ static int clcdfb_of_dma_setup(struct clcd_fb *fb) if (err) return err; - framesize = fb->panel->mode.xres * fb->panel->mode.yres * - fb->panel->bpp / 8; + framesize = PAGE_ALIGN(fb->panel->mode.xres * fb->panel->mode.yres * + fb->panel->bpp / 8); fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, &dma, GFP_KERNEL); if (!fb->fb.screen_base) -- cgit v1.2.3 From 7d6140b4de8b7e41f5cc9fab01fd7a91f72108f9 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Wed, 29 Mar 2017 15:00:54 +1100 Subject: drm/radeon: Fail fb creation from imported dma-bufs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a294043b2fbd8de69d161457ed0c7a4026bbfa5a ] Any use of the framebuffer will migrate it to VRAM, which is not sensible for an imported dma-buf. v2: Use DRM_DEBUG_KMS to prevent userspace accidentally spamming dmesg. Reviewed-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Christopher James Halse Rogers CC: amd-gfx@lists.freedesktop.org Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_display.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index cdb8cb568c15..ca1caf405832 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1352,6 +1352,12 @@ radeon_user_framebuffer_create(struct drm_device *dev, return ERR_PTR(-ENOENT); } + /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ + if (obj->import_attach) { + DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n"); + return ERR_PTR(-EINVAL); + } + radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); if (radeon_fb == NULL) { drm_gem_object_unreference_unlocked(obj); -- cgit v1.2.3 From 3820303837014a00e40e69f9a648aed6cc78f92a Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Wed, 29 Mar 2017 15:02:11 +1100 Subject: drm/amdgpu: Fail fb creation from imported dma-bufs. (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 1769152ac64b0b07583f696b621624df2ca4c840 ] Any use of the framebuffer will migrate it to VRAM, which is not sensible for an imported dma-buf. v2: Use DRM_DEBUG_KMS to prevent userspace accidentally spamming dmesg. Reviewed-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Christopher James Halse Rogers CC: amd-gfx@lists.freedesktop.org Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 083e2b429872..15a2d8f3725d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -533,6 +533,12 @@ amdgpu_user_framebuffer_create(struct drm_device *dev, return ERR_PTR(-ENOENT); } + /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ + if (obj->import_attach) { + DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n"); + return ERR_PTR(-EINVAL); + } + amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL); if (amdgpu_fb == NULL) { drm_gem_object_unreference_unlocked(obj); -- cgit v1.2.3 From 543a1817e58005b5db834a5aa60a78d9095cad81 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Thu, 6 Apr 2017 20:31:20 +0800 Subject: drm/rockchip: vop: Enable pm domain before vop_initial [ Upstream commit 5e570373c015b60a68828b1cd9d475cb33d3be4b ] We're trying to access vop registers here, so need to make sure the pm domain is on. Normally it should be enabled by the bootloader, but there's no guarantee of it. And if we wanna do unbind/bind, it would also cause the device to hang. And this patch also does these: 1/ move vop_initial to the end of vop_bind for eaiser error handling. 2/ correct the err_put_pm_runtime of vop_enable. Signed-off-by: Jeffy Chen Signed-off-by: Sean Paul Link: http://patchwork.freedesktop.org/patch/msgid/1491481885-13775-8-git-send-email-jeffy.chen@rock-chips.com Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c7eba305c488..6e3c4acb16ac 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -503,7 +503,7 @@ static int vop_enable(struct drm_crtc *crtc) ret = pm_runtime_get_sync(vop->dev); if (ret < 0) { dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); - goto err_put_pm_runtime; + return ret; } ret = clk_enable(vop->hclk); @@ -1348,10 +1348,16 @@ static int vop_initial(struct vop *vop) return PTR_ERR(vop->dclk); } + ret = pm_runtime_get_sync(vop->dev); + if (ret < 0) { + dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); + return ret; + } + ret = clk_prepare(vop->dclk); if (ret < 0) { dev_err(vop->dev, "failed to prepare dclk\n"); - return ret; + goto err_put_pm_runtime; } /* Enable both the hclk and aclk to setup the vop */ @@ -1411,6 +1417,8 @@ static int vop_initial(struct vop *vop) vop->is_enabled = false; + pm_runtime_put_sync(vop->dev); + return 0; err_disable_aclk: @@ -1419,6 +1427,8 @@ err_disable_hclk: clk_disable_unprepare(vop->hclk); err_unprepare_dclk: clk_unprepare(vop->dclk); +err_put_pm_runtime: + pm_runtime_put_sync(vop->dev); return ret; } @@ -1519,12 +1529,6 @@ static int vop_bind(struct device *dev, struct device *master, void *data) if (!vop->regsbak) return -ENOMEM; - ret = vop_initial(vop); - if (ret < 0) { - dev_err(&pdev->dev, "cannot initial vop dev - err %d\n", ret); - return ret; - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "cannot find irq for vop\n"); @@ -1551,8 +1555,17 @@ static int vop_bind(struct device *dev, struct device *master, void *data) pm_runtime_enable(&pdev->dev); + ret = vop_initial(vop); + if (ret < 0) { + dev_err(&pdev->dev, "cannot initial vop dev - err %d\n", ret); + goto err_disable_pm_runtime; + } + return 0; +err_disable_pm_runtime: + pm_runtime_disable(&pdev->dev); + vop_destroy_crtc(vop); err_enable_irq: enable_irq(vop->irq); /* To balance out the disable_irq above */ return ret; -- cgit v1.2.3 From a9a100b20d71c2a2a959418bebdb651379f99b6a Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 4 Apr 2017 12:40:16 -0700 Subject: i40e: only register client on iWarp-capable devices [ Upstream commit 004eb614c4d2fcc12a98714fd887a860582f203a ] The client interface is only intended for use on devices that support iWarp. Only register with the client if this is the case. This fixes a panic when loading i40iw on X710 devices. Signed-off-by: Mitch Williams Reported-by: Stefan Assmann Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_main.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index becffd15c092..57c7456a5751 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -11142,10 +11142,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) round_jiffies(jiffies + pf->service_timer_period)); /* add this PF to client device list and launch a client service task */ - err = i40e_lan_add_device(pf); - if (err) - dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n", - err); + if (pf->flags & I40E_FLAG_IWARP_ENABLED) { + err = i40e_lan_add_device(pf); + if (err) + dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n", + err); + } #ifdef I40E_FCOE /* create FCoE interface */ @@ -11323,10 +11325,11 @@ static void i40e_remove(struct pci_dev *pdev) i40e_vsi_release(pf->vsi[pf->lan_vsi]); /* remove attached clients */ - ret_code = i40e_lan_del_device(pf); - if (ret_code) { - dev_warn(&pdev->dev, "Failed to delete client device: %d\n", - ret_code); + if (pf->flags & I40E_FLAG_IWARP_ENABLED) { + ret_code = i40e_lan_del_device(pf); + if (ret_code) + dev_warn(&pdev->dev, "Failed to delete client device: %d\n", + ret_code); } /* shutdown and destroy the HMC */ -- cgit v1.2.3 From b1a579996f63e2b6a88e8360953884bb6f965ced Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Mon, 27 Mar 2017 11:09:33 -0600 Subject: coresight: Fixes coresight DT parse to get correct output port ID. [ Upstream commit eeedc5421dd3b51de73e6106405c5c77f920f281 ] Corrected to get the port numbering to allow programmable replicator driver to operate correctly. By convention, CoreSight devices number ports, not endpoints in the .dts files:- port { reg endpoint { } } Existing code read endpoint number - always 0x0, rather than the correct port number. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/of_coresight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 629e031b7456..09142e99e915 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -149,7 +149,7 @@ struct coresight_platform_data *of_get_coresight_platform_data( continue; /* The local out port number */ - pdata->outports[i] = endpoint.id; + pdata->outports[i] = endpoint.port; /* * Get a handle on the remote port and parent -- cgit v1.2.3 From ad8d41ba596be6c054e5956b145fa223a5bb8b37 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Mar 2017 11:57:27 +0200 Subject: lkdtm: turn off kcov for lkdtm_rodata_do_nothing: [ Upstream commit 7064dc7fc13b2994d33ae540ffb7a3a05ac463bf ] I ran into a link error on ARM64 for lkdtm_rodata_do_nothing: drivers/misc/built-in.o: In function `lkdtm_rodata_do_nothing': :(.rodata+0x68c8): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__sanitizer_cov_trace_pc' defined in .text section in kernel/built-in.o I did not analyze this further, but my theory is that we would need a trampoline to call __sanitizer_cov_trace_pc(), but the linker (correctly) only adds trampolines for callers in executable sections. Disabling KCOV for this one file avoids the build failure with no other practical downsides I can think of. The problem can only happen on kernels that contain both kcov and lkdtm, so if we want to backport this, it should be in the earliest version that has both (v4.8). Fixes: 5c9a8750a640 ("kernel: add kcov code coverage") Fixes: 9a49a528dcf3 ("lkdtm: add function for testing .rodata section") Signed-off-by: Arnd Bergmann Acked-by: Dmitry Vyukov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 31983366090a..2bf79ba4a39e 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -61,6 +61,8 @@ lkdtm-$(CONFIG_LKDTM) += lkdtm_perms.o lkdtm-$(CONFIG_LKDTM) += lkdtm_rodata_objcopy.o lkdtm-$(CONFIG_LKDTM) += lkdtm_usercopy.o +KCOV_INSTRUMENT_lkdtm_rodata.o := n + OBJCOPYFLAGS := OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \ --set-section-flags .text=alloc,readonly \ -- cgit v1.2.3 From 7d257fe12895703db6a7f0b47b2fe2a918512310 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Sat, 1 Apr 2017 19:42:09 +0000 Subject: tty: amba-pl011: Fix spurious TX interrupts [ Upstream commit 7d05587c9e0e4611650bb403812e2d492c178a9f ] On SMP systems, we see a lot of spurious TX interrupts when a program generates a steady stream of output to the pl011 UART. The problem can be easily seen when one CPU generates the output while another CPU handles the pl011 interrupts, and the rate of output is low enough not to fill the TX FIFO. The problem seems to be: -- CPU a -- -- CPU b -- (take port lock) pl011_start_tx pl011_start_tx_pio enable TXIM in REG_IMSC -> causes uart tx intr (pl011_int) pl011_tx_chars pl011_int ...tx chars, all done... (wait for port lock) pl011_stop_tx . disable TXIM . (release port lock) -> (take port lock) check for TXIM, not enabled (release port lock) return IRQ_NONE Enabling the TXIM in pl011_start_tx_pio() causes the interrupt to be generated and delivered to CPU b, even though pl011_tx_chars() is able to complete the TX and then disable the tx interrupt. Fix this by enabling TXIM only after pl011_tx_chars, if it is needed. pl011_tx_chars will return a boolean indicating whether the TX interrupts have to be enabled. Debugged-by: Vijaya Kumar Signed-off-by: Jayachandran C Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index e2c33b9528d8..b42d7f1c9089 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1302,14 +1302,15 @@ static void pl011_stop_tx(struct uart_port *port) pl011_dma_tx_stop(uap); } -static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); +static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); /* Start TX with programmed I/O only (no DMA) */ static void pl011_start_tx_pio(struct uart_amba_port *uap) { - uap->im |= UART011_TXIM; - pl011_write(uap->im, uap, REG_IMSC); - pl011_tx_chars(uap, false); + if (pl011_tx_chars(uap, false)) { + uap->im |= UART011_TXIM; + pl011_write(uap->im, uap, REG_IMSC); + } } static void pl011_start_tx(struct uart_port *port) @@ -1389,25 +1390,26 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, return true; } -static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) +/* Returns true if tx interrupts have to be (kept) enabled */ +static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) { struct circ_buf *xmit = &uap->port.state->xmit; int count = uap->fifosize >> 1; if (uap->port.x_char) { if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) - return; + return true; uap->port.x_char = 0; --count; } if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { pl011_stop_tx(&uap->port); - return; + return false; } /* If we are using DMA mode, try to send some characters. */ if (pl011_dma_tx_irq(uap)) - return; + return true; do { if (likely(from_irq) && count-- == 0) @@ -1422,8 +1424,11 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); - if (uart_circ_empty(xmit)) + if (uart_circ_empty(xmit)) { pl011_stop_tx(&uap->port); + return false; + } + return true; } static void pl011_modem_status(struct uart_amba_port *uap) -- cgit v1.2.3 From 57a84887bc773d937bc87a558ffdf2f21f91c786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 4 Apr 2017 11:18:51 +0200 Subject: serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e61c38d85b7392e033ee03bca46f1d6006156175 ] If the UART is operated in DTE mode and UCR3_DCD or UCR3_RI are 1 (which is the reset default) and the opposite side pulls the respective line to its active level the irq triggers after it is requested in .probe. These irqs were already disabled in .startup but this might be too late. Also setup of the UFCR_DCEDTE bit (currently done in .set_termios) is done very late which is critical as it also controls direction of some pins. So setup UFCR_DCEDTE earlier (in .probe) and also disable the broken irqs in DTE mode there before requesting irqs. Acked-by: Lucas Stach Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 521a6e450755..f575a33974fa 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1316,19 +1316,10 @@ static int imx_startup(struct uart_port *port) if (!is_imx1_uart(sport)) { temp = readl(sport->port.membase + UCR3); - /* - * The effect of RI and DCD differs depending on the UFCR_DCEDTE - * bit. In DCE mode they control the outputs, in DTE mode they - * enable the respective irqs. At least the DCD irq cannot be - * cleared on i.MX25 at least, so it's not usable and must be - * disabled. I don't have test hardware to check if RI has the - * same problem but I consider this likely so it's disabled for - * now, too. - */ - temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | - UCR3_DTRDEN | UCR3_RI | UCR3_DCD; + temp |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD; if (sport->dte_mode) + /* disable broken interrupts */ temp &= ~(UCR3_RI | UCR3_DCD); writel(temp, sport->port.membase + UCR3); @@ -1583,8 +1574,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, ufcr = readl(sport->port.membase + UFCR); ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div); - if (sport->dte_mode) - ufcr |= UFCR_DCEDTE; writel(ufcr, sport->port.membase + UFCR); writel(num, sport->port.membase + UBIR); @@ -2149,6 +2138,27 @@ static int serial_imx_probe(struct platform_device *pdev) UCR1_TXMPTYEN | UCR1_RTSDEN); writel_relaxed(reg, sport->port.membase + UCR1); + if (!is_imx1_uart(sport) && sport->dte_mode) { + /* + * The DCEDTE bit changes the direction of DSR, DCD, DTR and RI + * and influences if UCR3_RI and UCR3_DCD changes the level of RI + * and DCD (when they are outputs) or enables the respective + * irqs. So set this bit early, i.e. before requesting irqs. + */ + writel(UFCR_DCEDTE, sport->port.membase + UFCR); + + /* + * Disable UCR3_RI and UCR3_DCD irqs. They are also not + * enabled later because they cannot be cleared + * (confirmed on i.MX25) which makes them unusable. + */ + writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR, + sport->port.membase + UCR3); + + } else { + writel(0, sport->port.membase + UFCR); + } + clk_disable_unprepare(sport->clk_ipg); /* -- cgit v1.2.3 From 735b0f043d484a535a7a8f57157e32bade8ae1ef Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 6 Jan 2017 10:15:28 -0200 Subject: v4l: vsp1: Prevent multiple streamon race commencing pipeline early [ Upstream commit 4461c84b52b4a952c657505ef7e4e06b016783df ] With multiple inputs through the BRU it is feasible for the streams to race each other at stream-on. Multiple VIDIOC_STREAMON calls racing each other could have process N-1 skipping over the pipeline setup section and then start the pipeline early, if videobuf2 has already enqueued buffers to the driver for process N but not called the .start_streaming() operation yet In the case of the video pipelines, this can present two serious issues. 1) A null-dereference if the pipe->dl is committed at the same time as the vsp1_video_setup_pipeline() is processing 2) A hardware hang, where a display list is committed without having called vsp1_video_setup_pipeline() first Repair this issue, by ensuring that only the stream which configures the pipeline is able to start it. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/vsp1/vsp1_video.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index d351b9c768d2..743aa0febc09 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -792,6 +792,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vsp1_video *video = vb2_get_drv_priv(vq); struct vsp1_pipeline *pipe = video->rwpf->pipe; + bool start_pipeline = false; unsigned long flags; int ret; @@ -802,11 +803,23 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) mutex_unlock(&pipe->lock); return ret; } + + start_pipeline = true; } pipe->stream_count++; mutex_unlock(&pipe->lock); + /* + * vsp1_pipeline_ready() is not sufficient to establish that all streams + * are prepared and the pipeline is configured, as multiple streams + * can race through streamon with buffers already queued; Therefore we + * don't even attempt to start the pipeline until the last stream has + * called through here. + */ + if (!start_pipeline) + return 0; + spin_lock_irqsave(&pipe->irqlock, flags); if (vsp1_pipeline_ready(pipe)) vsp1_video_pipeline_run(pipe); -- cgit v1.2.3 From d7928e10b468c465b597d738bc93e30aa4b34dff Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Mon, 27 Feb 2017 10:40:34 -0300 Subject: v4l: vsp1: Register pipe with output WPF [ Upstream commit 1531a208ed861e4bd287444f9466ffcf98383de2 ] The DRM object does not register the pipe with the WPF object. This is used internally throughout the driver as a means of accessing the pipe. As such this breaks operations which require access to the pipe from WPF interrupts. Register the pipe inside the WPF object after it has been declared as the output. Fixes: ff7e97c94d9f ("[media] v4l: vsp1: Store pipeline pointer in rwpf") Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/vsp1/vsp1_drm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index cd209dccff1b..8e2aa3f8e52f 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -596,6 +596,7 @@ int vsp1_drm_init(struct vsp1_device *vsp1) pipe->bru = &vsp1->bru->entity; pipe->lif = &vsp1->lif->entity; pipe->output = vsp1->wpf[0]; + pipe->output->pipe = pipe; return 0; } -- cgit v1.2.3 From b42b97a5657f49c51f523f691e8a867708a38b80 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 Apr 2017 12:11:32 +1000 Subject: md/raid6: Fix anomily when recovering a single device in RAID6. [ Upstream commit 7471fb77ce4dc4cb81291189947fcdf621a97987 ] When recoverying a single missing/failed device in a RAID6, those stripes where the Q block is on the missing device are handled a bit differently. In these cases it is easy to check that the P block is correct, so we do. This results in the P block be destroy. Consequently the P block needs to be read a second time in order to compute Q. This causes lots of seeks and hurts performance. It shouldn't be necessary to re-read P as it can be computed from the DATA. But we only compute blocks on missing devices, since c337869d9501 ("md: do not compute parity unless it is on a failed drive"). So relax the change made in that commit to allow computing of the P block in a RAID6 which it is the only missing that block. This makes RAID6 recovery run much faster as the disk just "before" the recovering device is no longer seeking back-and-forth. Reported-by-tested-by: Brad Campbell Reviewed-by: Dan Williams Signed-off-by: NeilBrown Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid5.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 475a7a1bcfe0..4493be50fc6a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3391,9 +3391,20 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, BUG_ON(test_bit(R5_Wantcompute, &dev->flags)); BUG_ON(test_bit(R5_Wantread, &dev->flags)); BUG_ON(sh->batch_head); + + /* + * In the raid6 case if the only non-uptodate disk is P + * then we already trusted P to compute the other failed + * drives. It is safe to compute rather than re-read P. + * In other cases we only compute blocks from failed + * devices, otherwise check/repair might fail to detect + * a real inconsistency. + */ + if ((s->uptodate == disks - 1) && + ((sh->qd_idx >= 0 && sh->pd_idx == disk_idx) || (s->failed && (disk_idx == s->failed_num[0] || - disk_idx == s->failed_num[1]))) { + disk_idx == s->failed_num[1])))) { /* have disk failed, and we're requested to fetch it; * do compute it */ -- cgit v1.2.3 From 1f8fe98e0e096728a47bda7bf9a632b3e89970b5 Mon Sep 17 00:00:00 2001 From: Zhilong Liu Date: Mon, 10 Apr 2017 14:15:55 +0800 Subject: md.c:didn't unlock the mddev before return EINVAL in array_size_store [ Upstream commit b670883bb9e55ba63a278d83e034faefc01ce2cf ] md.c: it needs to release the mddev lock before the array_size_store() returns. Fixes: ab5a98b132fd ("md-cluster: change array_sectors and update size are not supported") Signed-off-by: Zhilong Liu Reviewed-by: Guoqing Jiang Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/md.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 27d8bb21e04f..a7bc70334f0e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4826,8 +4826,10 @@ array_size_store(struct mddev *mddev, const char *buf, size_t len) return err; /* cluster raid doesn't support change array_sectors */ - if (mddev_is_clustered(mddev)) + if (mddev_is_clustered(mddev)) { + mddev_unlock(mddev); return -EINVAL; + } if (strncmp(buf, "default", 7) == 0) { if (mddev->pers) -- cgit v1.2.3 From 813bd8c7e5a0a02c6f9bb332d5b44ec20db02ab0 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 13 Feb 2017 20:08:08 -0800 Subject: usb: dwc2: Make sure we disconnect the gadget state [ Upstream commit dad3f793f20fbb5c0c342f0f5a0bdf69a4d76089 ] I had seen some odd behavior with HiKey's usb-gadget interface that I finally seemed to have chased down. Basically every other time I plugged in the OTG port, the gadget interface would properly initialize. The other times, I'd get a big WARN_ON in dwc2_hsotg_init_fifo() about the fifo_map not being clear. Ends up if we don't disconnect the gadget state, the fifo-map doesn't get cleared properly, which causes WARN_ON messages and also results in the device not properly being setup as a gadget every other time the OTG port is connected. So this patch adds a call to dwc2_hsotg_disconnect() in the reset path so the state is properly cleared. With it, the gadget interface initializes properly on every plug in. Cc: Wei Xu Cc: Guodong Xu Cc: Amit Pundir Cc: Rob Herring Cc: John Youn Cc: Douglas Anderson Cc: Chen Yu Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Acked-by: John Youn Signed-off-by: John Stultz Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/hcd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index df5a06578005..dfc0566bb155 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3220,6 +3220,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); spin_lock_irqsave(&hsotg->lock, flags); + dwc2_hsotg_disconnect(hsotg); dwc2_hsotg_core_init_disconnected(hsotg, false); spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hsotg_core_connect(hsotg); -- cgit v1.2.3 From d9586e4a882a054e1abd41f3eeb224ecb94e2632 Mon Sep 17 00:00:00 2001 From: Yuyang Du Date: Fri, 24 Mar 2017 04:06:11 +0800 Subject: usb: gadget: dummy_hcd: Fix wrong power status bit clear/reset in dummy_hub_control() [ Upstream commit 9f20dfb44d03745d0d3cef2ffb3abf8d8024fa61 ] This fixes the commit: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support"). In the case of ClearPortFeature and USB_PORT_FEAT_POWER, simply clear the right bit regardless of what the wValue is. Acked-by: Alan Stern Signed-off-by: Yuyang Du Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/dummy_hcd.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index b62a3de65075..ff4d6cac7ac0 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -2103,16 +2103,13 @@ static int dummy_hub_control( } break; case USB_PORT_FEAT_POWER: - if (hcd->speed == HCD_USB3) { - if (dum_hcd->port_status & USB_PORT_STAT_POWER) - dev_dbg(dummy_dev(dum_hcd), - "power-off\n"); - } else - if (dum_hcd->port_status & - USB_SS_PORT_STAT_POWER) - dev_dbg(dummy_dev(dum_hcd), - "power-off\n"); - /* FALLS THROUGH */ + dev_dbg(dummy_dev(dum_hcd), "power-off\n"); + if (hcd->speed == HCD_USB3) + dum_hcd->port_status &= ~USB_SS_PORT_STAT_POWER; + else + dum_hcd->port_status &= ~USB_PORT_STAT_POWER; + set_link_state(dum_hcd); + break; default: dum_hcd->port_status &= ~(1 << wValue); set_link_state(dum_hcd); @@ -2283,14 +2280,13 @@ static int dummy_hub_control( if ((dum_hcd->port_status & USB_SS_PORT_STAT_POWER) != 0) { dum_hcd->port_status |= (1 << wValue); - set_link_state(dum_hcd); } } else if ((dum_hcd->port_status & USB_PORT_STAT_POWER) != 0) { dum_hcd->port_status |= (1 << wValue); - set_link_state(dum_hcd); } + set_link_state(dum_hcd); } break; case GetPortErrorCount: -- cgit v1.2.3 From 3efaebb3bbc1a5d702ed0a943b91cd14f78d0bab Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 14 Dec 2016 13:48:04 +0100 Subject: iwlwifi: mvm: fix RX SKB header size and align it properly [ Upstream commit 5cddd05c9cbe420436799716d009bc0372ef8268 ] When receiving a frame, we currently pull in sizeof(*hdr) plus some extra (crypto/snap), which is too much, most headers aren't actually sizeof(*hdr) since that takes into account the 4-address format but doesn't take into account QoS. As a result, a typical frame will have 4 bytes of the payload in the SKB header already. Fix this by calculating the correct header length, and now that we have that, align the end of the SKB header to a multiple of 4 so that the IP header will be aligned properly when pulled in. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 0e60e38b2acf..b78e60eb600f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -104,7 +104,20 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, u8 crypt_len, struct iwl_rx_cmd_buffer *rxb) { - unsigned int hdrlen, fraglen; + unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); + unsigned int fraglen; + + /* + * The 'hdrlen' (plus the 8 bytes for the SNAP and the crypt_len, + * but those are all multiples of 4 long) all goes away, but we + * want the *end* of it, which is going to be the start of the IP + * header, to be aligned when it gets pulled in. + * The beginning of the skb->data is aligned on at least a 4-byte + * boundary after allocation. Everything here is aligned at least + * on a 2-byte boundary so we can just take hdrlen & 3 and pad by + * the result. + */ + skb_reserve(skb, hdrlen & 3); /* If frame is small enough to fit in skb->head, pull it completely. * If not, only pull ieee80211_hdr (including crypto if present, and @@ -118,8 +131,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, * If the latter changes (there are efforts in the standards group * to do so) we should revisit this and ieee80211_data_to_8023(). */ - hdrlen = (len <= skb_tailroom(skb)) ? len : - sizeof(*hdr) + crypt_len + 8; + hdrlen = (len <= skb_tailroom(skb)) ? len : hdrlen + crypt_len + 8; memcpy(skb_put(skb, hdrlen), hdr, hdrlen); fraglen = len - hdrlen; -- cgit v1.2.3 From 80e1caf00d148ff8034861551d41faa6c537df8c Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 11 Apr 2017 09:39:49 +0100 Subject: drivers/perf: arm_pmu: handle no platform_device [ Upstream commit 7654137071fa706e5c91f4f27bc2a5cd7e435a9b ] In armpmu_dispatch_irq() we look at arm_pmu::plat_device to acquire platdata, so that we can defer to platform-specific IRQ handling, required on some 32-bit parts. With the advent of ACPI we won't always have a platform_device, and so we must avoid trying to dereference fields from it. This patch fixes up armpmu_dispatch_irq() to avoid doing so, introducing a new armpmu_get_platdata() helper. Signed-off-by: Mark Rutland Tested-by: Jeremy Linton Cc: Will Deacon Signed-off-by: Will Deacon Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/perf/arm_pmu.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index b37b57294566..af82edc7fa5c 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -322,10 +322,16 @@ validate_group(struct perf_event *event) return 0; } +static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu) +{ + struct platform_device *pdev = armpmu->plat_device; + + return pdev ? dev_get_platdata(&pdev->dev) : NULL; +} + static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) { struct arm_pmu *armpmu; - struct platform_device *plat_device; struct arm_pmu_platdata *plat; int ret; u64 start_clock, finish_clock; @@ -337,8 +343,8 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) * dereference. */ armpmu = *(void **)dev; - plat_device = armpmu->plat_device; - plat = dev_get_platdata(&plat_device->dev); + + plat = armpmu_get_platdata(armpmu); start_clock = sched_clock(); if (plat && plat->handle_irq) -- cgit v1.2.3 From 8c4e5168dd2776147acb4a94f941508809262365 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Tue, 11 Apr 2017 19:13:06 +0800 Subject: net: fec: add phy-reset-gpios PROBE_DEFER check [ Upstream commit 9269e5560b261eb9ee157497890dc0948db76cf8 ] Many boards use i2c/spi expander gpio as phy-reset-gpios and these gpios maybe registered after fec port, driver should check the return value of .of_get_named_gpio(). Signed-off-by: Fugang Duan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/fec_main.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 917091871259..dd6e07c748f5 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3209,7 +3209,7 @@ static int fec_enet_init(struct net_device *ndev) } #ifdef CONFIG_OF -static void fec_reset_phy(struct platform_device *pdev) +static int fec_reset_phy(struct platform_device *pdev) { int err, phy_reset; bool active_high = false; @@ -3217,7 +3217,7 @@ static void fec_reset_phy(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; if (!np) - return; + return 0; of_property_read_u32(np, "phy-reset-duration", &msec); /* A sane reset duration should not be longer than 1s */ @@ -3225,8 +3225,10 @@ static void fec_reset_phy(struct platform_device *pdev) msec = 1; phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); - if (!gpio_is_valid(phy_reset)) - return; + if (phy_reset == -EPROBE_DEFER) + return phy_reset; + else if (!gpio_is_valid(phy_reset)) + return 0; active_high = of_property_read_bool(np, "phy-reset-active-high"); @@ -3235,7 +3237,7 @@ static void fec_reset_phy(struct platform_device *pdev) "phy-reset"); if (err) { dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err); - return; + return err; } if (msec > 20) @@ -3244,14 +3246,17 @@ static void fec_reset_phy(struct platform_device *pdev) usleep_range(msec * 1000, msec * 1000 + 1000); gpio_set_value_cansleep(phy_reset, !active_high); + + return 0; } #else /* CONFIG_OF */ -static void fec_reset_phy(struct platform_device *pdev) +static int fec_reset_phy(struct platform_device *pdev) { /* * In case of platform probe, the reset has been done * by machine code. */ + return 0; } #endif /* CONFIG_OF */ @@ -3422,6 +3427,7 @@ fec_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to enable phy regulator: %d\n", ret); + clk_disable_unprepare(fep->clk_ipg); goto failed_regulator; } } else { @@ -3434,7 +3440,9 @@ fec_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - fec_reset_phy(pdev); + ret = fec_reset_phy(pdev); + if (ret) + goto failed_reset; if (fep->bufdesc_ex) fec_ptp_init(pdev); @@ -3495,8 +3503,10 @@ failed_init: fec_ptp_stop(pdev); if (fep->reg_phy) regulator_disable(fep->reg_phy); +failed_reset: + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); failed_regulator: - clk_disable_unprepare(fep->clk_ipg); failed_clk_ipg: fec_enet_clk_enable(ndev, false); failed_clk: -- cgit v1.2.3 From 5d7601dcb29d4b51cc32da4a744533f524a6fc8a Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 24 Mar 2017 17:44:06 +1100 Subject: vfio/powerpc/spapr_tce: Enforce IOMMU type compatibility check [ Upstream commit 1282ba7fc28dbc66c3f0e4aaafaaa228361d1ae5 ] The existing SPAPR TCE driver advertises both VFIO_SPAPR_TCE_IOMMU and VFIO_SPAPR_TCE_v2_IOMMU types to the userspace and the userspace usually picks the v2. Normally the userspace would create a container, attach an IOMMU group to it and only then set the IOMMU type (which would normally be v2). However a specific IOMMU group may not support v2, in other words it may not implement set_window/unset_window/take_ownership/ release_ownership and such a group should not be attached to a v2 container. This adds extra checks that a new group can do what the selected IOMMU type suggests. The userspace can then test the return value from ioctl(VFIO_SET_IOMMU, VFIO_SPAPR_TCE_v2_IOMMU) and try VFIO_SPAPR_TCE_IOMMU. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/vfio_iommu_spapr_tce.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 59b3f62a2d64..87ad0d72d8a9 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -1332,8 +1332,16 @@ static int tce_iommu_attach_group(void *iommu_data, if (!table_group->ops || !table_group->ops->take_ownership || !table_group->ops->release_ownership) { + if (container->v2) { + ret = -EPERM; + goto unlock_exit; + } ret = tce_iommu_take_ownership(container, table_group); } else { + if (!container->v2) { + ret = -EPERM; + goto unlock_exit; + } ret = tce_iommu_take_ownership_ddw(container, table_group); if (!tce_groups_attached(container) && !container->tables[0]) container->def_window_pending = true; -- cgit v1.2.3 From bab8ac1b274eb835a6ac33501dbd010fc0262822 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Mon, 27 Mar 2017 14:23:40 +1100 Subject: vfio/spapr_tce: Check kzalloc() return when preregistering memory [ Upstream commit 3393af24b665cb0aea7353b05e522b03ab1e7d73 ] This adds missing checking for kzalloc() return value. Fixes: 4b6fad7097f8 ("powerpc/mm/iommu, vfio/spapr: Put pages on VFIO container shutdown") Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/vfio_iommu_spapr_tce.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 87ad0d72d8a9..70c748a5fbcc 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -195,6 +195,11 @@ static long tce_iommu_register_pages(struct tce_container *container, return ret; tcemem = kzalloc(sizeof(*tcemem), GFP_KERNEL); + if (!tcemem) { + mm_iommu_put(container->mm, mem); + return -ENOMEM; + } + tcemem->mem = mem; list_add(&tcemem->next, &container->prereg_list); -- cgit v1.2.3 From 602f933e0314b6ec4fca46e57127a08f917ed7c5 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Fri, 7 Apr 2017 09:34:15 +0200 Subject: scsi: sg: check for valid direction before starting the request [ Upstream commit 28676d869bbb5257b5f14c0c95ad3af3a7019dd5 ] Check for a valid direction before starting the request, otherwise we risk running into an assertion in the scsi midlayer checking for valid requests. [mkp: fixed typo] Signed-off-by: Johannes Thumshirn Link: http://www.spinics.net/lists/linux-scsi/msg104400.html Reported-by: Dmitry Vyukov Signed-off-by: Hannes Reinecke Tested-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cd9537ddc19f..6b6064dc3467 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -663,18 +663,14 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) * is a non-zero input_size, so emit a warning. */ if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV) { - static char cmd[TASK_COMM_LEN]; - if (strcmp(current->comm, cmd)) { - printk_ratelimited(KERN_WARNING - "sg_write: data in/out %d/%d bytes " - "for SCSI command 0x%x-- guessing " - "data in;\n program %s not setting " - "count and/or reply_len properly\n", - old_hdr.reply_len - (int)SZ_SG_HEADER, - input_size, (unsigned int) cmnd[0], - current->comm); - strcpy(cmd, current->comm); - } + printk_ratelimited(KERN_WARNING + "sg_write: data in/out %d/%d bytes " + "for SCSI command 0x%x-- guessing " + "data in;\n program %s not setting " + "count and/or reply_len properly\n", + old_hdr.reply_len - (int)SZ_SG_HEADER, + input_size, (unsigned int) cmnd[0], + current->comm); } k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking); return (k < 0) ? k : count; @@ -753,6 +749,29 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, return count; } +static bool sg_is_valid_dxfer(sg_io_hdr_t *hp) +{ + switch (hp->dxfer_direction) { + case SG_DXFER_NONE: + if (hp->dxferp || hp->dxfer_len > 0) + return false; + return true; + case SG_DXFER_TO_DEV: + case SG_DXFER_FROM_DEV: + case SG_DXFER_TO_FROM_DEV: + if (!hp->dxferp || hp->dxfer_len == 0) + return false; + return true; + case SG_DXFER_UNKNOWN: + if ((!hp->dxferp && hp->dxfer_len) || + (hp->dxferp && hp->dxfer_len == 0)) + return false; + return true; + default: + return false; + } +} + static int sg_common_write(Sg_fd * sfp, Sg_request * srp, unsigned char *cmnd, int timeout, int blocking) @@ -773,6 +792,9 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, "sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) cmnd[0], (int) hp->cmd_len)); + if (!sg_is_valid_dxfer(hp)) + return -EINVAL; + k = sg_start_req(srp, cmnd); if (k) { SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, -- cgit v1.2.3 From ae9b6ae2e77947534e255903627cc62746ea77e2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 7 Apr 2017 09:34:17 +0200 Subject: scsi: sg: close race condition in sg_remove_sfp_usercontext() [ Upstream commit 97d27b0dd015e980ade63fda111fd1353276e28b ] sg_remove_sfp_usercontext() is clearing any sg requests, but needs to take 'rq_list_lock' when modifying the list. Reported-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Tested-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 6b6064dc3467..e6333cae8550 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -524,6 +524,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) } else count = (old_hdr->result == 0) ? 0 : -EIO; sg_finish_rem_req(srp); + sg_remove_request(sfp, srp); retval = count; free_old_hdr: kfree(old_hdr); @@ -564,6 +565,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) } err_out: err2 = sg_finish_rem_req(srp); + sg_remove_request(sfp, srp); return err ? : err2 ? : count; } @@ -800,6 +802,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, "sg_common_write: start_req err=%d\n", k)); sg_finish_rem_req(srp); + sg_remove_request(sfp, srp); return k; /* probably out of space --> ENOMEM */ } if (atomic_read(&sdp->detaching)) { @@ -812,6 +815,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, } sg_finish_rem_req(srp); + sg_remove_request(sfp, srp); return -ENODEV; } @@ -1302,6 +1306,7 @@ sg_rq_end_io_usercontext(struct work_struct *work) struct sg_fd *sfp = srp->parentfp; sg_finish_rem_req(srp); + sg_remove_request(sfp, srp); kref_put(&sfp->f_ref, sg_remove_sfp); } @@ -1846,8 +1851,6 @@ sg_finish_rem_req(Sg_request *srp) else sg_remove_scat(sfp, req_schp); - sg_remove_request(sfp, srp); - return ret; } @@ -2194,12 +2197,17 @@ sg_remove_sfp_usercontext(struct work_struct *work) struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work); struct sg_device *sdp = sfp->parentdp; Sg_request *srp; + unsigned long iflags; /* Cleanup any responses which were never read(). */ + write_lock_irqsave(&sfp->rq_list_lock, iflags); while (!list_empty(&sfp->rq_list)) { srp = list_first_entry(&sfp->rq_list, Sg_request, entry); sg_finish_rem_req(srp); + list_del(&srp->entry); + srp->parentfp = NULL; } + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); if (sfp->reserve.bufflen > 0) { SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp, -- cgit v1.2.3 From 99f3e3b0a8dbbf72173b18fe8b8df625c94cc7df Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 7 Apr 2017 15:04:00 +0530 Subject: pwm: tegra: Increase precision in PWM rate calculation [ Upstream commit 250b76f43f57d578ebff5e7211eb2c73aa5cd6ca ] The rate of the PWM calculated as follows: hz = NSEC_PER_SEC / period_ns; rate = (rate + (hz / 2)) / hz; This has the precision loss in lower PWM rate. Change this to have more precision as: hz = DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC * 100, period_ns); rate = DIV_ROUND_CLOSEST(rate * 100, hz) Example: 1. period_ns = 16672000, PWM clock rate is 200 KHz. Based on old formula hz = NSEC_PER_SEC / period_ns = 1000000000ul/16672000 = 59 (59.98) rate = (200K + 59/2)/59 = 3390 Based on new method: hz = 5998 rate = DIV_ROUND_CLOSE(200000*100, 5998) = 3334 If we measure the PWM signal rate, we will get more accurate period with rate value of 3334 instead of 3390. 2. period_ns = 16803898, PWM clock rate is 200 KHz. Based on old formula: hz = 59, rate = 3390 Based on new formula: hz = 5951, rate = 3360 The PWM signal rate of 3360 is more near to requested period than 3333. Signed-off-by: Laxman Dewangan Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-tegra.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index e4647840cd6e..7e8906d6ab7a 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -76,6 +76,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip); unsigned long long c = duty_ns; unsigned long rate, hz; + unsigned long long ns100 = NSEC_PER_SEC; u32 val = 0; int err; @@ -95,9 +96,11 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, * cycles at the PWM clock rate will take period_ns nanoseconds. */ rate = clk_get_rate(pc->clk) >> PWM_DUTY_WIDTH; - hz = NSEC_PER_SEC / period_ns; - rate = (rate + (hz / 2)) / hz; + /* Consider precision in PWM_SCALE_WIDTH rate calculation */ + ns100 *= 100; + hz = DIV_ROUND_CLOSEST_ULL(ns100, period_ns); + rate = DIV_ROUND_CLOSEST(rate * 100, hz); /* * Since the actual PWM divider is the register's frequency divider -- cgit v1.2.3 From 59665fc5e5f5ff1275d1adb4fa63ec1a707e7e89 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Mar 2017 13:13:40 +0530 Subject: clk: qcom: msm8996: Fix the vfe1 powerdomain name [ Upstream commit a62ca337b36e31621b582cbe8f17d9404a48e120 ] Fix a typo which caused both vfe0 and vfe1 powerdomains to be named as vfe0. Signed-off-by: Rajendra Nayak Fixes: 7e824d507909 ("clk: qcom: gdsc: Add mmcc gdscs for msm8996 family") Signed-off-by: Stephen Boyd Signed-off-by: Michael Turquette Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/qcom/mmcc-msm8996.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index ca97e1151797..3b171bef913a 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -2984,7 +2984,7 @@ static struct gdsc vfe1_gdsc = { .cxcs = (unsigned int []){ 0x36ac }, .cxc_count = 1, .pd = { - .name = "vfe0", + .name = "vfe1", }, .parent = &camss_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, -- cgit v1.2.3 From 6335d2350f4273c5ed4ff82929958ebf8b635aa2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 13 Apr 2017 10:31:16 +0200 Subject: mac80211_hwsim: use per-interface power level [ Upstream commit 1d5e9f80ab021e3e1f9436627a4ad07a143ccb2c ] When channel contexts are used, there's no global power level (the power_level is always 0). Use the per-interface TX power in mac80211_hwsim to have a proper setting for both cases. This fixes the bgscan_simple and bgscan_learn test cases when the number of channels advertised by hwsim is >1 by default. Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mac80211_hwsim.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 61e85eac706a..3757036af93e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -552,8 +552,6 @@ struct mac80211_hwsim_data { /* wmediumd portid responsible for netgroup of this radio */ u32 wmediumd; - int power_level; - /* difference between this hw's clock and the real clock, in usecs */ s64 tsf_offset; s64 bcn_delta; @@ -1208,7 +1206,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI) rx_status.flag |= RX_FLAG_SHORT_GI; /* TODO: simulate real signal strength (and optional packet loss) */ - rx_status.signal = data->power_level - 50; + rx_status.signal = -50; + if (info->control.vif) + rx_status.signal += info->control.vif->bss_conf.txpower; if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -1607,7 +1607,6 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) WARN_ON(data->channel && data->use_chanctx); - data->power_level = conf->power_level; if (!data->started || !data->beacon_int) tasklet_hrtimer_cancel(&data->beacon_timer); else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { @@ -2212,7 +2211,6 @@ static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = { "d_tx_failed", "d_ps_mode", "d_group", - "d_tx_power", }; #define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats) @@ -2249,7 +2247,6 @@ static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw, data[i++] = ar->tx_failed; data[i++] = ar->ps; data[i++] = ar->group; - data[i++] = ar->power_level; WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN); } -- cgit v1.2.3 From 0a83f6943ae16a73a3f6af5c89f2a453129406f4 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 4 Apr 2017 22:22:56 +0530 Subject: ath10k: fix compile time sanity check for CE4 buffer size [ Upstream commit 62ca0690cd495bb7c1414cdf0cf790c2922a1d79 ] In 'ath10k_ce_alloc_pipe' the compile time sanity check to ensure that there is sufficient buffers in CE4 for HTT Tx MSDU descriptors, but this did not take into account of the case with 'peer flow control' enabled, fix this. Cc: Michal Kazior Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/ce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 0b4d79659884..041ef3be87b9 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -1059,7 +1059,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, */ BUILD_BUG_ON(2 * TARGET_NUM_MSDU_DESC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); - BUILD_BUG_ON(2 * TARGET_10X_NUM_MSDU_DESC > + BUILD_BUG_ON(2 * TARGET_10_4_NUM_MSDU_DESC_PFC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); BUILD_BUG_ON(2 * TARGET_TLV_NUM_MSDU_DESC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -- cgit v1.2.3 From c7fd50a893f31450bafba5ccd0adb09a2de1ab55 Mon Sep 17 00:00:00 2001 From: Hamad Kadmany Date: Wed, 5 Apr 2017 14:58:08 +0300 Subject: wil6210: fix protection against connections during reset [ Upstream commit b819447dfc4bd120c9d6cd8521252d544fce8fe7 ] Existing code that ignores connection events during reset flow will never take effect since it locks the same mutex taken by the reset flow. In addition, in case of unsolicited disconnect events ignore those as well since device is about to get reset. Signed-off-by: Hamad Kadmany Signed-off-by: Maya Erez Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/wil6210/wmi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index fae4f1285d08..94a356bbb6b9 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -501,16 +501,16 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) assoc_resp_ielen = 0; } - mutex_lock(&wil->mutex); if (test_bit(wil_status_resetting, wil->status) || !test_bit(wil_status_fwready, wil->status)) { wil_err(wil, "status_resetting, cancel connect event, CID %d\n", evt->cid); - mutex_unlock(&wil->mutex); /* no need for cleanup, wil_reset will do that */ return; } + mutex_lock(&wil->mutex); + if ((wdev->iftype == NL80211_IFTYPE_STATION) || (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { if (!test_bit(wil_status_fwconnecting, wil->status)) { @@ -608,6 +608,13 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, wil->sinfo_gen++; + if (test_bit(wil_status_resetting, wil->status) || + !test_bit(wil_status_fwready, wil->status)) { + wil_err(wil, "status_resetting, cancel disconnect event\n"); + /* no need for cleanup, wil_reset will do that */ + return; + } + mutex_lock(&wil->mutex); wil6210_disconnect(wil, evt->bssid, reason_code, true); mutex_unlock(&wil->mutex); -- cgit v1.2.3 From d546045ebfe80880e57be141d33a89176ec4713f Mon Sep 17 00:00:00 2001 From: Dedy Lansky Date: Wed, 5 Apr 2017 14:58:11 +0300 Subject: wil6210: fix memory access violation in wil_memcpy_from/toio_32 [ Upstream commit 0f6edfe2bbbb59d161580cb4870fcc46f5490f85 ] In case count is not multiple of 4, there is a read access in wil_memcpy_toio_32() from outside src buffer boundary. In wil_memcpy_fromio_32(), in case count is not multiple of 4, there is a write access to outside dst io memory boundary. Fix these issues with proper handling of the last 1 to 4 copied bytes. Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/wil6210/main.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 24b07a0ce6f7..f8bce58d48cc 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -129,9 +129,15 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, u32 *d = dst; const volatile u32 __iomem *s = src; - /* size_t is unsigned, if (count%4 != 0) it will wrap */ - for (count += 4; count > 4; count -= 4) + for (; count >= 4; count -= 4) *d++ = __raw_readl(s++); + + if (unlikely(count)) { + /* count can be 1..3 */ + u32 tmp = __raw_readl(s); + + memcpy(d, &tmp, count); + } } void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst, @@ -148,8 +154,16 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, volatile u32 __iomem *d = dst; const u32 *s = src; - for (count += 4; count > 4; count -= 4) + for (; count >= 4; count -= 4) __raw_writel(*s++, d++); + + if (unlikely(count)) { + /* count can be 1..3 */ + u32 tmp = 0; + + memcpy(&tmp, s, count); + __raw_writel(tmp, d); + } } void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil, -- cgit v1.2.3 From ac09628e707f00a95effed606fa7f013cef77e52 Mon Sep 17 00:00:00 2001 From: Ganapathi Bhat Date: Tue, 4 Apr 2017 10:16:28 +0530 Subject: mwifiex: Fix invalid port issue [ Upstream commit ecd7eb7c2bcf99f6c23d68ad56ce15949da848a1 ] We have to use start port, for TX/RX of single packet, instead of current aggregating port. This will fix SDIO CMD53(TX/RX) returning -ETIMEDOUT and halting the data path. Fixes: 0cb52aac4d19 ("mwifiex: do not set multiport flag for tx/rx single packet") Signed-off-by: Ganapathi Bhat Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/marvell/mwifiex/sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 8d601dcf2948..486b8c75cd1f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -1458,7 +1458,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, } if (card->mpa_rx.pkt_cnt == 1) - mport = adapter->ioport + port; + mport = adapter->ioport + card->mpa_rx.start_port; if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, card->mpa_rx.buf_len, mport, 1)) @@ -1891,7 +1891,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, } if (card->mpa_tx.pkt_cnt == 1) - mport = adapter->ioport + port; + mport = adapter->ioport + card->mpa_tx.start_port; ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, card->mpa_tx.buf_len, mport); -- cgit v1.2.3 From 9bf2ce49d3d4cea17e8597f7f9f0379280247113 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Nov 2017 16:20:58 +0200 Subject: drm/edid: set ELD connector type in drm_edid_to_eld() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 1d1c36650752b7fb81cee515a9bba4131cac4b7c ] Since drm_edid_to_eld() knows the connector type, we can set the type in ELD while at it. Most connectors this gets called on are not DP encoders, and with the HDMI type being 0, this does not change behaviour for non-DP. For i915 having this in place earlier would have saved a considerable amount of debugging that lead to the fix 2d8f63297b9f ("drm/i915: always update ELD connector type after get modes"). I don't see other drivers, even the ones calling drm_edid_to_eld() on DP connectors, setting the connector type in ELD. Cc: Alex Deucher Cc: Christian König Cc: Archit Taneja Cc: Andrzej Hajda Cc: Russell King Cc: CK Hu Cc: Philipp Zabel Cc: Ben Skeggs Cc: Mark Yao Cc: Benjamin Gaignard Cc: Vincent Abriou Cc: Thierry Reding Cc: Eric Anholt Reviewed-by: Ville Syrjälä Reviewed-by: Alex Deucher Acked-by: Thierry Reding Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d527b31619528c477c2c136f25cdf118bc0cfc1d.1509545641.git.jani.nikula@intel.com Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_edid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c6b281aa762f..6b31e0474271 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3347,8 +3347,7 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name); * @edid: EDID to parse * * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The - * Conn_Type, HDCP and Port_ID ELD fields are left for the graphics driver to - * fill in. + * HDCP and Port_ID ELD fields are left for the graphics driver to fill in. */ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) { @@ -3426,6 +3425,12 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) } eld[5] |= total_sad_count << 4; + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector->connector_type == DRM_MODE_CONNECTOR_eDP) + eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP; + else + eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI; + eld[DRM_ELD_BASELINE_ELD_LEN] = DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4); -- cgit v1.2.3 From 088d552d986e18f0a03a5367cf11b7841597c210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 13 Nov 2017 19:04:18 +0200 Subject: video/hdmi: Allow "empty" HDMI infoframes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 593f4b19a094c4426bd1e1e3cbab87a48bd13c71 ] HDMI 2.0 Appendix F suggest that we should keep sending the infoframe when switching from 3D to 2D mode, even if the infoframe isn't strictly necessary (ie. not needed to transmit the VIC or stereo information). This is a workaround against some sinks that fail to realize that they should switch from 3D to 2D mode when the source stop transmitting the infoframe. v2: Handle unpack() as well Pull the length calculation into a helper Cc: Shashank Sharma Cc: Andrzej Hajda Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Reviewed-by: Andrzej Hajda #v1 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171113170427.4150-2-ville.syrjala@linux.intel.com Reviewed-by: Shashank Sharma Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/hdmi.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 162689227a23..b73520aaf697 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -321,6 +321,17 @@ int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) } EXPORT_SYMBOL(hdmi_vendor_infoframe_init); +static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame) +{ + /* for side by side (half) we also need to provide 3D_Ext_Data */ + if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) + return 6; + else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) + return 5; + else + return 4; +} + /** * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer * @frame: HDMI infoframe @@ -341,19 +352,11 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, u8 *ptr = buffer; size_t length; - /* empty info frame */ - if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID) - return -EINVAL; - /* only one of those can be supplied */ if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) return -EINVAL; - /* for side by side (half) we also need to provide 3D_Ext_Data */ - if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) - frame->length = 6; - else - frame->length = 5; + frame->length = hdmi_vendor_infoframe_length(frame); length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; @@ -372,14 +375,16 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, ptr[5] = 0x0c; ptr[6] = 0x00; - if (frame->vic) { - ptr[7] = 0x1 << 5; /* video format */ - ptr[8] = frame->vic; - } else { + if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { ptr[7] = 0x2 << 5; /* video format */ ptr[8] = (frame->s3d_struct & 0xf) << 4; if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) ptr[9] = (frame->s3d_ext_data & 0xf) << 4; + } else if (frame->vic) { + ptr[7] = 0x1 << 5; /* video format */ + ptr[8] = frame->vic; + } else { + ptr[7] = 0x0 << 5; /* video format */ } hdmi_infoframe_set_checksum(buffer, length); @@ -1161,7 +1166,7 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR || ptr[1] != 1 || - (ptr[2] != 5 && ptr[2] != 6)) + (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6)) return -EINVAL; length = ptr[2]; @@ -1189,16 +1194,22 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, hvf->length = length; - if (hdmi_video_format == 0x1) { - hvf->vic = ptr[4]; - } else if (hdmi_video_format == 0x2) { + if (hdmi_video_format == 0x2) { + if (length != 5 && length != 6) + return -EINVAL; hvf->s3d_struct = ptr[4] >> 4; if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) { - if (length == 6) - hvf->s3d_ext_data = ptr[5] >> 4; - else + if (length != 6) return -EINVAL; + hvf->s3d_ext_data = ptr[5] >> 4; } + } else if (hdmi_video_format == 0x1) { + if (length != 5) + return -EINVAL; + hvf->vic = ptr[4]; + } else { + if (length != 4) + return -EINVAL; } return 0; -- cgit v1.2.3 From 8e93b348ca667484b40c0dffceb50ae405540851 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 22 Nov 2017 11:19:51 +0100 Subject: HID: elo: clear BTN_LEFT mapping [ Upstream commit 9abd04af951e5734c9d5cfee9b49790844b734cf ] ELO devices have one Button usage in GenDesk field, which makes hid-input map it to BTN_LEFT; that confuses userspace, which then considers the device to be a mouse/touchpad instead of touchscreen. Fix that by unmapping BTN_LEFT and keeping only BTN_TOUCH in place. Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-elo.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c index 0cd4f7216239..5eea6fe0d7bd 100644 --- a/drivers/hid/hid-elo.c +++ b/drivers/hid/hid-elo.c @@ -42,6 +42,12 @@ static int elo_input_configured(struct hid_device *hdev, { struct input_dev *input = hidinput->input; + /* + * ELO devices have one Button usage in GenDesk field, which makes + * hid-input map it to BTN_LEFT; that confuses userspace, which then + * considers the device to be a mouse/touchpad instead of touchscreen. + */ + clear_bit(BTN_LEFT, input->keybit); set_bit(BTN_TOUCH, input->keybit); set_bit(ABS_PRESSURE, input->absbit); input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0); -- cgit v1.2.3 From e95928a6407f32c716f11a4483e6438f88a0ed9f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 19 Oct 2017 21:36:04 +0300 Subject: iwlwifi: mvm: rs: don't override the rate history in the search cycle [ Upstream commit 992172e3aec19e5b0ea5b757ba40a146b9282d1e ] When we are in a search cycle, we try different combinations of parameters. Those combinations are called 'columns'. When we switch to a new column, we first need to check if this column has a suitable rate, if not, we can't try it. This means we must not erase the statistics we gathered for the previous column until we are sure that we are indeed switching column. The code that tries to switch to a new column first sets a whole bunch of things for the new column, and only then checks that we can find suitable rates in that column. While doing that, the code mistakenly erased the rate statistics. This code was right until struct iwl_scale_tbl_info grew up for TPC. Fix this to make sure we don't erase the rate statistics until we are sure that we can indeed switch to the new column. Note that this bug is really harmless since it causes a change in the behavior only when we can't find any rate in the new column which should really not happen. In the case we do find a suitable we reset the rate statistics a few lines later anyway. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 227c5ed9cbe6..0aea476ebf50 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -1867,12 +1867,10 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, struct rs_rate *rate = &search_tbl->rate; const struct rs_tx_column *column = &rs_tx_columns[col_id]; const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; - u32 sz = (sizeof(struct iwl_scale_tbl_info) - - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); unsigned long rate_mask = 0; u32 rate_idx = 0; - memcpy(search_tbl, tbl, sz); + memcpy(search_tbl, tbl, offsetof(struct iwl_scale_tbl_info, win)); rate->sgi = column->sgi; rate->ant = column->ant; -- cgit v1.2.3 From 05fafb80ba2412da75ef8e23f37bec2285ac7f6f Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Tue, 7 Nov 2017 22:12:23 +0800 Subject: clk: meson: gxbb: fix wrong clock for SARADC/SANA [ Upstream commit 75eccf5ed83250c0aeaeeb76f7288254ac0a87b4 ] According to the datasheet, in Meson-GXBB/GXL series, The clock gate bit for SARADC is HHI_GCLK_MPEG2 bit[22], while clock gate bit for SANA is HHI_GCLK_MPEG0 bit[10]. Test passed at gxl-s905x-p212 board. The following published datasheets are wrong and should be updated [1] GXBB v1.1.4 [2] GXL v0.3_20170314 Fixes: 738f66d3211d ("clk: gxbb: add AmLogic GXBB clk controller driver") Tested-by: Xingyu Chen Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/meson/gxbb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 9d9af446bafc..37e05d6e010a 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -572,7 +572,7 @@ static MESON_GATE(gxbb_pl301, HHI_GCLK_MPEG0, 6); static MESON_GATE(gxbb_periphs, HHI_GCLK_MPEG0, 7); static MESON_GATE(gxbb_spicc, HHI_GCLK_MPEG0, 8); static MESON_GATE(gxbb_i2c, HHI_GCLK_MPEG0, 9); -static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG0, 10); +static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG0, 10); static MESON_GATE(gxbb_smart_card, HHI_GCLK_MPEG0, 11); static MESON_GATE(gxbb_rng0, HHI_GCLK_MPEG0, 12); static MESON_GATE(gxbb_uart0, HHI_GCLK_MPEG0, 13); @@ -623,7 +623,7 @@ static MESON_GATE(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); static MESON_GATE(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11); static MESON_GATE(gxbb_dvin, HHI_GCLK_MPEG2, 12); static MESON_GATE(gxbb_uart2, HHI_GCLK_MPEG2, 15); -static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG2, 22); +static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG2, 22); static MESON_GATE(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25); static MESON_GATE(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); static MESON_GATE(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29); -- cgit v1.2.3 From 6f8e8ec3d1bd6333f6af8ada6d092314bc9f73c6 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 28 Nov 2017 13:53:12 +0100 Subject: net: ieee802154: adf7242: Fix bug if defined DEBUG [ Upstream commit 388b3b2b03701f3b3c10975c272892d7f78080df ] This fixes undefined reference to struct adf7242_local *lp in case DEBUG is defined. Signed-off-by: Michael Hennerich Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ieee802154/adf7242.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c index f355df7cf84a..1b980f12663a 100644 --- a/drivers/net/ieee802154/adf7242.c +++ b/drivers/net/ieee802154/adf7242.c @@ -888,7 +888,7 @@ static struct ieee802154_ops adf7242_ops = { .set_cca_ed_level = adf7242_set_cca_ed_level, }; -static void adf7242_debug(u8 irq1) +static void adf7242_debug(struct adf7242_local *lp, u8 irq1) { #ifdef DEBUG u8 stat; @@ -932,7 +932,7 @@ static irqreturn_t adf7242_isr(int irq, void *data) dev_err(&lp->spi->dev, "%s :ERROR IRQ1 = 0x%X\n", __func__, irq1); - adf7242_debug(irq1); + adf7242_debug(lp, irq1); xmit = test_bit(FLAG_XMIT, &lp->flags); -- cgit v1.2.3 From da2ad1d8d47adb3fb0dbc86bdf27d0f84d5b0a59 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 8 Nov 2017 17:00:27 +0100 Subject: mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]() [ Upstream commit df467899da0b71465760b4e35127bce837244eee ] Some drivers (like nand_hynix.c) call ->cmdfunc() with NAND_CMD_NONE and a column address and expect the controller to only send address cycles. Right now, the default ->cmdfunc() implementations provided by the core do not filter out the command cycle in this case and forwards the request to the controller driver through the ->cmd_ctrl() method. The thing is, NAND controller drivers can get this wrong and send a command cycle with a NAND_CMD_NONE opcode and since NAND_CMD_NONE is -1, and the command field is usually casted to an u8, we end up sending the 0xFF command which is actually a RESET operation. Add conditions in nand_command[_lp]() functions to sending the initial command cycle when command == NAND_CMD_NONE. Signed-off-by: Miquel Raynal Signed-off-by: Boris Brezillon Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/nand_base.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 21c03086bb7f..a3e86e52640a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -715,7 +715,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, chip->cmd_ctrl(mtd, readcmd, ctrl); ctrl &= ~NAND_CTRL_CHANGE; } - chip->cmd_ctrl(mtd, command, ctrl); + if (command != NAND_CMD_NONE) + chip->cmd_ctrl(mtd, command, ctrl); /* Address cycle, when necessary */ ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE; @@ -744,6 +745,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, */ switch (command) { + case NAND_CMD_NONE: case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: @@ -806,7 +808,9 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, } /* Command latch cycle */ - chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); + if (command != NAND_CMD_NONE) + chip->cmd_ctrl(mtd, command, + NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); if (column != -1 || page_addr != -1) { int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; @@ -842,6 +846,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, */ switch (command) { + case NAND_CMD_NONE: case NAND_CMD_CACHEDPROG: case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: -- cgit v1.2.3 From 7c865a3d27274733a680bcd8be8cd50d3841d133 Mon Sep 17 00:00:00 2001 From: Sunil Goutham Date: Fri, 24 Nov 2017 15:04:03 +0300 Subject: net: thunderx: Set max queue count taking XDP_TX into account [ Upstream commit 87de083857aa269fb171ef0b39696b2888361c58 ] on T81 there are only 4 cores, hence setting max queue count to 4 would leave nothing for XDP_TX. This patch fixes this by doubling max queue count in above scenarios. Signed-off-by: Sunil Goutham Signed-off-by: cjacob Signed-off-by: Aleksey Makarov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 8a37012c9c89..c75d4ea9342b 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -1576,6 +1576,11 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) nic->pdev = pdev; nic->pnicvf = nic; nic->max_queues = qcount; + /* If no of CPUs are too low, there won't be any queues left + * for XDP_TX, hence double it. + */ + if (!nic->t88) + nic->max_queues *= 2; /* MAP VF's configuration registers */ nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0); -- cgit v1.2.3 From 88347216d8e493d2a8bdcc3eb45beb55a8c0e4ef Mon Sep 17 00:00:00 2001 From: Jagdish Gediya Date: Thu, 23 Nov 2017 17:04:31 +0530 Subject: mtd: nand: ifc: update bufnum mask for ver >= 2.0.0 [ Upstream commit bccb06c353af3764ca86d9da47652458e6c2eb41 ] Bufnum mask is used to calculate page position in the internal SRAM. As IFC version 2.0.0 has 16KB of internal SRAM as compared to older versions which had 8KB. Hence bufnum mask needs to be updated. Signed-off-by: Jagdish Gediya Signed-off-by: Prabhakar Kushwaha Signed-off-by: Boris Brezillon Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/fsl_ifc_nand.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index d1570f512f0b..f8f12ccc6471 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -907,6 +907,13 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) if (ctrl->version == FSL_IFC_VERSION_1_1_0) fsl_ifc_sram_init(priv); + /* + * As IFC version 2.0.0 has 16KB of internal SRAM as compared to older + * versions which had 8KB. Hence bufnum mask needs to be updated. + */ + if (ctrl->version >= FSL_IFC_VERSION_2_0_0) + priv->bufnum_mask = (priv->bufnum_mask * 2) + 1; + return 0; } -- cgit v1.2.3 From c21a7793a743dec2cdb7538168a6758b3bef165b Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 30 Nov 2017 21:16:56 -0800 Subject: leds: pm8058: Silence pointer to integer size warning [ Upstream commit 8f52df50d9366f770a894d14ef724e5e04574e98 ] The pointer returned by of_device_get_match_data() doesn't have the same size as u32 on 64-bit architectures, causing a compile warning when compile-testing the driver on such platform. Cast the return value of of_device_get_match_data() to unsigned long and then to u32 to silence this warning. Fixes: 7f866986e705 ("leds: add PM8058 LEDs driver") Signed-off-by: Bjorn Andersson Reviewed-by: Linus Walleij Acked-by: Pavel Machek Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/leds/leds-pm8058.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/leds-pm8058.c b/drivers/leds/leds-pm8058.c index a52674327857..8988ba3b2d65 100644 --- a/drivers/leds/leds-pm8058.c +++ b/drivers/leds/leds-pm8058.c @@ -106,7 +106,7 @@ static int pm8058_led_probe(struct platform_device *pdev) if (!led) return -ENOMEM; - led->ledtype = (u32)of_device_get_match_data(&pdev->dev); + led->ledtype = (u32)(unsigned long)of_device_get_match_data(&pdev->dev); map = dev_get_regmap(pdev->dev.parent, NULL); if (!map) { -- cgit v1.2.3 From 4aac8ff4c4d85603629ede10ca569e4e27a1e1ea Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 22 Nov 2017 21:27:31 +0100 Subject: power: supply: ab8500_charger: Fix an error handling path [ Upstream commit bf59fddde1c3eab89eb8dca8f3d3dc097887d2bb ] 'ret' is know to be 0 at this point, because it has not been updated by the the previous call to 'abx500_mask_and_set_register_interruptible()'. Fix it by updating 'ret' before checking if an error occurred. Fixes: 84edbeeab67c ("ab8500-charger: AB8500 charger driver") Signed-off-by: Christophe JAILLET Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/ab8500_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 5cee9aa87aa3..037e93224c38 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -3218,7 +3218,7 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) } /* Enable backup battery charging */ - abx500_mask_and_set_register_interruptible(di->dev, + ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, RTC_BUP_CH_ENA); if (ret < 0) -- cgit v1.2.3 From 7c3632572ab2dbc399f61aca8156b3c18ecf4651 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 22 Nov 2017 21:31:20 +0100 Subject: power: supply: ab8500_charger: Bail out in case of error in 'ab8500_charger_init_hw_registers()' [ Upstream commit 09edcb647542487864e23aa8d2ef26be3e08978a ] If an error occurs when we enable the backup battery charging, we should go through the error handling path directly. Before commit db43e6c473b5 ("ab8500-bm: Add usb power path support") this was the case, but this commit has added some code between the last test and the 'out' label. So, in case of error, this added code is executed and the error may be silently ignored. Fix it by adding the missing 'goto out', as done in all other error handling paths. Fixes: db43e6c473b5 ("ab8500-bm: Add usb power path support") Signed-off-by: Christophe JAILLET Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/ab8500_charger.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 037e93224c38..48a11fd86a7f 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -3221,8 +3221,10 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, RTC_BUP_CH_ENA); - if (ret < 0) + if (ret < 0) { dev_err(di->dev, "%s mask and set failed\n", __func__); + goto out; + } if (is_ab8540(di->parent)) { ret = abx500_mask_and_set_register_interruptible(di->dev, -- cgit v1.2.3 From 103188787d9c1ceb3a0aceeaa37a2f252c58111f Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Mon, 6 Nov 2017 13:39:31 +0530 Subject: ath10k: update tdls teardown state to target [ Upstream commit 424ea0d174e82365f85c6770225dba098b8f1d5f ] It is required to update the teardown state of the peer when a tdls link with that peer is terminated. This information is useful for the target to perform some cleanups wrt the tdls peer. Without proper cleanup, target assumes that the peer is connected and blocks future connection requests, updating the teardown state of the peer addresses the problem. Tested this change on QCA9888 with 10.4-3.5.1-00018 fw version. Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/mac.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 696b90270615..1e6e63dbd61c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6054,6 +6054,16 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, "mac vdev %d peer delete %pM sta %pK (sta gone)\n", arvif->vdev_id, sta->addr, sta); + if (sta->tdls) { + ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, + sta, + WMI_TDLS_PEER_STATE_TEARDOWN); + if (ret) + ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n", + sta->addr, + WMI_TDLS_PEER_STATE_TEARDOWN, ret); + } + ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); if (ret) ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", -- cgit v1.2.3 From c6656ab87a0ea6185591d30ee965e5afa49e8c7f Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Tue, 14 Nov 2017 10:48:04 +1100 Subject: scsi: ses: don't ask for diagnostic pages repeatedly during probe [ Upstream commit 9c0a50022b8ac7e863e6ec8342fa476fe5d1d75c ] We are testing if there is a match with the ses device in a loop by calling ses_match_to_enclosure(), which will issue scsi receive diagnostics commands to the ses device for every device on the same host. On one of our boxes with 840 disks, it takes a long time to load the driver: [root@g1b-oss06 ~]# time modprobe ses real 40m48.247s user 0m0.001s sys 0m0.196s With the patch: [root@g1b-oss06 ~]# time modprobe ses real 0m17.915s user 0m0.008s sys 0m0.053s Note that we still need to refresh page 10 when we see a new disk to create the link. Signed-off-by: Li Dongyang Tested-by: Jason Ozolins Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index f1cdf32d7514..69046d342bc5 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -578,13 +578,16 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, } static void ses_match_to_enclosure(struct enclosure_device *edev, - struct scsi_device *sdev) + struct scsi_device *sdev, + int refresh) { + struct scsi_device *edev_sdev = to_scsi_device(edev->edev.parent); struct efd efd = { .addr = 0, }; - ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); + if (refresh) + ses_enclosure_data_process(edev, edev_sdev, 0); if (scsi_is_sas_rphy(sdev->sdev_target->dev.parent)) efd.addr = sas_get_address(sdev); @@ -615,7 +618,7 @@ static int ses_intf_add(struct device *cdev, struct enclosure_device *prev = NULL; while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) { - ses_match_to_enclosure(edev, sdev); + ses_match_to_enclosure(edev, sdev, 1); prev = edev; } return -ENODEV; @@ -727,7 +730,7 @@ static int ses_intf_add(struct device *cdev, shost_for_each_device(tmp_sdev, sdev->host) { if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev)) continue; - ses_match_to_enclosure(edev, tmp_sdev); + ses_match_to_enclosure(edev, tmp_sdev, 0); } return 0; -- cgit v1.2.3 From 93f092f2c3c4d8f091f4b59b930283a8b4c5d6c0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 7 Nov 2017 13:18:53 +0800 Subject: pwm: stmpe: Fix wrong register offset for hwpwm=2 case [ Upstream commit 8472b529e113e0863ea064fdee51bf73c3f86fd6 ] Fix trivial copy/paste bug. Signed-off-by: Axel Lin Reviewed-by: Linus Walleij Fixes: ef1f09eca74a ("pwm: Add a driver for the STMPE PWM") Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-stmpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c index e464582a390a..3439f1e902cb 100644 --- a/drivers/pwm/pwm-stmpe.c +++ b/drivers/pwm/pwm-stmpe.c @@ -145,7 +145,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, break; case 2: - offset = STMPE24XX_PWMIC1; + offset = STMPE24XX_PWMIC2; break; default: -- cgit v1.2.3 From a40eb9e8aaf6799a632de003c7231b6307ed47fc Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 6 Dec 2017 12:11:38 +0000 Subject: clk: qcom: msm8916: fix mnd_width for codec_digcodec [ Upstream commit d8e488e8242ecf129eebc440c92d800a99ca109d ] This patch fixes missing mnd_width for codec_digital clk, this is now set to 8 inline with datasheet. Fixes: 3966fab8b6ab ("clk: qcom: Add MSM8916 Global Clock Controller support") Signed-off-by: Srinivas Kandagatla Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/qcom/gcc-msm8916.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index 5c4e193164d4..8dd71345b5d0 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -1437,6 +1437,7 @@ static const struct freq_tbl ftbl_codec_clk[] = { static struct clk_rcg2 codec_digcodec_clk_src = { .cmd_rcgr = 0x1c09c, + .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll1_emclk_sleep_map, .freq_tbl = ftbl_codec_clk, -- cgit v1.2.3 From 128e61839d68dee6bfccf9b64e80a041e85789fb Mon Sep 17 00:00:00 2001 From: Limin Zhu Date: Thu, 30 Nov 2017 14:22:34 +0800 Subject: mwifiex: cfg80211: do not change virtual interface during scan processing [ Upstream commit c61cfe49f0f0f0d1f8b56d0b045838d597e8c3a3 ] (1) Change virtual interface operation in cfg80211 process reset and reinitilize private data structure. (2) Scan result event processed in main process will dereference private data structure concurrently, ocassionly crash the kernel. The cornel case could be trigger by below steps: (1) wpa_cli mlan0 scan (2) ./hostapd mlan0.conf Cfg80211 asynchronous scan procedure is not all the time operated under rtnl lock, here we add the protect to serialize the cfg80211 scan and change_virtual interface operation. Signed-off-by: Limin Zhu Signed-off-by: Xinming Hu Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 8677a53ef725..48d51be11f9b 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -1109,6 +1109,12 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); enum nl80211_iftype curr_iftype = dev->ieee80211_ptr->iftype; + if (priv->scan_request) { + mwifiex_dbg(priv->adapter, ERROR, + "change virtual interface: scan in process\n"); + return -EBUSY; + } + switch (curr_iftype) { case NL80211_IFTYPE_ADHOC: switch (type) { -- cgit v1.2.3 From 7f4d2f7547010aeded32f0269a206f8dac0cf88b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sat, 2 Dec 2017 16:50:49 +0200 Subject: ath10k: fix invalid STS_CAP_OFFSET_MASK [ Upstream commit 8cec57f5277ef0e354e37a0bf909dc71bc1f865b ] The 10.4 firmware defines this as a 3-bit field, as does the mac80211 stack. The 4th bit is defined as CONF_IMPLICIT_BF at least in the firmware header I have seen. This patch fixes the ath10k wmi header to match the firmware. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/wmi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 1b243c899bef..9b8562ff6698 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -5017,7 +5017,8 @@ enum wmi_10_4_vdev_param { #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) #define WMI_TXBF_STS_CAP_OFFSET_LSB 4 -#define WMI_TXBF_STS_CAP_OFFSET_MASK 0xf0 +#define WMI_TXBF_STS_CAP_OFFSET_MASK 0x70 +#define WMI_TXBF_CONF_IMPLICIT_BF BIT(7) #define WMI_BF_SOUND_DIM_OFFSET_LSB 8 #define WMI_BF_SOUND_DIM_OFFSET_MASK 0xf00 -- cgit v1.2.3 From 26cae37274f3ea5dad4c4b7e8db08caaf502f14f Mon Sep 17 00:00:00 2001 From: Tobias Jordan Date: Thu, 7 Dec 2017 15:04:53 +0100 Subject: spi: sun6i: disable/unprepare clocks on remove [ Upstream commit 2d9bbd02c54094ceffa555143b0d68cd06504d63 ] sun6i_spi_probe() uses sun6i_spi_runtime_resume() to prepare/enable clocks, so sun6i_spi_remove() should use sun6i_spi_runtime_suspend() to disable/unprepare them if we're not suspended. Replacing pm_runtime_disable() by pm_runtime_force_suspend() will ensure that sun6i_spi_runtime_suspend() is called if needed. Found by Linux Driver Verification project (linuxtesting.org). Fixes: 3558fe900e8af (spi: sunxi: Add Allwinner A31 SPI controller driver) Signed-off-by: Tobias Jordan Acked-by: Maxime Ripard Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-sun6i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 9918a57a6a6e..7e7da97982aa 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -464,7 +464,7 @@ err_free_master: static int sun6i_spi_remove(struct platform_device *pdev) { - pm_runtime_disable(&pdev->dev); + pm_runtime_force_suspend(&pdev->dev); return 0; } -- cgit v1.2.3 From c3dec92f3d792d9180d29b29b2da88d8b861b03d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 6 Dec 2017 17:31:22 -0500 Subject: bnxt_en: Don't print "Link speed -1 no longer supported" messages. [ Upstream commit a8168b6cee6e9334dfebb4b9108e8d73794f6088 ] On some dual port NICs, the 2 ports have to be configured with compatible link speeds. Under some conditions, a port's configured speed may no longer be supported. The firmware will send a message to the driver when this happens. Improve this logic that prints out the warning by only printing it if we can determine the link speed that is no longer supported. If the speed is unknown or it is in autoneg mode, skip the warning message. Reported-by: Thomas Bogendoerfer Signed-off-by: Michael Chan Tested-by: Thomas Bogendoerfer Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index bbb3641eddcb..3aa993bbafd9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1498,12 +1498,16 @@ static int bnxt_async_event_process(struct bnxt *bp, if (BNXT_VF(bp)) goto async_event_process_exit; - if (data1 & 0x20000) { + + /* print unsupported speed warning in forced speed mode only */ + if (!(link_info->autoneg & BNXT_AUTONEG_SPEED) && + (data1 & 0x20000)) { u16 fw_speed = link_info->force_link_speed; u32 speed = bnxt_fw_to_ethtool_speed(fw_speed); - netdev_warn(bp->dev, "Link speed %d no longer supported\n", - speed); + if (speed != SPEED_UNKNOWN) + netdev_warn(bp->dev, "Link speed %d no longer supported\n", + speed); } set_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, &bp->sp_event); /* fall thru */ -- cgit v1.2.3 From f2e152e2b04717f5d449256317afb9c0670f0fdd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 4 Dec 2017 10:36:31 -0800 Subject: scsi: core: scsi_get_device_flags_keyed(): Always return device flags [ Upstream commit a44c9d36509c83cf64f33b93f6ab2e63822c01eb ] Since scsi_get_device_flags_keyed() callers do not check whether or not the returned value is an error code, change that function such that it returns a flags value even if the 'key' argument is invalid. Note: since commit 28a0bc4120d3 ("scsi: sd: Implement blacklist option for WRITE SAME w/ UNMAP") bit 31 is a valid device information flag so checking whether bit 31 is set in the return value is not sufficient to tell the difference between an error code and a flags value. Signed-off-by: Bart Van Assche Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Johannes Thumshirn Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_devinfo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 26e6b05d05fc..9545c40daa5e 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -596,17 +596,12 @@ int scsi_get_device_flags_keyed(struct scsi_device *sdev, int key) { struct scsi_dev_info_list *devinfo; - int err; devinfo = scsi_dev_info_list_find(vendor, model, key); if (!IS_ERR(devinfo)) return devinfo->flags; - err = PTR_ERR(devinfo); - if (err != -ENOENT) - return err; - - /* nothing found, return nothing */ + /* key or device not found: return nothing */ if (key != SCSI_DEVINFO_GLOBAL) return 0; -- cgit v1.2.3 From 5f3e85ab6ac55b37ddce0cbbecb222a12831b1e7 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Fri, 17 Nov 2017 21:31:36 +0100 Subject: scsi: devinfo: apply to HP XP the same flags as Hitachi VSP [ Upstream commit b369a0471503130cfc74f9f62071db97f48948c3 ] Commit 56f3d383f37b ("scsi: scsi_devinfo: Add TRY_VPD_PAGES to HITACHI OPEN-V blacklist entry") modified some Hitachi entries: HITACHI is always supporting VPD pages, even though it's claiming to support SCSI Revision 3 only. The same should have been done also for HP-rebranded. [mkp: checkpatch and tweaked commit message] Cc: Hannes Reinecke Cc: Takahiro Yasui Cc: Matthias Rudolph Cc: Martin K. Petersen Cc: James E.J. Bottomley Cc: SCSI ML Signed-off-by: Xose Vazquez Perez Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_devinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 9545c40daa5e..43d4b30cbf65 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -180,7 +180,7 @@ static struct { {"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ - {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */ + {"HP", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, /* HP XP Arrays */ {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, {"HP", "C1557A", NULL, BLIST_FORCELUN}, -- cgit v1.2.3 From 1b2981c3cba7fdd0b3f48c7a52fcc69aa11bb5e9 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Fri, 17 Nov 2017 22:05:13 +0100 Subject: scsi: dh: add new rdac devices [ Upstream commit 4b3aec2bbbce1c35f50e7475a9fd78d24b9ea4ea ] Add IBM 3542 and 3552, arrays: FAStT200 and FAStT500. Add full STK OPENstorage family, arrays: 9176, D173, D178, D210, D220, D240 and D280. Add STK BladeCtlr family, arrays: B210, B220, B240 and B280. These changes were done in multipath-tools time ago. Cc: NetApp RDAC team Cc: Hannes Reinecke Cc: Christophe Varoqui Cc: Martin K. Petersen Cc: James E.J. Bottomley Cc: SCSI ML Cc: device-mapper development Signed-off-by: Xose Vazquez Perez Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_dh.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index 84addee05be6..a5e30e9449ef 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -56,10 +56,13 @@ static const struct scsi_dh_blist scsi_dh_blist[] = { {"IBM", "1815", "rdac", }, {"IBM", "1818", "rdac", }, {"IBM", "3526", "rdac", }, + {"IBM", "3542", "rdac", }, + {"IBM", "3552", "rdac", }, {"SGI", "TP9", "rdac", }, {"SGI", "IS", "rdac", }, - {"STK", "OPENstorage D280", "rdac", }, + {"STK", "OPENstorage", "rdac", }, {"STK", "FLEXLINE 380", "rdac", }, + {"STK", "BladeCtlr", "rdac", }, {"SUN", "CSM", "rdac", }, {"SUN", "LCSM100", "rdac", }, {"SUN", "STK6580_6780", "rdac", }, -- cgit v1.2.3 From 947e2e9bd754b68bb4379b67ef3cb44879ad2ee9 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Mon, 4 Dec 2017 06:01:11 -0500 Subject: media: vsp1: Prevent suspending and resuming DRM pipelines [ Upstream commit a17d2d6cd9985ca09a9e384f1bc71d710f7e5203 ] When used as part of a display pipeline, the VSP is stopped and restarted explicitly by the DU from its suspend and resume handlers. There is thus no need to stop or restart pipelines in the VSP suspend and resume handlers, and doing so would cause the hardware to be left in a misconfigured state. Ensure that the VSP suspend and resume handlers do not affect DRM-based pipelines. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/vsp1/vsp1_drv.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 57c713a4e1df..4ac1ff482a0b 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -509,7 +509,13 @@ static int __maybe_unused vsp1_pm_suspend(struct device *dev) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); - vsp1_pipelines_suspend(vsp1); + /* + * When used as part of a display pipeline, the VSP is stopped and + * restarted explicitly by the DU. + */ + if (!vsp1->drm) + vsp1_pipelines_suspend(vsp1); + pm_runtime_force_suspend(vsp1->dev); return 0; @@ -520,7 +526,13 @@ static int __maybe_unused vsp1_pm_resume(struct device *dev) struct vsp1_device *vsp1 = dev_get_drvdata(dev); pm_runtime_force_resume(vsp1->dev); - vsp1_pipelines_resume(vsp1); + + /* + * When used as part of a display pipeline, the VSP is stopped and + * restarted explicitly by the DU. + */ + if (!vsp1->drm) + vsp1_pipelines_resume(vsp1); return 0; } -- cgit v1.2.3 From ff54d5e95ad2ba7067ddd4764136bbded8a8129c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Nov 2017 16:28:14 -0500 Subject: media: cpia2: Fix a couple off by one bugs [ Upstream commit d5ac225c7d64c9c3ef821239edc035634e594ec9 ] The cam->buffers[] array has cam->num_frames elements so the > needs to be changed to >= to avoid going beyond the end of the array. The ->buffers[] array is allocated in cpia2_allocate_buffers() if you want to confirm. Fixes: ab33d5071de7 ("V4L/DVB (3376): Add cpia2 camera support") Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/cpia2/cpia2_v4l.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c index 9caea8344547..d793c630f1dd 100644 --- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c @@ -812,7 +812,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->index > cam->num_frames) + buf->index >= cam->num_frames) return -EINVAL; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; @@ -863,7 +863,7 @@ static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->memory != V4L2_MEMORY_MMAP || - buf->index > cam->num_frames) + buf->index >= cam->num_frames) return -EINVAL; DBG("QBUF #%d\n", buf->index); -- cgit v1.2.3 From c3fd4d3c1966b34bad24ecd6629ebe55b865df10 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 7 Dec 2017 15:40:20 -0800 Subject: veth: set peer GSO values [ Upstream commit 72d24955b44a4039db54a1c252b5031969eeaac3 ] When new veth is created, and GSO values have been configured on one device, clone those values to the peer. For example: # ip link add dev vm1 gso_max_size 65530 type veth peer name vm2 This should create vm1 <--> vm2 with both having GSO maximum size set to 65530. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/veth.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index fbc853e64531..ee7460ee3d05 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -425,6 +425,9 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, if (ifmp && (dev->ifindex != 0)) peer->ifindex = ifmp->ifi_index; + peer->gso_max_size = dev->gso_max_size; + peer->gso_max_segs = dev->gso_max_segs; + err = register_netdevice(peer); put_net(net); net = NULL; -- cgit v1.2.3 From 049cff8555d41211c3dfbdcfc46cbb818d32eeae Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Fri, 8 Dec 2017 23:08:48 -0500 Subject: drm/amdkfd: Fix memory leaks in kfd topology [ Upstream commit 5108d768408abc80e4e8d99f5b406a73cb04056b ] Kobject created using kobject_create_and_add() can be freed using kobject_put() when there is no referenece any more. However, kobject memory allocated with kzalloc() has to set up a release callback in order to free it when the counter decreases to 0. Otherwise it causes memory leak. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 1e5064749959..8c6e47c5507f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -519,11 +519,17 @@ static ssize_t sysprops_show(struct kobject *kobj, struct attribute *attr, return ret; } +static void kfd_topology_kobj_release(struct kobject *kobj) +{ + kfree(kobj); +} + static const struct sysfs_ops sysprops_ops = { .show = sysprops_show, }; static struct kobj_type sysprops_type = { + .release = kfd_topology_kobj_release, .sysfs_ops = &sysprops_ops, }; @@ -559,6 +565,7 @@ static const struct sysfs_ops iolink_ops = { }; static struct kobj_type iolink_type = { + .release = kfd_topology_kobj_release, .sysfs_ops = &iolink_ops, }; @@ -586,6 +593,7 @@ static const struct sysfs_ops mem_ops = { }; static struct kobj_type mem_type = { + .release = kfd_topology_kobj_release, .sysfs_ops = &mem_ops, }; @@ -625,6 +633,7 @@ static const struct sysfs_ops cache_ops = { }; static struct kobj_type cache_type = { + .release = kfd_topology_kobj_release, .sysfs_ops = &cache_ops, }; @@ -747,6 +756,7 @@ static const struct sysfs_ops node_ops = { }; static struct kobj_type node_type = { + .release = kfd_topology_kobj_release, .sysfs_ops = &node_ops, }; -- cgit v1.2.3 From 678131a9cbeb64c50e347edcc9171b9feedb2c0d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Dec 2017 21:46:16 +0000 Subject: agp/intel: Flush all chipset writes after updating the GGTT [ Upstream commit 8516673a996870ea0ceb337ee4f83c33c5ec3111 ] Before accessing the GGTT we must flush the PTE writes and make them visible to the chipset, or else the indirect access may end up in the wrong page. In commit 3497971a71d8 ("agp/intel: Flush chipset writes after updating a single PTE"), we noticed corruption of the uploads for pwrite and for capturing GPU error states, but it was presumed that the explicit calls to intel_gtt_chipset_flush() were sufficient for the execbuffer path. However, we have not been flushing the chipset between the PTE writes and access via the GTT itself. For simplicity, do the flush after any PTE update rather than try and batch the flushes on a just-in-time basis. References: 3497971a71d8 ("agp/intel: Flush chipset writes after updating a single PTE") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: drm-intel-fixes@lists.freedesktop.org Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171208214616.30147-1-chris@chris-wilson.co.uk Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/char/agp/intel-gtt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 0f7d28a98b9a..a7cc5b7be598 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -871,6 +871,8 @@ void intel_gtt_insert_sg_entries(struct sg_table *st, } } wmb(); + if (intel_private.driver->chipset_flush) + intel_private.driver->chipset_flush(); } EXPORT_SYMBOL(intel_gtt_insert_sg_entries); -- cgit v1.2.3 From d8f060c2a8c0f81eede6a7775998e3afd91fea6f Mon Sep 17 00:00:00 2001 From: Adiel Aloni Date: Fri, 1 Dec 2017 13:50:53 +0200 Subject: mac80211_hwsim: enforce PS_MANUAL_POLL to be set after PS_ENABLED [ Upstream commit e16ea4bb516bc21ea2202f2107718b29218bea59 ] Enforce using PS_MANUAL_POLL in ps hwsim debugfs to trigger a poll, only if PS_ENABLED was set before. This is required due to commit c9491367b759 ("mac80211: always update the PM state of a peer on MGMT / DATA frames") that enforces the ap to check only mgmt/data frames ps bit, and then update station's power save accordingly. When sending only ps-poll (control frame) the ap will not be aware that the station entered power save. Setting ps enable before triggering ps_poll, will send NDP with PM bit enabled first. Signed-off-by: Adiel Aloni Signed-off-by: Luca Coelho Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mac80211_hwsim.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 3757036af93e..4182c3775a72 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -728,16 +728,21 @@ static int hwsim_fops_ps_write(void *dat, u64 val) val != PS_MANUAL_POLL) return -EINVAL; - old_ps = data->ps; - data->ps = val; - - local_bh_disable(); if (val == PS_MANUAL_POLL) { + if (data->ps != PS_ENABLED) + return -EINVAL; + local_bh_disable(); ieee80211_iterate_active_interfaces_atomic( data->hw, IEEE80211_IFACE_ITER_NORMAL, hwsim_send_ps_poll, data); - data->ps_poll_pending = true; - } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { + local_bh_enable(); + return 0; + } + old_ps = data->ps; + data->ps = val; + + local_bh_disable(); + if (old_ps == PS_DISABLED && val != PS_DISABLED) { ieee80211_iterate_active_interfaces_atomic( data->hw, IEEE80211_IFACE_ITER_NORMAL, hwsim_send_nullfunc_ps, data); -- cgit v1.2.3 From 283b46fcece41113f4b11cde33d86e336db4bde6 Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Thu, 7 Dec 2017 15:15:43 -0800 Subject: ipvlan: add L2 check for packets arriving via virtual devices [ Upstream commit 92ff42645028fa6f9b8aa767718457b9264316b4 ] Packets that don't have dest mac as the mac of the master device should not be entertained by the IPvlan rx-handler. This is mostly true as the packet path mostly takes care of that, except when the master device is a virtual device. As demonstrated in the following case - ip netns add ns1 ip link add ve1 type veth peer name ve2 ip link add link ve2 name iv1 type ipvlan mode l2 ip link set dev iv1 netns ns1 ip link set ve1 up ip link set ve2 up ip -n ns1 link set iv1 up ip addr add 192.168.10.1/24 dev ve1 ip -n ns1 addr 192.168.10.2/24 dev iv1 ping -c2 192.168.10.2 ip neigh show dev ve1 ip neigh show 192.168.10.2 lladdr dev ve1 ping -c2 192.168.10.2 This patch adds that missing check in the IPvlan rx-handler. Reported-by: Amit Sikka Signed-off-by: Mahesh Bandewar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ipvlan/ipvlan_core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 627eb825eb74..c747ab652665 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -299,6 +299,10 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff **pskb, if (dev_forward_skb(ipvlan->dev, skb) == NET_RX_SUCCESS) success = true; } else { + if (!ether_addr_equal_64bits(eth_hdr(skb)->h_dest, + ipvlan->phy_dev->dev_addr)) + skb->pkt_type = PACKET_OTHERHOST; + ret = RX_HANDLER_ANOTHER; success = true; } -- cgit v1.2.3 From 691ac858a381049c3e49d4a84b4d0fa8a1cad201 Mon Sep 17 00:00:00 2001 From: Salil Date: Sat, 1 Apr 2017 12:03:48 +0100 Subject: net: hns: Some checkpatch.pl script & warning fixes commit b4957ab0826f6f7efdfdc648521e1c4c3fc6ceda upstream. This patch fixes some checkpatch.pl script caught errors and warnings during the compilation time. [ backported to 4.9.y to fix build warnings caused by the backporting of 64ec10dc2ab8 ("net: hns: Correct HNS RSS key set function") by Sasha - gregkh] Signed-off-by: Salil Mehta Signed-off-by: David S. Miller Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 11 +++++------ drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 1 - drivers/net/ethernet/hisilicon/hns/hns_enet.c | 5 +++-- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 1 - 5 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 1e1eb92998fb..02a03bccde7b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -86,12 +86,11 @@ static void hns_gmac_disable(void *mac_drv, enum mac_commom_mode mode) dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0); } -/** -*hns_gmac_get_en - get port enable -*@mac_drv:mac device -*@rx:rx enable -*@tx:tx enable -*/ +/* hns_gmac_get_en - get port enable + * @mac_drv:mac device + * @rx:rx enable + * @tx:tx enable + */ static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx) { struct mac_driver *drv = (struct mac_driver *)mac_drv; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index c494fc52be74..62a12991ce9a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -70,7 +70,7 @@ enum dsaf_roce_qos_sl { }; #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset)))) -#define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP) +#define HNS_DSAF_IS_DEBUG(dev) ((dev)->dsaf_mode == DSAF_MODE_DISABLE_SP) enum hal_dsaf_mode { HRD_DSAF_NO_DSAF_MODE = 0x0, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index f0ed80d6ef9c..f3be9ac47bfb 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -430,7 +430,6 @@ static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb *ring_pair_cb) static int hns_rcb_get_port_in_comm( struct rcb_common_cb *rcb_common, int ring_idx) { - return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn); } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index c06845b7b666..a79e0a1100aa 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -511,7 +511,8 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i, int last_offset; bool twobufs; - twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048); + twobufs = ((PAGE_SIZE < 8192) && + hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048); desc = &ring->desc[ring->next_to_clean]; size = le16_to_cpu(desc->rx.size); @@ -1700,7 +1701,7 @@ static void hns_nic_reset_subtask(struct hns_nic_priv *priv) static void hns_nic_service_event_complete(struct hns_nic_priv *priv) { WARN_ON(!test_bit(NIC_STATE_SERVICE_SCHED, &priv->state)); - + /* make sure to commit the things */ smp_mb__before_atomic(); clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state); } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 8490cba230bd..86a496d71995 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -1243,7 +1243,6 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; - int ret; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, -- cgit v1.2.3 From 0ca43b0aa033dc7240f8e94d01fa69cb16c89cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 9 Mar 2018 14:42:54 +0100 Subject: drm/amdgpu: fix prime teardown order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 342038d92403b3efa1138a8599666b9f026279d6 upstream. We unmapped imported DMA-bufs when the GEM handle was dropped, not when the hardware was done with the buffere. Signed-off-by: Christian König Reviewed-by: Michel Dänzer CC: stable@vger.kernel.org Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index a7ea9a3b454e..d5e4748e3300 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -36,8 +36,6 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj) struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); if (robj) { - if (robj->gem_base.import_attach) - drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); amdgpu_mn_unregister(robj); amdgpu_bo_unref(&robj); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index f3efb1c5dae9..5afe72778518 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -94,6 +94,8 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) amdgpu_update_memory_usage(bo->adev, &bo->tbo.mem, NULL); + if (bo->gem_base.import_attach) + drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg); drm_gem_object_release(&bo->gem_base); amdgpu_bo_unref(&bo->parent); if (!list_empty(&bo->shadow_list)) { -- cgit v1.2.3 From 16c809b7daebfbd8a547d731df88a35a85c1fd12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 9 Mar 2018 18:26:18 +0100 Subject: drm/amdgpu/dce: Don't turn off DP sink when disconnected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7d617264eb22b18d979eac6e85877a141253034e upstream. Turning off the sink in this case causes various issues, because userspace expects it to stay on until it turns it off explicitly. Instead, turn the sink off and back on when a display is connected again. This dance seems necessary for link training to work correctly. Bugzilla: https://bugs.freedesktop.org/105308 Cc: stable@vger.kernel.org Reviewed-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 31 ++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index c82b04b24bf9..e9311eb7b8d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector) /* don't do anything if sink is not display port, i.e., * passive dp->(dvi|hdmi) adaptor */ - if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { - int saved_dpms = connector->dpms; - /* Only turn off the display if it's physically disconnected */ - if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) { - /* Don't try to start link training before we - * have the dpcd */ - if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector)) - return; - - /* set it to OFF so that drm_helper_connector_dpms() - * won't return immediately since the current state - * is ON at this point. - */ - connector->dpms = DRM_MODE_DPMS_OFF; - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - connector->dpms = saved_dpms; + if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT && + amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) && + amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) { + /* Don't start link training before we have the DPCD */ + if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector)) + return; + + /* Turn the connector off and back on immediately, which + * will trigger link training + */ + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } } } -- cgit v1.2.3 From 43166185da4a7802dd011d629fcdb4e1df0d2bd3 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 6 Mar 2018 15:51:32 +0000 Subject: irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis commit 4f2c7583e33eb08dc09dd2e25574b80175ba7d93 upstream. When struct its_device instances are created, the nr_ites member will be set to a power of 2 that equals or exceeds the requested number of MSIs passed to the msi_prepare() callback. At the same time, the LPI map is allocated to be some multiple of 32 in size, where the allocated size may be less than the requested size depending on whether a contiguous range of sufficient size is available in the global LPI bitmap. This may result in the situation where the nr_ites < nr_lpis, and since nr_ites is what we program into the hardware when we map the device, the additional LPIs will be non-functional. For bog standard hardware, this does not really matter. However, in cases where ITS device IDs are shared between different PCIe devices, we may end up allocating these additional LPIs without taking into account that they don't actually work. So let's make nr_ites at least 32. This ensures that all allocated LPIs are 'live', and that its_alloc_device_irq() will fail when attempts are made to allocate MSIs beyond what was allocated in the first place. Signed-off-by: Ard Biesheuvel [maz: updated comment] Signed-off-by: Marc Zyngier [ardb: trivial tweak of unrelated context] Signed-off-by: Ard Biesheuvel Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-gic-v3-its.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index acb9d250a905..ac15e5d5d9b2 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -684,7 +684,7 @@ static struct irq_chip its_irq_chip = { * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. */ #define IRQS_PER_CHUNK_SHIFT 5 -#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) +#define IRQS_PER_CHUNK (1UL << IRQS_PER_CHUNK_SHIFT) static unsigned long *lpi_bitmap; static u32 lpi_chunks; @@ -1320,11 +1320,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, dev = kzalloc(sizeof(*dev), GFP_KERNEL); /* - * At least one bit of EventID is being used, hence a minimum - * of two entries. No, the architecture doesn't let you - * express an ITT with a single entry. + * We allocate at least one chunk worth of LPIs bet device, + * and thus that many ITEs. The device may require less though. */ - nr_ites = max(2UL, roundup_pow_of_two(nvecs)); + nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kzalloc(sz, GFP_KERNEL); -- cgit v1.2.3 From 691db1857ee784f026e4d2c267229db4885494ad Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Fri, 7 Jul 2017 10:56:38 +0200 Subject: scsi: sg: fix SG_DXFER_FROM_DEV transfers commit 68c59fcea1f2c6a54c62aa896cc623c1b5bc9b47 upstream. SG_DXFER_FROM_DEV transfers do not necessarily have a dxferp as we set it to NULL for the old sg_io read/write interface, but must have a length bigger than 0. This fixes a regression introduced by commit 28676d869bbb ("scsi: sg: check for valid direction before starting the request") Signed-off-by: Johannes Thumshirn Fixes: 28676d869bbb ("scsi: sg: check for valid direction before starting the request") Reported-by: Chris Clayton Tested-by: Chris Clayton Cc: Douglas Gilbert Reviewed-by: Hannes Reinecke Tested-by: Chris Clayton Acked-by: Douglas Gilbert Signed-off-by: Martin K. Petersen Cc: Cristian Crinteanu Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index e6333cae8550..1536f143566d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -758,8 +758,11 @@ static bool sg_is_valid_dxfer(sg_io_hdr_t *hp) if (hp->dxferp || hp->dxfer_len > 0) return false; return true; - case SG_DXFER_TO_DEV: case SG_DXFER_FROM_DEV: + if (hp->dxfer_len < 0) + return false; + return true; + case SG_DXFER_TO_DEV: case SG_DXFER_TO_FROM_DEV: if (!hp->dxferp || hp->dxfer_len == 0) return false; -- cgit v1.2.3 From cbdcbd909efe41bbb10b7c15ff1ff15c1b4971a0 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Mon, 17 Jul 2017 15:11:42 +0200 Subject: scsi: sg: fix static checker warning in sg_is_valid_dxfer commit 14074aba4bcda3764c9a702b276308b89901d5b6 upstream. dxfer_len is an unsigned int and we always assign a value > 0 to it, so it doesn't make any sense to check if it is < 0. We can't really check dxferp as well as we have both NULL and not NULL cases in the possible call paths. So just return true for SG_DXFER_FROM_DEV transfer in sg_is_valid_dxfer(). Signed-off-by: Johannes Thumshirn Reported-by: Colin Ian King Reported-by: Dan Carpenter Cc: Douglas Gilbert Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 1536f143566d..638d11d9262f 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -759,8 +759,11 @@ static bool sg_is_valid_dxfer(sg_io_hdr_t *hp) return false; return true; case SG_DXFER_FROM_DEV: - if (hp->dxfer_len < 0) - return false; + /* + * for SG_DXFER_FROM_DEV we always set dxfer_len to > 0. dxferp + * can either be NULL or != NULL so there's no point in checking + * it either. So just return true. + */ return true; case SG_DXFER_TO_DEV: case SG_DXFER_TO_FROM_DEV: -- cgit v1.2.3 From 887cb857e5122a72caa02a3bea402b1c8bf4056b Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Thu, 27 Jul 2017 09:11:26 +0200 Subject: scsi: sg: only check for dxfer_len greater than 256M commit f930c7043663188429cd9b254e9d761edfc101ce upstream. Don't make any assumptions on the sg_io_hdr_t::dxfer_direction or the sg_io_hdr_t::dxferp in order to determine if it is a valid request. The only way we can check for bad requests is by checking if the length exceeds 256M. Signed-off-by: Johannes Thumshirn Fixes: 28676d869bbb (scsi: sg: check for valid direction before starting the request) Reported-by: Jason L Tibbitts III Tested-by: Jason L Tibbitts III Suggested-by: Doug Gilbert Cc: Doug Gilbert Cc: Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 638d11d9262f..7592ac8514d2 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -751,35 +751,6 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, return count; } -static bool sg_is_valid_dxfer(sg_io_hdr_t *hp) -{ - switch (hp->dxfer_direction) { - case SG_DXFER_NONE: - if (hp->dxferp || hp->dxfer_len > 0) - return false; - return true; - case SG_DXFER_FROM_DEV: - /* - * for SG_DXFER_FROM_DEV we always set dxfer_len to > 0. dxferp - * can either be NULL or != NULL so there's no point in checking - * it either. So just return true. - */ - return true; - case SG_DXFER_TO_DEV: - case SG_DXFER_TO_FROM_DEV: - if (!hp->dxferp || hp->dxfer_len == 0) - return false; - return true; - case SG_DXFER_UNKNOWN: - if ((!hp->dxferp && hp->dxfer_len) || - (hp->dxferp && hp->dxfer_len == 0)) - return false; - return true; - default: - return false; - } -} - static int sg_common_write(Sg_fd * sfp, Sg_request * srp, unsigned char *cmnd, int timeout, int blocking) @@ -800,7 +771,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, "sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) cmnd[0], (int) hp->cmd_len)); - if (!sg_is_valid_dxfer(hp)) + if (hp->dxfer_len >= SZ_256M) return -EINVAL; k = sg_start_req(srp, cmnd); -- cgit v1.2.3 From 9f4a71db144905a41c795e5a67236e36cb20bb16 Mon Sep 17 00:00:00 2001 From: Bill Kuzeja Date: Thu, 25 May 2017 15:26:31 -0400 Subject: scsi: qla2xxx: Fix extraneous ref on sp's after adapter break commit 4cd3b6ebff8510b2139d64024411207090cfe0a9 upstream. Hung task timeouts can result if a qlogic board breaks unexpectedly while running I/O. These tasks become hung because command srb reference counts are not going to zero, hence the affected srbs and commands do not get freed. This fix accounts for this extra reference in the srbs in the case of a board failure. Fixes: a465537ad1a4 ("qla2xxx: Disable the adapter and skip error recovery in case of register disconnect") Signed-off-by: Bill Kuzeja Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_os.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 94630d4738e6..baccd116f864 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1443,7 +1443,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) void qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) { - int que, cnt; + int que, cnt, status; unsigned long flags; srb_t *sp; struct qla_hw_data *ha = vha->hw; @@ -1473,8 +1473,12 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) */ sp_get(sp); spin_unlock_irqrestore(&ha->hardware_lock, flags); - qla2xxx_eh_abort(GET_CMD_SP(sp)); + status = qla2xxx_eh_abort(GET_CMD_SP(sp)); spin_lock_irqsave(&ha->hardware_lock, flags); + /* Get rid of extra reference if immediate exit + * from ql2xxx_eh_abort */ + if (status == FAILED && (qla2x00_isp_reg_stat(ha))) + atomic_dec(&sp->ref_count); } req->outstanding_cmds[cnt] = NULL; sp->done(vha, sp, res); -- cgit v1.2.3 From 30fe81cca111c22bc6048ef8998691c8e51b0d7a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Jan 2018 09:35:14 +0000 Subject: USB: gadget: udc: Add missing platform_device_put() on error in bdc_pci_probe() commit 8874ae5f15f3feef3b4a415b9aed51edcf449aa1 upstream. Add the missing platform_device_put() before return from bdc_pci_probe() in the platform_device_add_resources() error handling case. Fixes: efed421a94e6 ("usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC") Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/bdc/bdc_pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c index 02968842b359..708e36f530d8 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_pci.c +++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c @@ -82,6 +82,7 @@ static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) if (ret) { dev_err(&pci->dev, "couldn't add resources to bdc device\n"); + platform_device_put(bdc); return ret; } -- cgit v1.2.3 From ecb1886f9b4fea6408f4d9c6defcc7ba3db88c29 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Fri, 2 Feb 2018 13:21:35 -0800 Subject: usb: dwc3: Fix GDBGFIFOSPACE_TYPE values commit b16ea8b9492e99e03b1269fe93ebdbf8e4eabf8a upstream. The FIFO/Queue type values are incorrect. Correct them according to DWC_usb3 programming guide section 1.2.27 (or DWC_usb31 section 1.2.25). Additionally, this patch includes ProtocolStatusQ and AuxEventQ types. Fixes: cf6d867d3b57 ("usb: dwc3: core: add fifo space helper") Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index bc3678e9dcb1..94d6a3e2ad97 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -159,13 +159,15 @@ #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) #define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff) -#define DWC3_TXFIFOQ 1 -#define DWC3_RXFIFOQ 3 -#define DWC3_TXREQQ 5 -#define DWC3_RXREQQ 7 -#define DWC3_RXINFOQ 9 -#define DWC3_DESCFETCHQ 13 -#define DWC3_EVENTQ 15 +#define DWC3_TXFIFOQ 0 +#define DWC3_RXFIFOQ 1 +#define DWC3_TXREQQ 2 +#define DWC3_RXREQQ 3 +#define DWC3_RXINFOQ 4 +#define DWC3_PSTATQ 5 +#define DWC3_DESCFETCHQ 6 +#define DWC3_EVENTQ 7 +#define DWC3_AUXEVENTQ 8 /* Global RX Threshold Configuration Register */ #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19) -- cgit v1.2.3 From 9fad15931cc5bc42a8cd4739d58ebab527ac1d42 Mon Sep 17 00:00:00 2001 From: Srinath Mannam Date: Thu, 15 Jun 2017 14:39:22 +0530 Subject: usb: gadget: bdc: 64-bit pointer capability check commit c8e4e5bdb62a5ac6f860ebcaaf7b467b62f453f1 upstream. Corrected the register to check the 64-bit pointer capability state. 64-bit pointer implementation capability was checking in wrong register, which causes the BDC enumeration failure in 64-bit memory address. Fixes: efed421a94e6 ("usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC") Reviewed-by: Florian Fainelli Signed-off-by: Srinath Mannam Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/bdc/bdc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index ccb9c213cc9f..e9bd8d4abca0 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -475,7 +475,7 @@ static int bdc_probe(struct platform_device *pdev) bdc->dev = dev; dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); - temp = bdc_readl(bdc->regs, BDC_BDCSC); + temp = bdc_readl(bdc->regs, BDC_BDCCAP1); if ((temp & BDC_P64) && !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { dev_dbg(bdc->dev, "Using 64-bit address\n"); -- cgit v1.2.3 From 890962b83636836b044022773995d5ae558499ea Mon Sep 17 00:00:00 2001 From: Jeremy Boone Date: Thu, 8 Feb 2018 12:28:08 -0800 Subject: tpm: fix potential buffer overruns caused by bit glitches on the bus commit 3be23274755ee85771270a23af7691dc9b3a95db upstream. Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. If a bit does flip it could cause an overrun if it's in one of the size parameters, so sanity check that we're not overrunning the provided buffer when doing a memcpy(). Signed-off-by: Jeremy Boone Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm-interface.c | 5 +++++ drivers/char/tpm/tpm2-cmd.c | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index d0ac2d56520f..830d7e30e508 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -1078,6 +1078,11 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) break; recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); + if (recd > num_bytes) { + total = -EFAULT; + break; + } + memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd); dest += recd; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 17896d654033..a5780ebe15ef 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -668,6 +668,11 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, if (!rc) { data_len = be16_to_cpup( (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]); + if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) { + rc = -EFAULT; + goto out; + } + data = &buf.data[TPM_HEADER_SIZE + 6]; memcpy(payload->key, data, data_len - 1); @@ -675,6 +680,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, payload->migratable = data[data_len - 1]; } +out: tpm_buf_destroy(&buf); return rc; } -- cgit v1.2.3 From d3c79a38843b7d44734dacc17694a72a0b269b74 Mon Sep 17 00:00:00 2001 From: Yisheng Xie Date: Wed, 28 Feb 2018 14:59:22 +0800 Subject: staging: android: ashmem: Fix possible deadlock in ashmem_ioctl commit 740a5759bf222332fbb5eda42f89aa25ba38f9b2 upstream. ashmem_mutex may create a chain of dependencies like: CPU0 CPU1 mmap syscall ioctl syscall -> mmap_sem (acquired) -> ashmem_ioctl -> ashmem_mmap -> ashmem_mutex (acquired) -> ashmem_mutex (try to acquire) -> copy_from_user -> mmap_sem (try to acquire) There is a lock odering problem between mmap_sem and ashmem_mutex causing a lockdep splat[1] during a syzcaller test. This patch fixes the problem by move copy_from_user out of ashmem_mutex. [1] https://www.spinics.net/lists/kernel/msg2733200.html Fixes: ce8a3a9e76d0 (staging: android: ashmem: Fix a race condition in pin ioctls) Reported-by: syzbot+d7a918a7a8e1c952bc36@syzkaller.appspotmail.com Signed-off-by: Yisheng Xie Cc: "Joel Fernandes (Google)" Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index db100154f85c..6d690e5fa9bb 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -718,16 +718,14 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, size_t pgstart, pgend; int ret = -EINVAL; + if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) + return -EFAULT; + mutex_lock(&ashmem_mutex); if (unlikely(!asma->file)) goto out_unlock; - if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) { - ret = -EFAULT; - goto out_unlock; - } - /* per custom, you can pass zero for len to mean "everything onward" */ if (!pin.len) pin.len = PAGE_ALIGN(asma->size) - pin.offset; -- cgit v1.2.3 From 2d07d7d7032c340564d84cedfba60a4d53355e95 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 19 Mar 2018 20:23:18 +0100 Subject: Revert "led: core: Fix brightness setting when setting delay_off=0" This reverts commit 86b9fa2190907f4f550d9d6bf490c5f89ca33836 which was commit 2b83ff96f51d0b039c4561b9f95c824d7bddb85c upstream. The commit being reverted has two flaws: - it introduces a regression, fixed in the upstream commit 7b6af2c53192f1766892ef40c8f48a413509ed72. - it has truncated commit message Reported-by: Sasha Levin Reported-by: Matthias Schiffer Signed-off-by: Jacek Anaszewski Signed-off-by: Greg Kroah-Hartman --- drivers/leds/led-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index d70d4a5273b8..3bce44893021 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - led_stop_software_blink(led_cdev); + del_timer_sync(&led_cdev->blink_timer); led_cdev->flags &= ~LED_BLINK_ONESHOT; led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; -- cgit v1.2.3 From d1ef7ed6e586ef69b366719bc37f1009e1d7d5d4 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 19 Mar 2018 20:23:19 +0100 Subject: led: core: Clear LED_BLINK_SW flag in led_blink_set() [Only needed in 4.9.y due to other fixes in mainline - gregkh] With the current code, the following sequence won't work : echo timer > trigger echo 0 > delay_off * at this point we call ** led_delay_off_store ** led_blink_set --- drivers/leds/led-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 3bce44893021..454ed4dc6ec1 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -188,6 +188,7 @@ void led_blink_set(struct led_classdev *led_cdev, { del_timer_sync(&led_cdev->blink_timer); + led_cdev->flags &= ~LED_BLINK_SW; led_cdev->flags &= ~LED_BLINK_ONESHOT; led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; -- cgit v1.2.3 From 09604c91cb04979eff200d05e44df845cd0fb7cf Mon Sep 17 00:00:00 2001 From: Santeri Toivonen Date: Tue, 4 Apr 2017 21:09:00 +0300 Subject: platform/x86: asus-nb-wmi: Add wapf4 quirk for the X302UA [ Upstream commit f35823619db8bbaa2afea8705f239c3cecb9d22f ] Asus laptop X302UA starts up with Wi-Fi disabled, without a way to enable it. Set wapf=4 to fix the problem. Signed-off-by: Santeri Toivonen Signed-off-by: Darren Hart (VMware) Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 6eb2837f6b89..ab44326ea3e7 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -150,6 +150,15 @@ static const struct dmi_system_id asus_quirks[] = { */ .driver_data = &quirk_asus_wapf4, }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. X302UA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"), + }, + .driver_data = &quirk_asus_wapf4, + }, { .callback = dmi_matched, .ident = "ASUSTeK COMPUTER INC. X401U", -- cgit v1.2.3 From 86138a4972c4c347413f8461cd06f6a947947dfc Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Tue, 11 Apr 2017 22:36:00 -0700 Subject: bonding: handle link transition from FAIL to UP correctly [ Upstream commit fb9eb899a6dc663e4a2deed9af2ac28f507d0ffb ] When link transitions from LINK_FAIL to LINK_UP, the commit phase is not called. This leads to an erroneous state causing slave-link state to get stuck in "going down" state while its speed and duplex are perfectly fine. This issue is a side-effect of splitting link-set into propose and commit phases introduced by de77ecd4ef02 ("bonding: improve link-status update in mii-monitoring") This patch fixes these issues by calling commit phase whenever link state change is proposed. Fixes: de77ecd4ef02 ("bonding: improve link-status update in mii-monitoring") Signed-off-by: Mahesh Bandewar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c3f3096b24ae..4907c9b57565 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2067,6 +2067,7 @@ static int bond_miimon_inspect(struct bonding *bond) (bond->params.downdelay - slave->delay) * bond->params.miimon, slave->dev->name); + commit++; continue; } @@ -2104,7 +2105,7 @@ static int bond_miimon_inspect(struct bonding *bond) (bond->params.updelay - slave->delay) * bond->params.miimon, slave->dev->name); - + commit++; continue; } -- cgit v1.2.3 From 8623759933ff15a3864d33225ad26ae87566655d Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 12 Apr 2017 09:58:47 +0800 Subject: regulator: anatop: set default voltage selector for pcie [ Upstream commit 9bf944548169f6153c3d3778cf983cb5db251a0e ] Set the initial voltage selector for vddpcie in case it's disabled by default. This fixes the below warning: 20c8000.anatop:regulator-vddpcie: Failed to read a valid default voltage selector. anatop_regulator: probe of 20c8000.anatop:regulator-vddpcie failed with error -22 Cc: Liam Girdwood Cc: Mark Brown Cc: Shawn Guo Cc: Sascha Hauer Cc: Robin Gong Cc: Richard Zhu Signed-off-by: Richard Zhu Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/anatop-regulator.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3a6d0290c54c..c5e272ea4372 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -296,6 +296,11 @@ static int anatop_regulator_probe(struct platform_device *pdev) if (!sreg->sel && !strcmp(sreg->name, "vddpu")) sreg->sel = 22; + /* set the default voltage of the pcie phy to be 1.100v */ + if (!sreg->sel && rdesc->name && + !strcmp(rdesc->name, "vddpcie")) + sreg->sel = 0x10; + if (!sreg->bypass && !sreg->sel) { dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n"); return -EINVAL; -- cgit v1.2.3 From f15ea8e12821a5709b2eec406cbefa1dba27ff5b Mon Sep 17 00:00:00 2001 From: Liam Breck Date: Tue, 11 Apr 2017 04:59:54 -0700 Subject: power: supply: bq24190_charger: Limit over/under voltage fault logging [ Upstream commit d63d07c6fc25182af6d3ab5b3b8737b0c1025ebd ] If the charger is unplugged before the battery is full we may see an over/under voltage fault. Ignore this rather then emitting a message or uevent. This fixes messages like these getting logged on charger unplug + replug: bq24190-charger 15-006b: Fault: boost 0, charge 1, battery 0, ntc 0 bq24190-charger 15-006b: Fault: boost 0, charge 0, battery 0, ntc 0 Cc: Tony Lindgren Cc: Hans de Goede Signed-off-by: Liam Breck Acked-by: Tony Lindgren Reviewed-by: Hans de Goede Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq24190_charger.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 50171fd3cc6d..cdd71ecd72ed 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -1184,8 +1184,13 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) } } while (f_reg && ++i < 2); + /* ignore over/under voltage fault after disconnect */ + if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) && + !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) + f_reg = 0; + if (f_reg != bdi->f_reg) { - dev_info(bdi->dev, + dev_warn(bdi->dev, "Fault: boost %d, charge %d, battery %d, ntc %d\n", !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK), !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK), -- cgit v1.2.3 From f114850808ea4aadc9d033f895ff024b7faf8dee Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Mar 2017 14:45:49 +0100 Subject: rtc: cmos: Do not assume irq 8 for rtc when there are no legacy irqs [ Upstream commit a1e23a42f1bdc00e32fc4869caef12e4e6272f26 ] On some systems (e.g. Intel Bay Trail systems) the legacy PIC is not used, in this case virq 8 will be a random irq, rather then hw_irq 8 from the PIC. Requesting virq 8 in this case will not help us to get alarm irqs and may cause problems for other drivers which actually do need virq 8, for example on an Asus Transformer T100TA this leads to: [ 28.745155] genirq: Flags mismatch irq 8. 00000088 (mmc0) vs. 00000080 (rtc0) [ 28.753700] mmc0: Failed to request IRQ 8: -16 [ 28.975934] sdhci-acpi: probe of 80860F14:01 failed with error -16 This commit fixes this by making the rtc-cmos driver continue without using an irq rather then claiming irq 8 when no irq is specified in the pnp-info and there are no legacy-irqs. Signed-off-by: Hans de Goede Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-cmos.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 7030d7cd3861..c554e529fc4e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -41,6 +41,9 @@ #include #include #include +#ifdef CONFIG_X86 +#include +#endif /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ #include @@ -1117,17 +1120,23 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) { cmos_wake_setup(&pnp->dev); - if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) + if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) { + unsigned int irq = 0; +#ifdef CONFIG_X86 /* Some machines contain a PNP entry for the RTC, but * don't define the IRQ. It should always be safe to - * hardcode it in these cases + * hardcode it on systems with a legacy PIC. */ + if (nr_legacy_irqs()) + irq = 8; +#endif return cmos_do_probe(&pnp->dev, - pnp_get_resource(pnp, IORESOURCE_IO, 0), 8); - else + pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); + } else { return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), pnp_irq(pnp, 0)); + } } static void cmos_pnp_remove(struct pnp_dev *pnp) -- cgit v1.2.3 From 4dbe5cc3885b98f3a8e45065e42d90901c1f33c2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 12 Dec 2016 15:32:57 -0800 Subject: Input: ar1021_i2c - fix too long name in driver's device table [ Upstream commit 95123fc43560d6f4a60e74f72836e63cd8848f76 ] The name field in structure i2c_device_id is 20 characters, and we expect it to be NULL-terminated, however we are trying to stuff it with 21 bytes and thus NULL-terminator is lost. This causes issues when one creates device with name "MICROCHIP_AR1021_I2C" as i2c core cuts off the last "C", and automatic module loading by alias does not work as result. The -I2C suffix in the device name is superfluous, we know what bus we are dealing with, so let's drop it. Also, no other driver uses capitals, and the manufacturer name is normally not included, except in very rare cases of incompatible name collisions. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116211 Fixes: dd4cae8bf166 ("Input: Add Microchip AR1021 i2c touchscreen") Reviewed-By: Christian Gmeiner Tested-by: Martin Kepplinger Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/ar1021_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c index 71b5a634cf6d..e7bb155911d0 100644 --- a/drivers/input/touchscreen/ar1021_i2c.c +++ b/drivers/input/touchscreen/ar1021_i2c.c @@ -152,7 +152,7 @@ static int __maybe_unused ar1021_i2c_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume); static const struct i2c_device_id ar1021_i2c_id[] = { - { "MICROCHIP_AR1021_I2C", 0 }, + { "ar1021", 0 }, { }, }; MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id); -- cgit v1.2.3 From 58e7fd9cae5f0b8deabfae1f1f87526b5a874e08 Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Sun, 26 Mar 2017 12:04:13 -0700 Subject: time: Change posix clocks ops interfaces to use timespec64 [ Upstream commit d340266e19ddb70dbd608f9deedcfb35fdb9d419 ] struct timespec is not y2038 safe on 32 bit machines. The posix clocks apis use struct timespec directly and through struct itimerspec. Replace the posix clock interfaces to use struct timespec64 and struct itimerspec64 instead. Also fix up their implementations accordingly. Note that the clock_getres() interface has also been changed to use timespec64 even though this particular interface is not affected by the y2038 problem. This helps verification for internal kernel code for y2038 readiness by getting rid of time_t/ timeval/ timespec. Signed-off-by: Deepa Dinamani Cc: arnd@arndb.de Cc: y2038@lists.linaro.org Cc: netdev@vger.kernel.org Cc: Richard Cochran Cc: john.stultz@linaro.org Link: http://lkml.kernel.org/r/1490555058-4603-3-git-send-email-deepa.kernel@gmail.com Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/ptp/ptp_clock.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 86280b7e41f3..2aa5b37cc6d2 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -97,30 +97,26 @@ static s32 scaled_ppm_to_ppb(long ppm) /* posix clock implementation */ -static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) +static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp) { tp->tv_sec = 0; tp->tv_nsec = 1; return 0; } -static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) +static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - struct timespec64 ts = timespec_to_timespec64(*tp); - return ptp->info->settime64(ptp->info, &ts); + return ptp->info->settime64(ptp->info, tp); } -static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp) +static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - struct timespec64 ts; int err; - err = ptp->info->gettime64(ptp->info, &ts); - if (!err) - *tp = timespec64_to_timespec(ts); + err = ptp->info->gettime64(ptp->info, tp); return err; } @@ -133,7 +129,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) ops = ptp->info; if (tx->modes & ADJ_SETOFFSET) { - struct timespec ts; + struct timespec64 ts; ktime_t kt; s64 delta; @@ -146,7 +142,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC) return -EINVAL; - kt = timespec_to_ktime(ts); + kt = timespec64_to_ktime(ts); delta = ktime_to_ns(kt); err = ops->adjtime(ops, delta); } else if (tx->modes & ADJ_FREQUENCY) { -- cgit v1.2.3 From 723dde3922983e1eb5bbc336d826fe6eac57fc9a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 12 Apr 2017 22:07:33 +0200 Subject: ACPI/processor: Fix error handling in __acpi_processor_start() [ Upstream commit a5cbdf693a60d5b86d4d21dfedd90f17754eb273 ] When acpi_install_notify_handler() fails the cooling device stays registered and the sysfs files created via acpi_pss_perf_init() are leaked and the function returns success. Undo acpi_pss_perf_init() and return a proper error code. Signed-off-by: Thomas Gleixner Cc: Fenghua Yu Cc: Tony Luck Cc: Herbert Xu Cc: "Rafael J. Wysocki" Cc: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: Sebastian Siewior Cc: Lai Jiangshan Cc: linux-acpi@vger.kernel.org Cc: Viresh Kumar Cc: Michael Ellerman Cc: Tejun Heo Cc: "David S. Miller" Cc: Len Brown Link: http://lkml.kernel.org/r/20170412201042.695499645@linutronix.de Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_driver.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9d5f0c7ed3f7..eab8cdad7dc3 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -251,6 +251,9 @@ static int __acpi_processor_start(struct acpi_device *device) if (ACPI_SUCCESS(status)) return 0; + result = -ENODEV; + acpi_pss_perf_exit(pr, device); + err_power_exit: acpi_processor_power_exit(pr); return result; -- cgit v1.2.3 From b7e5f1a204e1209c6abeda71956b58f0f6ee21fe Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 12 Apr 2017 22:07:34 +0200 Subject: ACPI/processor: Replace racy task affinity logic [ Upstream commit 8153f9ac43897f9f4786b30badc134fcc1a4fb11 ] acpi_processor_get_throttling() requires to invoke the getter function on the target CPU. This is achieved by temporarily setting the affinity of the calling user space thread to the requested CPU and reset it to the original affinity afterwards. That's racy vs. CPU hotplug and concurrent affinity settings for that thread resulting in code executing on the wrong CPU and overwriting the new affinity setting. acpi_processor_get_throttling() is invoked in two ways: 1) The CPU online callback, which is already running on the target CPU and obviously protected against hotplug and not affected by affinity settings. 2) The ACPI driver probe function, which is not protected against hotplug during modprobe. Switch it over to work_on_cpu() and protect the probe function against CPU hotplug. Signed-off-by: Thomas Gleixner Cc: Fenghua Yu Cc: Tony Luck Cc: Herbert Xu Cc: "Rafael J. Wysocki" Cc: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: Sebastian Siewior Cc: Lai Jiangshan Cc: linux-acpi@vger.kernel.org Cc: Viresh Kumar Cc: Michael Ellerman Cc: Tejun Heo Cc: "David S. Miller" Cc: Len Brown Link: http://lkml.kernel.org/r/20170412201042.785920903@linutronix.de Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_driver.c | 7 ++++- drivers/acpi/processor_throttling.c | 62 +++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index eab8cdad7dc3..8697a82bd465 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -262,11 +262,16 @@ err_power_exit: static int acpi_processor_start(struct device *dev) { struct acpi_device *device = ACPI_COMPANION(dev); + int ret; if (!device) return -ENODEV; - return __acpi_processor_start(device); + /* Protect against concurrent CPU hotplug operations */ + get_online_cpus(); + ret = __acpi_processor_start(device); + put_online_cpus(); + return ret; } static int acpi_processor_stop(struct device *dev) diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d51ca1c05619..207e9bbb9490 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -62,8 +62,8 @@ struct acpi_processor_throttling_arg { #define THROTTLING_POSTCHANGE (2) static int acpi_processor_get_throttling(struct acpi_processor *pr); -int acpi_processor_set_throttling(struct acpi_processor *pr, - int state, bool force); +static int __acpi_processor_set_throttling(struct acpi_processor *pr, + int state, bool force, bool direct); static int acpi_processor_update_tsd_coord(void) { @@ -891,7 +891,8 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid throttling state, reset\n")); state = 0; - ret = acpi_processor_set_throttling(pr, state, true); + ret = __acpi_processor_set_throttling(pr, state, true, + true); if (ret) return ret; } @@ -901,36 +902,31 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) return 0; } -static int acpi_processor_get_throttling(struct acpi_processor *pr) +static long __acpi_processor_get_throttling(void *data) { - cpumask_var_t saved_mask; - int ret; + struct acpi_processor *pr = data; + + return pr->throttling.acpi_processor_get_throttling(pr); +} +static int acpi_processor_get_throttling(struct acpi_processor *pr) +{ if (!pr) return -EINVAL; if (!pr->flags.throttling) return -ENODEV; - if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) - return -ENOMEM; - /* - * Migrate task to the cpu pointed by pr. + * This is either called from the CPU hotplug callback of + * processor_driver or via the ACPI probe function. In the latter + * case the CPU is not guaranteed to be online. Both call sites are + * protected against CPU hotplug. */ - cpumask_copy(saved_mask, ¤t->cpus_allowed); - /* FIXME: use work_on_cpu() */ - if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { - /* Can't migrate to the target pr->id CPU. Exit */ - free_cpumask_var(saved_mask); + if (!cpu_online(pr->id)) return -ENODEV; - } - ret = pr->throttling.acpi_processor_get_throttling(pr); - /* restore the previous state */ - set_cpus_allowed_ptr(current, saved_mask); - free_cpumask_var(saved_mask); - return ret; + return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr); } static int acpi_processor_get_fadt_info(struct acpi_processor *pr) @@ -1080,8 +1076,15 @@ static long acpi_processor_throttling_fn(void *data) arg->target_state, arg->force); } -int acpi_processor_set_throttling(struct acpi_processor *pr, - int state, bool force) +static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) +{ + if (direct) + return fn(arg); + return work_on_cpu(cpu, fn, arg); +} + +static int __acpi_processor_set_throttling(struct acpi_processor *pr, + int state, bool force, bool direct) { int ret = 0; unsigned int i; @@ -1130,7 +1133,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, arg.pr = pr; arg.target_state = state; arg.force = force; - ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg); + ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, &arg, + direct); } else { /* * When the T-state coordination is SW_ALL or HW_ALL, @@ -1163,8 +1167,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, arg.pr = match_pr; arg.target_state = state; arg.force = force; - ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, - &arg); + ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, + &arg, direct); } } /* @@ -1182,6 +1186,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, return ret; } +int acpi_processor_set_throttling(struct acpi_processor *pr, int state, + bool force) +{ + return __acpi_processor_set_throttling(pr, state, force, false); +} + int acpi_processor_get_throttling_info(struct acpi_processor *pr) { int result = 0; -- cgit v1.2.3 From ade9f4ba0d7af1ee2a310f1dda96c9174e35202b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 12 Apr 2017 22:07:36 +0200 Subject: cpufreq/sh: Replace racy task affinity logic [ Upstream commit 205dcc1ecbc566cbc20acf246e68de3b080b3ecf ] The target() callback must run on the affected cpu. This is achieved by temporarily setting the affinity of the calling thread to the requested CPU and reset it to the original affinity afterwards. That's racy vs. concurrent affinity settings for that thread resulting in code executing on the wrong CPU. Replace it by work_on_cpu(). All call pathes which invoke the callbacks are already protected against CPU hotplug. Signed-off-by: Thomas Gleixner Acked-by: Viresh Kumar Cc: Fenghua Yu Cc: Tony Luck Cc: Herbert Xu Cc: "Rafael J. Wysocki" Cc: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: Sebastian Siewior Cc: linux-pm@vger.kernel.org Cc: Lai Jiangshan Cc: Michael Ellerman Cc: Tejun Heo Cc: "David S. Miller" Cc: Len Brown Link: http://lkml.kernel.org/r/20170412201042.958216363@linutronix.de Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/sh-cpufreq.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 86628e22b2a3..719c3d9f07fb 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c @@ -30,54 +30,63 @@ static DEFINE_PER_CPU(struct clk, sh_cpuclk); +struct cpufreq_target { + struct cpufreq_policy *policy; + unsigned int freq; +}; + static unsigned int sh_cpufreq_get(unsigned int cpu) { return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000; } -/* - * Here we notify other drivers of the proposed change and the final change. - */ -static int sh_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static long __sh_cpufreq_target(void *arg) { - unsigned int cpu = policy->cpu; + struct cpufreq_target *target = arg; + struct cpufreq_policy *policy = target->policy; + int cpu = policy->cpu; struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - cpumask_t cpus_allowed; struct cpufreq_freqs freqs; struct device *dev; long freq; - cpus_allowed = current->cpus_allowed; - set_cpus_allowed_ptr(current, cpumask_of(cpu)); - - BUG_ON(smp_processor_id() != cpu); + if (smp_processor_id() != cpu) + return -ENODEV; dev = get_cpu_device(cpu); /* Convert target_freq from kHz to Hz */ - freq = clk_round_rate(cpuclk, target_freq * 1000); + freq = clk_round_rate(cpuclk, target->freq * 1000); if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) return -EINVAL; - dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000); + dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000); freqs.old = sh_cpufreq_get(cpu); freqs.new = (freq + 500) / 1000; freqs.flags = 0; - cpufreq_freq_transition_begin(policy, &freqs); - set_cpus_allowed_ptr(current, &cpus_allowed); + cpufreq_freq_transition_begin(target->policy, &freqs); clk_set_rate(cpuclk, freq); - cpufreq_freq_transition_end(policy, &freqs, 0); + cpufreq_freq_transition_end(target->policy, &freqs, 0); dev_dbg(dev, "set frequency %lu Hz\n", freq); - return 0; } +/* + * Here we notify other drivers of the proposed change and the final change. + */ +static int sh_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct cpufreq_target data = { .policy = policy, .freq = target_freq }; + + return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); +} + static int sh_cpufreq_verify(struct cpufreq_policy *policy) { struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); -- cgit v1.2.3 From 8cda29d440c39e267ab67217171ed708ac27a0b4 Mon Sep 17 00:00:00 2001 From: Edgar Cherkasov Date: Tue, 4 Apr 2017 19:18:27 +0300 Subject: i2c: i2c-scmi: add a MS HID [ Upstream commit e058e7a4bc89104540a8a303682248614b5df6f1 ] Description of the problem: - i2c-scmi driver contains only two identifiers "SMBUS01" and "SMBUSIBM"; - the fist HID (SMBUS01) is clearly defined in "SMBus Control Method Interface Specification, version 1.0": "Each device must specify 'SMBUS01' as its _HID and use a unique _UID value"; - unfortunately, BIOS vendors (like AMI) seem to ignore this requirement and implement "SMB0001" HID instead of "SMBUS01"; - I speculate that they do this because only "SMB0001" is hard coded in Windows SMBus driver produced by Microsoft. This leads to following situation: - SMBus works out of box in Windows but not in Linux; - board vendors are forced to add correct "SMBUS01" HID to BIOS to make SMBus work in Linux. Moreover the same board vendors complain that tools (3-rd party ASL compiler) do not like the "SMBUS01" identifier and produce errors. So they need to constantly patch the compiler for each new version of BIOS. As it is very unlikely that BIOS vendors implement a correct HID in future, I would propose to consider whether it is possible to work around the problem by adding MS HID to the Linux i2c-scmi driver. v2: move the definition of the new HID to the driver itself. Signed-off-by: Edgar Cherkasov Signed-off-by: Michael Brunner Acked-by: Viktor Krasnov Reviewed-by: Jean Delvare Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-scmi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index dfc98df7b1b6..7aa7b9cb6203 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -18,6 +18,9 @@ #define ACPI_SMBUS_HC_CLASS "smbus" #define ACPI_SMBUS_HC_DEVICE_NAME "cmi" +/* SMBUS HID definition as supported by Microsoft Windows */ +#define ACPI_SMBUS_MS_HID "SMB0001" + ACPI_MODULE_NAME("smbus_cmi"); struct smbus_methods_t { @@ -51,6 +54,7 @@ static const struct smbus_methods_t ibm_smbus_methods = { static const struct acpi_device_id acpi_smbus_cmi_ids[] = { {"SMBUS01", (kernel_ulong_t)&smbus_methods}, {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods}, + {ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods}, {"", 0} }; MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids); -- cgit v1.2.3 From 355edc25c3f9b5171abaea2a160c569a1e52f4d2 Mon Sep 17 00:00:00 2001 From: Jasmin J Date: Fri, 17 Mar 2017 23:04:20 -0300 Subject: media/dvb-core: Race condition when writing to CAM [ Upstream commit e7080d4471d805d921a9ea21b32f911a91e248cb ] It started with a sporadic message in syslog: "CAM tried to send a buffer larger than the ecount size" This message is not the fault itself, but a consecutive fault, after a read error from the CAM. This happens only on several CAMs, several hardware, and of course sporadic. It is a consecutive fault, if the last read from the CAM did fail. I guess this will not happen on all CAMs, but at least it did on mine. There was a write error to the CAM and during the re-initialization procedure, the CAM finished the last read, although it got a RS. The write error to the CAM happened because a race condition between HC write, checking DA and FR. This patch added an additional check for DA(RE), just after checking FR. It is important to read the CAMs status register again, to give the CAM the necessary time for a proper reaction to HC. Please note the description within the source code (patch below). [mchehab@s-opensource.com: make checkpatch happy] Signed-off-by: Jasmin jessich Tested-by: Ralph Metzler Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-core/dvb_ca_en50221.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index b5b5b195ea7f..42ce88ceac66 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -779,6 +779,29 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b goto exit; } + /* + * It may need some time for the CAM to settle down, or there might + * be a race condition between the CAM, writing HC and our last + * check for DA. This happens, if the CAM asserts DA, just after + * checking DA before we are setting HC. In this case it might be + * a bug in the CAM to keep the FR bit, the lower layer/HW + * communication requires a longer timeout or the CAM needs more + * time internally. But this happens in reality! + * We need to read the status from the HW again and do the same + * we did for the previous check for DA + */ + status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + if (status < 0) + goto exit; + + if (status & (STATUSREG_DA | STATUSREG_RE)) { + if (status & STATUSREG_DA) + dvb_ca_en50221_thread_wakeup(ca); + + status = -EAGAIN; + goto exit; + } + /* send the amount of data */ if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) goto exit; -- cgit v1.2.3 From f5df9a59c68ea8272960cb88d31434ccb69b3510 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 18 Apr 2017 20:09:06 +0200 Subject: spi: dw: Disable clock after unregistering the host [ Upstream commit 400c18e3dc86e04ef5afec9b86a8586ca629b9e9 ] The dw_mmio driver disables the block clock before unregistering the host. The code unregistering the host may access the SPI block registers. If register access happens with block clock disabled, this may lead to a bus hang. Disable the clock after unregistering the host to prevent such situation. This bug was observed on Altera Cyclone V SoC. Signed-off-by: Marek Vasut Cc: Andy Shevchenko Cc: Mark Brown Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-dw-mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 447497e9124c..d25cc4037e23 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -115,8 +115,8 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) { struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); - clk_disable_unprepare(dwsmmio->clk); dw_spi_remove_host(&dwsmmio->dws); + clk_disable_unprepare(dwsmmio->clk); return 0; } -- cgit v1.2.3 From 723052b2540bf8bea0df3b73547c75c50bdd86ae Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 12 Apr 2017 23:19:37 +0530 Subject: ath: Fix updating radar flags for coutry code India [ Upstream commit c0c345d4cacc6a1f39d4856f37dcf6e34f51a5e4 ] As per latest regulatory update for India, channel 52, 56, 60, 64 is no longer restricted to DFS. Enabling DFS/no infra flags in driver results in applying all DFS related restrictions (like doing CAC etc before this channel moves to 'available state') for these channels even though the country code is programmed as 'India' in he hardware, fix this by relaxing the frequency range while applying RADAR flags only if the country code is programmed to India. If the frequency range needs to modified based on different country code, ath_is_radar_freq can be extended/modified dynamically. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/regd.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f8506037736f..404fc306cb2a 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -254,8 +254,12 @@ bool ath_is_49ghz_allowed(u16 regdomain) EXPORT_SYMBOL(ath_is_49ghz_allowed); /* Frequency is one where radar detection is required */ -static bool ath_is_radar_freq(u16 center_freq) +static bool ath_is_radar_freq(u16 center_freq, + struct ath_regulatory *reg) + { + if (reg->country_code == CTRY_INDIA) + return (center_freq >= 5500 && center_freq <= 5700); return (center_freq >= 5260 && center_freq <= 5700); } @@ -306,7 +310,7 @@ __ath_reg_apply_beaconing_flags(struct wiphy *wiphy, enum nl80211_reg_initiator initiator, struct ieee80211_channel *ch) { - if (ath_is_radar_freq(ch->center_freq) || + if (ath_is_radar_freq(ch->center_freq, reg) || (ch->flags & IEEE80211_CHAN_RADAR)) return; @@ -395,8 +399,9 @@ ath_reg_apply_ir_flags(struct wiphy *wiphy, } } -/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ -static void ath_reg_apply_radar_flags(struct wiphy *wiphy) +/* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */ +static void ath_reg_apply_radar_flags(struct wiphy *wiphy, + struct ath_regulatory *reg) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -409,7 +414,7 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if (!ath_is_radar_freq(ch->center_freq)) + if (!ath_is_radar_freq(ch->center_freq, reg)) continue; /* We always enable radar detection/DFS on this * frequency range. Additionally we also apply on @@ -505,7 +510,7 @@ void ath_reg_notifier_apply(struct wiphy *wiphy, struct ath_common *common = container_of(reg, struct ath_common, regulatory); /* We always apply this */ - ath_reg_apply_radar_flags(wiphy); + ath_reg_apply_radar_flags(wiphy, reg); /* * This would happen when we have sent a custom regulatory request @@ -653,7 +658,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, } wiphy_apply_custom_regulatory(wiphy, regd); - ath_reg_apply_radar_flags(wiphy); + ath_reg_apply_radar_flags(wiphy, reg); ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); return 0; } -- cgit v1.2.3 From cfa8803d3876f8842152df5034b4434930efd1f5 Mon Sep 17 00:00:00 2001 From: Bharat Kumar Reddy Gooty Date: Mon, 20 Mar 2017 18:12:14 -0400 Subject: clk: ns2: Correct SDIO bits [ Upstream commit 8973aa4aecac223548366ca81818309a0f0efa6d ] Corrected the bits for power and iso. Signed-off-by: Bharat Kumar Reddy Gooty Signed-off-by: Jon Mason Fixes: f7225a83 ("clk: ns2: add clock support for Broadcom Northstar 2 SoC") Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/bcm/clk-ns2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c index a564e9248814..adc14145861a 100644 --- a/drivers/clk/bcm/clk-ns2.c +++ b/drivers/clk/bcm/clk-ns2.c @@ -103,7 +103,7 @@ CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr", static const struct iproc_pll_ctrl genpll_sw = { .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, - .aon = AON_VAL(0x0, 2, 9, 8), + .aon = AON_VAL(0x0, 1, 11, 10), .reset = RESET_VAL(0x4, 2, 1), .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3), .ndiv_int = REG_VAL(0x8, 4, 10), -- cgit v1.2.3 From e2b737ef004896714a3f73c9bab0444da8dfc7b7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 13 Feb 2017 11:29:16 +0200 Subject: iwlwifi: split the handler and the wake parts of the notification infra [ Upstream commit 2220fb2960b72915e7fd9da640a4695dceff238c ] The notification infrastructure (iwl_notification_wait_* functions) allows to wait until a list of notifications will come up from the firmware and to run a special handler (notif_wait handler) when those are received. The operation mode notifies the notification infrastructure about any Rx being received by the mean of iwl_notification_wait_notify() which will do two things: 1) call the notif_wait handler 2) wakeup the thread that was waiting for the notification Typically, only after those two steps happened, the operation mode will run its own handler for the notification that was received from the firmware. This means that the thread that was waiting for that notification can be running before the operation mode's handler was called. When the operation mode's handler is ASYNC, things get even worse since the thread that was waiting for the notification isn't even guaranteed that the ASYNC callback was added to async_handlers_list before it starts to run. This means that even calling iwl_mvm_wait_for_async_handlers() can't guarantee that absolutely everything related to that notification has run. The following can happen: Thread sending the command Operation mode's Rx path -------------------------- ------------------------ iwl_init_notification_wait() iwl_mvm_send_cmd() iwl_mvm_rx_common() iwl_notification_wait_notify() iwl_mvm_wait_for_async_handlers() // Possibly free some data // structure list_add_tail(async_handlers_list); schedule_work(async_handlers_wk); // Access the freed structure Split the 'run notif_wait's handler' and the 'wake up the thread' parts to fix this. This allows the operation mode to do the following: Thread sending the command Operation mode's Rx path -------------------------- ------------------------ iwl_init_notification_wait() iwl_mvm_send_cmd() iwl_mvm_rx_common() iwl_notification_wait() // Will run the notif_wait's handler list_add_tail(async_handlers_list); schedule_work(async_handlers_wk); iwl_notification_notify() iwl_mvm_wait_for_async_handlers() This way, the waiter is guaranteed that all the handlers have been run (if SYNC), or at least enqueued (if ASYNC) by the time it wakes up. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- .../net/wireless/intel/iwlwifi/iwl-notif-wait.c | 10 ++++----- .../net/wireless/intel/iwlwifi/iwl-notif-wait.h | 25 +++++++++++++++++----- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c index 88f260db3744..68412ff2112e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c @@ -76,8 +76,8 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) } IWL_EXPORT_SYMBOL(iwl_notification_wait_init); -void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, - struct iwl_rx_packet *pkt) +bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt) { bool triggered = false; @@ -118,13 +118,11 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, } } spin_unlock(¬if_wait->notif_wait_lock); - } - if (triggered) - wake_up_all(¬if_wait->notif_waitq); + return triggered; } -IWL_EXPORT_SYMBOL(iwl_notification_wait_notify); +IWL_EXPORT_SYMBOL(iwl_notification_wait); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h index 0f9995ed71cd..368884be4e7c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -32,6 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,10 +90,10 @@ struct iwl_notif_wait_data { * * This structure is not used directly, to wait for a * notification declare it on the stack, and call - * iwlagn_init_notification_wait() with appropriate + * iwl_init_notification_wait() with appropriate * parameters. Then do whatever will cause the ucode * to notify the driver, and to wait for that then - * call iwlagn_wait_notification(). + * call iwl_wait_notification(). * * Each notification is one-shot. If at some point we * need to support multi-shot notifications (which @@ -114,10 +115,24 @@ struct iwl_notification_wait { /* caller functions */ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data); -void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, - struct iwl_rx_packet *pkt); +bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data); +static inline void +iwl_notification_notify(struct iwl_notif_wait_data *notif_data) +{ + wake_up_all(¬if_data->notif_waitq); +} + +static inline void +iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt) +{ + if (iwl_notification_wait(notif_data, pkt)) + iwl_notification_notify(notif_data); +} + /* user functions */ void __acquires(wait_entry) iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data, -- cgit v1.2.3 From 0bb43a3a7542c907d2c32e811d75faed6d55eda1 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 19 Feb 2017 10:42:40 +0200 Subject: iwlwifi: a000: fix memory offsets and lengths [ Upstream commit f4d1047914ea05e0f8393944da18f6ee5dad24c4 ] Memory offsets and lengths for A000 HW is different than currently specified. Fixes: e34d975e40ff ("iwlwifi: Add a000 HW family support") Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/iwl-a000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c index ea1618525878..e267377edbe7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c @@ -65,12 +65,12 @@ #define IWL_A000_TX_POWER_VERSION 0xffff /* meaningless */ /* Memory offsets and lengths */ -#define IWL_A000_DCCM_OFFSET 0x800000 -#define IWL_A000_DCCM_LEN 0x18000 +#define IWL_A000_DCCM_OFFSET 0x800000 /* LMAC1 */ +#define IWL_A000_DCCM_LEN 0x10000 /* LMAC1 */ #define IWL_A000_DCCM2_OFFSET 0x880000 #define IWL_A000_DCCM2_LEN 0x8000 #define IWL_A000_SMEM_OFFSET 0x400000 -#define IWL_A000_SMEM_LEN 0x68000 +#define IWL_A000_SMEM_LEN 0xD0000 #define IWL_A000_FW_PRE "iwlwifi-Qu-a0-jf-b0-" #define IWL_A000_MODULE_FIRMWARE(api) \ -- cgit v1.2.3 From 489e563cd3e1086ef30ac0b3a4a76ef25b8e3ff2 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 13 Apr 2017 12:13:00 +1000 Subject: scsi: virtio_scsi: Always try to read VPD pages [ Upstream commit 25d1d50e23275e141e3a3fe06c25a99f4c4bf4e0 ] Passed through SCSI targets may have transfer limits which come from the host SCSI controller or something on the host side other than the target itself. To make this work properly, the hypervisor can adjust the target's VPD information to advertise these limits. But for that to work, the guest has to look at the VPD pages, which we won't do by default if it is an SPC-2 device, even if it does actually support it. This adds a workaround to address this, forcing devices attached to a virtio-scsi controller to always check the VPD pages. This is modelled on a similar workaround for the storvsc (Hyper-V) SCSI controller, although that exists for slightly different reasons. A specific case which causes this is a volume from IBM's IPR RAID controller (which presents as an SPC-2 device, although it does support VPD) passed through with qemu's 'scsi-block' device. [mkp: fixed typo] Signed-off-by: David Gibson Acked-by: Paolo Bonzini Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/virtio_scsi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index c680d7641311..8f4adc1d9588 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #define VIRTIO_SCSI_MEMPOOL_SZ 64 @@ -705,6 +706,28 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc) return virtscsi_tmf(vscsi, cmd); } +static int virtscsi_device_alloc(struct scsi_device *sdevice) +{ + /* + * Passed through SCSI targets (e.g. with qemu's 'scsi-block') + * may have transfer limits which come from the host SCSI + * controller or something on the host side other than the + * target itself. + * + * To make this work properly, the hypervisor can adjust the + * target's VPD information to advertise these limits. But + * for that to work, the guest has to look at the VPD pages, + * which we won't do by default if it is an SPC-2 device, even + * if it does actually support it. + * + * So, set the blist to always try to read the VPD pages. + */ + sdevice->sdev_bflags = BLIST_TRY_VPD_PAGES; + + return 0; +} + + /** * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth * @sdev: Virtscsi target whose queue depth to change @@ -776,6 +799,7 @@ static struct scsi_host_template virtscsi_host_template_single = { .change_queue_depth = virtscsi_change_queue_depth, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .slave_alloc = virtscsi_device_alloc, .can_queue = 1024, .dma_boundary = UINT_MAX, -- cgit v1.2.3 From c1c0f99f4fab4ccc194a846693288b820404e833 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 14 Apr 2017 14:51:20 -0700 Subject: mwifiex: don't leak 'chan_stats' on reset [ Upstream commit fb9e67bee3ab7111513130c516ffe378d885c0d0 ] 'chan_stats' is (re)allocated in _mwifiex_fw_dpc() -> mwifiex_init_channel_scan_gap(), which is called whenever the device is initialized -- at probe or at reset. But we only free it in we completely unregister the adapter, meaning we leak a copy of it during every reset. Let's free it in the shutdown / removal paths instead (and in the error-handling path), to avoid the leak. Ideally, we can eventually unify much of mwifiex_shutdown_sw() and mwifiex_remove_card() (way too much copy-and-paste) to reduce the burden on bugfixes like this. But that's work for tomorrow. Signed-off-by: Brian Norris Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/marvell/mwifiex/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 2478ccd6f2d9..1e36f11831a9 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -146,7 +146,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter) kfree(adapter->regd); - vfree(adapter->chan_stats); kfree(adapter); return 0; } @@ -636,6 +635,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto done; err_add_intf: + vfree(adapter->chan_stats); wiphy_unregister(adapter->wiphy); wiphy_free(adapter->wiphy); err_init_fw: @@ -1429,6 +1429,7 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter, struct semaphore *sem) mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev); rtnl_unlock(); } + vfree(adapter->chan_stats); up(sem); exit_sem_err: @@ -1729,6 +1730,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev); rtnl_unlock(); } + vfree(adapter->chan_stats); wiphy_unregister(adapter->wiphy); wiphy_free(adapter->wiphy); -- cgit v1.2.3 From 994f316d50e2a3ee7ec83745824398a169a030e2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 20 Apr 2017 10:07:34 +0100 Subject: irqchip/mips-gic: Separate IPI reservation & usage tracking [ Upstream commit f8dcd9e81797ae24acc44c84f0eb3b9e6cee9791 ] Since commit 2af70a962070 ("irqchip/mips-gic: Add a IPI hierarchy domain") introduced the GIC IPI IRQ domain we have tracked both reservation of interrupts & their use with a single bitmap - ipi_resrv. If an interrupt is reserved for use as an IPI but not actually in use then the appropriate bit is set in ipi_resrv. If an interrupt is either not reserved for use as an IPI or has been allocated as one then the appropriate bit is clear in ipi_resrv. Unfortunately this means that checking whether a bit is set in ipi_resrv to prevent IPI interrupts being allocated for use with a device is broken, because if the interrupt has been allocated as an IPI first then its bit will be clear. Fix this by separating the tracking of IPI reservation & usage, introducing a separate ipi_available bitmap for the latter. This means that ipi_resrv will now always have bits set corresponding to all interrupts reserved for use as IPIs, whether or not they have been allocated yet, and therefore that checking it when allocating device interrupts works as expected. Fixes: 2af70a962070 ("irqchip/mips-gic: Add a IPI hierarchy domain") Signed-off-by: Paul Burton Signed-off-by: Matt Redfearn Cc: linux-mips@linux-mips.org Cc: Jason Cooper Cc: Marc Zyngier Cc: Ralf Baechle Link: http://lkml.kernel.org/r/1492679256-14513-2-git-send-email-matt.redfearn@imgtec.com Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-mips-gic.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index d74374f25392..abf696b49dd7 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -55,6 +55,7 @@ static unsigned int gic_cpu_pin; static unsigned int timer_cpu_pin; static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS); +DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS); static void __gic_irq_dispatch(void); @@ -746,17 +747,17 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, return gic_setup_dev_chip(d, virq, spec->hwirq); } else { - base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs); + base_hwirq = find_first_bit(ipi_available, gic_shared_intrs); if (base_hwirq == gic_shared_intrs) { return -ENOMEM; } /* check that we have enough space */ for (i = base_hwirq; i < nr_irqs; i++) { - if (!test_bit(i, ipi_resrv)) + if (!test_bit(i, ipi_available)) return -EBUSY; } - bitmap_clear(ipi_resrv, base_hwirq, nr_irqs); + bitmap_clear(ipi_available, base_hwirq, nr_irqs); /* map the hwirq for each cpu consecutively */ i = 0; @@ -787,7 +788,7 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, return 0; error: - bitmap_set(ipi_resrv, base_hwirq, nr_irqs); + bitmap_set(ipi_available, base_hwirq, nr_irqs); return ret; } @@ -802,7 +803,7 @@ void gic_irq_domain_free(struct irq_domain *d, unsigned int virq, return; base_hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(data)); - bitmap_set(ipi_resrv, base_hwirq, nr_irqs); + bitmap_set(ipi_available, base_hwirq, nr_irqs); } int gic_irq_domain_match(struct irq_domain *d, struct device_node *node, @@ -1066,6 +1067,7 @@ static void __init __gic_init(unsigned long gic_base_addr, 2 * gic_vpes); } + bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); gic_basic_init(); } -- cgit v1.2.3 From a3a9a972e230b6198aea87c66fec0104c2b55ad1 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 12 Apr 2017 00:21:26 -0500 Subject: iommu/omap: Register driver before setting IOMMU ops [ Upstream commit abaa7e5b054aae567861628b74dbc7fbf8ed79e8 ] Move the registration of the OMAP IOMMU platform driver before setting the IOMMU callbacks on the platform bus. This causes the IOMMU devices to be probed first before the .add_device() callback is invoked for all registered devices, and allows the iommu_group support to be added to the OMAP IOMMU driver. While at this, also check for the return status from bus_set_iommu. Signed-off-by: Suman Anna Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/omap-iommu.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index e2583cce2cc1..54556713c8d1 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1299,6 +1299,7 @@ static int __init omap_iommu_init(void) const unsigned long flags = SLAB_HWCACHE_ALIGN; size_t align = 1 << 10; /* L2 pagetable alignement */ struct device_node *np; + int ret; np = of_find_matching_node(NULL, omap_iommu_of_match); if (!np) @@ -1312,11 +1313,25 @@ static int __init omap_iommu_init(void) return -ENOMEM; iopte_cachep = p; - bus_set_iommu(&platform_bus_type, &omap_iommu_ops); - omap_iommu_debugfs_init(); - return platform_driver_register(&omap_iommu_driver); + ret = platform_driver_register(&omap_iommu_driver); + if (ret) { + pr_err("%s: failed to register driver\n", __func__); + goto fail_driver; + } + + ret = bus_set_iommu(&platform_bus_type, &omap_iommu_ops); + if (ret) + goto fail_bus; + + return 0; + +fail_bus: + platform_driver_unregister(&omap_iommu_driver); +fail_driver: + kmem_cache_destroy(iopte_cachep); + return ret; } subsys_initcall(omap_iommu_init); /* must be ready before omap3isp is probed */ -- cgit v1.2.3 From 8a09ef5ba1592302c2f2d6ee7f3301191b2a5296 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Mon, 17 Apr 2017 17:11:05 +0800 Subject: md/raid10: wait up frozen array in handle_write_completed [ Upstream commit cf25ae78fc50010f66b9be945017796da34c434d ] Since nr_queued is changed, we need to call wake_up here if the array is already frozen and waiting for condition "nr_pending == nr_queued + extra" to be true. And commit 824e47daddbf ("RAID1: avoid unnecessary spin locks in I/O barrier code") which has already added the wake_up for raid1. Signed-off-by: Guoqing Jiang Reviewed-by: NeilBrown Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid10.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b19b551bb34b..b1daff78f7b2 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2704,6 +2704,11 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio) list_add(&r10_bio->retry_list, &conf->bio_end_io_list); conf->nr_queued++; spin_unlock_irq(&conf->device_lock); + /* + * In case freeze_array() is waiting for condition + * nr_pending == nr_queued + extra to be true. + */ + wake_up(&conf->wait_barrier); md_wakeup_thread(conf->mddev->thread); } else { if (test_bit(R10BIO_WriteError, -- cgit v1.2.3 From 91dbad3979787d6b4e6f7194191698b0f35040b9 Mon Sep 17 00:00:00 2001 From: Bernd Faust Date: Thu, 16 Feb 2017 19:42:07 +0100 Subject: e1000e: fix timing for 82579 Gigabit Ethernet controller [ Upstream commit 5313eeccd2d7f486be4e5c7560e3e2be239ec8f7 ] After an upgrade to Linux kernel v4.x the hardware timestamps of the 82579 Gigabit Ethernet Controller are different than expected. The values that are being read are almost four times as big as before the kernel upgrade. The difference is that after the upgrade the driver sets the clock frequency to 25MHz, where before the upgrade it was set to 96MHz. Intel confirmed that the correct frequency for this network adapter is 96MHz. Signed-off-by: Bernd Faust Acked-by: Sasha Neftin Acked-by: Jacob Keller Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000e/netdev.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 0feddf3393f9..528a926dd979 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3528,6 +3528,12 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) switch (hw->mac.type) { case e1000_pch2lan: + /* Stable 96MHz frequency */ + incperiod = INCPERIOD_96MHz; + incvalue = INCVALUE_96MHz; + shift = INCVALUE_SHIFT_96MHz; + adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz; + break; case e1000_pch_lpt: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) { /* Stable 96MHz frequency */ -- cgit v1.2.3 From 7bd191b0a0946f877f4d355e44aa944e6849fd63 Mon Sep 17 00:00:00 2001 From: Feras Daoud Date: Sun, 19 Mar 2017 11:18:55 +0200 Subject: IB/ipoib: Fix deadlock between ipoib_stop and mcast join flow [ Upstream commit 3e31a490e01a6e67cbe9f6e1df2f3ff0fbf48972 ] Before calling ipoib_stop, rtnl_lock should be taken, then the flow clears the IPOIB_FLAG_ADMIN_UP and IPOIB_FLAG_OPER_UP flags, and waits for mcast completion if IPOIB_MCAST_FLAG_BUSY is set. On the other hand, the flow of multicast join task initializes a mcast completion, sets the IPOIB_MCAST_FLAG_BUSY and calls ipoib_mcast_join. If IPOIB_FLAG_OPER_UP flag is not set, this call returns EINVAL without setting the mcast completion and leads to a deadlock. ipoib_stop | | | clear_bit(IPOIB_FLAG_ADMIN_UP) | | | Context Switch | | ipoib_mcast_join_task | | | spin_lock_irq(lock) | | | init_completion(mcast) | | | set_bit(IPOIB_MCAST_FLAG_BUSY) | | | Context Switch | | clear_bit(IPOIB_FLAG_OPER_UP) | | | spin_lock_irqsave(lock) | | | Context Switch | | ipoib_mcast_join | return (-EINVAL) | | | spin_unlock_irq(lock) | | | Context Switch | | ipoib_mcast_dev_flush | wait_for_completion(mcast) | ipoib_stop will wait for mcast completion for ever, and will not release the rtnl_lock. As a result panic occurs with the following trace: [13441.639268] Call Trace: [13441.640150] [] schedule+0x29/0x70 [13441.641038] [] schedule_timeout+0x239/0x2d0 [13441.641914] [] ? complete+0x47/0x50 [13441.642765] [] ? flush_workqueue_prep_pwqs+0x16d/0x200 [13441.643580] [] wait_for_completion+0x116/0x170 [13441.644434] [] ? wake_up_state+0x20/0x20 [13441.645293] [] ipoib_mcast_dev_flush+0x150/0x190 [ib_ipoib] [13441.646159] [] ipoib_ib_dev_down+0x37/0x60 [ib_ipoib] [13441.647013] [] ipoib_stop+0x75/0x150 [ib_ipoib] Fixes: 08bc327629cb ("IB/ipoib: fix for rare multicast join race condition") Signed-off-by: Feras Daoud Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 6b6826f3e446..8f79caedf905 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -487,6 +487,9 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast) !test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) return -EINVAL; + init_completion(&mcast->done); + set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); + ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw); rec.mgid = mcast->mcmember.mgid; @@ -645,8 +648,6 @@ void ipoib_mcast_join_task(struct work_struct *work) if (mcast->backoff == 1 || time_after_eq(jiffies, mcast->delay_until)) { /* Found the next unjoined group */ - init_completion(&mcast->done); - set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); if (ipoib_mcast_join(dev, mcast)) { spin_unlock_irq(&priv->lock); return; @@ -666,11 +667,9 @@ out: queue_delayed_work(priv->wq, &priv->mcast_task, delay_until - jiffies); } - if (mcast) { - init_completion(&mcast->done); - set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); + if (mcast) ipoib_mcast_join(dev, mcast); - } + spin_unlock_irq(&priv->lock); } -- cgit v1.2.3 From 089f13786bdc483d0ff54367d9dbe0dd19746481 Mon Sep 17 00:00:00 2001 From: Feras Daoud Date: Sun, 19 Mar 2017 11:18:54 +0200 Subject: IB/ipoib: Update broadcast object if PKey value was changed in index 0 [ Upstream commit 9a9b8112699d78e7f317019b37f377e90023f3ed ] Update the broadcast address in the priv->broadcast object when the Pkey value changes in index 0, otherwise the multicast GID value will keep the previous value of the PKey, and will not be updated. This leads to interface state down because the interface will keep the old PKey value. For example, in SR-IOV environment, if the PF changes the value of PKey index 0 for one of the VFs, then the VF receives PKey change event that triggers heavy flush. This flush calls update_parent_pkey that update the broadcast object and its relevant members. If in this case the multicast GID will not be updated, the interface state will be down. Fixes: c2904141696e ("IPoIB: Fix pkey change flow for virtualization environments") Signed-off-by: Feras Daoud Signed-off-by: Erez Shitrit Reviewed-by: Alex Vesker Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 335bd2c9e16e..34122c96522b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -974,6 +974,19 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv) */ priv->dev->broadcast[8] = priv->pkey >> 8; priv->dev->broadcast[9] = priv->pkey & 0xff; + + /* + * Update the broadcast address in the priv->broadcast object, + * in case it already exists, otherwise no one will do that. + */ + if (priv->broadcast) { + spin_lock_irq(&priv->lock); + memcpy(priv->broadcast->mcmember.mgid.raw, + priv->dev->broadcast + 4, + sizeof(union ib_gid)); + spin_unlock_irq(&priv->lock); + } + return 0; } -- cgit v1.2.3 From 2b09da0e7718bc7bd203b9ea62c21d7a088dbe98 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Apr 2017 13:39:09 +0300 Subject: HSI: ssi_protocol: double free in ssip_pn_xmit() [ Upstream commit 3026050179a3a9a6f5c892c414b5e36ecf092081 ] If skb_pad() fails then it frees skb and we don't need to free it again at the end of the function. Fixes: dc7bf5d7 ("HSI: Introduce driver for SSI Protocol") Signed-off-by: Dan Carpenter Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hsi/clients/ssi_protocol.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c index 6031cd146556..802afc98e8bd 100644 --- a/drivers/hsi/clients/ssi_protocol.c +++ b/drivers/hsi/clients/ssi_protocol.c @@ -989,7 +989,7 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; /* Pad to 32-bits - FIXME: Revisit*/ if ((skb->len & 3) && skb_pad(skb, 4 - (skb->len & 3))) - goto drop; + goto inc_dropped; /* * Modem sends Phonet messages over SSI with its own endianess... @@ -1041,8 +1041,9 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev) drop2: hsi_free_msg(msg); drop: - dev->stats.tx_dropped++; dev_kfree_skb(skb); +inc_dropped: + dev->stats.tx_dropped++; return 0; } -- cgit v1.2.3 From 0021b4613a8acf33937c7492817fe484e19e4381 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 29 Mar 2017 06:03:00 +0300 Subject: IB/mlx4: Take write semaphore when changing the vma struct [ Upstream commit 22c3653d04bd0c67b75e99d85e0c0bdf83947df5 ] When the driver disassociate user context, it changes the vma to anonymous by setting the vm_ops to null and zap the vma ptes. In order to avoid race in the kernel, we need to take write lock before we change the vma entries. Fixes: ae184ddeca5db ('IB/mlx4_ib: Disassociate support') Signed-off-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx4/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index c41c8d0a4ac0..129dbd790dba 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1168,7 +1168,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) /* need to protect from a race on closing the vma as part of * mlx4_ib_vma_close(). */ - down_read(&owning_mm->mmap_sem); + down_write(&owning_mm->mmap_sem); for (i = 0; i < HW_BAR_COUNT; i++) { vma = context->hw_bar_info[i].vma; if (!vma) @@ -1186,7 +1186,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) context->hw_bar_info[i].vma->vm_ops = NULL; } - up_read(&owning_mm->mmap_sem); + up_write(&owning_mm->mmap_sem); mmput(owning_mm); put_task_struct(owning_process); } -- cgit v1.2.3 From df7aedb171e262c4f2c692f323bc9b1c8c13ef59 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 29 Mar 2017 06:03:01 +0300 Subject: IB/mlx4: Change vma from shared to private [ Upstream commit ca37a664a8e4e9988b220988ceb4d79e3316f195 ] Anonymous VMA (->vm_ops == NULL) cannot be shared, otherwise it would lead to SIGBUS. Remove the shared flags from the vma after we change it to be anonymous. This is easily reproduced by doing modprobe -r while running a user-space application such as raw_ethernet_bw. Fixes: ae184ddeca5db ('IB/mlx4_ib: Disassociate support') Signed-off-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx4/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 129dbd790dba..19bc1c2186ff 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1182,6 +1182,8 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) BUG_ON(1); } + context->hw_bar_info[i].vma->vm_flags &= + ~(VM_SHARED | VM_MAYSHARE); /* context going to be destroyed, should not access ops any more */ context->hw_bar_info[i].vma->vm_ops = NULL; } -- cgit v1.2.3 From 9238066e2838e2981c908e66bfc599442fd6917b Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 29 Mar 2017 06:03:02 +0300 Subject: IB/mlx5: Take write semaphore when changing the vma struct [ Upstream commit ecc7d83be3243835c9396a1a2fb8ce95f205207b ] When the driver disassociate user context, it changes the vma to anonymous by setting the vm_ops to null and zap the vma ptes. In order to avoid race in the kernel, we need to take write lock before we change the vma entries. Fixes: 7c2344c3bbf97 ('IB/mlx5: Implements disassociate_ucontext API') Signed-off-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5e29fbd3a5a0..150227786969 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1313,7 +1313,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) /* need to protect from a race on closing the vma as part of * mlx5_ib_vma_close. */ - down_read(&owning_mm->mmap_sem); + down_write(&owning_mm->mmap_sem); list_for_each_entry_safe(vma_private, n, &context->vma_private_list, list) { vma = vma_private->vma; @@ -1327,7 +1327,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) list_del(&vma_private->list); kfree(vma_private); } - up_read(&owning_mm->mmap_sem); + up_write(&owning_mm->mmap_sem); mmput(owning_mm); put_task_struct(owning_process); } -- cgit v1.2.3 From c404dff4874d44e89783d2a4534d3b29ca7b68f0 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 29 Mar 2017 06:03:03 +0300 Subject: IB/mlx5: Change vma from shared to private [ Upstream commit 1377661298d2820d675553d186c31b6f46c140d0 ] Anonymous VMA (->vm_ops == NULL) cannot be shared, otherwise it would lead to SIGBUS. Remove the shared flags from the vma after we change it to be anonymous. This is easily reproduced by doing modprobe -r while running a user-space application such as raw_ethernet_bw. Fixes: 7c2344c3bbf97 ('IB/mlx5: Implements disassociate_ucontext API') Signed-off-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 150227786969..d7da1dca765f 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1323,6 +1323,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) /* context going to be destroyed, should * not access ops any more. */ + vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE); vma->vm_ops = NULL; list_del(&vma_private->list); kfree(vma_private); -- cgit v1.2.3 From 4b829c03c902b4b79f3078402b130a61e5cce286 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Thu, 20 Apr 2017 13:26:54 +0300 Subject: IB/mlx5: Set correct SL in completion for RoCE [ Upstream commit 12f8fedef2ec94c783f929126b20440a01512c14 ] There is a difference when parsing a completion entry between Ethernet and IB ports. When link layer is Ethernet the bits describe the type of L3 header in the packet. In the case when link layer is Ethernet and VLAN header is present the value of SL is equal to the 3 UP bits in the VLAN header. If VLAN header is not present then the SL is undefined and consumer of the completion should check if IB_WC_WITH_VLAN is set. While that, this patch also fills the vlan_id field in the completion if present. Signed-off-by: Moni Shoua Reviewed-by: Majd Dibbiny Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/cq.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 9cdcff77b9a8..fc62a7ded734 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -172,6 +172,8 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, struct mlx5_ib_srq *srq; struct mlx5_ib_wq *wq; u16 wqe_ctr; + u8 roce_packet_type; + bool vlan_present; u8 g; if (qp->ibqp.srq || qp->ibqp.xrcd) { @@ -223,7 +225,6 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, break; } wc->slid = be16_to_cpu(cqe->slid); - wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf; wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff; wc->dlid_path_bits = cqe->ml_path; g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3; @@ -237,10 +238,22 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, wc->pkey_index = 0; } - if (ll != IB_LINK_LAYER_ETHERNET) + if (ll != IB_LINK_LAYER_ETHERNET) { + wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf; return; + } + + vlan_present = cqe->l4_l3_hdr_type & 0x1; + roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3; + if (vlan_present) { + wc->vlan_id = (be16_to_cpu(cqe->vlan_info)) & 0xfff; + wc->sl = (be16_to_cpu(cqe->vlan_info) >> 13) & 0x7; + wc->wc_flags |= IB_WC_WITH_VLAN; + } else { + wc->sl = 0; + } - switch (wc->sl & 0x3) { + switch (roce_packet_type) { case MLX5_CQE_ROCE_L3_HEADER_TYPE_GRH: wc->network_hdr_type = RDMA_NETWORK_IB; break; -- cgit v1.2.3 From 5a049986d6a6759ae23685cb2fd93ce56163bb34 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 19 Apr 2017 13:45:10 -0400 Subject: ibmvnic: Disable irq prior to close [ Upstream commit dd9c20fa07ba5cfb5a0ab3181d68530506610605 ] Add some code to call disable_irq on all the vnic interface's irqs. This fixes a crash observed when closing an active interface, as seen in the oops below when we try to access a buffer in the interrupt handler which we've already freed. Unable to handle kernel paging request for data at address 0x00000001 Faulting instruction address: 0xd000000003886824 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=2048 NUMA pSeries Modules linked in: ibmvnic(OEN) rpadlpar_io(X) rpaphp(X) tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag rpcsec_ Supported: No, Unsupported modules are loaded CPU: 8 PID: 0 Comm: swapper/8 Tainted: G OE NX 4.4.49-92.11-default #1 task: c00000007f990110 ti: c0000000fffa0000 task.ti: c00000007f9b8000 NIP: d000000003886824 LR: d000000003886824 CTR: c0000000007eff60 REGS: c0000000fffa3a70 TRAP: 0300 Tainted: G OE NX (4.4.49-92.11-default) MSR: 8000000000009033 CR: 22008042 XER: 20000008 CFAR: c000000000008468 DAR: 0000000000000001 DSISR: 40000000 SOFTE: 0 GPR00: d000000003886824 c0000000fffa3cf0 d000000003894118 0000000000000000 GPR04: 0000000000000000 0000000000000000 c000000001249da0 0000000000000000 GPR08: 000000000000000e 0000000000000000 c0000000ccb00000 d000000003889180 GPR12: c0000000007eff60 c000000007af4c00 0000000000000001 c0000000010def30 GPR16: c00000007f9b8000 c000000000b98c30 c00000007f9b8080 c000000000bab858 GPR20: 0000000000000005 0000000000000000 c0000000ff5d7e80 c0000000f809f648 GPR24: c0000000ff5d7ec8 0000000000000000 0000000000000000 c0000000ccb001a0 GPR28: 000000000000000a c0000000f809f600 c0000000fd4cd900 c0000000f9cd5b00 NIP [d000000003886824] ibmvnic_interrupt_tx+0x114/0x380 [ibmvnic] LR [d000000003886824] ibmvnic_interrupt_tx+0x114/0x380 [ibmvnic] Call Trace: [c0000000fffa3cf0] [d000000003886824] ibmvnic_interrupt_tx+0x114/0x380 [ibmvnic] (unreliable) [c0000000fffa3dd0] [c000000000132940] __handle_irq_event_percpu+0x90/0x2e0 [c0000000fffa3e90] [c000000000132bcc] handle_irq_event_percpu+0x3c/0x90 [c0000000fffa3ed0] [c000000000132c88] handle_irq_event+0x68/0xc0 [c0000000fffa3f00] [c000000000137edc] handle_fasteoi_irq+0xec/0x250 [c0000000fffa3f30] [c000000000131b04] generic_handle_irq+0x54/0x80 [c0000000fffa3f60] [c000000000011190] __do_irq+0x80/0x1d0 [c0000000fffa3f90] [c0000000000248d8] call_do_irq+0x14/0x24 [c00000007f9bb9e0] [c000000000011380] do_IRQ+0xa0/0x120 [c00000007f9bba40] [c000000000002594] hardware_interrupt_common+0x114/0x180 Signed-off-by: Brian King Signed-off-by: Nathan Fontenot Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ibm/ibmvnic.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 7c6c1468628b..49094c965697 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -511,6 +511,23 @@ alloc_napi_failed: return -ENOMEM; } +static void disable_sub_crqs(struct ibmvnic_adapter *adapter) +{ + int i; + + if (adapter->tx_scrq) { + for (i = 0; i < adapter->req_tx_queues; i++) + if (adapter->tx_scrq[i]) + disable_irq(adapter->tx_scrq[i]->irq); + } + + if (adapter->rx_scrq) { + for (i = 0; i < adapter->req_rx_queues; i++) + if (adapter->rx_scrq[i]) + disable_irq(adapter->rx_scrq[i]->irq); + } +} + static int ibmvnic_close(struct net_device *netdev) { struct ibmvnic_adapter *adapter = netdev_priv(netdev); @@ -519,6 +536,7 @@ static int ibmvnic_close(struct net_device *netdev) int i; adapter->closing = true; + disable_sub_crqs(adapter); for (i = 0; i < adapter->req_rx_queues; i++) napi_disable(&adapter->napi[i]); -- cgit v1.2.3 From 72bded3b6c5201d15050ec639e9ec8d9aeceda10 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 19 Apr 2017 13:53:49 -0700 Subject: netvsc: Deal with rescinded channels correctly [ Upstream commit 73e64fa4f417b22d8d5521999a631ced8e2d442e ] We will not be able to send packets over a channel that has been rescinded. Make necessary adjustments so we can properly cleanup even when the channel is rescinded. This issue can be trigerred in the NIC hot-remove path. Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/hyperv/netvsc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index c2ac39a940f7..14f58b60d1b5 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -151,6 +151,13 @@ static void netvsc_destroy_buf(struct hv_device *device) sizeof(struct nvsp_message), (unsigned long)revoke_packet, VM_PKT_DATA_INBAND, 0); + /* If the failure is because the channel is rescinded; + * ignore the failure since we cannot send on a rescinded + * channel. This would allow us to properly cleanup + * even when the channel is rescinded. + */ + if (device->channel->rescind) + ret = 0; /* * If we failed here, we might as well return and * have a leak rather than continue and a bugchk @@ -211,6 +218,15 @@ static void netvsc_destroy_buf(struct hv_device *device) sizeof(struct nvsp_message), (unsigned long)revoke_packet, VM_PKT_DATA_INBAND, 0); + + /* If the failure is because the channel is rescinded; + * ignore the failure since we cannot send on a rescinded + * channel. This would allow us to properly cleanup + * even when the channel is rescinded. + */ + if (device->channel->rescind) + ret = 0; + /* If we failed here, we might as well return and * have a leak rather than continue and a bugchk */ -- cgit v1.2.3 From 730ff617b9ed6f35a98b6a8d7a5f8d5baa042556 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 21 Apr 2017 16:04:56 -0700 Subject: Fix driver usage of 128B WQEs when WQ_CREATE is V1. [ Upstream commit 3f247de750b8dd8f50a2c1390e2a1238790a9dff ] There are two versions of a structure for queue creation and setup that the driver shares with FW. The driver was only treating as version 0. Verify WQ_CREATE with 128B WQEs in V0 and V1. Code review of another bug showed the driver passing 128B WQEs and 8 pages in WQ CREATE and V0. Code inspection/instrumentation showed that the driver uses V0 in WQ_CREATE and if the caller passes queue->entry_size 128B, the driver sets the hdr_version to V1 so all is good. When I tested the V1 WQ_CREATE, the mailbox failed causing the driver to unload. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Johannes Thumshirn Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/lpfc/lpfc_sli.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8f1df76a77b6..0902ed204ba8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -13696,6 +13696,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, case LPFC_Q_CREATE_VERSION_1: bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, wq->entry_count); + bf_set(lpfc_mbox_hdr_version, &shdr->request, + LPFC_Q_CREATE_VERSION_1); + switch (wq->entry_size) { default: case 64: -- cgit v1.2.3 From c5406a7557444708a5742a08acb83c6d339d0bb9 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 21 Apr 2017 16:05:05 -0700 Subject: Fix Express lane queue creation. [ Upstream commit 7e04e21afa82ef024416f5413b5bdb66e0505bcd ] The older sli4 adapters only supported the 64 byte WQE entry size. The new adapter (fw) support both 64 and 128 byte WQE entry sizies. The Express lane WQ was not being created with the 128 byte WQE sizes when it was supported. Not having the right WQE size created for the express lane work queue caused the the firmware to overwrite the lun indentifier in the FCP header. This patch correctly creates the express lane work queue with the supported size. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Johannes Thumshirn Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/lpfc/lpfc_init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f7e3f27bb5c5..e9ea8f4ea2c9 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11312,6 +11312,7 @@ int lpfc_fof_queue_create(struct lpfc_hba *phba) { struct lpfc_queue *qdesc; + uint32_t wqesize; /* Create FOF EQ */ qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize, @@ -11332,8 +11333,11 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) phba->sli4_hba.oas_cq = qdesc; /* Create OAS WQ */ - qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize, + wqesize = (phba->fcp_embed_io) ? + LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; + qdesc = lpfc_sli4_queue_alloc(phba, wqesize, phba->sli4_hba.wq_ecount); + if (!qdesc) goto out_error; -- cgit v1.2.3 From 9907f1f6d86d10aecdc14427f7224cf95d32dd73 Mon Sep 17 00:00:00 2001 From: Kuppuswamy Sathyanarayanan Date: Fri, 14 Apr 2017 10:29:25 -0700 Subject: gpio: gpio-wcove: fix irq pending status bit width [ Upstream commit 7c2d176fe3f8dce632b948f79c7e89916ffe2c70 ] Whiskey cove PMIC has three GPIO banks with total number of 13 GPIO pins. But when checking for the pending status, for_each_set_bit() uses bit width of 7 and hence it only checks the status for first 7 GPIO pins missing to check/clear the status of rest of the GPIO pins. This patch fixes this issue. Signed-off-by: Kuppuswamy Sathyanarayanan Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-wcove.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index d0ddba7a9d08..1012c86925ad 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -318,7 +318,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) while (pending) { /* One iteration is for all pending bits */ for_each_set_bit(gpio, (const unsigned long *)&pending, - GROUP0_NR_IRQS) { + WCOVE_GPIO_NUM) { offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0; mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) : BIT(gpio); -- cgit v1.2.3 From abff7f51914942f1d1a80d674cb21aa48a534ba0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 10 Apr 2017 16:54:17 +0300 Subject: mmc: host: omap_hsmmc: checking for NULL instead of IS_ERR() [ Upstream commit ec5ab8933772c87f24ad62a4a602fe8949f423c2 ] devm_pinctrl_get() returns error pointers, it never returns NULL. Fixes: 455e5cd6f736 ("mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x") Signed-off-by: Dan Carpenter Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/omap_hsmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5f2f24a7360d..a082aa330f47 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1762,8 +1762,8 @@ static int omap_hsmmc_configure_wake_irq(struct omap_hsmmc_host *host) */ if (host->pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) { struct pinctrl *p = devm_pinctrl_get(host->dev); - if (!p) { - ret = -ENODEV; + if (IS_ERR(p)) { + ret = PTR_ERR(p); goto err_free_irq; } if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_DEFAULT))) { -- cgit v1.2.3 From eff9431cafa95b343fc6035833a0ed342e6120d0 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 17:38:35 +0800 Subject: wan: pc300too: abort path on failure [ Upstream commit 2a39e7aa8a98f777f0732ca7125b6c9668791760 ] In function pc300_pci_init_one(), on the ioremap error path, function pc300_pci_remove_one() is called to free the allocated memory. However, the path is not terminated, and the freed memory will be used later, resulting in use-after-free bugs. This path fixes the bug. Signed-off-by: Pan Bian Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/pc300too.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index db363856e0b5..2b064998915f 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -347,6 +347,7 @@ static int pc300_pci_init_one(struct pci_dev *pdev, card->rambase == NULL) { pr_err("ioremap() failed\n"); pc300_pci_remove_one(pdev); + return -ENOMEM; } /* PLX PCI 9050 workaround for local configuration register read bug */ -- cgit v1.2.3 From bf4b579b67141d6d62ea3a243ce8397fb693d52c Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 20:04:04 +0800 Subject: qlcnic: fix unchecked return value [ Upstream commit 91ec701a553cb3de470fd471c6fefe3ad1125455 ] Function pci_find_ext_capability() may return 0, which is an invalid address. In function qlcnic_sriov_virtid_fn(), its return value is used without validation. This may result in invalid memory access bugs. This patch fixes the bug. Signed-off-by: Pan Bian Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index d7107055ec60..2f656f395f39 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -128,6 +128,8 @@ static int qlcnic_sriov_virtid_fn(struct qlcnic_adapter *adapter, int vf_id) return 0; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) + return 0; pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset); pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride); -- cgit v1.2.3 From 9338ee7eea66913d821e1db1ae7b308c1f99adbb Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Mon, 24 Apr 2017 23:35:21 +0200 Subject: platform/x86: intel-vbtn: add volume up and down [ Upstream commit 8d9e29972836b75eb74f533594999500a4c7cc19 ] Tested on HP Elite X2 1012 G1. Matches event report of Lenovo Helix 2 (https://www.spinics.net/lists/ibm-acpi-devel/msg03982.html). Signed-off-by: Maarten Maathuis [andy: fixed indentation of comments and massaged title of the change] Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/intel-vbtn.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index 78080763df51..a74340dff530 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c @@ -37,6 +37,10 @@ static const struct acpi_device_id intel_vbtn_ids[] = { static const struct key_entry intel_vbtn_keymap[] = { { KE_IGNORE, 0xC0, { KEY_POWER } }, /* power key press */ { KE_KEY, 0xC1, { KEY_POWER } }, /* power key release */ + { KE_KEY, 0xC4, { KEY_VOLUMEUP } }, /* volume-up key press */ + { KE_IGNORE, 0xC5, { KEY_VOLUMEUP } }, /* volume-up key release */ + { KE_KEY, 0xC6, { KEY_VOLUMEDOWN } }, /* volume-down key press */ + { KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } }, /* volume-down key release */ { KE_END }, }; -- cgit v1.2.3 From 8a15303518c005ae63ce1e22053822ea43db6dd1 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 2 Apr 2017 17:08:05 +1000 Subject: scsi: mac_esp: Replace bogus memory barrier with spinlock [ Upstream commit 4da2b1eb230ba4ad19b58984dc52e05b1073df5f ] Commit da244654c66e ("[SCSI] mac_esp: fix for quadras with two esp chips") added mac_scsi_esp_intr() to handle the IRQ lines from a pair of on-board ESP chips (a normal shared IRQ did not work). Proper mutual exclusion was missing from that patch. This patch fixes race conditions between comparison and assignment of esp_chips[] pointers. Signed-off-by: Finn Thain Reviewed-by: Michael Schmitz Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mac_esp.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index 14c0334f41e4..26c67c42985c 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -55,6 +55,7 @@ struct mac_esp_priv { int error; }; static struct esp *esp_chips[2]; +static DEFINE_SPINLOCK(esp_chips_lock); #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ platform_get_drvdata((struct platform_device *) \ @@ -562,15 +563,18 @@ static int esp_mac_probe(struct platform_device *dev) } host->irq = IRQ_MAC_SCSI; - esp_chips[dev->id] = esp; - mb(); - if (esp_chips[!dev->id] == NULL) { - err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL); - if (err < 0) { - esp_chips[dev->id] = NULL; - goto fail_free_priv; - } + + /* The request_irq() call is intended to succeed for the first device + * and fail for the second device. + */ + err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL); + spin_lock(&esp_chips_lock); + if (err < 0 && esp_chips[!dev->id] == NULL) { + spin_unlock(&esp_chips_lock); + goto fail_free_priv; } + esp_chips[dev->id] = esp; + spin_unlock(&esp_chips_lock); err = scsi_esp_register(esp, &dev->dev); if (err) @@ -579,8 +583,13 @@ static int esp_mac_probe(struct platform_device *dev) return 0; fail_free_irq: - if (esp_chips[!dev->id] == NULL) + spin_lock(&esp_chips_lock); + esp_chips[dev->id] = NULL; + if (esp_chips[!dev->id] == NULL) { + spin_unlock(&esp_chips_lock); free_irq(host->irq, esp); + } else + spin_unlock(&esp_chips_lock); fail_free_priv: kfree(mep); fail_free_command_block: @@ -599,9 +608,13 @@ static int esp_mac_remove(struct platform_device *dev) scsi_esp_unregister(esp); + spin_lock(&esp_chips_lock); esp_chips[dev->id] = NULL; - if (!(esp_chips[0] || esp_chips[1])) + if (esp_chips[!dev->id] == NULL) { + spin_unlock(&esp_chips_lock); free_irq(irq, NULL); + } else + spin_unlock(&esp_chips_lock); kfree(mep); -- cgit v1.2.3 From 81fa3239900f7fb378764318d200b5bb9c477cd6 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Fri, 24 Mar 2017 15:55:17 -0400 Subject: infiniband/uverbs: Fix integer overflows [ Upstream commit 4f7f4dcfff2c19debbcdbcc861c325610a15e0c5 ] The 'num_sge' variable is verfied to be smaller than the 'sge_count' variable; however, since both are user-controlled it's possible to cause an integer overflow for the kmalloc multiply on 32-bit platforms (num_sge and sge_count are both defined u32). By crafting an input that causes a smaller-than-expected allocation it's possible to write controlled data out-of-bounds. Signed-off-by: Vlad Tsyrklevich Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/uverbs_cmd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index d118ffe0bfb6..4b717cf50d27 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -2491,9 +2491,13 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, static void *alloc_wr(size_t wr_size, __u32 num_sge) { + if (num_sge >= (U32_MAX - ALIGN(wr_size, sizeof (struct ib_sge))) / + sizeof (struct ib_sge)) + return NULL; + return kmalloc(ALIGN(wr_size, sizeof (struct ib_sge)) + num_sge * sizeof (struct ib_sge), GFP_KERNEL); -}; +} ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, struct ib_device *ib_dev, @@ -2720,6 +2724,13 @@ static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf, goto err; } + if (user_wr->num_sge >= + (U32_MAX - ALIGN(sizeof *next, sizeof (struct ib_sge))) / + sizeof (struct ib_sge)) { + ret = -EINVAL; + goto err; + } + next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + user_wr->num_sge * sizeof (struct ib_sge), GFP_KERNEL); -- cgit v1.2.3 From 19b0f2fad8ceb65480e8faf5cb8f7de015b94655 Mon Sep 17 00:00:00 2001 From: Shrirang Bagul Date: Wed, 19 Apr 2017 22:05:00 +0800 Subject: iio: st_pressure: st_accel: Initialise sensor platform data properly [ Upstream commit 7383d44b84c94aaca4bf695a6bd8a69f2295ef1a ] This patch fixes the sensor platform data initialisation for st_pressure and st_accel device drivers. Without this patch, the driver fails to register the sensors when the user removes and re-loads the driver. 1. Unload the kernel modules for st_pressure $ sudo rmmod st_pressure_i2c $ sudo rmmod st_pressure 2. Re-load the driver $ sudo insmod st_pressure $ sudo insmod st_pressure_i2c Signed-off-by: Jonathan Cameron Acked-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/accel/st_accel_core.c | 7 ++++--- drivers/iio/pressure/st_pressure_core.c | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 3a557e3181ea..fe94415a0bc7 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -827,6 +827,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { int st_accel_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *adata = iio_priv(indio_dev); + struct st_sensors_platform_data *pdata = + (struct st_sensors_platform_data *)adata->dev->platform_data; int irq = adata->get_irq_data_ready(indio_dev); int err; @@ -853,9 +855,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev) &adata->sensor_settings->fs.fs_avl[0]; adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; - if (!adata->dev->platform_data) - adata->dev->platform_data = - (struct st_sensors_platform_data *)&default_accel_pdata; + if (!pdata) + pdata = (struct st_sensors_platform_data *)&default_accel_pdata; err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); if (err < 0) diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 44e46c159a7e..bec60299b6ec 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -638,6 +638,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = { int st_press_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *press_data = iio_priv(indio_dev); + struct st_sensors_platform_data *pdata = + (struct st_sensors_platform_data *)press_data->dev->platform_data; int irq = press_data->get_irq_data_ready(indio_dev); int err; @@ -673,10 +675,8 @@ int st_press_common_probe(struct iio_dev *indio_dev) press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!press_data->dev->platform_data && - press_data->sensor_settings->drdy_irq.addr) - press_data->dev->platform_data = - (struct st_sensors_platform_data *)&default_press_pdata; + if (!pdata && press_data->sensor_settings->drdy_irq.addr) + pdata = (struct st_sensors_platform_data *)&default_press_pdata; err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); if (err < 0) -- cgit v1.2.3 From 9d79cd54ba0e3b712d734eb24210432680900154 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 15:00:23 +0800 Subject: mt7601u: check return value of alloc_skb [ Upstream commit 5fb01e91daf84ad1e50edfcf63116ecbe31e7ba7 ] Function alloc_skb() will return a NULL pointer if there is no enough memory. However, in function mt7601u_mcu_msg_alloc(), its return value is not validated before it is used. This patch fixes it. Signed-off-by: Pan Bian Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mediatek/mt7601u/mcu.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.c b/drivers/net/wireless/mediatek/mt7601u/mcu.c index dbdfb3f5c507..a9f5f398b2f8 100644 --- a/drivers/net/wireless/mediatek/mt7601u/mcu.c +++ b/drivers/net/wireless/mediatek/mt7601u/mcu.c @@ -66,8 +66,10 @@ mt7601u_mcu_msg_alloc(struct mt7601u_dev *dev, const void *data, int len) WARN_ON(len % 4); /* if length is not divisible by 4 we need to pad */ skb = alloc_skb(len + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - skb_reserve(skb, MT_DMA_HDR_LEN); - memcpy(skb_put(skb, len), data, len); + if (skb) { + skb_reserve(skb, MT_DMA_HDR_LEN); + memcpy(skb_put(skb, len), data, len); + } return skb; } @@ -170,6 +172,8 @@ static int mt7601u_mcu_function_select(struct mt7601u_dev *dev, }; skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg)); + if (!skb) + return -ENOMEM; return mt7601u_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5); } @@ -205,6 +209,8 @@ mt7601u_mcu_calibrate(struct mt7601u_dev *dev, enum mcu_calibrate cal, u32 val) }; skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg)); + if (!skb) + return -ENOMEM; return mt7601u_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true); } -- cgit v1.2.3 From 0397b294e87940c35af30e0a5bd6cfc110d132cb Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 21:19:38 +0800 Subject: libertas: check return value of alloc_workqueue [ Upstream commit dc3f89c38a8406554ffeffa370aad086a9c5e9de ] Function alloc_workqueue() will return a NULL pointer if there is no enough memory, and its return value should be validated before using. However, in function if_spi_probe(), its return value is not checked. This may result in a NULL dereference bug. This patch fixes the bug. Signed-off-by: Pan Bian Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/marvell/libertas/if_spi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c index c3a53cd6988e..7b4955cc38db 100644 --- a/drivers/net/wireless/marvell/libertas/if_spi.c +++ b/drivers/net/wireless/marvell/libertas/if_spi.c @@ -1181,6 +1181,10 @@ static int if_spi_probe(struct spi_device *spi) /* Initialize interrupt handling stuff. */ card->workqueue = alloc_workqueue("libertas_spi", WQ_MEM_RECLAIM, 0); + if (!card->workqueue) { + err = -ENOMEM; + goto remove_card; + } INIT_WORK(&card->packet_work, if_spi_host_to_card_worker); INIT_WORK(&card->resume_work, if_spi_resume_worker); @@ -1209,6 +1213,7 @@ release_irq: free_irq(spi->irq, card); terminate_workqueue: destroy_workqueue(card->workqueue); +remove_card: lbs_remove_card(priv); /* will call free_netdev */ free_card: free_if_spi_card(card); -- cgit v1.2.3 From c3161cdbccf1ea0d516ad029ef6f1b3be0b65708 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Mon, 24 Apr 2017 08:40:28 +0800 Subject: rndis_wlan: add return value validation [ Upstream commit 9dc7efd3978aa67ae598129d2a3f240b390ce508 ] Function create_singlethread_workqueue() will return a NULL pointer if there is no enough memory, and its return value should be validated before using. However, in function rndis_wlan_bind(), its return value is not checked. This may cause NULL dereference bugs. This patch fixes it. Signed-off-by: Pan Bian Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rndis_wlan.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 603c90470225..15b2350d9f45 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -3427,6 +3427,10 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); + if (!priv->workqueue) { + wiphy_free(wiphy); + return -ENOMEM; + } INIT_WORK(&priv->work, rndis_wlan_worker); INIT_DELAYED_WORK(&priv->dev_poller_work, rndis_device_poller); INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); -- cgit v1.2.3 From 3a0c4d9778df57772d07ea241a2cc1f734dee986 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 19 Apr 2017 15:35:48 +0100 Subject: iio: hid-sensor: fix return of -EINVAL on invalid values in ret or value [ Upstream commit c894acc7bf400d039bf740420b22f0b71b7fb504 ] Ensure that when an invalid value in ret or value is found -EINVAL is returned. A previous commit broke the way the return error is being returned and instead caused the return code in ret to be re-assigned rather than be returned. Fixes: 5d9854eaea776 ("iio: hid-sensor: Store restore poll and hysteresis on S3") Signed-off-by: Colin Ian King Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/common/hid-sensors/hid-sensor-attributes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index ab646a90e3da..af85db50412e 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c @@ -215,7 +215,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id, st->poll.index, sizeof(value), &value); if (ret < 0 || value < 0) - ret = -EINVAL; + return -EINVAL; ret = sensor_hub_get_feature(st->hsdev, st->poll.report_id, @@ -265,7 +265,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, st->sensitivity.index, sizeof(value), &value); if (ret < 0 || value < 0) - ret = -EINVAL; + return -EINVAL; ret = sensor_hub_get_feature(st->hsdev, st->sensitivity.report_id, -- cgit v1.2.3 From 6ed083b35d291e06b1792fd4ff3fb45b5ab6e5c5 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 10 Nov 2016 10:39:18 +0530 Subject: mfd: palmas: Reset the POWERHOLD mux during power off [ Upstream commit 85fdaf8eb9bbec1f0f8a52fd5d85659d60738816 ] POWERHOLD signal has higher priority over the DEV_ON bit. So power off will not happen if the POWERHOLD is held high. Hence reset the MUX to GPIO_7 mode to release the POWERHOLD and the DEV_ON bit to take effect to power off the PMIC. PMIC Power off happens in dire situations like thermal shutdown so irrespective of the POWERHOLD setting go ahead and turn off the powerhold. Currently poweroff is broken on boards that have powerhold enabled. This fixes poweroff on those boards. Signed-off-by: Keerthy Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/palmas.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 8f8bacb67a15..a6b5259ffbdd 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -430,6 +430,20 @@ static void palmas_power_off(void) { unsigned int addr; int ret, slave; + struct device_node *np = palmas_dev->dev->of_node; + + if (of_property_read_bool(np, "ti,palmas-override-powerhold")) { + addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD2); + slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); + + ret = regmap_update_bits(palmas_dev->regmap[slave], addr, + PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0); + if (ret) + dev_err(palmas_dev->dev, + "Unable to write PRIMARY_SECONDARY_PAD2 %d\n", + ret); + } if (!palmas_dev) return; -- cgit v1.2.3 From db54facd56a40e7766bf7f7cda1ae138e72a691c Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 27 Apr 2017 07:45:18 -0600 Subject: mtip32xx: use runtime tag to initialize command header [ Upstream commit a4e84aae8139aca9fbfbced1f45c51ca81b57488 ] mtip32xx supposes that 'request_idx' passed to .init_request() is tag of the request, and use that as request's tag to initialize command header. After MQ IO scheduler is in, request tag assigned isn't same with the request index anymore, so cause strange hardware failure on mtip32xx, even whole system panic is triggered. This patch fixes the issue by initializing command header via request's real tag. Signed-off-by: Ming Lei Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/block/mtip32xx/mtip32xx.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 3cfd879267b2..b86273fdf48e 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -169,6 +169,25 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev) return false; /* device present */ } +/* we have to use runtime tag to setup command header */ +static void mtip_init_cmd_header(struct request *rq) +{ + struct driver_data *dd = rq->q->queuedata; + struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); + u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; + + /* Point the command headers at the command tables. */ + cmd->command_header = dd->port->command_list + + (sizeof(struct mtip_cmd_hdr) * rq->tag); + cmd->command_header_dma = dd->port->command_list_dma + + (sizeof(struct mtip_cmd_hdr) * rq->tag); + + if (host_cap_64) + cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); + + cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); +} + static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) { struct request *rq; @@ -180,6 +199,9 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) if (IS_ERR(rq)) return NULL; + /* Internal cmd isn't submitted via .queue_rq */ + mtip_init_cmd_header(rq); + return blk_mq_rq_to_pdu(rq); } @@ -3811,6 +3833,8 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq = bd->rq; int ret; + mtip_init_cmd_header(rq); + if (unlikely(mtip_check_unal_depth(hctx, rq))) return BLK_MQ_RQ_QUEUE_BUSY; @@ -3842,7 +3866,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, { struct driver_data *dd = data; struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); - u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; /* * For flush requests, request_idx starts at the end of the @@ -3859,17 +3882,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, memset(cmd->command, 0, CMD_DMA_ALLOC_SZ); - /* Point the command headers at the command tables. */ - cmd->command_header = dd->port->command_list + - (sizeof(struct mtip_cmd_hdr) * request_idx); - cmd->command_header_dma = dd->port->command_list_dma + - (sizeof(struct mtip_cmd_hdr) * request_idx); - - if (host_cap_64) - cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); - - cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); - sg_init_table(cmd->sg, MTIP_MAX_SG); return 0; } -- cgit v1.2.3 From ccda7d225dc55e8518a8aad974885ea3f0456a65 Mon Sep 17 00:00:00 2001 From: Kuppuswamy Sathyanarayanan Date: Mon, 24 Apr 2017 12:15:04 -0700 Subject: gpio: gpio-wcove: fix GPIO IRQ status mask [ Upstream commit 881ebd229f4a5ea88f269c1225245e50db9ba303 ] According to Whiskey Cove PMIC spec, bit 7 of GPIOIRQ0_REG belongs to battery IO. So we should skip this bit when checking for GPIO IRQ pending status. Otherwise, wcove_gpio_irq_handler() might go into the infinite loop until IRQ "pending" status becomes 0. This patch fixes this issue. Signed-off-by: Kuppuswamy Sathyanarayanan Acked-by: Mika Westerberg Acked-by: Andy Shevchenko Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-wcove.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 1012c86925ad..5ef4980f3f14 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -51,6 +51,8 @@ #define GROUP1_NR_IRQS 6 #define IRQ_MASK_BASE 0x4e19 #define IRQ_STATUS_BASE 0x4e0b +#define GPIO_IRQ0_MASK GENMASK(6, 0) +#define GPIO_IRQ1_MASK GENMASK(5, 0) #define UPDATE_IRQ_TYPE BIT(0) #define UPDATE_IRQ_MASK BIT(1) @@ -310,7 +312,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) return IRQ_NONE; } - pending = p[0] | (p[1] << 8); + pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7); if (!pending) return IRQ_NONE; @@ -334,7 +336,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) break; } - pending = p[0] | (p[1] << 8); + pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7); } return IRQ_HANDLED; -- cgit v1.2.3 From 6806bc0a63ef0797f429b0284f85f1c277d709be Mon Sep 17 00:00:00 2001 From: Sameer Wadgaonkar Date: Tue, 18 Apr 2017 16:55:25 -0400 Subject: staging: unisys: visorhba: fix s-Par to boot with option CONFIG_VMAP_STACK set to y [ Upstream commit 3c2bf0bd08123f3497bd3e84bd9088c937b0cb40 ] The root issue is that we are not allowed to have items on the stack being passed to "DMA" like operations. In this case we have a vmcall and an inline completion of scsi command. This patch fixes the issue by moving the variables on stack in do_scsi_nolinuxstat() to heap memory. Signed-off-by: Sameer Wadgaonkar Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorhba/visorhba_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 5a7a87efed27..28b5392153a8 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -842,7 +842,7 @@ static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; - unsigned char buf[36]; + unsigned char *buf; struct scatterlist *sg; unsigned int i; char *this_page; @@ -857,6 +857,10 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) if (cmdrsp->scsi.no_disk_result == 0) return; + buf = kzalloc(sizeof(char) * 36, GFP_KERNEL); + if (!buf) + return; + /* Linux scsi code wants a device at Lun 0 * to issue report luns, but we don't want * a disk there so we'll present a processor @@ -868,6 +872,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) if (scsi_sg_count(scsicmd) == 0) { memcpy(scsi_sglist(scsicmd), buf, cmdrsp->scsi.bufflen); + kfree(buf); return; } @@ -879,6 +884,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) memcpy(this_page, buf + bufind, sg[i].length); kunmap_atomic(this_page_orig); } + kfree(buf); } else { devdata = (struct visorhba_devdata *)scsidev->host->hostdata; for_each_vdisk_match(vdisk, devdata, scsidev) { -- cgit v1.2.3 From 419707a9fbe14ec1877159707ecf4111197c38e8 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 19:53:58 +0800 Subject: staging: wilc1000: fix unchecked return value [ Upstream commit 9e96652756ad647b7bcc03cb99ffc9756d7b5f93 ] Function dev_alloc_skb() will return a NULL pointer if there is no enough memory. However, in function WILC_WFI_mon_xmit(), its return value is used without validation. This may result in a bad memory access bug. This patch fixes the bug. Signed-off-by: Pan Bian Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_mon.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 242f82f4d24f..d8ab4cb11289 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -197,6 +197,8 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) { skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + if (!skb2) + return -ENOMEM; memcpy(skb_put(skb2, skb->len), skb->data, skb->len); -- cgit v1.2.3 From ff3d5600e2e6240869dd73e4c205108d672db7d7 Mon Sep 17 00:00:00 2001 From: yangbo lu Date: Thu, 20 Apr 2017 14:58:29 +0800 Subject: mmc: sdhci-of-esdhc: limit SD clock for ls1012a/ls1046a [ Upstream commit a627f025eb0534052ff451427c16750b3530634c ] The ls1046a datasheet specified that the max SD clock frequency for eSDHC SDR104/HS200 was 167MHz, and the ls1012a datasheet specified it's 125MHz for ls1012a. So this patch is to add the limitation. Signed-off-by: Yangbo Lu Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-of-esdhc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 3c27401cf7fe..a51d636c2312 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -432,6 +432,20 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) if (esdhc->vendor_ver < VENDOR_V_23) pre_div = 2; + /* + * Limit SD clock to 167MHz for ls1046a according to its datasheet + */ + if (clock > 167000000 && + of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc")) + clock = 167000000; + + /* + * Limit SD clock to 125MHz for ls1012a according to its datasheet + */ + if (clock > 125000000 && + of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc")) + clock = 125000000; + /* Workaround to reduce the clock frequency for p1010 esdhc */ if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) { if (clock > 20000000) -- cgit v1.2.3 From 566edbdefb71f4b4852aa3d8c55b79ebf3fc1f09 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 27 Apr 2017 12:14:20 +0300 Subject: IB/rdmavt: restore IRQs on error path in rvt_create_ah() [ Upstream commit f0bb2d44ca26b7090dc7bade8877b77005f07dfc ] We need to call spin_unlock_irqrestore() instead of vanilla spin_unlock() on this error path. Fixes: 119a8e708d16 ("IB/rdmavt: Add AH to rdmavt") Signed-off-by: Dan Carpenter Reviewed-by: Leon Romanovsky Acked-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/sw/rdmavt/ah.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/sw/rdmavt/ah.c b/drivers/infiniband/sw/rdmavt/ah.c index 16c446142c2a..b0f09fb45c72 100644 --- a/drivers/infiniband/sw/rdmavt/ah.c +++ b/drivers/infiniband/sw/rdmavt/ah.c @@ -119,7 +119,7 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd, spin_lock_irqsave(&dev->n_ahs_lock, flags); if (dev->n_ahs_allocated == dev->dparms.props.max_ah) { - spin_unlock(&dev->n_ahs_lock); + spin_unlock_irqrestore(&dev->n_ahs_lock, flags); kfree(ah); return ERR_PTR(-ENOMEM); } -- cgit v1.2.3 From b38508b8e016e5017c3920000bd9233e0c4d3666 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Fri, 28 Apr 2017 10:40:02 -0700 Subject: IB/hfi1: Fix softlockup issue [ Upstream commit 22546b741af8355cd2e16739b6af4a8f17081839 ] Soft lockups can occur because the mad processing on different CPUs acquire the spin lock dc8051_lock: [534552.835870] [] ? read_dev_port_cntr.isra.37+0x23/0x160 [hfi1] [534552.835880] [] read_dev_cntr+0x4f/0x60 [hfi1] [534552.835893] [] pma_get_opa_portstatus+0x64d/0x8c0 [hfi1] [534552.835904] [] hfi1_process_mad+0x48d/0x18c0 [hfi1] [534552.835908] [] ? __slab_free+0x81/0x2f0 [534552.835936] [] ? ib_mad_recv_done+0x21e/0xa30 [ib_core] [534552.835939] [] ? __kmalloc+0x1f3/0x240 [534552.835947] [] ib_mad_recv_done+0x2cb/0xa30 [ib_core] [534552.835955] [] __ib_process_cq+0x55/0xd0 [ib_core] [534552.835962] [] ib_cq_poll_work+0x20/0x60 [ib_core] [534552.835964] [] process_one_work+0x17b/0x470 [534552.835966] [] worker_thread+0x126/0x410 [534552.835969] [] ? rescuer_thread+0x460/0x460 [534552.835971] [] kthread+0xcf/0xe0 [534552.835974] [] ? kthread_create_on_node+0x140/0x140 [534552.835977] [] ret_from_fork+0x58/0x90 [534552.835980] [] ? kthread_create_on_node+0x140/0x140 This issue is made worse when the 8051 is busy and the reads take longer. Fix by using a non-spinning lock procure. Reviewed-by: Michael J. Ruhl Reviewed-by: Mike Marciszyn Signed-off-by: Tadeusz Struk Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/hfi1/chip.c | 86 +++++++++++++++++++++++---------------- drivers/infiniband/hw/hfi1/hfi.h | 7 ++-- drivers/infiniband/hw/hfi1/init.c | 2 +- 3 files changed, 57 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 3be62ef154d1..7853b0caad32 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -6379,18 +6379,17 @@ static void lcb_shutdown(struct hfi1_devdata *dd, int abort) * * The expectation is that the caller of this routine would have taken * care of properly transitioning the link into the correct state. + * NOTE: the caller needs to acquire the dd->dc8051_lock lock + * before calling this function. */ -static void dc_shutdown(struct hfi1_devdata *dd) +static void _dc_shutdown(struct hfi1_devdata *dd) { - unsigned long flags; + lockdep_assert_held(&dd->dc8051_lock); - spin_lock_irqsave(&dd->dc8051_lock, flags); - if (dd->dc_shutdown) { - spin_unlock_irqrestore(&dd->dc8051_lock, flags); + if (dd->dc_shutdown) return; - } + dd->dc_shutdown = 1; - spin_unlock_irqrestore(&dd->dc8051_lock, flags); /* Shutdown the LCB */ lcb_shutdown(dd, 1); /* @@ -6401,35 +6400,45 @@ static void dc_shutdown(struct hfi1_devdata *dd) write_csr(dd, DC_DC8051_CFG_RST, 0x1); } +static void dc_shutdown(struct hfi1_devdata *dd) +{ + mutex_lock(&dd->dc8051_lock); + _dc_shutdown(dd); + mutex_unlock(&dd->dc8051_lock); +} + /* * Calling this after the DC has been brought out of reset should not * do any damage. + * NOTE: the caller needs to acquire the dd->dc8051_lock lock + * before calling this function. */ -static void dc_start(struct hfi1_devdata *dd) +static void _dc_start(struct hfi1_devdata *dd) { - unsigned long flags; - int ret; + lockdep_assert_held(&dd->dc8051_lock); - spin_lock_irqsave(&dd->dc8051_lock, flags); if (!dd->dc_shutdown) - goto done; - spin_unlock_irqrestore(&dd->dc8051_lock, flags); + return; + /* Take the 8051 out of reset */ write_csr(dd, DC_DC8051_CFG_RST, 0ull); /* Wait until 8051 is ready */ - ret = wait_fm_ready(dd, TIMEOUT_8051_START); - if (ret) { + if (wait_fm_ready(dd, TIMEOUT_8051_START)) dd_dev_err(dd, "%s: timeout starting 8051 firmware\n", __func__); - } + /* Take away reset for LCB and RX FPE (set in lcb_shutdown). */ write_csr(dd, DCC_CFG_RESET, 0x10); /* lcb_shutdown() with abort=1 does not restore these */ write_csr(dd, DC_LCB_ERR_EN, dd->lcb_err_en); - spin_lock_irqsave(&dd->dc8051_lock, flags); dd->dc_shutdown = 0; -done: - spin_unlock_irqrestore(&dd->dc8051_lock, flags); +} + +static void dc_start(struct hfi1_devdata *dd) +{ + mutex_lock(&dd->dc8051_lock); + _dc_start(dd); + mutex_unlock(&dd->dc8051_lock); } /* @@ -8418,16 +8427,11 @@ static int do_8051_command( { u64 reg, completed; int return_code; - unsigned long flags; unsigned long timeout; hfi1_cdbg(DC8051, "type %d, data 0x%012llx", type, in_data); - /* - * Alternative to holding the lock for a long time: - * - keep busy wait - have other users bounce off - */ - spin_lock_irqsave(&dd->dc8051_lock, flags); + mutex_lock(&dd->dc8051_lock); /* We can't send any commands to the 8051 if it's in reset */ if (dd->dc_shutdown) { @@ -8453,10 +8457,8 @@ static int do_8051_command( return_code = -ENXIO; goto fail; } - spin_unlock_irqrestore(&dd->dc8051_lock, flags); - dc_shutdown(dd); - dc_start(dd); - spin_lock_irqsave(&dd->dc8051_lock, flags); + _dc_shutdown(dd); + _dc_start(dd); } /* @@ -8534,8 +8536,7 @@ static int do_8051_command( write_csr(dd, DC_DC8051_CFG_HOST_CMD_0, 0); fail: - spin_unlock_irqrestore(&dd->dc8051_lock, flags); - + mutex_unlock(&dd->dc8051_lock); return return_code; } @@ -11849,6 +11850,10 @@ static void free_cntrs(struct hfi1_devdata *dd) dd->scntrs = NULL; kfree(dd->cntrnames); dd->cntrnames = NULL; + if (dd->update_cntr_wq) { + destroy_workqueue(dd->update_cntr_wq); + dd->update_cntr_wq = NULL; + } } static u64 read_dev_port_cntr(struct hfi1_devdata *dd, struct cntr_entry *entry, @@ -12004,7 +12009,7 @@ u64 write_port_cntr(struct hfi1_pportdata *ppd, int index, int vl, u64 data) return write_dev_port_cntr(ppd->dd, entry, sval, ppd, vl, data); } -static void update_synth_timer(unsigned long opaque) +static void do_update_synth_timer(struct work_struct *work) { u64 cur_tx; u64 cur_rx; @@ -12013,8 +12018,8 @@ static void update_synth_timer(unsigned long opaque) int i, j, vl; struct hfi1_pportdata *ppd; struct cntr_entry *entry; - - struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque; + struct hfi1_devdata *dd = container_of(work, struct hfi1_devdata, + update_cntr_work); /* * Rather than keep beating on the CSRs pick a minimal set that we can @@ -12097,7 +12102,13 @@ static void update_synth_timer(unsigned long opaque) } else { hfi1_cdbg(CNTR, "[%d] No update necessary", dd->unit); } +} + +static void update_synth_timer(unsigned long opaque) +{ + struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque; + queue_work(dd->update_cntr_wq, &dd->update_cntr_work); mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME); } @@ -12333,6 +12344,13 @@ static int init_cntrs(struct hfi1_devdata *dd) if (init_cpu_counters(dd)) goto bail; + dd->update_cntr_wq = alloc_ordered_workqueue("hfi1_update_cntr_%d", + WQ_MEM_RECLAIM, dd->unit); + if (!dd->update_cntr_wq) + goto bail; + + INIT_WORK(&dd->update_cntr_work, do_update_synth_timer); + mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME); return 0; bail: diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index cc87fd4e534b..a3279f3d2578 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h @@ -475,7 +475,7 @@ struct rvt_sge_state; #define HFI1_PART_ENFORCE_OUT 0x2 /* how often we check for synthetic counter wrap around */ -#define SYNTH_CNT_TIME 2 +#define SYNTH_CNT_TIME 3 /* Counter flags */ #define CNTR_NORMAL 0x0 /* Normal counters, just read register */ @@ -929,8 +929,9 @@ struct hfi1_devdata { spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */ /* around rcd and (user ctxts) ctxt_cnt use (intr vs free) */ spinlock_t uctxt_lock; /* rcd and user context changes */ - /* exclusive access to 8051 */ - spinlock_t dc8051_lock; + struct mutex dc8051_lock; /* exclusive access to 8051 */ + struct workqueue_struct *update_cntr_wq; + struct work_struct update_cntr_work; /* exclusive access to 8051 memory */ spinlock_t dc8051_memlock; int dc8051_timed_out; /* remember if the 8051 timed out */ diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index a3dd27b1305d..84a97f3f9299 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -1078,11 +1078,11 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) spin_lock_init(&dd->uctxt_lock); spin_lock_init(&dd->hfi1_diag_trans_lock); spin_lock_init(&dd->sc_init_lock); - spin_lock_init(&dd->dc8051_lock); spin_lock_init(&dd->dc8051_memlock); seqlock_init(&dd->sc2vl_lock); spin_lock_init(&dd->sde_map_lock); spin_lock_init(&dd->pio_map_lock); + mutex_init(&dd->dc8051_lock); init_waitqueue_head(&dd->event_queue); dd->int_counter = alloc_percpu(u64); -- cgit v1.2.3 From 7c1c184bb571e696ffcd57ed43c65f8c91a6d03e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 28 Apr 2017 16:19:49 +0200 Subject: platform/x86: asus-wmi: try to set als by default [ Upstream commit e9b615186805e2c18a0ac76aca62c1543ecfdbb8 ] some laptops, for example ASUS UX330UAK, have brocken als_get function but working als_set funktion. In this case, ALS will stay turned off. Method (WMNB, 3, Serialized) { ... If (Local0 == 0x53545344) { ... If (IIA0 == 0x00050001) { If (!ALSP) { Return (0x02) } Local0 = (GALS & 0x10) <<<---- bug, should be: (GALS () & 0x10) If (Local0) { Return (0x00050001) } Else { Return (0x00050000) } } ..... If (Local0 == 0x53564544) { ... If (IIA0 == 0x00050001) { Return (ALSC (IIA1)) } ...... Method (GALS, 0, NotSerialized) { Local0 = Zero Local0 |= 0x20 If (ALAE) { Local0 |= 0x10 } Local1 = 0x0A Local1 <<= 0x08 Local0 |= Local1 Return (Local0) } Since it works without problems on Windows I assume ASUS WMI driver for Win never trying to get ALS state, and instead it is setting it by default to ON. This patch will do the same. Turn ALS on by default. Signed-off-by: Oleksij Rempel Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/asus-nb-wmi.c | 13 +++++++++++++ drivers/platform/x86/asus-wmi.c | 12 ++++++++++++ drivers/platform/x86/asus-wmi.h | 1 + 3 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index ab44326ea3e7..687cc5b922ee 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -120,6 +120,10 @@ static struct quirk_entry quirk_asus_x550lb = { .xusb2pr = 0x01D9, }; +static struct quirk_entry quirk_asus_ux330uak = { + .wmi_force_als_set = true, +}; + static int dmi_matched(const struct dmi_system_id *dmi) { quirks = dmi->driver_data; @@ -420,6 +424,15 @@ static const struct dmi_system_id asus_quirks[] = { }, .driver_data = &quirk_asus_ux303ub, }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. UX330UAK", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"), + }, + .driver_data = &quirk_asus_ux330uak, + }, { .callback = dmi_matched, .ident = "ASUSTeK COMPUTER INC. X550LB", diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 8499d3ae4257..8a1bfd489c26 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1108,6 +1108,15 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) orig_ports_available, ports_available); } +/* + * Some devices dont support or have borcken get_als method + * but still support set method. + */ +static void asus_wmi_set_als(void) +{ + asus_wmi_set_devstate(ASUS_WMI_DEVID_ALS_ENABLE, 1, NULL); +} + /* * Hwmon device */ @@ -2120,6 +2129,9 @@ static int asus_wmi_add(struct platform_device *pdev) goto fail_rfkill; } + if (asus->driver->quirks->wmi_force_als_set) + asus_wmi_set_als(); + /* Some Asus desktop boards export an acpi-video backlight interface, stop this from showing up */ chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index fdff626c3b51..5db052d1de1e 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -45,6 +45,7 @@ struct quirk_entry { bool store_backlight_power; bool wmi_backlight_power; bool wmi_backlight_native; + bool wmi_force_als_set; int wapf; /* * For machines with AMD graphic chips, it will send out WMI event -- cgit v1.2.3 From e9e5ad6b0ef2f00ba23f550c1347bbfb44b66e20 Mon Sep 17 00:00:00 2001 From: Robert Lippert Date: Thu, 20 Apr 2017 16:49:47 -0700 Subject: ipmi/watchdog: fix wdog hang on panic waiting for ipmi response [ Upstream commit 2c1175c2e8e5487233cabde358a19577562ac83e ] Commit c49c097610fe ("ipmi: Don't call receive handler in the panic context") means that the panic_recv_free is not called during a panic and the atomic count does not drop to 0. Fix this by only expecting one decrement of the atomic variable which comes from panic_smi_free. Signed-off-by: Robert Lippert Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_watchdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 909311016108..055d2ce378a7 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -515,7 +515,7 @@ static void panic_halt_ipmi_heartbeat(void) msg.cmd = IPMI_WDOG_RESET_TIMER; msg.data = NULL; msg.data_len = 0; - atomic_add(2, &panic_done_count); + atomic_add(1, &panic_done_count); rv = ipmi_request_supply_msgs(watchdog_user, (struct ipmi_addr *) &addr, 0, @@ -525,7 +525,7 @@ static void panic_halt_ipmi_heartbeat(void) &panic_halt_heartbeat_recv_msg, 1); if (rv) - atomic_sub(2, &panic_done_count); + atomic_sub(1, &panic_done_count); } static struct ipmi_smi_msg panic_halt_smi_msg = { @@ -549,12 +549,12 @@ static void panic_halt_ipmi_set_timeout(void) /* Wait for the messages to be free. */ while (atomic_read(&panic_done_count) != 0) ipmi_poll_interface(watchdog_user); - atomic_add(2, &panic_done_count); + atomic_add(1, &panic_done_count); rv = i_ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (rv) { - atomic_sub(2, &panic_done_count); + atomic_sub(1, &panic_done_count); printk(KERN_WARNING PFX "Unable to extend the watchdog timeout."); } else { -- cgit v1.2.3 From ec4b63f5c0a47d01b92af90cd645f47e03f36a98 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Apr 2017 13:48:08 +0200 Subject: ACPI / PMIC: xpower: Fix power_table addresses [ Upstream commit 2bde7c32b1db162692f05c6be066b5bcd3d9fdbe ] The power table addresses should be contiguous, but there was a hole where 0x34 was missing. On most devices this is not a problem as addresses above 0x34 are used for the BUC# convertors which are not used in the DSDTs I've access to but after the BUC# convertors there is a field named GPI1 in the DSTDs, which does get used in some cases and ended up turning BUC6 on and off due to the wrong addresses, resulting in turning the entire device off (or causing it to reboot). Removing the hole in the addresses fixes this, fixing one of my Bay Trail tablets turning off while booting the mainline kernel. While at it add comments with the field names used in the DSDTs to make it easier to compare the register and bits used at each address with the datasheet. Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/pmic/intel_pmic_xpower.c | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c index e6e991ac20f3..0c6874e6a9b6 100644 --- a/drivers/acpi/pmic/intel_pmic_xpower.c +++ b/drivers/acpi/pmic/intel_pmic_xpower.c @@ -28,97 +28,97 @@ static struct pmic_table power_table[] = { .address = 0x00, .reg = 0x13, .bit = 0x05, - }, + }, /* ALD1 */ { .address = 0x04, .reg = 0x13, .bit = 0x06, - }, + }, /* ALD2 */ { .address = 0x08, .reg = 0x13, .bit = 0x07, - }, + }, /* ALD3 */ { .address = 0x0c, .reg = 0x12, .bit = 0x03, - }, + }, /* DLD1 */ { .address = 0x10, .reg = 0x12, .bit = 0x04, - }, + }, /* DLD2 */ { .address = 0x14, .reg = 0x12, .bit = 0x05, - }, + }, /* DLD3 */ { .address = 0x18, .reg = 0x12, .bit = 0x06, - }, + }, /* DLD4 */ { .address = 0x1c, .reg = 0x12, .bit = 0x00, - }, + }, /* ELD1 */ { .address = 0x20, .reg = 0x12, .bit = 0x01, - }, + }, /* ELD2 */ { .address = 0x24, .reg = 0x12, .bit = 0x02, - }, + }, /* ELD3 */ { .address = 0x28, .reg = 0x13, .bit = 0x02, - }, + }, /* FLD1 */ { .address = 0x2c, .reg = 0x13, .bit = 0x03, - }, + }, /* FLD2 */ { .address = 0x30, .reg = 0x13, .bit = 0x04, - }, + }, /* FLD3 */ { - .address = 0x38, + .address = 0x34, .reg = 0x10, .bit = 0x03, - }, + }, /* BUC1 */ { - .address = 0x3c, + .address = 0x38, .reg = 0x10, .bit = 0x06, - }, + }, /* BUC2 */ { - .address = 0x40, + .address = 0x3c, .reg = 0x10, .bit = 0x05, - }, + }, /* BUC3 */ { - .address = 0x44, + .address = 0x40, .reg = 0x10, .bit = 0x04, - }, + }, /* BUC4 */ { - .address = 0x48, + .address = 0x44, .reg = 0x10, .bit = 0x01, - }, + }, /* BUC5 */ { - .address = 0x4c, + .address = 0x48, .reg = 0x10, .bit = 0x00 - }, + }, /* BUC6 */ }; /* TMP0 - TMP5 are the same, all from GPADC */ -- cgit v1.2.3 From 8112fa3c00c68f4407c970aeaa73a8e64c1e717b Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Mon, 24 Apr 2017 17:09:15 +0800 Subject: drm/amdgpu: fix gpu reset crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 51687759be93fbc553f2727e86be25c38126ba93 ] [ 413.687439] BUG: unable to handle kernel NULL pointer dereference at 0000000000000548 [ 413.687479] IP: [] to_live_kthread+0x5/0x60 [ 413.687507] PGD 1efd12067 [ 413.687519] PUD 1efd11067 [ 413.687531] PMD 0 [ 413.687543] Oops: 0000 [#1] SMP [ 413.687557] Modules linked in: amdgpu(OE) ttm(OE) drm_kms_helper(E) drm(E) i2c_algo_bit(E) fb_sys_fops(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) rpcsec_gss_krb5(E) nfsv4(E) nfs(E) fscache(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) snd_hda_codec_hdmi(E) snd_hda_intel(E) eeepc_wmi(E) snd_hda_codec(E) asus_wmi(E) snd_hda_core(E) sparse_keymap(E) snd_hwdep(E) video(E) snd_pcm(E) snd_seq_midi(E) joydev(E) snd_seq_midi_event(E) snd_rawmidi(E) snd_seq(E) snd_seq_device(E) snd_timer(E) kvm(E) irqbypass(E) crct10dif_pclmul(E) snd(E) crc32_pclmul(E) ghash_clmulni_intel(E) soundcore(E) aesni_intel(E) aes_x86_64(E) lrw(E) gf128mul(E) glue_helper(E) ablk_helper(E) cryptd(E) shpchp(E) serio_raw(E) i2c_piix4(E) 8250_dw(E) i2c_designware_platform(E) i2c_designware_core(E) mac_hid(E) binfmt_misc(E) [ 413.687894] parport_pc(E) ppdev(E) lp(E) parport(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) sunrpc(E) autofs4(E) hid_generic(E) usbhid(E) hid(E) psmouse(E) ahci(E) r8169(E) mii(E) libahci(E) wmi(E) [ 413.687989] CPU: 13 PID: 1134 Comm: kworker/13:2 Tainted: G OE 4.9.0-custom #4 [ 413.688019] Hardware name: System manufacturer System Product Name/PRIME B350-PLUS, BIOS 0606 04/06/2017 [ 413.688089] Workqueue: events amd_sched_job_timedout [amdgpu] [ 413.688116] task: ffff88020f9657c0 task.stack: ffffc90001a88000 [ 413.688139] RIP: 0010:[] [] to_live_kthread+0x5/0x60 [ 413.688171] RSP: 0018:ffffc90001a8bd60 EFLAGS: 00010282 [ 413.688191] RAX: ffff88020f0073f8 RBX: ffff88020f000000 RCX: 0000000000000000 [ 413.688217] RDX: 0000000000000001 RSI: ffff88020f9670c0 RDI: 0000000000000000 [ 413.688243] RBP: ffffc90001a8bd78 R08: 0000000000000000 R09: 0000000000001000 [ 413.688269] R10: 0000006051b11a82 R11: 0000000000000001 R12: 0000000000000000 [ 413.688295] R13: ffff88020f002770 R14: ffff88020f004838 R15: ffff8801b23c2c60 [ 413.688321] FS: 0000000000000000(0000) GS:ffff88021ef40000(0000) knlGS:0000000000000000 [ 413.688352] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 413.688373] CR2: 0000000000000548 CR3: 00000001efd0f000 CR4: 00000000003406e0 [ 413.688399] Stack: [ 413.688407] ffffffff8109b304 ffff88020f000000 0000000000000070 ffffc90001a8bdf0 [ 413.688439] ffffffffa05ce29d ffffffffa052feb7 ffffffffa07b5820 ffffc90001a8bda0 [ 413.688470] ffffffff00000018 ffff8801bb88f060 0000000001a8bdb8 ffff88021ef59280 [ 413.688502] Call Trace: [ 413.688514] [] ? kthread_park+0x14/0x60 [ 413.688555] [] amdgpu_gpu_reset+0x7d/0x670 [amdgpu] [ 413.688589] [] ? drm_printk+0x97/0xa0 [drm] [ 413.688643] [] amdgpu_job_timedout+0x46/0x50 [amdgpu] [ 413.688700] [] amd_sched_job_timedout+0x17/0x20 [amdgpu] [ 413.688727] [] process_one_work+0x153/0x3f0 [ 413.688751] [] worker_thread+0x12b/0x4b0 [ 413.688773] [] ? do_syscall_64+0x6e/0x180 [ 413.688795] [] ? rescuer_thread+0x350/0x350 [ 413.688818] [] ? do_syscall_64+0x6e/0x180 [ 413.688839] [] kthread+0xd3/0xf0 [ 413.688858] [] ? kthread_park+0x60/0x60 [ 413.688881] [] ret_from_fork+0x25/0x30 [ 413.688901] Code: 25 40 d3 00 00 48 8b 80 48 05 00 00 48 89 e5 5d 48 8b 40 c8 48 c1 e8 02 83 e0 01 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 <48> 8b b7 48 05 00 00 55 48 89 e5 48 85 f6 74 31 8b 97 f8 18 00 [ 413.689045] RIP [] to_live_kthread+0x5/0x60 [ 413.689064] RSP [ 413.689076] CR2: 0000000000000548 [ 413.697985] ---[ end trace 0a314a64821f84e9 ]--- The root cause is some ring doesn't have scheduler, like KIQ ring Reviewed-by: Christian König Signed-off-by: Chunming Zhou Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 50f18f666d67..d0c3e56ece74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2237,7 +2237,7 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring) + if (!ring || !ring->sched.thread) continue; kthread_park(ring->sched.thread); amd_sched_hw_job_reset(&ring->sched); @@ -2326,7 +2326,8 @@ retry: } for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring) + + if (!ring || !ring->sched.thread) continue; amd_sched_job_recovery(&ring->sched); @@ -2335,7 +2336,7 @@ retry: } else { dev_err(adev->dev, "asic resume failed (%d).\n", r); for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - if (adev->rings[i]) { + if (adev->rings[i] && adev->rings[i]->sched.thread) { kthread_unpark(adev->rings[i]->sched.thread); } } -- cgit v1.2.3 From 7be76fbbd25c4cd838125f8ea843d1fb1c657db0 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 24 Apr 2017 01:59:34 +0200 Subject: drm/nouveau/kms: Increase max retries in scanout position queries. [ Upstream commit 60b95d709525e3ce1c51e1fc93175dcd1755d345 ] So far we only allowed for 1 retry and just failed the query - and thereby high precision vblank timestamping - if we did not get a reasonable result, as such a failure wasn't considered all too horrible. There are a few NVidia gpu models out there which may need a bit more than 1 retry to get a successful query result under some conditions. Since Linux 4.4 the update code for vblank counter and timestamp in drm_update_vblank_count() changed so that the implementation assumes that high precision vblank timestamping of a kms driver either consistently succeeds or consistently fails for a given video mode and encoder/connector combo. Iow. switching from success to fail or vice versa on a modeset or connector change is ok, but spurious temporary failure for a given setup can confuse the core code and potentially cause bad miscounting of vblanks and confusion or hangs in userspace clients which rely on vblank stuff, e.g., desktop compositors. Therefore change the max retry count to a larger number - more than any gpu so far is known to need to succeed, but still low enough so that these queries which do also happen in vblank interrupt are still fast enough to be not disastrously long if something would go badly wrong with them. As such sporadic retries only happen seldom even on affected gpu's, this could mean a vblank irq could take a few dozen microseconds longer every few hours of uptime -- better than a desktop compositor randomly hanging every couple of hours or days of uptime in a hard to reproduce manner. Signed-off-by: Mario Kleiner Signed-off-by: Ben Skeggs Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nouveau_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 2c2b86d68129..6526a3366087 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -106,7 +106,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, }; struct nouveau_display *disp = nouveau_display(crtc->dev); struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; - int ret, retry = 1; + int ret, retry = 20; do { ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); -- cgit v1.2.3 From b1b6f948b41cb69fe4ac81f49eb218df9399507c Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 30 Mar 2017 20:49:02 -0700 Subject: ixgbevf: fix size of queue stats length [ Upstream commit f87fc44770f54ff1b54d44ae9cec11f10efeca02 ] IXGBEVF_QUEUE_STATS_LEN is based on ixgebvf_stats, not ixgbe_stats. This change fixes a bug where ethtool -S displayed some empty fields. Signed-off-by: Emil Tantilov Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/ixgbevf/ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index 508e72c5f1c2..d665de8849a2 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -80,7 +80,7 @@ static struct ixgbe_stats ixgbevf_gstrings_stats[] = { #define IXGBEVF_QUEUE_STATS_LEN ( \ (((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \ ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \ - (sizeof(struct ixgbe_stats) / sizeof(u64))) + (sizeof(struct ixgbevf_stats) / sizeof(u64))) #define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats) #define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN) -- cgit v1.2.3 From b0d0441f2a6ae3dc20ee4a6871d48178c17911a7 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 7 Feb 2017 10:05:09 +0100 Subject: net: ethernet: ucc_geth: fix MEM_PART_MURAM mode [ Upstream commit 8b8642af15ed14b9a7a34d3401afbcc274533e13 ] Since commit 5093bb965a163 ("powerpc/QE: switch to the cpm_muram implementation"), muram area is not part of immrbar mapping anymore so immrbar_virt_to_phys() is not usable anymore. Fixes: 5093bb965a163 ("powerpc/QE: switch to the cpm_muram implementation") Signed-off-by: Christophe Leroy Acked-by: David S. Miller Acked-by: Li Yang Signed-off-by: Scott Wood Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/ucc_geth.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index f76d33279454..ef9bc26ebc1a 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -2594,11 +2594,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } else if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_MURAM) { out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, - (u32) immrbar_virt_to_phys(ugeth-> - p_tx_bd_ring[i])); + (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i])); out_be32(&ugeth->p_send_q_mem_reg->sqqd[i]. last_bd_completed_address, - (u32) immrbar_virt_to_phys(endOfRing)); + (u32)qe_muram_dma(endOfRing)); } } @@ -2844,8 +2843,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } else if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_MURAM) { out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr, - (u32) immrbar_virt_to_phys(ugeth-> - p_rx_bd_ring[i])); + (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i])); } /* rest of fields handled by QE */ } -- cgit v1.2.3 From 949b9dc1818a100941ed63c5147059a5f64c7987 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:45 +0100 Subject: soc/fsl/qe: round brg_freq to 1kHz granularity [ Upstream commit 2ccf80b7566cc035d903dd0ac5d7ebd25c2c1060 ] Because of integer computation rounding in u-boot (that sets the QE brg-frequency DTS prop), the clk value is 99999999 Hz even though it is 100 MHz. When setting brg clks that are exact divisors of 100 MHz, this small differnce plays a role and can result in lower clks to be output (for instance 20 MHz - divide by 5 - results in 16.666 MHz - divide by 6). This patch fixes that by "forcing" the brg_clk to the nearest kHz when the difference is below 2 integer rounding errors (i.e. 4). Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/soc/fsl/qe/qe.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index 2707a827261b..5482302d3d9e 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -163,11 +163,15 @@ EXPORT_SYMBOL(qe_issue_cmd); */ static unsigned int brg_clk = 0; +#define CLK_GRAN (1000) +#define CLK_GRAN_LIMIT (5) + unsigned int qe_get_brg_clk(void) { struct device_node *qe; int size; const u32 *prop; + unsigned int mod; if (brg_clk) return brg_clk; @@ -185,6 +189,15 @@ unsigned int qe_get_brg_clk(void) of_node_put(qe); + /* round this if near to a multiple of CLK_GRAN */ + mod = brg_clk % CLK_GRAN; + if (mod) { + if (mod < CLK_GRAN_LIMIT) + brg_clk -= mod; + else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT)) + brg_clk += CLK_GRAN - mod; + } + return brg_clk; } EXPORT_SYMBOL(qe_get_brg_clk); -- cgit v1.2.3 From bbb952d00c8b254890e1cef7f7b7d23874c3aaa9 Mon Sep 17 00:00:00 2001 From: Dean Jenkins Date: Fri, 28 Apr 2017 13:57:25 +0100 Subject: Bluetooth: hci_ldisc: Add protocol check to hci_uart_dequeue() [ Upstream commit 048e1bd3a27fbeb84ccdff52e165370c1339a193 ] Before attempting to dequeue a Data Link protocol encapsulated message, check that the Data Link protocol is still bound to the HCI UART driver. This makes the code consistent with the usage of the other proto function pointers. Therefore, add a check for HCI_UART_PROTO_READY into hci_uart_dequeue() and return NULL if the Data Link protocol is not bound. This is needed for robustness as there is a scheduling race condition. hci_uart_write_work() is scheduled to run via work queue hu->write_work from hci_uart_tx_wakeup(). Therefore, there is a delay between scheduling hci_uart_write_work() to run and hci_uart_dequeue() running whereby the Data Link protocol layer could become unbound during the scheduling delay. In this case, without the check, the call to the unbound Data Link protocol layer dequeue function can crash. It is noted that hci_uart_tty_close() has a "cancel_work_sync(&hu->write_work)" statement but this only reduces the window of the race condition because it is possible for a new work-item to be added to work queue hu->write_work after the call to cancel_work_sync(). For example, Data Link layer retransmissions can be added to the work queue after the cancel_work_sync() has finished. Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 9497c469efd2..7ec73945351c 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -113,10 +113,12 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) { struct sk_buff *skb = hu->tx_skb; - if (!skb) - skb = hu->proto->dequeue(hu); - else + if (!skb) { + if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) + skb = hu->proto->dequeue(hu); + } else { hu->tx_skb = NULL; + } return skb; } -- cgit v1.2.3 From b5d95e85b20634f58c2d57f4041222a9adefd282 Mon Sep 17 00:00:00 2001 From: Dean Jenkins Date: Fri, 28 Apr 2017 13:57:26 +0100 Subject: Bluetooth: hci_ldisc: Add protocol check to hci_uart_tx_wakeup() [ Upstream commit 2d6f1da168e1d62c47f7d50135ac4cbd8411dcb1 ] Before attempting to schedule a work-item onto hu->write_work in hci_uart_tx_wakeup(), check that the Data Link protocol layer is still bound to the HCI UART driver. Failure to perform this protocol check causes a race condition between the work queue hu->write_work running hci_uart_write_work() and the Data Link protocol layer being unbound (closed) in hci_uart_tty_close(). Note hci_uart_tty_close() does have a "cancel_work_sync(&hu->write_work)" but it is ineffective because it cannot prevent work-items being added to hu->write_work after cancel_work_sync() has run. Therefore, add a check for HCI_UART_PROTO_READY into hci_uart_tx_wakeup() which prevents scheduling of the work queue when HCI_UART_PROTO_READY is in the clear state. However, note a small race condition remains because the hci_uart_tx_wakeup() thread can run in parallel with the hci_uart_tty_close() thread so it is possible that a schedule of hu->write_work can occur when HCI_UART_PROTO_READY is cleared. A complete solution needs locking of the threads which is implemented in a future commit. Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 7ec73945351c..2230f9368c21 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -125,6 +125,9 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) int hci_uart_tx_wakeup(struct hci_uart *hu) { + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) + return 0; + if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); return 0; -- cgit v1.2.3 From 9c8cd2a87247a9561536345715ef63143551f0c9 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Thu, 27 Apr 2017 21:24:35 +0200 Subject: vxlan: correctly handle ipv6.disable module parameter [ Upstream commit d074bf9600443403aa24fbc12c1f18eadc90f5aa ] When IPv6 is compiled but disabled at runtime, __vxlan_sock_add returns -EAFNOSUPPORT. For metadata based tunnels, this causes failure of the whole operation of bringing up the tunnel. Ignore failure of IPv6 socket creation for metadata based tunnels caused by IPv6 not being available. Fixes: b1be00a6c39f ("vxlan: support both IPv4 and IPv6 sockets in a single vxlan device") Signed-off-by: Jiri Benc Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 50570d779b01..0f5dfb8a545d 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2816,17 +2816,21 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6) static int vxlan_sock_add(struct vxlan_dev *vxlan) { - bool ipv6 = vxlan->flags & VXLAN_F_IPV6; bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA; + bool ipv6 = vxlan->flags & VXLAN_F_IPV6 || metadata; + bool ipv4 = !ipv6 || metadata; int ret = 0; RCU_INIT_POINTER(vxlan->vn4_sock, NULL); #if IS_ENABLED(CONFIG_IPV6) RCU_INIT_POINTER(vxlan->vn6_sock, NULL); - if (ipv6 || metadata) + if (ipv6) { ret = __vxlan_sock_add(vxlan, true); + if (ret < 0 && ret != -EAFNOSUPPORT) + ipv4 = false; + } #endif - if (!ret && (!ipv6 || metadata)) + if (ipv4) ret = __vxlan_sock_add(vxlan, false); if (ret < 0) vxlan_sock_release(vxlan); -- cgit v1.2.3 From 498d02453e734133baff5ae24d54bf2b72abb179 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 Apr 2017 15:56:09 +0300 Subject: qed: Unlock on error in qed_vf_pf_acquire() [ Upstream commit 66117a9d9a8ca948680d6554769ef9e88f936954 ] My static checker complains that we're holding a mutex on this error path. Let's goto exit instead of returning directly. Fixes: b0bccb69eba3 ("qed: Change locking scheme for VF channel") Signed-off-by: Dan Carpenter Acked-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_vf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c index abf5bf11f865..0645124a887b 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_vf.c +++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c @@ -204,7 +204,7 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) /* send acquire request */ rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); if (rc) - return rc; + goto exit; /* copy acquire response from buffer to p_hwfn */ memcpy(&p_iov->acquire_resp, resp, sizeof(p_iov->acquire_resp)); -- cgit v1.2.3 From 909dbba2106f370d93bb4b6dc7520a8ef7791f08 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 28 Apr 2017 19:17:41 -0500 Subject: bnx2x: Align RX buffers [ Upstream commit 9b70de6d0266888b3743f03802502e43131043c8 ] The bnx2x driver is not providing proper alignment on the receive buffers it passes to build_skb(), causing skb_shared_info to be misaligned. skb_shared_info contains an atomic, and while PPC normally supports unaligned accesses, it does not support unaligned atomics. Aligning the size of rx buffers will ensure that page_frag_alloc() returns aligned addresses. This can be reproduced on PPC by setting the network MTU to 1450 (or other non-multiple-of-4) and then generating sufficient inbound network traffic (one or two large "wget"s usually does it), producing the following oops: Unable to handle kernel paging request for unaligned access at address 0xc00000ffc43af656 Faulting instruction address: 0xc00000000080ef8c Oops: Kernel access of bad area, sig: 7 [#1] SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: vmx_crypto powernv_rng rng_core powernv_op_panel leds_powernv led_class nfsd ip_tables x_tables autofs4 xfs lpfc bnx2x mdio libcrc32c crc_t10dif crct10dif_generic crct10dif_common CPU: 104 PID: 0 Comm: swapper/104 Not tainted 4.11.0-rc8-00088-g4c761da #2 task: c00000ffd4892400 task.stack: c00000ffd4920000 NIP: c00000000080ef8c LR: c00000000080eee8 CTR: c0000000001f8320 REGS: c00000ffffc33710 TRAP: 0600 Not tainted (4.11.0-rc8-00088-g4c761da) MSR: 9000000000009033 CR: 24082042 XER: 00000000 CFAR: c00000000080eea0 DAR: c00000ffc43af656 DSISR: 00000000 SOFTE: 1 GPR00: c000000000907f64 c00000ffffc33990 c000000000dd3b00 c00000ffcaf22100 GPR04: c00000ffcaf22e00 0000000000000000 0000000000000000 0000000000000000 GPR08: 0000000000b80008 c00000ffc43af636 c00000ffc43af656 0000000000000000 GPR12: c0000000001f6f00 c00000000fe1a000 000000000000049f 000000000000c51f GPR16: 00000000ffffef33 0000000000000000 0000000000008a43 0000000000000001 GPR20: c00000ffc58a90c0 0000000000000000 000000000000dd86 0000000000000000 GPR24: c000007fd0ed10c0 00000000ffffffff 0000000000000158 000000000000014a GPR28: c00000ffc43af010 c00000ffc9144000 c00000ffcaf22e00 c00000ffcaf22100 NIP [c00000000080ef8c] __skb_clone+0xdc/0x140 LR [c00000000080eee8] __skb_clone+0x38/0x140 Call Trace: [c00000ffffc33990] [c00000000080fb74] skb_clone+0x74/0x110 (unreliable) [c00000ffffc339c0] [c000000000907f64] packet_rcv+0x144/0x510 [c00000ffffc33a40] [c000000000827b64] __netif_receive_skb_core+0x5b4/0xd80 [c00000ffffc33b00] [c00000000082b2bc] netif_receive_skb_internal+0x2c/0xc0 [c00000ffffc33b40] [c00000000082c49c] napi_gro_receive+0x11c/0x260 [c00000ffffc33b80] [d000000066483d68] bnx2x_poll+0xcf8/0x17b0 [bnx2x] [c00000ffffc33d00] [c00000000082babc] net_rx_action+0x31c/0x480 [c00000ffffc33e10] [c0000000000d5a44] __do_softirq+0x164/0x3d0 [c00000ffffc33f00] [c0000000000d60a8] irq_exit+0x108/0x120 [c00000ffffc33f20] [c000000000015b98] __do_irq+0x98/0x200 [c00000ffffc33f90] [c000000000027f14] call_do_irq+0x14/0x24 [c00000ffd4923a90] [c000000000015d94] do_IRQ+0x94/0x110 [c00000ffd4923ae0] [c000000000008d90] hardware_interrupt_common+0x150/0x160 Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 596f88b693ef..ca6c4718000f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2026,6 +2026,7 @@ static void bnx2x_set_rx_buf_size(struct bnx2x *bp) ETH_OVREHEAD + mtu + BNX2X_FW_RX_ALIGN_END; + fp->rx_buf_size = SKB_DATA_ALIGN(fp->rx_buf_size); /* Note : rx_buf_size doesn't take into account NET_SKB_PAD */ if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE) fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD; -- cgit v1.2.3 From 5ac685af62fb165a8bec3ca26c0c180e4de04929 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Apr 2017 18:52:33 +0200 Subject: power: supply: bq24190_charger: Add disable-reset device-property [ Upstream commit 6cf62a3b97e78ba41d31390e59a1ddc98a9e3622 ] Allow platform-code to disable the reset on probe and suspend/resume by setting a "disable-reset" boolean device property on the device. There are several reasons why the platform-code may want to disable the reset on probe and suspend/resume: 1) Resetting the charger should never be necessary it should always have sane values programmed. If it is running with invalid values while we are not running (system turned off or suspended) there is a big problem as that may lead to overcharging the battery. 2) The reset in suspend() is meant to put the charger back into default mode, but this is not necessary and not a good idea. If the charger has been programmed with a higher max charge_current / charge_voltage then putting it back in default-mode will reset those to the safe power-on defaults, leading to slower charging, or charging to a lower voltage (and thus not using the full capacity) while suspended which is undesirable. Reprogramming the max charge_current / charge_voltage after the reset will not help here as that will put the charger back in host mode and start the i2c watchdog if the host then does not do anything for 40s (iow if we're suspended for more then 40s) the watchdog expires resetting the device to default-mode, including resetting all the registers to there safe power-on defaults. So the only way to keep using custom charge settings while suspending is to keep the charger in its normal running state with the i2c watchdog disabled. This is fine as the charger will still automatically switch from constant current to constant voltage and stop charging when the battery is full. 3) Besides never being necessary resetting the charger also causes problems on systems where the charge voltage limit is set higher then the reset value, if this is the case and the charger is reset while charging and the battery voltage is between the 2 voltages, then about half the time the charger gets confused and claims to be charging (REG08 contains 0x64) but in reality the charger has decoupled itself from VBUS (Q1 off) and is drawing 0A from VBUS, leaving the system running from the battery. This last problem is happening on a GPD-win mini PC with a bq24292i charger chip combined with a max17047 fuel-gauge and a LiHV battery. I've checked and TI does not list any errata for the bq24292i which could explain this (there are no errata at all). Cc: Liam Breck Cc: Tony Lindgren Signed-off-by: Hans de Goede Acked-by: Liam Breck Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq24190_charger.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index cdd71ecd72ed..8ed2782d1bb1 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -506,6 +506,9 @@ static int bq24190_register_reset(struct bq24190_dev_info *bdi) int ret, limit = 100; u8 v; + if (device_property_read_bool(bdi->dev, "disable-reset")) + return 0; + /* Reset the registers */ ret = bq24190_write_mask(bdi, BQ24190_REG_POC, BQ24190_REG_POC_RESET_MASK, -- cgit v1.2.3 From 9822cb80738a31f4e4821e385920547ddb95828e Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Mon, 24 Apr 2017 16:22:08 +0800 Subject: power: supply: isp1704: Fix unchecked return value of devm_kzalloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 8b20839988f1ed5e534b270f3776709b640dc7e0 ] Function devm_kzalloc() will return a NULL pointer. However, in function isp1704_charger_probe(), the return value of devm_kzalloc() is directly used without validation. This may result in a bad memory access bug. Fixes: 34a109610e2a ("isp1704_charger: Add DT support") Signed-off-by: Pan Bian Reviewed-by: Pali Rohár Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/isp1704_charger.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/power/supply/isp1704_charger.c b/drivers/power/supply/isp1704_charger.c index 4cd6899b961e..95af5f305838 100644 --- a/drivers/power/supply/isp1704_charger.c +++ b/drivers/power/supply/isp1704_charger.c @@ -418,6 +418,10 @@ static int isp1704_charger_probe(struct platform_device *pdev) pdata = devm_kzalloc(&pdev->dev, sizeof(struct isp1704_charger_data), GFP_KERNEL); + if (!pdata) { + ret = -ENOMEM; + goto fail0; + } pdata->enable_gpio = gpio; dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio); -- cgit v1.2.3 From 5b65f7d823f3ce0e6e46eb08b2d35972e6092699 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 25 Apr 2017 15:18:05 +0200 Subject: power: supply: pda_power: move from timer to delayed_work [ Upstream commit 633e8799ddc09431be2744c4a1efdbda13af2b0b ] This changed is needed to avoid locking problem during boot as shown: <5>[ 8.824096] Registering SWP/SWPB emulation handler <6>[ 8.977294] clock: disabling unused clocks to save power <3>[ 9.108154] BUG: sleeping function called from invalid context at kernel_albert/kernel/mutex.c:269 <3>[ 9.122894] in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: swapper/0 <4>[ 9.130249] 3 locks held by swapper/0/1: <4>[ 9.134613] #0: (&__lockdep_no_validate__){......}, at: [] __driver_attach+0x58/0xa8 <4>[ 9.144500] #1: (&__lockdep_no_validate__){......}, at: [] __driver_attach+0x68/0xa8 <4>[ 9.154357] #2: (&polling_timer){......}, at: [] run_timer_softirq+0x108/0x3ec <4>[ 9.163726] Backtrace: <4>[ 9.166473] [] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x20/0x24) <4>[ 9.175811] r6:00203230 r5:0000010d r4:d782e000 r3:60000113 <4>[ 9.182250] [] (dump_stack+0x0/0x24) from [] (__might_sleep+0x10c/0x128) <4>[ 9.191650] [] (__might_sleep+0x0/0x128) from [] (mutex_lock_nested+0x34/0x36c) <4>[ 9.201660] r5:c02d5350 r4:d79a0c64 <4>[ 9.205688] [] (mutex_lock_nested+0x0/0x36c) from [] (regulator_set_current_limit+0x30/0x118) <4>[ 9.217071] [] (regulator_set_current_limit+0x0/0x118) from [] (update_charger+0x84/0xc4) <4>[ 9.228027] r7:d782fb20 r6:00000101 r5:c1767e94 r4:00000000 <4>[ 9.234436] [] (update_charger+0x0/0xc4) from [] (psy_changed+0x20/0x48) <4>[ 9.243804] r5:d782e000 r4:c1767e94 <4>[ 9.247802] [] (psy_changed+0x0/0x48) from [] (polling_timer_func+0x84/0xb8) <4>[ 9.257537] r4:c1767e94 r3:00000002 <4>[ 9.261566] [] (polling_timer_func+0x0/0xb8) from [] (run_timer_softirq+0x17c/0x3ec) <4>[ 9.272033] r4:c1767eb0 r3:00000000 <4>[ 9.276062] [] (run_timer_softirq+0x0/0x3ec) from [] (__do_softirq+0xf0/0x298) <4>[ 9.286010] [] (__do_softirq+0x0/0x298) from [] (irq_exit+0x98/0xa0) <4>[ 9.295013] [] (irq_exit+0x0/0xa0) from [] (handle_IRQ+0x60/0xc0) <4>[ 9.303680] r4:c1194e98 r3:c00bc778 <4>[ 9.307708] [] (handle_IRQ+0x0/0xc0) from [] (gic_handle_irq+0x34/0x68) <4>[ 9.316955] r8:000ac383 r7:d782fc3c r6:d782fc08 r5:c11936c4 r4:e0802100 <4>[ 9.324310] r3:c026ba48 <4>[ 9.327301] [] (gic_handle_irq+0x0/0x68) from [] (__irq_svc+0x40/0x74) <4>[ 9.336456] Exception stack(0xd782fc08 to 0xd782fc50) <4>[ 9.342041] fc00: d6e30e6c ac383627 00000000 ac383417 ea19c000 ea200000 <4>[ 9.351104] fc20: beffffff 00000667 000ac383 d6e30670 d6e3066c d782fc94 d782fbe8 d782fc50 <4>[ 9.360168] fc40: c026ba48 c001d1f0 00000113 ffffffff Fixes: b2998049cfae ("[BATTERY] pda_power platform driver") Signed-off-by: Michael Trimarchi Signed-off-by: Anthony Brandon Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/pda_power.c | 49 ++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/pda_power.c b/drivers/power/supply/pda_power.c index dfe1ee89f7c7..922a86787c5c 100644 --- a/drivers/power/supply/pda_power.c +++ b/drivers/power/supply/pda_power.c @@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags(struct resource *res) static struct device *dev; static struct pda_power_pdata *pdata; static struct resource *ac_irq, *usb_irq; -static struct timer_list charger_timer; -static struct timer_list supply_timer; -static struct timer_list polling_timer; +static struct delayed_work charger_work; +static struct delayed_work polling_work; +static struct delayed_work supply_work; static int polling; static struct power_supply *pda_psy_ac, *pda_psy_usb; @@ -140,7 +140,7 @@ static void update_charger(void) } } -static void supply_timer_func(unsigned long unused) +static void supply_work_func(struct work_struct *work) { if (ac_status == PDA_PSY_TO_CHANGE) { ac_status = new_ac_status; @@ -161,11 +161,12 @@ static void psy_changed(void) * Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ - mod_timer(&supply_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_charger)); + cancel_delayed_work(&supply_work); + schedule_delayed_work(&supply_work, + msecs_to_jiffies(pdata->wait_for_charger)); } -static void charger_timer_func(unsigned long unused) +static void charger_work_func(struct work_struct *work) { update_status(); psy_changed(); @@ -184,13 +185,14 @@ static irqreturn_t power_changed_isr(int irq, void *power_supply) * Wait a bit before reading ac/usb line status and setting charger, * because ac/usb status readings may lag from irq. */ - mod_timer(&charger_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_status)); + cancel_delayed_work(&charger_work); + schedule_delayed_work(&charger_work, + msecs_to_jiffies(pdata->wait_for_status)); return IRQ_HANDLED; } -static void polling_timer_func(unsigned long unused) +static void polling_work_func(struct work_struct *work) { int changed = 0; @@ -211,8 +213,9 @@ static void polling_timer_func(unsigned long unused) if (changed) psy_changed(); - mod_timer(&polling_timer, - jiffies + msecs_to_jiffies(pdata->polling_interval)); + cancel_delayed_work(&polling_work); + schedule_delayed_work(&polling_work, + msecs_to_jiffies(pdata->polling_interval)); } #if IS_ENABLED(CONFIG_USB_PHY) @@ -250,8 +253,9 @@ static int otg_handle_notification(struct notifier_block *nb, * Wait a bit before reading ac/usb line status and setting charger, * because ac/usb status readings may lag from irq. */ - mod_timer(&charger_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_status)); + cancel_delayed_work(&charger_work); + schedule_delayed_work(&charger_work, + msecs_to_jiffies(pdata->wait_for_status)); return NOTIFY_OK; } @@ -300,8 +304,8 @@ static int pda_power_probe(struct platform_device *pdev) if (!pdata->ac_max_uA) pdata->ac_max_uA = 500000; - setup_timer(&charger_timer, charger_timer_func, 0); - setup_timer(&supply_timer, supply_timer_func, 0); + INIT_DELAYED_WORK(&charger_work, charger_work_func); + INIT_DELAYED_WORK(&supply_work, supply_work_func); ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); @@ -385,9 +389,10 @@ static int pda_power_probe(struct platform_device *pdev) if (polling) { dev_dbg(dev, "will poll for status\n"); - setup_timer(&polling_timer, polling_timer_func, 0); - mod_timer(&polling_timer, - jiffies + msecs_to_jiffies(pdata->polling_interval)); + INIT_DELAYED_WORK(&polling_work, polling_work_func); + cancel_delayed_work(&polling_work); + schedule_delayed_work(&polling_work, + msecs_to_jiffies(pdata->polling_interval)); } if (ac_irq || usb_irq) @@ -433,9 +438,9 @@ static int pda_power_remove(struct platform_device *pdev) free_irq(ac_irq->start, pda_psy_ac); if (polling) - del_timer_sync(&polling_timer); - del_timer_sync(&charger_timer); - del_timer_sync(&supply_timer); + cancel_delayed_work_sync(&polling_work); + cancel_delayed_work_sync(&charger_work); + cancel_delayed_work_sync(&supply_work); if (pdata->is_usb_online) power_supply_unregister(pda_psy_usb); -- cgit v1.2.3 From edc0bfd6e2276e3d53dc3ebb7f454d1b940e4967 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Fri, 28 Apr 2017 10:25:51 -0700 Subject: Input: twl4030-pwrbutton - use correct device for irq request [ Upstream commit 3071e9dd6cd3f2290d770117330f2c8b2e9a97e4 ] The interrupt should be requested for the platform device and not for the input device. Fixes: 7f9ce649d267 ("Input: twl4030-pwrbutton - simplify driver using devm_*") Signed-off-by: Sebastian Reichel Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/twl4030-pwrbutton.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index 603fc2fadf05..12b20840fb74 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -70,7 +70,7 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev) pwr->phys = "twl4030_pwrbutton/input0"; pwr->dev.parent = &pdev->dev; - err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq, + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, powerbutton_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_pwrbutton", pwr); -- cgit v1.2.3 From 9002e49554da9e3a4d70b2c18e7603d6fcefdbfe Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Thu, 6 Apr 2017 14:49:44 +0200 Subject: IB/rxe: Don't clamp residual length to mtu [ Upstream commit d52418502e288b5c7e9e2e6cf1de5f1d3d79d2e1 ] When reading a RDMA WRITE FIRST packet we copy the DMA length from the RDMA header into the qp->resp.resid variable for later use. Later in check_rkey() we clamp it to the MTU if the packet is an RDMA WRITE packet and has a residual length bigger than the MTU. Later in write_data_in() we subtract the payload of the packet from the residual length. If the packet happens to have a payload of exactly the MTU size we end up with a residual length of 0 despite the packet not being the last in the conversation. When the next packet in the conversation arrives, we don't have any residual length left and thus set the QP into an error state. This broke NVMe over Fabrics functionality over rdma_rxe.ko The patch was verified using the following test. # echo eth0 > /sys/module/rdma_rxe/parameters/add # nvme connect -t rdma -a 192.168.155.101 -s 1023 -n nvmf-test # mkfs.xfs -fK /dev/nvme0n1 meta-data=/dev/nvme0n1 isize=256 agcount=4, agsize=65536 blks = sectsz=4096 attr=2, projid32bit=1 = crc=0 finobt=0, sparse=0 data = bsize=4096 blocks=262144, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 # mount /dev/nvme0n1 /tmp/ [ 148.923263] XFS (nvme0n1): Mounting V4 Filesystem [ 148.961196] XFS (nvme0n1): Ending clean mount # dd if=/dev/urandom of=test.bin bs=1M count=128 128+0 records in 128+0 records out 134217728 bytes (134 MB, 128 MiB) copied, 0.437991 s, 306 MB/s # sha256sum test.bin cde42941f045efa8c4f0f157ab6f29741753cdd8d1cff93a6b03649d83c4129a test.bin # cp test.bin /tmp/ sha256sum /tmp/test.bin cde42941f045efa8c4f0f157ab6f29741753cdd8d1cff93a6b03649d83c4129a /tmp/test.bin Signed-off-by: Johannes Thumshirn Cc: Hannes Reinecke Cc: Sagi Grimberg Cc: Max Gurtovoy Acked-by: Moni Shoua Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/sw/rxe/rxe_resp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 8c0ddd7165ae..0d25dc84d294 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -471,8 +471,6 @@ static enum resp_states check_rkey(struct rxe_qp *qp, state = RESPST_ERR_LENGTH; goto err; } - - qp->resp.resid = mtu; } else { if (pktlen != resid) { state = RESPST_ERR_LENGTH; -- cgit v1.2.3 From 2710fb8f0c828656a147870dccc5164c0f0c48ea Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 1 May 2017 12:15:07 -0700 Subject: md/raid10: skip spare disk as 'first' disk [ Upstream commit b506335e5d2b4ec687dde392a3bdbf7601778f1d ] Commit 6f287ca(md/raid10: reset the 'first' at the end of loop) ignores a case in reshape, the first rdev could be a spare disk, which shouldn't be accounted as the first disk since it doesn't include the offset info. Fix: 6f287ca(md/raid10: reset the 'first' at the end of loop) Cc: Guoqing Jiang Cc: NeilBrown Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid10.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b1daff78f7b2..18a4271bf569 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4089,6 +4089,7 @@ static int raid10_start_reshape(struct mddev *mddev) diff = 0; if (first || diff < min_offset_diff) min_offset_diff = diff; + first = 0; } } -- cgit v1.2.3 From a9b90d80db0e53ce4fe06a1ffe12ac683f7b06c9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 30 Apr 2017 22:54:16 +0200 Subject: ACPI / power: Delay turning off unused power resources after suspend [ Upstream commit 8ece1d83346bcc431090d59a2184276192189cdd ] Commit 660b1113e0f3 (ACPI / PM: Fix consistency check for power resources during resume) introduced a check for ACPI power resources which have been turned on by the BIOS during suspend and turns these back off again. This is causing problems on a Dell Venue Pro 11 7130 (i5-4300Y) it causes the following messages to show up in dmesg: [ 131.014605] ACPI: Waking up from system sleep state S3 [ 131.150271] acpi LNXPOWER:07: Turning OFF [ 131.150323] acpi LNXPOWER:06: Turning OFF [ 131.150911] acpi LNXPOWER:00: Turning OFF [ 131.169014] ACPI : EC: interrupt unblocked [ 131.181811] xhci_hcd 0000:00:14.0: System wakeup disabled by ACPI [ 133.535728] pci_raw_set_power_state: 76 callbacks suppressed [ 133.535735] iwlwifi 0000:01:00.0: Refused to change power state, currently in D3 [ 133.597672] PM: noirq resume of devices complete after 2428.891 msecs Followed by a bunch of iwlwifi errors later on and the pcie device dropping from the bus (acpiphp thinks it has been unplugged). Disabling the turning off of unused power resources fixes this. Instead of adding a quirk for this system, this commit fixes this by moving the disabling of unused power resources to later in the resume sequence when the iwlwifi card has been moved out of D3 so the ref_count for its power resource no longer is 0. This new behavior seems to match the intend of the original commit which commit-msg says: "(... which means that no devices are going to need them any time soon) and we should turn them off". This also avoids power resources which we need when bringing devices out of D3 from getting bounced off and then back on again. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/power.c | 10 ++++++++++ drivers/acpi/sleep.c | 1 + drivers/acpi/sleep.h | 1 + 3 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 1c2b846c5776..3a6c9b741b23 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -864,6 +864,16 @@ void acpi_resume_power_resources(void) mutex_unlock(&resource->resource_lock); } + + mutex_unlock(&power_resource_list_lock); +} + +void acpi_turn_off_unused_power_resources(void) +{ + struct acpi_power_resource *resource; + + mutex_lock(&power_resource_list_lock); + list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) { int result, state; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index a4327af676fe..097d630ab886 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -474,6 +474,7 @@ static void acpi_pm_start(u32 acpi_state) */ static void acpi_pm_end(void) { + acpi_turn_off_unused_power_resources(); acpi_scan_lock_release(); /* * This is necessary in case acpi_pm_finish() is not called during a diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index a9cc34e663f9..a82ff74faf7a 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h @@ -6,6 +6,7 @@ extern struct list_head acpi_wakeup_device_list; extern struct mutex acpi_device_lock; extern void acpi_resume_power_resources(void); +extern void acpi_turn_off_unused_power_resources(void); static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) { -- cgit v1.2.3 From f29bc9dc0bef0cb6f3ca069d96fbd535439d1680 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Fri, 31 Mar 2017 19:53:35 +0400 Subject: tcm_fileio: Prevent information leak for short reads [ Upstream commit f11b55d13563e9428c88c873f4f03a6bef11ec0a ] If we failed to read data from backing file (probably because some one truncate file under us), we must zerofill cmd's data, otherwise it will be returned as is. Most likely cmd's data are unitialized pages from page cache. This result in information leak. (Change BUG_ON into -EINVAL se_cmd failure - nab) testcase: https://github.com/dmonakhov/xfstests/commit/e11a1b7b907ca67b1be51a1594025600767366d5 Signed-off-by: Dmitry Monakhov Signed-off-by: Nicholas Bellinger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_file.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 97928b42ad62..57a3d3936364 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -276,12 +276,11 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, else ret = vfs_iter_read(fd, &iter, &pos); - kfree(bvec); - if (is_write) { if (ret < 0 || ret != data_length) { pr_err("%s() write returned %d\n", __func__, ret); - return (ret < 0 ? ret : -EINVAL); + if (ret >= 0) + ret = -EINVAL; } } else { /* @@ -294,17 +293,29 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, pr_err("%s() returned %d, expecting %u for " "S_ISBLK\n", __func__, ret, data_length); - return (ret < 0 ? ret : -EINVAL); + if (ret >= 0) + ret = -EINVAL; } } else { if (ret < 0) { pr_err("%s() returned %d for non S_ISBLK\n", __func__, ret); - return ret; + } else if (ret != data_length) { + /* + * Short read case: + * Probably some one truncate file under us. + * We must explicitly zero sg-pages to prevent + * expose uninizialized pages to userspace. + */ + if (ret < data_length) + ret += iov_iter_zero(data_length - ret, &iter); + else + ret = -EINVAL; } } } - return 1; + kfree(bvec); + return ret; } static sense_reason_t -- cgit v1.2.3 From e5ea3b04080c790a1d8a1ec2e8526bebb66f497b Mon Sep 17 00:00:00 2001 From: Maksim Salau Date: Tue, 2 May 2017 13:47:53 +0200 Subject: video: fbdev: udlfb: Fix buffer on stack [ Upstream commit 45f580c42e5c125d55dbd8099750a1998de3d917 ] Allocate buffers on HEAP instead of STACK for local array that is to be sent using usb_control_msg(). Signed-off-by: Maksim Salau Cc: Bernie Thompson Cc: Geert Uytterhoeven Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/udlfb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 53326badfb61..2add8def83be 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -1487,15 +1487,25 @@ static struct device_attribute fb_device_attrs[] = { static int dlfb_select_std_channel(struct dlfb_data *dev) { int ret; - u8 set_def_chn[] = { 0x57, 0xCD, 0xDC, 0xA7, + void *buf; + static const u8 set_def_chn[] = { + 0x57, 0xCD, 0xDC, 0xA7, 0x1C, 0x88, 0x5E, 0x15, 0x60, 0xFE, 0xC6, 0x97, 0x16, 0x3D, 0x47, 0xF2 }; + buf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL); + + if (!buf) + return -ENOMEM; + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), NR_USB_REQUEST_CHANNEL, (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0, - set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT); + buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT); + + kfree(buf); + return ret; } -- cgit v1.2.3 From e22a6754abda4ab563fce3f3241e71a8c917c979 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Tue, 2 May 2017 13:47:53 +0200 Subject: sm501fb: don't return zero on failure path in sm501fb_start() [ Upstream commit dc85e9a87420613b3129d5cc5ecd79c58351c546 ] If fbmem iomemory mapping failed, sm501fb_start() breaks off initialization, deallocates resources, but returns zero. As a result, double deallocation can happen in sm501fb_stop(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Cc: Tomi Valkeinen Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/sm501fb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index d0a4e2f79a57..d215faacce04 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1600,6 +1600,7 @@ static int sm501fb_start(struct sm501fb_info *info, info->fbmem = ioremap(res->start, resource_size(res)); if (info->fbmem == NULL) { dev_err(dev, "cannot remap framebuffer\n"); + ret = -ENXIO; goto err_mem_res; } -- cgit v1.2.3 From b2a863dba3defce5f37af95007999ce9f48f8af6 Mon Sep 17 00:00:00 2001 From: Timmy Li Date: Tue, 2 May 2017 10:46:52 +0800 Subject: net: hns: fix ethtool_get_strings overflow in hns driver [ Upstream commit 412b65d15a7f8a93794653968308fc100f2aa87c ] hns_get_sset_count() returns HNS_NET_STATS_CNT and the data space allocated is not enough for ethtool_get_strings(), which will cause random memory corruption. When SLAB and DEBUG_SLAB are both enabled, memory corruptions like the the following can be observed without this patch: [ 43.115200] Slab corruption (Not tainted): Acpi-ParseExt start=ffff801fb0b69030, len=80 [ 43.115206] Redzone: 0x9f911029d006462/0x5f78745f31657070. [ 43.115208] Last user: [<5f7272655f746b70>](0x5f7272655f746b70) [ 43.115214] 010: 70 70 65 31 5f 74 78 5f 70 6b 74 00 6b 6b 6b 6b ppe1_tx_pkt.kkkk [ 43.115217] 030: 70 70 65 31 5f 74 78 5f 70 6b 74 5f 6f 6b 00 6b ppe1_tx_pkt_ok.k [ 43.115218] Next obj: start=ffff801fb0b69098, len=80 [ 43.115220] Redzone: 0x706d655f6f666966/0x9f911029d74e35b. [ 43.115229] Last user: [](acpi_os_release_object+0x28/0x38) [ 43.115231] 000: 74 79 00 6b 6b 6b 6b 6b 70 70 65 31 5f 74 78 5f ty.kkkkkppe1_tx_ [ 43.115232] 010: 70 6b 74 5f 65 72 72 5f 63 73 75 6d 5f 66 61 69 pkt_err_csum_fai Signed-off-by: Timmy Li Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 02a03bccde7b..34b5e699a1d5 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -671,7 +671,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data) static int hns_gmac_get_sset_count(int stringset) { - if (stringset == ETH_SS_STATS) + if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) return ARRAY_SIZE(g_gmac_stats_string); return 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index 6ea872287307..4ecb809785f9 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb) int hns_ppe_get_sset_count(int stringset) { - if (stringset == ETH_SS_STATS) + if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) return ETH_PPE_STATIC_NUM; return 0; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index f3be9ac47bfb..fbbbbffd58dc 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -798,7 +798,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data) */ int hns_rcb_get_ring_sset_count(int stringset) { - if (stringset == ETH_SS_STATS) + if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) return HNS_RING_STATIC_REG_NUM; return 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c index 8f4f0e8da984..d1c868c800f9 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c @@ -776,7 +776,7 @@ static void hns_xgmac_get_strings(u32 stringset, u8 *data) */ static int hns_xgmac_get_sset_count(int stringset) { - if (stringset == ETH_SS_STATS) + if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) return ARRAY_SIZE(g_xgmac_stats_string); return 0; -- cgit v1.2.3 From a06dfdb14333c5b7e8069339fb5561debe5068e4 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Mon, 24 Apr 2017 15:05:11 -0700 Subject: rtc: ds1374: wdt: Fix issue with timeout scaling from secs to wdt ticks [ Upstream commit 453d0744f6c6ca3f9749b8c57c2e85b5b9f52514 ] The issue is that the internal counter that triggers the watchdog reset is actually running at 4096 Hz instead of 1Hz, therefore the value given by userland (in sec) needs to be multiplied by 4096 to get the correct behavior. Fixes: 920f91e50c5b ("drivers/rtc/rtc-ds1374.c: add watchdog support") Signed-off-by: Moritz Fischer Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-ds1374.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 3b3049c8c9e0..5b5bc7dc3a1c 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -527,6 +527,10 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, if (get_user(new_margin, (int __user *)arg)) return -EFAULT; + /* the hardware's tick rate is 4096 Hz, so + * the counter value needs to be scaled accordingly + */ + new_margin <<= 12; if (new_margin < 1 || new_margin > 16777216) return -EINVAL; @@ -535,7 +539,8 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, ds1374_wdt_ping(); /* fallthrough */ case WDIOC_GETTIMEOUT: - return put_user(wdt_margin, (int __user *)arg); + /* when returning ... inverse is true */ + return put_user((wdt_margin >> 12), (int __user *)arg); case WDIOC_SETOPTIONS: if (copy_from_user(&options, (int __user *)arg, sizeof(int))) return -EFAULT; -- cgit v1.2.3 From 0e37c9f8d3f5a77cfebca019a25478ce7e2f7874 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Mon, 24 Apr 2017 15:05:12 -0700 Subject: rtc: ds1374: wdt: Fix stop/start ioctl always returning -EINVAL [ Upstream commit 538c08f4c89580fc644e2bc64e0a4b86c925da4e ] The WDIOC_SETOPTIONS case in the watchdog ioctl would alwayss falls through to the -EINVAL case. This is wrong since thew watchdog does actually get stopped or started correctly. Fixes: 920f91e50c5b ("drivers/rtc/rtc-ds1374.c: add watchdog support") Signed-off-by: Moritz Fischer Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-ds1374.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 5b5bc7dc3a1c..c0eb113588ff 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -548,14 +548,15 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, if (options & WDIOS_DISABLECARD) { pr_info("disable watchdog\n"); ds1374_wdt_disable(); + return 0; } if (options & WDIOS_ENABLECARD) { pr_info("enable watchdog\n"); ds1374_wdt_settimeout(wdt_margin); ds1374_wdt_ping(); + return 0; } - return -EINVAL; } return -ENOTTY; -- cgit v1.2.3 From 975760baa6e74d57502909b5dd0f01507187c6ff Mon Sep 17 00:00:00 2001 From: Michael Mera Date: Mon, 24 Apr 2017 16:11:57 +0900 Subject: ath10k: fix out of bounds access to local buffer [ Upstream commit a16703aaeaedec7a8bee5be5522c7c3e75478951 ] During write to debugfs file simulate_fw_crash, fixed-size local buffer 'buf' is accessed and modified at index 'count-1', where 'count' is the size of the write (so potentially out of bounds). This patch fixes this problem. Signed-off-by: Michael Mera Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/debug.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 6aa2b93497dd..0dadc6044dba 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -624,17 +624,21 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; - char buf[32]; + char buf[32] = {0}; + ssize_t rc; int ret; - simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); + /* filter partial writes and invalid commands */ + if (*ppos != 0 || count >= sizeof(buf) || count == 0) + return -EINVAL; - /* make sure that buf is null terminated */ - buf[sizeof(buf) - 1] = 0; + rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); + if (rc < 0) + return rc; /* drop the possible '\n' from the end */ - if (buf[count - 1] == '\n') - buf[count - 1] = 0; + if (buf[*ppos - 1] == '\n') + buf[*ppos - 1] = '\0'; mutex_lock(&ar->conf_mutex); -- cgit v1.2.3 From f37dc00bace9e9deb2c3db35fc7bf815dbf0c913 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 6 Nov 2017 12:16:56 +0100 Subject: Bluetooth: hci_qca: Avoid setup failure on missing rampatch [ Upstream commit ba8f3597900291a93604643017fff66a14546015 ] Assuming that the original code idea was to enable in-band sleeping only if the setup_rome method returns succes and run in 'standard' mode otherwise, we should not return setup_rome return value which makes qca_setup fail if no rampatch/nvm file found. This fixes BT issue on the dragonboard-820C p4 which includes the following QCA controller: hci0: Product:0x00000008 hci0: Patch :0x00000111 hci0: ROM :0x00000302 hci0: SOC :0x00000044 Since there is no rampatch for this controller revision, just make it work as is. Signed-off-by: Loic Poulain Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_qca.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 6c867fbc56a7..74b2f4a14643 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -936,6 +936,9 @@ static int qca_setup(struct hci_uart *hu) if (!ret) { set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); qca_debugfs_init(hdev); + } else if (ret == -ENOENT) { + /* No patch/nvm-config found, run with original fw/config */ + ret = 0; } /* Setup bdaddr */ -- cgit v1.2.3 From dadb6c1a8d889b5cab5ff6ed44db9cdb445467e7 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Wed, 22 Nov 2017 15:03:17 +0100 Subject: Bluetooth: btqcomsmd: Fix skb double free corruption [ Upstream commit 67b8fbead4685b36d290a0ef91c6ddffc4920ec9 ] In case of hci send frame failure, skb is still owned by the caller (hci_core) and then should not be freed. This fixes crash on dragonboard-410c when sending SCO packet. skb is freed by both btqcomsmd and hci_core. Fixes: 1511cc750c3d ("Bluetooth: Introduce Qualcomm WCNSS SMD based HCI driver") Signed-off-by: Loic Poulain Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/btqcomsmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c index 08c2c93887c1..3aac78a5091b 100644 --- a/drivers/bluetooth/btqcomsmd.c +++ b/drivers/bluetooth/btqcomsmd.c @@ -85,7 +85,8 @@ static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb) break; } - kfree_skb(skb); + if (!ret) + kfree_skb(skb); return ret; } -- cgit v1.2.3 From bac8b847be924575031d0486b2c53ccad7c910b8 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 20 Nov 2017 09:00:55 -0500 Subject: media: c8sectpfe: fix potential NULL pointer dereference in c8sectpfe_timer_interrupt [ Upstream commit baed3c4bc4c13de93e0dba0a26d601411ebcb389 ] _channel_ is being dereferenced before it is null checked, hence there is a potential null pointer dereference. Fix this by moving the pointer dereference after _channel_ has been null checked. This issue was detected with the help of Coccinelle. Fixes: c5f5d0f99794 ("[media] c8sectpfe: STiH407/10 Linux DVB demux support") Signed-off-by: Gustavo A. R. Silva Acked-by: Patrice Chotard Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 30c148b9d65e..06e2cfd09855 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -83,7 +83,7 @@ static void c8sectpfe_timer_interrupt(unsigned long ac8sectpfei) static void channel_swdemux_tsklet(unsigned long data) { struct channel_info *channel = (struct channel_info *)data; - struct c8sectpfei *fei = channel->fei; + struct c8sectpfei *fei; unsigned long wp, rp; int pos, num_packets, n, size; u8 *buf; @@ -91,6 +91,8 @@ static void channel_swdemux_tsklet(unsigned long data) if (unlikely(!channel || !channel->irec)) return; + fei = channel->fei; + wp = readl(channel->irec + DMA_PRDS_BUSWP_TP(0)); rp = readl(channel->irec + DMA_PRDS_BUSRP_TP(0)); -- cgit v1.2.3 From af302f2d047a4dccb501bfd7c74b7537e35ea4bf Mon Sep 17 00:00:00 2001 From: Prakash Kamliya Date: Mon, 4 Dec 2017 19:10:15 +0530 Subject: drm/msm: fix leak in failed get_pages [ Upstream commit 62e3a3e342af3c313ab38603811ecdb1fcc79edb ] get_pages doesn't keep a reference of the pages allocated when it fails later in the code path. This can lead to a memory leak. Keep reference of the allocated pages so that it can be freed when msm_gem_free_object gets called later during cleanup. Signed-off-by: Prakash Kamliya Signed-off-by: Sharat Masetty Signed-off-by: Rob Clark Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/msm/msm_gem.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index b6ac27e31929..797d1f8340b9 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -91,14 +91,17 @@ static struct page **get_pages(struct drm_gem_object *obj) return p; } + msm_obj->pages = p; + msm_obj->sgt = drm_prime_pages_to_sg(p, npages); if (IS_ERR(msm_obj->sgt)) { + void *ptr = ERR_CAST(msm_obj->sgt); + dev_err(dev->dev, "failed to allocate sgt\n"); - return ERR_CAST(msm_obj->sgt); + msm_obj->sgt = NULL; + return ptr; } - msm_obj->pages = p; - /* For non-cached buffers, ensure the new pages are clean * because display controller, GPU, etc. are not coherent: */ @@ -121,7 +124,10 @@ static void put_pages(struct drm_gem_object *obj) if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, msm_obj->sgt->nents, DMA_BIDIRECTIONAL); - sg_free_table(msm_obj->sgt); + + if (msm_obj->sgt) + sg_free_table(msm_obj->sgt); + kfree(msm_obj->sgt); if (use_pages(obj)) -- cgit v1.2.3 From 7c06c3dd3af35953963cb54b4cbecc327fc81b2e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 29 Nov 2017 09:47:33 +0100 Subject: RDMA/iwpm: Fix uninitialized error code in iwpm_send_mapinfo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 302d6424e4a293a5761997e6c9fc3dfb1e4c355f ] With gcc-4.1.2: drivers/infiniband/core/iwpm_util.c: In function ‘iwpm_send_mapinfo’: drivers/infiniband/core/iwpm_util.c:647: warning: ‘ret’ may be used uninitialized in this function Indeed, if nl_client is not found in any of the scanned has buckets, ret will be used uninitialized. Preinitialize ret to -EINVAL to fix this. Fixes: 30dc5e63d6a5ad24 ("RDMA/core: Add support for iWARP Port Mapper user space service") Signed-off-by: Geert Uytterhoeven Reviewed-by: Tatyana Nikolova Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/iwpm_util.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index ade71e7f0131..2fe4c2c921de 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -664,6 +664,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid) } skb_num++; spin_lock_irqsave(&iwpm_mapinfo_lock, flags); + ret = -EINVAL; for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { hlist_for_each_entry(map_info, &iwpm_hash_bucket[i], hlist_node) { -- cgit v1.2.3 From 1f13ef920ad0ceccf22ba1d309f84d55608ef4eb Mon Sep 17 00:00:00 2001 From: Tsang-Shian Lin Date: Sat, 9 Dec 2017 11:37:10 -0600 Subject: rtlwifi: rtl_pci: Fix the bug when inactiveps is enabled. [ Upstream commit b7573a0a27bfa8270dea9b145448f6884b7cacc1 ] Reset the driver current tx read/write index to zero when inactiveps nic out of sync with HW state. Wrong driver tx read/write index will cause Tx fail. Signed-off-by: Tsang-Shian Lin Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtlwifi/pci.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 75ffeaa54ed8..e15b462d096b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -1572,7 +1572,14 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) dev_kfree_skb_irq(skb); ring->idx = (ring->idx + 1) % ring->entries; } + + if (rtlpriv->use_new_trx_flow) { + rtlpci->tx_ring[i].cur_tx_rp = 0; + rtlpci->tx_ring[i].cur_tx_wp = 0; + } + ring->idx = 0; + ring->entries = rtlpci->txringcount[i]; } } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); -- cgit v1.2.3 From a20f36c59b459881d6ecf30eb6b34c461e81d5b5 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 21 Sep 2017 19:23:56 -0400 Subject: media: bt8xx: Fix err 'bt878_probe()' [ Upstream commit 45392ff6881dbe56d41ef0b17c2e576065f8ffa1 ] This is odd to call 'pci_disable_device()' in an error path before a coresponding successful 'pci_enable_device()'. Return directly instead. Fixes: 77e0be12100a ("V4L/DVB (4176): Bug-fix: Fix memory overflow") Signed-off-by: Christophe JAILLET Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/pci/bt8xx/bt878.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 8aa726651630..90fcccc05b56 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) bt878_num); if (bt878_num >= BT878_MAX) { printk(KERN_ERR "bt878: Too many devices inserted\n"); - result = -ENOMEM; - goto fail0; + return -ENOMEM; } if (pci_enable_device(dev)) return -EIO; -- cgit v1.2.3 From bb32772bc409f3cb0a40c318a5dda37f177107c3 Mon Sep 17 00:00:00 2001 From: Balaji Pothunoori Date: Thu, 7 Dec 2017 16:58:04 +0200 Subject: ath10k: handling qos at STA side based on AP WMM enable/disable [ Upstream commit 07ffb4497360ae8789f05555fec8171ee952304d ] Data packets are not sent by STA in case of STA joined to non QOS AP (WMM disabled AP). This is happening because of STA is sending data packets to firmware from host with qos enabled along with non qos queue value(TID = 16). Due to qos enabled, firmware is discarding the packet. This patch fixes this issue by updating the qos based on station WME capability field if WMM is disabled in AP. This patch is required by 10.4 family chipsets like QCA4019/QCA9888/QCA9884/QCA99X0. Firmware Versoin : 10.4-3.5.1-00018. For 10.2.4 family chipsets QCA988X/QCA9887 and QCA6174 this patch has no effect. Signed-off-by: Balaji Pothunoori Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1e6e63dbd61c..a497bf31953d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2505,7 +2505,7 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, } break; case WMI_VDEV_TYPE_STA: - if (vif->bss_conf.qos) + if (sta->wme) arg->peer_flags |= arvif->ar->wmi.peer_flags->qos; break; case WMI_VDEV_TYPE_IBSS: -- cgit v1.2.3 From 034371788a56304c2836eb58706b9e2f04387359 Mon Sep 17 00:00:00 2001 From: Ron Economos Date: Mon, 11 Dec 2017 19:51:53 -0500 Subject: media: [RESEND] media: dvb-frontends: Add delay to Si2168 restart [ Upstream commit 380a6c86457573aa42d27ae11e025eb25941a0b7 ] On faster CPUs a delay is required after the resume command and the restart command. Without the delay, the restart command often returns -EREMOTEIO and the Si2168 does not restart. Note that this patch fixes the same issue as https://patchwork.linuxtv.org/patch/44304/, but I believe my udelay() fix addresses the actual problem. Signed-off-by: Ron Economos Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/si2168.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 20b4a659e2e4..0fe69f79a24d 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -14,6 +14,8 @@ * GNU General Public License for more details. */ +#include + #include "si2168_priv.h" static const struct dvb_frontend_ops si2168_ops; @@ -378,6 +380,7 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; + udelay(100); memcpy(cmd.args, "\x85", 1); cmd.wlen = 1; cmd.rlen = 1; -- cgit v1.2.3 From 8ee96dfd01bcab79e50a596c9d5142e0bf05c787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 14 Dec 2017 19:55:50 +0100 Subject: qmi_wwan: set FLAG_SEND_ZLP to avoid network initiated disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 245d21190aec547c0de64f70c0e6de871c185a24 ] It has been reported that the dummy byte we add to avoid ZLPs can be forwarded by the modem to the PGW/GGSN, and that some operators will drop the connection if this happens. In theory, QMI devices are based on CDC ECM and should as such both support ZLPs and silently ignore the dummy byte. The latter assumption failed. Let's test out the first. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index a30d6a6dbd95..973e90fb4a24 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -531,7 +531,7 @@ err: static const struct driver_info qmi_wwan_info = { .description = "WWAN/QMI device", - .flags = FLAG_WWAN, + .flags = FLAG_WWAN | FLAG_SEND_ZLP, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, @@ -540,7 +540,7 @@ static const struct driver_info qmi_wwan_info = { static const struct driver_info qmi_wwan_info_quirk_dtr = { .description = "WWAN/QMI device", - .flags = FLAG_WWAN, + .flags = FLAG_WWAN | FLAG_SEND_ZLP, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, -- cgit v1.2.3 From a50521b04da98f22d1223b8396144d48427ff2fb Mon Sep 17 00:00:00 2001 From: Stefan Potyra Date: Wed, 6 Dec 2017 16:46:12 +0100 Subject: serial: 8250_dw: Disable clock on error [ Upstream commit 8af016aa5a27c6a2505460eb4d83f1e70c38dc43 ] If there is no clock rate for uartclk defined, disable the previously enabled clock again. Found by Linux Driver Verification project (linuxtesting.org). Fixes: 23f5b3fdd04e serial: 8250_dw: only get the clock rate in one place Signed-off-by: Stefan Potyra Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 459d726f9d59..3eb01a719d22 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -464,7 +464,8 @@ static int dw8250_probe(struct platform_device *pdev) /* If no clock rate is defined, fail. */ if (!p->uartclk) { dev_err(dev, "clock rate not defined\n"); - return -EINVAL; + err = -EINVAL; + goto err_clk; } data->pclk = devm_clk_get(dev, "apb_pclk"); -- cgit v1.2.3 From 32dc29cf72e866fafca3a12ea821954632a0edca Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 4 Dec 2017 15:49:48 +0100 Subject: cros_ec: fix nul-termination for firmware build info [ Upstream commit 50a0d71a5d20e1d3eff1d974fdc8559ad6d74892 ] As gcc-8 reports, we zero out the wrong byte: drivers/platform/chrome/cros_ec_sysfs.c: In function 'show_ec_version': drivers/platform/chrome/cros_ec_sysfs.c:190:12: error: array subscript 4294967295 is above array bounds of 'uint8_t[]' [-Werror=array-bounds] This changes the code back to what it did before changing to a zero-length array structure. Fixes: a841178445bb ("mfd: cros_ec: Use a zero-length array for command data") Signed-off-by: Arnd Bergmann Signed-off-by: Benson Leung Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/platform/chrome/cros_ec_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index f3baf9973989..24f1630a8b3f 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -187,7 +187,7 @@ static ssize_t show_ec_version(struct device *dev, count += scnprintf(buf + count, PAGE_SIZE - count, "Build info: EC error %d\n", msg->result); else { - msg->data[sizeof(msg->data) - 1] = '\0'; + msg->data[EC_HOST_PARAM_SIZE - 1] = '\0'; count += scnprintf(buf + count, PAGE_SIZE - count, "Build info: %s\n", msg->data); } -- cgit v1.2.3 From 6ad31f858328e0c4257c3b0367271d7e99d16af2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Sep 2017 09:17:01 -0700 Subject: watchdog: Fix potential kref imbalance when opening watchdog [ Upstream commit 4bcd615fad6adddc68b058d498b30a9e0e0db77a ] If a watchdog driver's open function sets WDOG_HW_RUNNING with the expectation that the watchdog can not be stopped, but then stops the watchdog anyway in its stop function, kref_get() wil not be called in watchdog_open(). If the watchdog then stops on close, WDOG_HW_RUNNING will be cleared and kref_put() will be called, causing a kref imbalance. As result the character device data structure will be released, which in turn will cause the system to crash on the next call to watchdog_open(). Fixes: ee142889e32f5 ("watchdog: Introduce WDOG_HW_RUNNING flag") Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/watchdog_dev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 32930a073a12..977fe74e5abe 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -760,6 +760,7 @@ static int watchdog_open(struct inode *inode, struct file *file) { struct watchdog_core_data *wd_data; struct watchdog_device *wdd; + bool hw_running; int err; /* Get the corresponding watchdog device */ @@ -779,7 +780,8 @@ static int watchdog_open(struct inode *inode, struct file *file) * If the /dev/watchdog device is open, we don't want the module * to be unloaded. */ - if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) { + hw_running = watchdog_hw_running(wdd); + if (!hw_running && !try_module_get(wdd->ops->owner)) { err = -EBUSY; goto out_clear; } @@ -790,7 +792,7 @@ static int watchdog_open(struct inode *inode, struct file *file) file->private_data = wd_data; - if (!watchdog_hw_running(wdd)) + if (!hw_running) kref_get(&wd_data->kref); /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ -- cgit v1.2.3 From 236738a6df2c87a8e3d5553ba93b7465cd9a0f4c Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Fri, 8 Sep 2017 13:50:11 -0700 Subject: platform/chrome: Use proper protocol transfer function [ Upstream commit d48b8c58c57f6edbe2965f0a5f62c5cf9593ca96 ] pkt_xfer should be used for protocol v3, and cmd_xfer otherwise. We had one instance of these functions correct, but not the second, fall-back case. We use the fall-back only when the first command returns an IN_PROGRESS status, which is only used on some EC firmwares where we don't want to constantly poll the bus, but instead back off and sleep/retry for a little while. Fixes: 2c7589af3c4d ("mfd: cros_ec: add proto v3 skeleton") Signed-off-by: Shawn Nematbakhsh Signed-off-by: Brian Norris Reviewed-by: Javier Martinez Canillas Signed-off-by: Benson Leung Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/platform/chrome/cros_ec_proto.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 04053fe1e980..cfa3e850c49f 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -60,12 +60,14 @@ static int send_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { int ret; + int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg); if (ec_dev->proto_version > 2) - ret = ec_dev->pkt_xfer(ec_dev, msg); + xfer_fxn = ec_dev->pkt_xfer; else - ret = ec_dev->cmd_xfer(ec_dev, msg); + xfer_fxn = ec_dev->cmd_xfer; + ret = (*xfer_fxn)(ec_dev, msg); if (msg->result == EC_RES_IN_PROGRESS) { int i; struct cros_ec_command *status_msg; @@ -88,7 +90,7 @@ static int send_command(struct cros_ec_device *ec_dev, for (i = 0; i < EC_COMMAND_RETRIES; i++) { usleep_range(10000, 11000); - ret = ec_dev->cmd_xfer(ec_dev, status_msg); + ret = (*xfer_fxn)(ec_dev, status_msg); if (ret < 0) break; -- cgit v1.2.3 From 2d443c9ee9f71fb37f5dac530b868b1ea27d202e Mon Sep 17 00:00:00 2001 From: Kedareswara rao Appana Date: Thu, 7 Dec 2017 10:54:28 +0530 Subject: dmaengine: zynqmp_dma: Fix race condition in the probe [ Upstream commit 5ba080aada5e739165e0f38d5cc3b04c82b323c8 ] Incase of interrupt property is not present, Driver is trying to free an invalid irq, This patch fixes it by adding a check before freeing the irq. Signed-off-by: Kedareswara rao Appana Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/dma/xilinx/zynqmp_dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index 6d221e5c72ee..22658057fe27 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -933,7 +933,8 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan) if (!chan) return; - devm_free_irq(chan->zdev->dev, chan->irq, chan); + if (chan->irq) + devm_free_irq(chan->zdev->dev, chan->irq, chan); tasklet_kill(&chan->tasklet); list_del(&chan->common.device_node); clk_disable_unprepare(chan->clk_apb); -- cgit v1.2.3 From e7425b35a374cc25c18654c76ff7a88835e11380 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Tue, 5 Dec 2017 16:30:51 -0700 Subject: drm/tilcdc: ensure nonatomic iowrite64 is not used [ Upstream commit 4e5ca2d930aa8714400aedf4bf1dc959cb04280f ] Add a check to ensure iowrite64 is only used if it is atomic. It was decided in [1] that the tilcdc driver should not be using an atomic operation (so it was left out of this patchset). However, it turns out that through the drm code, a nonatomic header is actually included: include/linux/io-64-nonatomic-lo-hi.h is included from include/drm/drm_os_linux.h:9:0, from include/drm/drmP.h:74, from include/drm/drm_modeset_helper.h:26, from include/drm/drm_atomic_helper.h:33, from drivers/gpu/drm/tilcdc/tilcdc_crtc.c:19: And thus, without this change, this patchset would inadvertantly change the behaviour of the tilcdc driver. [1] lkml.kernel.org/r/CAK8P3a2HhO_zCnsTzq7hmWSz5La5Thu19FWZpun16iMnyyNreQ@mail.gmail.com Signed-off-by: Logan Gunthorpe Reviewed-by: Andy Shevchenko Cc: Jyri Sarha Cc: Arnd Bergmann Cc: Tomi Valkeinen Cc: David Airlie Signed-off-by: Jyri Sarha Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/tilcdc/tilcdc_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h index f57c0d62c76a..19d8dc3cdd40 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h @@ -124,7 +124,7 @@ static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data) struct tilcdc_drm_private *priv = dev->dev_private; volatile void __iomem *addr = priv->mmio + reg; -#ifdef iowrite64 +#if defined(iowrite64) && !defined(iowrite64_is_nonatomic) iowrite64(data, addr); #else __iowmb(); -- cgit v1.2.3 From 963f3129a189213876200d46e5698638d44c5e11 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 12 Dec 2017 10:49:02 +0000 Subject: mmc: avoid removing non-removable hosts during suspend [ Upstream commit de8dcc3d2c0e08e5068ee1e26fc46415c15e3637 ] The Weibu F3C MiniPC has an onboard AP6255 module, presenting two SDIO functions on a single MMC host (Bluetooth/btsdio and WiFi/brcmfmac), and the mmc layer correctly detects this as non-removable. After suspend/resume, the wifi and bluetooth interfaces disappear and do not get probed again. The conditions here are: 1. During suspend, we reach mmc_pm_notify() 2. mmc_pm_notify() calls mmc_sdio_pre_suspend() to see if we can suspend the SDIO host. However, mmc_sdio_pre_suspend() returns -ENOSYS because btsdio_driver does not have a suspend method. 3. mmc_pm_notify() proceeds to remove the card 4. Upon resume, mmc_rescan() does nothing with this host, because of the rescan_entered check which aims to only scan a non-removable device a single time (i.e. during boot). Fix the loss of functionality by detecting that we are unable to suspend a non-removable host, so avoid the forced removal in that case. The comment above this function already indicates that this code was only intended for removable devices. Signed-off-by: Daniel Drake Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/core/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 2553d903a82b..cff5829790c9 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2974,6 +2974,14 @@ static int mmc_pm_notify(struct notifier_block *notify_block, if (!err) break; + if (!mmc_card_is_removable(host)) { + dev_warn(mmc_dev(host), + "pre_suspend failed for non-removable host: " + "%d\n", err); + /* Avoid removing non-removable hosts */ + break; + } + /* Calling bus_ops->remove() with a claimed host can deadlock */ host->bus_ops->remove(host); mmc_claim_host(host); -- cgit v1.2.3 From 15e113da626f0c91cb003c597c1be57eac5fd576 Mon Sep 17 00:00:00 2001 From: Erez Shitrit Date: Tue, 14 Nov 2017 14:51:53 +0200 Subject: IB/ipoib: Avoid memory leak if the SA returns a different DGID [ Upstream commit 439000892ee17a9c92f1e4297818790ef8bb4ced ] The ipoib path database is organized around DGIDs from the LLADDR, but the SA is free to return a different GID when asked for path. This causes a bug because the SA's modified DGID is copied into the database key, even though it is no longer the correct lookup key, causing a memory leak and other malfunctions. Ensure the database key does not change after the SA query completes. Demonstration of the bug is as follows ipoib wants to send to GID fe80:0000:0000:0000:0002:c903:00ef:5ee2, it creates new record in the DB with that gid as a key, and issues a new request to the SM. Now, the SM from some reason returns path-record with other SGID (for example, 2001:0000:0000:0000:0002:c903:00ef:5ee2 that contains the local subnet prefix) now ipoib will overwrite the current entry with the new one, and if new request to the original GID arrives ipoib will not find it in the DB (was overwritten) and will create new record that in its turn will also be overwritten by the response from the SM, and so on till the driver eats all the device memory. Signed-off-by: Erez Shitrit Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index e37e918cb935..0df7d4504c06 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -799,6 +799,22 @@ static void path_rec_completion(int status, spin_lock_irqsave(&priv->lock, flags); if (!IS_ERR_OR_NULL(ah)) { + /* + * pathrec.dgid is used as the database key from the LLADDR, + * it must remain unchanged even if the SA returns a different + * GID to use in the AH. + */ + if (memcmp(pathrec->dgid.raw, path->pathrec.dgid.raw, + sizeof(union ib_gid))) { + ipoib_dbg( + priv, + "%s got PathRec for gid %pI6 while asked for %pI6\n", + dev->name, pathrec->dgid.raw, + path->pathrec.dgid.raw); + memcpy(pathrec->dgid.raw, path->pathrec.dgid.raw, + sizeof(union ib_gid)); + } + path->pathrec = *pathrec; old_ah = path->ah; -- cgit v1.2.3 From 211a1e9f5efc7eafbe24ddb5601c71e5325db435 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Tue, 14 Nov 2017 14:51:55 +0200 Subject: RDMA/cma: Use correct size when writing netlink stats [ Upstream commit 7baaa49af3716fb31877c61f59b74d029ce15b75 ] The code was using the src size when formatting the dst. They are almost certainly the same value but it reads wrong. Fixes: ce117ffac2e9 ("RDMA/cma: Export AF_IB statistics") Signed-off-by: Parav Pandit Reviewed-by: Daniel Jurgens Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 30f01613b518..de3d08c24715 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4336,7 +4336,7 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb) RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) goto out; if (ibnl_put_attr(skb, nlh, - rdma_addr_size(cma_src_addr(id_priv)), + rdma_addr_size(cma_dst_addr(id_priv)), cma_dst_addr(id_priv), RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) goto out; -- cgit v1.2.3 From 37c704e0ec7f33599866d41921379ffa8d8a7a9e Mon Sep 17 00:00:00 2001 From: Artemy Kovalyov Date: Tue, 14 Nov 2017 14:51:59 +0200 Subject: IB/umem: Fix use of npages/nmap fields [ Upstream commit edf1a84fe37c51290e2c88154ecaf48dadff3d27 ] In ib_umem structure npages holds original number of sg entries, while nmap is number of DMA blocks returned by dma_map_sg. Fixes: c5d76f130b28 ('IB/core: Add umem function to read data from user-space') Signed-off-by: Artemy Kovalyov Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/umem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 8e973a2993a6..e74aa1d60fdb 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -357,7 +357,7 @@ int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, return -EINVAL; } - ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length, + ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->npages, dst, length, offset + ib_umem_offset(umem)); if (ret < 0) -- cgit v1.2.3 From eba1940e654b8218c08ac575edb24865c1dc32c0 Mon Sep 17 00:00:00 2001 From: Bharat Potnuri Date: Tue, 28 Nov 2017 23:58:07 +0530 Subject: iser-target: avoid reinitializing rdma contexts for isert commands [ Upstream commit 66f53e6f5400578bae58db0c06d85a8820831f40 ] isert commands that failed during isert_rdma_rw_ctx_post() are queued to Queue-Full(QF) queue and are scheduled to be reposted during queue-full queue processing. During this reposting, the rdma contexts are initialised again in isert_rdma_rw_ctx_post(), which is leaking significant memory. unreferenced object 0xffff8830201d9640 (size 64): comm "kworker/0:2", pid 195, jiffies 4295374851 (age 4528.436s) hex dump (first 32 bytes): 00 60 8b cb 2e 00 00 00 00 10 00 00 00 00 00 00 .`.............. 00 90 e3 cb 2e 00 00 00 00 10 00 00 00 00 00 00 ................ backtrace: [] kmemleak_alloc+0x4e/0xb0 [] __kmalloc+0x125/0x2b0 [] rdma_rw_ctx_init+0x15f/0x6f0 [ib_core] [] isert_rdma_rw_ctx_post+0xc4/0x3c0 [ib_isert] [] isert_put_datain+0x112/0x1c0 [ib_isert] [] lio_queue_data_in+0x2e/0x30 [iscsi_target_mod] [] target_qf_do_work+0x2b2/0x4b0 [target_core_mod] [] process_one_work+0x1db/0x5d0 [] worker_thread+0x4d/0x3e0 [] kthread+0x117/0x150 [] ret_from_fork+0x27/0x40 [] 0xffffffffffffffff Here is patch to use the older rdma contexts while reposting the isert commands intead of reinitialising them. Signed-off-by: Potnuri Bharat Teja Reviewed-by: Sagi Grimberg Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/isert/ib_isert.c | 7 +++++++ drivers/infiniband/ulp/isert/ib_isert.h | 1 + 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 0983470929bd..b879d21b7548 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -2098,6 +2098,9 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn, u32 rkey, offset; int ret; + if (cmd->ctx_init_done) + goto rdma_ctx_post; + if (dir == DMA_FROM_DEVICE) { addr = cmd->write_va; rkey = cmd->write_stag; @@ -2125,11 +2128,15 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn, se_cmd->t_data_sg, se_cmd->t_data_nents, offset, addr, rkey, dir); } + if (ret < 0) { isert_err("Cmd: %p failed to prepare RDMA res\n", cmd); return ret; } + cmd->ctx_init_done = true; + +rdma_ctx_post: ret = rdma_rw_ctx_post(&cmd->rw, conn->qp, port_num, cqe, chain_wr); if (ret < 0) isert_err("Cmd: %p failed to post RDMA res\n", cmd); diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index c02ada57d7f5..85bd19753d55 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -124,6 +124,7 @@ struct isert_cmd { struct rdma_rw_ctx rw; struct work_struct comp_work; struct scatterlist sg; + bool ctx_init_done; }; static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc) -- cgit v1.2.3 From 87408eb1eae7c59e81e6e3efeadde168d3b3f130 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 1 Dec 2017 11:06:39 -0600 Subject: vgacon: Set VGA struct resource types [ Upstream commit c82084117f79bcae085e40da526253736a247120 ] Set the resource type when we reserve VGA-related I/O port resources. The resource code doesn't actually look at the type, so it inserts resources without a type in the tree correctly even without this change. But if we ever print a resource without a type, it looks like this: vga+ [??? 0x000003c0-0x000003df flags 0x0] Setting the type means it will be printed correctly as: vga+ [io 0x000003c0-0x000003df] Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/vgacon.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 11576611a974..dda1c4b3a229 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -405,7 +405,10 @@ static const char *vgacon_startup(void) vga_video_port_val = VGA_CRT_DM; if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { static struct resource ega_console_resource = - { .name = "ega", .start = 0x3B0, .end = 0x3BF }; + { .name = "ega", + .flags = IORESOURCE_IO, + .start = 0x3B0, + .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; vga_vram_size = 0x8000; display_desc = "EGA+"; @@ -413,9 +416,15 @@ static const char *vgacon_startup(void) &ega_console_resource); } else { static struct resource mda1_console_resource = - { .name = "mda", .start = 0x3B0, .end = 0x3BB }; + { .name = "mda", + .flags = IORESOURCE_IO, + .start = 0x3B0, + .end = 0x3BB }; static struct resource mda2_console_resource = - { .name = "mda", .start = 0x3BF, .end = 0x3BF }; + { .name = "mda", + .flags = IORESOURCE_IO, + .start = 0x3BF, + .end = 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; vga_vram_size = 0x2000; display_desc = "*MDA"; @@ -437,15 +446,21 @@ static const char *vgacon_startup(void) vga_vram_size = 0x8000; if (!screen_info.orig_video_isVGA) { - static struct resource ega_console_resource - = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; + static struct resource ega_console_resource = + { .name = "ega", + .flags = IORESOURCE_IO, + .start = 0x3C0, + .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; display_desc = "EGA"; request_resource(&ioport_resource, &ega_console_resource); } else { - static struct resource vga_console_resource - = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; + static struct resource vga_console_resource = + { .name = "vga+", + .flags = IORESOURCE_IO, + .start = 0x3C0, + .end = 0x3DF }; vga_video_type = VIDEO_TYPE_VGAC; display_desc = "VGA+"; request_resource(&ioport_resource, @@ -489,7 +504,10 @@ static const char *vgacon_startup(void) } } else { static struct resource cga_console_resource = - { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; + { .name = "cga", + .flags = IORESOURCE_IO, + .start = 0x3D4, + .end = 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; vga_vram_size = 0x2000; display_desc = "*CGA"; -- cgit v1.2.3 From 4ae338d139874259807f686738b02cb25a863535 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Tue, 28 Nov 2017 16:48:54 +0100 Subject: omapdrm: panel: fix compatible vendor string for td028ttec1 [ Upstream commit c1b9d4c75cd549e08bd0596d7f9dcc20f7f6e8fa ] The vendor name was "toppoly" but other panels and the vendor list have defined it as "tpo". So let's fix it in driver and bindings. We keep the old definition in parallel to stay compatible with potential older DTB setup. Signed-off-by: H. Nikolaus Schaller Signed-off-by: Tomi Valkeinen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 3 +++ drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c index e859b3f893f7..6112c32b994f 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c @@ -456,6 +456,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi) } static const struct of_device_id td028ttec1_of_match[] = { + { .compatible = "omapdss,tpo,td028ttec1", }, + /* keep to not break older DTB */ { .compatible = "omapdss,toppoly,td028ttec1", }, {}, }; @@ -475,6 +477,7 @@ static struct spi_driver td028ttec1_spi_driver = { module_spi_driver(td028ttec1_spi_driver); +MODULE_ALIAS("spi:tpo,td028ttec1"); MODULE_ALIAS("spi:toppoly,td028ttec1"); MODULE_AUTHOR("H. Nikolaus Schaller "); MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver"); diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c index b529a8c2b652..3984716096aa 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c @@ -455,6 +455,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi) } static const struct of_device_id td028ttec1_of_match[] = { + { .compatible = "omapdss,tpo,td028ttec1", }, + /* keep to not break older DTB */ { .compatible = "omapdss,toppoly,td028ttec1", }, {}, }; @@ -474,6 +476,7 @@ static struct spi_driver td028ttec1_spi_driver = { module_spi_driver(td028ttec1_spi_driver); +MODULE_ALIAS("spi:tpo,td028ttec1"); MODULE_ALIAS("spi:toppoly,td028ttec1"); MODULE_AUTHOR("H. Nikolaus Schaller "); MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver"); -- cgit v1.2.3 From abb3ee3ac5926b271af968737026674f24a90743 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 29 Sep 2017 14:49:49 +0300 Subject: drm/omap: DMM: Check for DMM readiness after successful transaction commit [ Upstream commit b7ea6b286c4051e043f691781785e3c4672f014a ] Check the status of the DMM engine after it is reported that the transaction was completed as in rare cases the engine might not reached a working state. The wait_status() will print information in case the DMM is not reached the expected state and the dmm_txn_commit() will return with an error code to make sure that we are not continuing with a broken setup. Signed-off-by: Peter Ujfalusi Signed-off-by: Tomi Valkeinen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index 4b83e9eeab06..7def04049498 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -298,7 +298,12 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) msecs_to_jiffies(100))) { dev_err(dmm->dev, "timed out waiting for done\n"); ret = -ETIMEDOUT; + goto cleanup; } + + /* Check the engine status before continue */ + ret = wait_status(engine, DMM_PATSTATUS_READY | + DMM_PATSTATUS_VALID | DMM_PATSTATUS_DONE); } cleanup: -- cgit v1.2.3 From d69cf8561fb995be0e72da6c92e206f342707d67 Mon Sep 17 00:00:00 2001 From: Sahara Date: Wed, 13 Dec 2017 09:10:48 +0400 Subject: pty: cancel pty slave port buf's work in tty_release [ Upstream commit 2b022ab7542df60021ab57854b3faaaf42552eaf ] In case that CONFIG_SLUB_DEBUG is on and pty is used, races between release_one_tty and flush_to_ldisc work threads may happen and lead to use-after-free condition on tty->link->port. Because SLUB_DEBUG is turned on, freed tty->link->port is filled with POISON_FREE value. So far without SLUB_DEBUG, port was filled with zero and flush_to_ldisc could return without a problem by checking if tty is NULL. CPU 0 CPU 1 ----- ----- release_tty pty_write cancel_work_sync(tty) to = tty->link tty_kref_put(tty->link) tty_schedule_flip(to->port) << workqueue >> ... release_one_tty ... pty_cleanup ... kfree(tty->link->port) << workqueue >> flush_to_ldisc tty = READ_ONCE(port->itty) tty is 0x6b6b6b6b6b6b6b6b !!PANIC!! access tty->ldisc Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b93 pgd = ffffffc0eb1c3000 [6b6b6b6b6b6b6b93] *pgd=0000000000000000, *pud=0000000000000000 ------------[ cut here ]------------ Kernel BUG at ffffff800851154c [verbose debug info unavailable] Internal error: Oops - BUG: 96000004 [#1] PREEMPT SMP CPU: 3 PID: 265 Comm: kworker/u8:9 Tainted: G W 3.18.31-g0a58eeb #1 Hardware name: Qualcomm Technologies, Inc. MSM 8996pro v1.1 + PMI8996 Carbide (DT) Workqueue: events_unbound flush_to_ldisc task: ffffffc0ed610ec0 ti: ffffffc0ed624000 task.ti: ffffffc0ed624000 PC is at ldsem_down_read_trylock+0x0/0x4c LR is at tty_ldisc_ref+0x24/0x4c pc : [] lr : [] pstate: 80400145 sp : ffffffc0ed627cd0 x29: ffffffc0ed627cd0 x28: 0000000000000000 x27: ffffff8009e05000 x26: ffffffc0d382cfa0 x25: 0000000000000000 x24: ffffff800a012f08 x23: 0000000000000000 x22: ffffffc0703fbc88 x21: 6b6b6b6b6b6b6b6b x20: 6b6b6b6b6b6b6b93 x19: 0000000000000000 x18: 0000000000000001 x17: 00e80000f80d6f53 x16: 0000000000000001 x15: 0000007f7d826fff x14: 00000000000000a0 x13: 0000000000000000 x12: 0000000000000109 x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffc0ed624000 x8 : ffffffc0ed611580 x7 : 0000000000000000 x6 : ffffff800a42e000 x5 : 00000000000003fc x4 : 0000000003bd1201 x3 : 0000000000000001 x2 : 0000000000000001 x1 : ffffff800851004c x0 : 6b6b6b6b6b6b6b93 Signed-off-by: Sahara Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 8d9f9a803b42..fb9bada5f1d5 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1702,6 +1702,8 @@ static void release_tty(struct tty_struct *tty, int idx) if (tty->link) tty->link->port->itty = NULL; tty_buffer_cancel_work(tty->port); + if (tty->link) + tty_buffer_cancel_work(tty->link->port); tty_kref_put(tty->link); tty_kref_put(tty); -- cgit v1.2.3 From ba936f25f95378142e854cc70e35375a452815a9 Mon Sep 17 00:00:00 2001 From: Robert Walker Date: Mon, 18 Dec 2017 11:05:44 -0700 Subject: coresight: Fix disabling of CoreSight TPIU [ Upstream commit 11595db8e17faaa05fadc25746c870e31276962f ] The CoreSight TPIU should be disabled when tracing to other sinks to allow them to operate at full bandwidth. This patch fixes tpiu_disable_hw() to correctly disable the TPIU by configuring the TPIU to stop on flush, initiating a manual flush, waiting for the flush to complete and then waits for the TPIU to indicate it has stopped. Signed-off-by: Robert Walker Tested-by: Mike Leach Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tpiu.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 0673baf0f2f5..ff579a7c6d00 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -46,8 +46,11 @@ #define TPIU_ITATBCTR0 0xef8 /** register definition **/ +/* FFSR - 0x300 */ +#define FFSR_FT_STOPPED BIT(1) /* FFCR - 0x304 */ #define FFCR_FON_MAN BIT(6) +#define FFCR_STOP_FI BIT(12) /** * @base: memory mapped base address for this component. @@ -85,10 +88,14 @@ static void tpiu_disable_hw(struct tpiu_drvdata *drvdata) { CS_UNLOCK(drvdata->base); - /* Clear formatter controle reg. */ - writel_relaxed(0x0, drvdata->base + TPIU_FFCR); + /* Clear formatter and stop on flush */ + writel_relaxed(FFCR_STOP_FI, drvdata->base + TPIU_FFCR); /* Generate manual flush */ - writel_relaxed(FFCR_FON_MAN, drvdata->base + TPIU_FFCR); + writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR); + /* Wait for flush to complete */ + coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN, 0); + /* Wait for formatter to stop */ + coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED, 1); CS_LOCK(drvdata->base); } -- cgit v1.2.3 From bd6552cfc5f7fce149a9bda2a5438a486db14831 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 1 Mar 2017 10:32:57 -0800 Subject: pinctrl: Really force states during suspend/resume [ Upstream commit 981ed1bfbc6c4660b2ddaa8392893e20a6255048 ] In case a platform only defaults a "default" set of pins, but not a "sleep" set of pins, and this particular platform suspends and resumes in a way that the pin states are not preserved by the hardware, when we resume, we would call pinctrl_single_resume() -> pinctrl_force_default() -> pinctrl_select_state() and the first thing we do is check that the pins state is the same as before, and do nothing. In order to fix this, decouple the actual state change from pinctrl_select_state() and move it pinctrl_commit_state(), while keeping the p->state == state check in pinctrl_select_state() not to change the caller assumptions. pinctrl_force_sleep() and pinctrl_force_default() are updated to bypass the state check by calling pinctrl_commit_state(). [Linus Walleij] The forced pin control states are currently only used in some pin controller drivers that grab their own reference to their own pins. This is equal to the pin control hogs: pins taken by pin control devices since there are no corresponding device in the Linux device hierarchy, such as memory controller lines or unused GPIO lines, or GPIO lines that are used orthogonally from the GPIO subsystem but pincontrol-wise managed as hogs (non-strict mode, allowing simultaneous use by GPIO and pin control). For this case forcing the state from the drivers' suspend()/resume() callbacks makes sense and should semantically match the name of the function. Fixes: 6e5e959dde0d ("pinctrl: API changes to support multiple states per device") Signed-off-by: Florian Fainelli Reviewed-by: Andy Shevchenko Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/core.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index fb38e208f32d..735d8f7f9d71 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -992,19 +992,16 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, EXPORT_SYMBOL_GPL(pinctrl_lookup_state); /** - * pinctrl_select_state() - select/activate/program a pinctrl state to HW + * pinctrl_commit_state() - select/activate/program a pinctrl state to HW * @p: the pinctrl handle for the device that requests configuration * @state: the state handle to select/activate/program */ -int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) { struct pinctrl_setting *setting, *setting2; struct pinctrl_state *old_state = p->state; int ret; - if (p->state == state) - return 0; - if (p->state) { /* * For each pinmux setting in the old state, forget SW's record @@ -1068,6 +1065,19 @@ unapply_new_state: return ret; } + +/** + * pinctrl_select_state() - select/activate/program a pinctrl state to HW + * @p: the pinctrl handle for the device that requests configuration + * @state: the state handle to select/activate/program + */ +int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +{ + if (p->state == state) + return 0; + + return pinctrl_commit_state(p, state); +} EXPORT_SYMBOL_GPL(pinctrl_select_state); static void devm_pinctrl_release(struct device *dev, void *res) @@ -1236,7 +1246,7 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) int pinctrl_force_sleep(struct pinctrl_dev *pctldev) { if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep)) - return pinctrl_select_state(pctldev->p, pctldev->hog_sleep); + return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep); return 0; } EXPORT_SYMBOL_GPL(pinctrl_force_sleep); @@ -1248,7 +1258,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep); int pinctrl_force_default(struct pinctrl_dev *pctldev) { if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default)) - return pinctrl_select_state(pctldev->p, pctldev->hog_default); + return pinctrl_commit_state(pctldev->p, pctldev->hog_default); return 0; } EXPORT_SYMBOL_GPL(pinctrl_force_default); -- cgit v1.2.3 From f03b94ef0e8792e06a0212912b1117f26cdc6dda Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 12 Dec 2017 09:43:43 -0800 Subject: pinctrl: rockchip: enable clock when reading pin direction register [ Upstream commit 5c9d8c4f6b8168738a26bcf288516cc3a0886810 ] We generally leave the GPIO clock disabled, unless an interrupt is requested or we're accessing IO registers. We forgot to do this for the ->get_direction() callback, which means we can sometimes [1] get incorrect results [2] from, e.g., /sys/kernel/debug/gpio. Enable the clock, so we get the right results! [1] Sometimes, because many systems have 1 or mor interrupt requested on each GPIO bank, so they always leave their clock on. [2] Incorrect, meaning the register returns 0, and so we interpret that as "input". Signed-off-by: Brian Norris Reviewed-by: Heiko Stuebner Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-rockchip.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 49bf7dcb7ed8..f826793e972c 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1278,8 +1278,16 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset) { struct rockchip_pin_bank *bank = gpiochip_get_data(chip); u32 data; + int ret; + ret = clk_enable(bank->clk); + if (ret < 0) { + dev_err(bank->drvdata->dev, + "failed to enable clock for bank %s\n", bank->name); + return ret; + } data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); + clk_disable(bank->clk); return !(data & BIT(offset)); } -- cgit v1.2.3 From 62088f53b14ff275c32e5c9efb95dbab9e8423c8 Mon Sep 17 00:00:00 2001 From: Jerry Snitselaar Date: Wed, 20 Dec 2017 09:48:56 -0700 Subject: iommu/vt-d: clean up pr_irq if request_threaded_irq fails [ Upstream commit 72d548113881dd32bf7f0b221d031e6586468437 ] It is unlikely request_threaded_irq will fail, but if it does for some reason we should clear iommu->pr_irq in the error path. Also intel_svm_finish_prq shouldn't try to clean up the page request interrupt if pr_irq is 0. Without these, if request_threaded_irq were to fail the following occurs: fail with no fixes: [ 0.683147] ------------[ cut here ]------------ [ 0.683148] NULL pointer, cannot free irq [ 0.683158] WARNING: CPU: 1 PID: 1 at kernel/irq/irqdomain.c:1632 irq_domain_free_irqs+0x126/0x140 [ 0.683160] Modules linked in: [ 0.683163] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2 #3 [ 0.683165] Hardware name: /NUC7i3BNB, BIOS BNKBL357.86A.0036.2017.0105.1112 01/05/2017 [ 0.683168] RIP: 0010:irq_domain_free_irqs+0x126/0x140 [ 0.683169] RSP: 0000:ffffc90000037ce8 EFLAGS: 00010292 [ 0.683171] RAX: 000000000000001d RBX: ffff880276283c00 RCX: ffffffff81c5e5e8 [ 0.683172] RDX: 0000000000000001 RSI: 0000000000000096 RDI: 0000000000000246 [ 0.683174] RBP: ffff880276283c00 R08: 0000000000000000 R09: 000000000000023c [ 0.683175] R10: 0000000000000007 R11: 0000000000000000 R12: 000000000000007a [ 0.683176] R13: 0000000000000001 R14: 0000000000000000 R15: 0000010010000000 [ 0.683178] FS: 0000000000000000(0000) GS:ffff88027ec80000(0000) knlGS:0000000000000000 [ 0.683180] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.683181] CR2: 0000000000000000 CR3: 0000000001c09001 CR4: 00000000003606e0 [ 0.683182] Call Trace: [ 0.683189] intel_svm_finish_prq+0x3c/0x60 [ 0.683191] free_dmar_iommu+0x1ac/0x1b0 [ 0.683195] init_dmars+0xaaa/0xaea [ 0.683200] ? klist_next+0x19/0xc0 [ 0.683203] ? pci_do_find_bus+0x50/0x50 [ 0.683205] ? pci_get_dev_by_id+0x52/0x70 [ 0.683208] intel_iommu_init+0x498/0x5c7 [ 0.683211] pci_iommu_init+0x13/0x3c [ 0.683214] ? e820__memblock_setup+0x61/0x61 [ 0.683217] do_one_initcall+0x4d/0x1a0 [ 0.683220] kernel_init_freeable+0x186/0x20e [ 0.683222] ? set_debug_rodata+0x11/0x11 [ 0.683225] ? rest_init+0xb0/0xb0 [ 0.683226] kernel_init+0xa/0xff [ 0.683229] ret_from_fork+0x1f/0x30 [ 0.683259] Code: 89 ee 44 89 e7 e8 3b e8 ff ff 5b 5d 44 89 e7 44 89 ee 41 5c 41 5d 41 5e e9 a8 84 ff ff 48 c7 c7 a8 71 a7 81 31 c0 e8 6a d3 f9 ff <0f> ff 5b 5d 41 5c 41 5d 41 5 e c3 0f 1f 44 00 00 66 2e 0f 1f 84 [ 0.683285] ---[ end trace f7650e42792627ca ]--- with iommu->pr_irq = 0, but no check in intel_svm_finish_prq: [ 0.669561] ------------[ cut here ]------------ [ 0.669563] Trying to free already-free IRQ 0 [ 0.669573] WARNING: CPU: 3 PID: 1 at kernel/irq/manage.c:1546 __free_irq+0xa4/0x2c0 [ 0.669574] Modules linked in: [ 0.669577] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2 #4 [ 0.669579] Hardware name: /NUC7i3BNB, BIOS BNKBL357.86A.0036.2017.0105.1112 01/05/2017 [ 0.669581] RIP: 0010:__free_irq+0xa4/0x2c0 [ 0.669582] RSP: 0000:ffffc90000037cc0 EFLAGS: 00010082 [ 0.669584] RAX: 0000000000000021 RBX: 0000000000000000 RCX: ffffffff81c5e5e8 [ 0.669585] RDX: 0000000000000001 RSI: 0000000000000086 RDI: 0000000000000046 [ 0.669587] RBP: 0000000000000000 R08: 0000000000000000 R09: 000000000000023c [ 0.669588] R10: 0000000000000007 R11: 0000000000000000 R12: ffff880276253960 [ 0.669589] R13: ffff8802762538a4 R14: ffff880276253800 R15: ffff880276283600 [ 0.669593] FS: 0000000000000000(0000) GS:ffff88027ed80000(0000) knlGS:0000000000000000 [ 0.669594] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.669596] CR2: 0000000000000000 CR3: 0000000001c09001 CR4: 00000000003606e0 [ 0.669602] Call Trace: [ 0.669616] free_irq+0x30/0x60 [ 0.669620] intel_svm_finish_prq+0x34/0x60 [ 0.669623] free_dmar_iommu+0x1ac/0x1b0 [ 0.669627] init_dmars+0xaaa/0xaea [ 0.669631] ? klist_next+0x19/0xc0 [ 0.669634] ? pci_do_find_bus+0x50/0x50 [ 0.669637] ? pci_get_dev_by_id+0x52/0x70 [ 0.669639] intel_iommu_init+0x498/0x5c7 [ 0.669642] pci_iommu_init+0x13/0x3c [ 0.669645] ? e820__memblock_setup+0x61/0x61 [ 0.669648] do_one_initcall+0x4d/0x1a0 [ 0.669651] kernel_init_freeable+0x186/0x20e [ 0.669653] ? set_debug_rodata+0x11/0x11 [ 0.669656] ? rest_init+0xb0/0xb0 [ 0.669658] kernel_init+0xa/0xff [ 0.669661] ret_from_fork+0x1f/0x30 [ 0.669662] Code: 7a 08 75 0e e9 c3 01 00 00 4c 39 7b 08 74 57 48 89 da 48 8b 5a 18 48 85 db 75 ee 89 ee 48 c7 c7 78 67 a7 81 31 c0 e8 4c 37 fa ff <0f> ff 48 8b 34 24 4c 89 ef e 8 0e 4c 68 00 49 8b 46 40 48 8b 80 [ 0.669688] ---[ end trace 58a470248700f2fc ]--- Cc: Alex Williamson Cc: Joerg Roedel Cc: Ashok Raj Signed-off-by: Jerry Snitselaar Reviewed-by: Ashok Raj Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/intel-svm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index cb72e0011310..3a1c40684213 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -127,6 +127,7 @@ int intel_svm_enable_prq(struct intel_iommu *iommu) pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n", iommu->name); dmar_free_hwirq(irq); + iommu->pr_irq = 0; goto err; } dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL); @@ -142,9 +143,11 @@ int intel_svm_finish_prq(struct intel_iommu *iommu) dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL); dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL); - free_irq(iommu->pr_irq, iommu); - dmar_free_hwirq(iommu->pr_irq); - iommu->pr_irq = 0; + if (iommu->pr_irq) { + free_irq(iommu->pr_irq, iommu); + dmar_free_hwirq(iommu->pr_irq); + iommu->pr_irq = 0; + } free_pages((unsigned long)iommu->prq, PRQ_ORDER); iommu->prq = NULL; -- cgit v1.2.3 From dc445b384679db0c811d789958963962f963767f Mon Sep 17 00:00:00 2001 From: Anton Vasilyev Date: Tue, 8 Aug 2017 18:56:37 +0300 Subject: RDMA/ocrdma: Fix permissions for OCRDMA_RESET_STATS [ Upstream commit 744820869166c8c78be891240cf5f66e8a333694 ] Debugfs file reset_stats is created with S_IRUSR permissions, but ocrdma_dbgfs_ops_read() doesn't support OCRDMA_RESET_STATS, whereas ocrdma_dbgfs_ops_write() supports only OCRDMA_RESET_STATS. The patch fixes misstype with permissions. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev Acked-by: Selvin Xavier Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/ocrdma/ocrdma_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c index 8bef09a8c49f..265943069b35 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c @@ -836,7 +836,7 @@ void ocrdma_add_port_stats(struct ocrdma_dev *dev) dev->reset_stats.type = OCRDMA_RESET_STATS; dev->reset_stats.dev = dev; - if (!debugfs_create_file("reset_stats", S_IRUSR, dev->dir, + if (!debugfs_create_file("reset_stats", 0200, dev->dir, &dev->reset_stats, &ocrdma_dbg_ops)) goto err; -- cgit v1.2.3 From 9fd65f85db4565a3c8ad5728dad3e894cf4ffd11 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 2 Nov 2017 00:36:09 -0700 Subject: clk: Don't touch hardware when reparenting during registration [ Upstream commit f8f8f1d04494d3a6546bee3f0618c4dba31d7b72 ] The orphan clocks reparent operation shouldn't touch the hardware if clocks are enabled, otherwise it may get a chance to disable a newly registered critical clock which triggers the warning below. Assuming we have two clocks: A and B, B is the parent of A. Clock A has flag: CLK_OPS_PARENT_ENABLE Clock B has flag: CLK_IS_CRITICAL Step 1: Clock A is registered, then it becomes orphan. Step 2: Clock B is registered. Before clock B reach the critical clock enable operation, orphan A will find the newly registered parent B and do reparent operation, then parent B will be finally disabled in __clk_set_parent_after() due to CLK_OPS_PARENT_ENABLE flag as there's still no users of B which will then trigger the following warning. WARNING: CPU: 0 PID: 0 at drivers/clk/clk.c:597 clk_core_disable+0xb4/0xe0 Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1-00056-gdff1f66-dirty #1373 Hardware name: Generic DT based system Backtrace: [] (dump_backtrace) from [] (show_stack+0x18/0x1c) r6:600000d3 r5:00000000 r4:c0e26358 r3:00000000 [] (show_stack) from [] (dump_stack+0xb4/0xe8) [] (dump_stack) from [] (__warn+0xd8/0x104) r10:c0c21cd0 r9:c048aa78 r8:00000255 r7:00000009 r6:c0c1cd90 r5:00000000 r4:00000000 r3:c0e01d34 [] (__warn) from [] (warn_slowpath_null+0x28/0x30) r9:00000000 r8:ef00bf80 r7:c165ac4c r6:ef00bf80 r5:ef00bf80 r4:ef00bf80 [] (warn_slowpath_null) from [] (clk_core_disable+0xb4/0xe0) [] (clk_core_disable) from [] (clk_core_disable_lock+0x20/0x2c) r4:000000d3 r3:c0e0af00 [] (clk_core_disable_lock) from [] (clk_core_disable_unprepare+0x14/0x28) r5:00000000 r4:ef00bf80 [] (clk_core_disable_unprepare) from [] (__clk_set_parent_after+0x38/0x54) r4:ef00bd80 r3:000010a0 [] (__clk_set_parent_after) from [] (clk_register+0x4d0/0x648) r6:ef00d500 r5:ef00bf80 r4:ef00bd80 r3:ef00bfd4 [] (clk_register) from [] (clk_hw_register+0x10/0x1c) r9:00000000 r8:00000003 r7:00000000 r6:00000824 r5:00000001 r4:ef00d500 [] (clk_hw_register) from [] (_register_divider+0xcc/0x120) [] (_register_divider) from [] (clk_register_divider+0x44/0x54) r10:00000004 r9:00000003 r8:00000001 r7:00000000 r6:00000003 r5:00000001 r4:f0810030 [] (clk_register_divider) from [] (imx7ulp_clocks_init+0x558/0xe98) r7:c0e296f8 r6:c165c808 r5:00000000 r4:c165c808 [] (imx7ulp_clocks_init) from [] (of_clk_init+0x118/0x1e0) r10:00000001 r9:c0e01f68 r8:00000000 r7:c0e01f60 r6:ef7f8974 r5:ef0035c0 r4:00000006 [] (of_clk_init) from [] (time_init+0x2c/0x38) r10:efffed40 r9:c0d61a48 r8:c0e78000 r7:c0e07900 r6:ffffffff r5:c0e78000 r4:00000000 [] (time_init) from [] (start_kernel+0x218/0x394) [] (start_kernel) from [<6000807c>] (0x6000807c) r10:00000000 r9:410fc075 r8:6000406a r7:c0e0c930 r6:c0d61a44 r5:c0e07918 r4:c0e78294 We know that the clk isn't enabled with any sort of prepare_count here so we don't need to enable anything to prevent a race. And we're holding the prepare mutex so set_rate/set_parent can't race here either. Based on an earlier patch by Dong Aisheng. Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)") Cc: Michael Turquette Cc: Shawn Guo Reported-by: Dong Aisheng Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0fb39fe217d1..097b0db43cbd 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2443,14 +2443,17 @@ static int __clk_core_init(struct clk_core *core) */ hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { struct clk_core *parent = __clk_init_parent(orphan); + unsigned long flags; /* * we could call __clk_set_parent, but that would result in a * redundant call to the .set_rate op, if it exists */ if (parent) { - __clk_set_parent_before(orphan, parent); - __clk_set_parent_after(orphan, parent, NULL); + /* update the clk tree topology */ + flags = clk_enable_lock(); + clk_reparent(orphan, parent); + clk_enable_unlock(flags); __clk_recalc_accuracies(orphan); __clk_recalc_rates(orphan, 0); } -- cgit v1.2.3 From c53ae7d94e9a79eb6e589d02d4b1fc40fbfa5b45 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 5 Sep 2017 11:32:40 +0200 Subject: clk: axi-clkgen: Correctly handle nocount bit in recalc_rate() [ Upstream commit 063578dc5f407f67d149133818efabe457daafda ] If the nocount bit is set the divider is bypassed and the settings for the divider count should be ignored and a divider value of 1 should be assumed. Handle this correctly in the driver recalc_rate() callback. While the driver sets up the part so that the read back dividers values yield the correct result the power-on reset settings of the part might not reflect this and hence calling e.g. clk_get_rate() without prior calls to clk_set_rate() will yield the wrong result. Signed-off-by: Lars-Peter Clausen Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk-axi-clkgen.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 5e918e7afaba..95a6e9834392 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -40,6 +40,10 @@ #define MMCM_REG_FILTER1 0x4e #define MMCM_REG_FILTER2 0x4f +#define MMCM_CLKOUT_NOCOUNT BIT(6) + +#define MMCM_CLK_DIV_NOCOUNT BIT(12) + struct axi_clkgen { void __iomem *base; struct clk_hw clk_hw; @@ -315,12 +319,27 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, unsigned int reg; unsigned long long tmp; - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®); - dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, ®); + if (reg & MMCM_CLKOUT_NOCOUNT) { + dout = 1; + } else { + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®); + dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); + } + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, ®); - d = (reg & 0x3f) + ((reg >> 6) & 0x3f); - axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®); - m = (reg & 0x3f) + ((reg >> 6) & 0x3f); + if (reg & MMCM_CLK_DIV_NOCOUNT) + d = 1; + else + d = (reg & 0x3f) + ((reg >> 6) & 0x3f); + + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, ®); + if (reg & MMCM_CLKOUT_NOCOUNT) { + m = 1; + } else { + axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®); + m = (reg & 0x3f) + ((reg >> 6) & 0x3f); + } if (d == 0 || dout == 0) return 0; -- cgit v1.2.3 From bc0e7313d869e2f67b83e099d540c295a4493281 Mon Sep 17 00:00:00 2001 From: Sergej Sawazki Date: Tue, 25 Jul 2017 23:21:02 +0200 Subject: clk: si5351: Rename internal plls to avoid name collisions [ Upstream commit cdba9a4fb0b53703959ac861e415816cb61aded4 ] This drivers probe fails due to a clock name collision if a clock named 'plla' or 'pllb' is already registered when registering this drivers internal plls. Fix it by renaming internal plls to avoid name collisions. Cc: Sebastian Hesselbarth Cc: Rabeeh Khoury Signed-off-by: Sergej Sawazki Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk-si5351.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index b051db43fae1..136a86094c53 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -72,7 +72,7 @@ static const char * const si5351_input_names[] = { "xtal", "clkin" }; static const char * const si5351_pll_names[] = { - "plla", "pllb", "vxco" + "si5351_plla", "si5351_pllb", "si5351_vxco" }; static const char * const si5351_msynth_names[] = { "ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7" -- cgit v1.2.3 From 559205f2899596550b0ea19f733b59b557cc6c1e Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Tue, 19 Dec 2017 12:51:16 +0200 Subject: dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63 [ Upstream commit d087f15786021a9605b20f4c678312510be4cac1 ] Register layout of a typical TPCC_EVT_MUX_M_N register is such that the lowest numbered event is at the lowest byte address and highest numbered event at highest byte address. But TPCC_EVT_MUX_60_63 register layout is different, in that the lowest numbered event is at the highest address and highest numbered event is at the lowest address. Therefore, modify ti_am335x_xbar_write() to handle TPCC_EVT_MUX_60_63 register accordingly. Signed-off-by: Vignesh R Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/dma/ti-dma-crossbar.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index 43e88d85129e..8c3c588834d2 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -54,7 +54,15 @@ struct ti_am335x_xbar_map { static inline void ti_am335x_xbar_write(void __iomem *iomem, int event, u8 val) { - writeb_relaxed(val, iomem + event); + /* + * TPCC_EVT_MUX_60_63 register layout is different than the + * rest, in the sense, that event 63 is mapped to lowest byte + * and event 60 is mapped to highest, handle it separately. + */ + if (event >= 60 && event <= 63) + writeb_relaxed(val, iomem + (63 - event % 4)); + else + writeb_relaxed(val, iomem + event); } static void ti_am335x_xbar_free(struct device *dev, void *route_data) -- cgit v1.2.3 From e2ee1a1843e5cf0e4040d006d6895262e47332d4 Mon Sep 17 00:00:00 2001 From: Boris Pismenny Date: Thu, 8 Mar 2018 15:51:41 +0200 Subject: IB/mlx5: Fix integer overflows in mlx5_ib_create_srq commit c2b37f76485f073f020e60b5954b6dc4e55f693c upstream. This patch validates user provided input to prevent integer overflow due to integer manipulation in the mlx5_ib_create_srq function. Cc: syzkaller Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Signed-off-by: Boris Pismenny Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/srq.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c index d61fd2c727c0..5c1dbe2f8757 100644 --- a/drivers/infiniband/hw/mlx5/srq.c +++ b/drivers/infiniband/hw/mlx5/srq.c @@ -243,8 +243,8 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, { struct mlx5_ib_dev *dev = to_mdev(pd->device); struct mlx5_ib_srq *srq; - int desc_size; - int buf_size; + size_t desc_size; + size_t buf_size; int err; struct mlx5_srq_attr in = {0}; __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); @@ -268,15 +268,18 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); + if (desc_size == 0 || srq->msrq.max_gs > desc_size) + return ERR_PTR(-EINVAL); desc_size = roundup_pow_of_two(desc_size); - desc_size = max_t(int, 32, desc_size); + desc_size = max_t(size_t, 32, desc_size); + if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) + return ERR_PTR(-EINVAL); srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / sizeof(struct mlx5_wqe_data_seg); srq->msrq.wqe_shift = ilog2(desc_size); buf_size = srq->msrq.max * desc_size; - mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n", - desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs, - srq->msrq.max_avail_gather); + if (buf_size < desc_size) + return ERR_PTR(-EINVAL); in.type = init_attr->srq_type; if (pd->uobject) -- cgit v1.2.3 From 971e09c7be1c051272663cd552c4a815d6f7a151 Mon Sep 17 00:00:00 2001 From: Boris Pismenny Date: Thu, 8 Mar 2018 15:51:40 +0200 Subject: IB/mlx5: Fix out-of-bounds read in create_raw_packet_qp_rq commit 2c292dbb398ee46fc1343daf6c3cf9715a75688e upstream. Add a check for the length of the qpin structure to prevent out-of-bounds reads BUG: KASAN: slab-out-of-bounds in create_raw_packet_qp+0x114c/0x15e2 Read of size 8192 at addr ffff880066b99290 by task syz-executor3/549 CPU: 3 PID: 549 Comm: syz-executor3 Not tainted 4.15.0-rc2+ #27 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 Call Trace: dump_stack+0x8d/0xd4 print_address_description+0x73/0x290 kasan_report+0x25c/0x370 ? create_raw_packet_qp+0x114c/0x15e2 memcpy+0x1f/0x50 create_raw_packet_qp+0x114c/0x15e2 ? create_raw_packet_qp_tis.isra.28+0x13d/0x13d ? lock_acquire+0x370/0x370 create_qp_common+0x2245/0x3b50 ? destroy_qp_user.isra.47+0x100/0x100 ? kasan_kmalloc+0x13d/0x170 ? sched_clock_cpu+0x18/0x180 ? fs_reclaim_acquire.part.15+0x5/0x30 ? __lock_acquire+0xa11/0x1da0 ? sched_clock_cpu+0x18/0x180 ? kmem_cache_alloc_trace+0x17e/0x310 ? mlx5_ib_create_qp+0x30e/0x17b0 mlx5_ib_create_qp+0x33d/0x17b0 ? sched_clock_cpu+0x18/0x180 ? create_qp_common+0x3b50/0x3b50 ? lock_acquire+0x370/0x370 ? __radix_tree_lookup+0x180/0x220 ? uverbs_try_lock_object+0x68/0xc0 ? rdma_lookup_get_uobject+0x114/0x240 create_qp.isra.5+0xce4/0x1e20 ? ib_uverbs_ex_create_cq_cb+0xa0/0xa0 ? copy_ah_attr_from_uverbs.isra.2+0xa00/0xa00 ? ib_uverbs_cq_event_handler+0x160/0x160 ? __might_fault+0x17c/0x1c0 ib_uverbs_create_qp+0x21b/0x2a0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ib_uverbs_write+0x55a/0xad0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ? ib_uverbs_open+0x760/0x760 ? futex_wake+0x147/0x410 ? check_prev_add+0x1680/0x1680 ? do_futex+0x3d3/0xa60 ? sched_clock_cpu+0x18/0x180 __vfs_write+0xf7/0x5c0 ? ib_uverbs_open+0x760/0x760 ? kernel_read+0x110/0x110 ? lock_acquire+0x370/0x370 ? __fget+0x264/0x3b0 vfs_write+0x18a/0x460 SyS_write+0xc7/0x1a0 ? SyS_read+0x1a0/0x1a0 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x18/0x85 RIP: 0033:0x4477b9 RSP: 002b:00007f1822cadc18 EFLAGS: 00000292 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00000000004477b9 RDX: 0000000000000070 RSI: 000000002000a000 RDI: 0000000000000005 RBP: 0000000000708000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000292 R12: 00000000ffffffff R13: 0000000000005d70 R14: 00000000006e6e30 R15: 0000000020010ff0 Allocated by task 549: __kmalloc+0x15e/0x340 kvmalloc_node+0xa1/0xd0 create_user_qp.isra.46+0xd42/0x1610 create_qp_common+0x2e63/0x3b50 mlx5_ib_create_qp+0x33d/0x17b0 create_qp.isra.5+0xce4/0x1e20 ib_uverbs_create_qp+0x21b/0x2a0 ib_uverbs_write+0x55a/0xad0 __vfs_write+0xf7/0x5c0 vfs_write+0x18a/0x460 SyS_write+0xc7/0x1a0 entry_SYSCALL_64_fastpath+0x18/0x85 Freed by task 368: kfree+0xeb/0x2f0 kernfs_fop_release+0x140/0x180 __fput+0x266/0x700 task_work_run+0x104/0x180 exit_to_usermode_loop+0xf7/0x110 syscall_return_slowpath+0x298/0x370 entry_SYSCALL_64_fastpath+0x83/0x85 The buggy address belongs to the object at ffff880066b99180 which belongs to the cache kmalloc-512 of size 512 The buggy address is located 272 bytes inside of 512-byte region [ffff880066b99180, ffff880066b99380) The buggy address belongs to the page: page:000000006040eedd count:1 mapcount:0 mapping: (null) index:0x0 compound_mapcount: 0 flags: 0x4000000000008100(slab|head) raw: 4000000000008100 0000000000000000 0000000000000000 0000000180190019 raw: ffffea00019a7500 0000000b0000000b ffff88006c403080 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff880066b99180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff880066b99200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff880066b99280: 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff880066b99300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff880066b99380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc Cc: syzkaller Fixes: 0fb2ed66a14c ("IB/mlx5: Add create and destroy functionality for Raw Packet QP") Signed-off-by: Boris Pismenny Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/qp.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index fdd156101a72..403df3591d29 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -1130,7 +1130,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev, ib_umem_release(sq->ubuffer.umem); } -static int get_rq_pas_size(void *qpc) +static size_t get_rq_pas_size(void *qpc) { u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12; u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride); @@ -1146,7 +1146,8 @@ static int get_rq_pas_size(void *qpc) } static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev, - struct mlx5_ib_rq *rq, void *qpin) + struct mlx5_ib_rq *rq, void *qpin, + size_t qpinlen) { struct mlx5_ib_qp *mqp = rq->base.container_mibqp; __be64 *pas; @@ -1155,9 +1156,12 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev, void *rqc; void *wq; void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc); - int inlen; + size_t rq_pas_size = get_rq_pas_size(qpc); + size_t inlen; int err; - u32 rq_pas_size = get_rq_pas_size(qpc); + + if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas)) + return -EINVAL; inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size; in = mlx5_vzalloc(inlen); @@ -1235,7 +1239,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev, } static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, - u32 *in, + u32 *in, size_t inlen, struct ib_pd *pd) { struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp; @@ -1262,7 +1266,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, if (qp->rq.wqe_cnt) { rq->base.container_mibqp = qp; - err = create_raw_packet_qp_rq(dev, rq, in); + err = create_raw_packet_qp_rq(dev, rq, in, inlen); if (err) goto err_destroy_sq; @@ -1753,10 +1757,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, qp->flags |= MLX5_IB_QP_LSO; } + if (inlen < 0) { + err = -EINVAL; + goto err; + } + if (init_attr->qp_type == IB_QPT_RAW_PACKET) { qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr; raw_packet_qp_copy_info(qp, &qp->raw_packet_qp); - err = create_raw_packet_qp(dev, qp, in, pd); + err = create_raw_packet_qp(dev, qp, in, inlen, pd); } else { err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen); } @@ -1796,6 +1805,7 @@ err_create: else if (qp->create_type == MLX5_QP_KERNEL) destroy_qp_kernel(dev, qp); +err: kvfree(in); return err; } -- cgit v1.2.3 From bbdfb44745abd2daa8af06e553d7628570daf250 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 14 Feb 2018 14:43:36 +0100 Subject: clk: migrate the count of orphaned clocks at init commit 99652a469df19086d594e8e89757d4081a812789 upstream. The orphan clocks reparents should migrate any existing count from the orphan clock to its new acestor clocks, otherwise we may have inconsistent counts in the tree and end-up with gated critical clocks Assuming we have two clocks, A and B. * Clock A has CLK_IS_CRITICAL flag set. * Clock B is an ancestor of A which can gate. Clock B gate is left enabled by the bootloader. Step 1: Clock A is registered. Since it is a critical clock, it is enabled. The clock being still an orphan, no parent are enabled. Step 2: Clock B is registered and reparented to clock A (potentially through several other clocks). We are now in situation where the enable count of clock A is 1 while the enable count of its ancestors is 0, which is not good. Step 3: in lateinit, clk_disable_unused() is called, the enable_count of clock B being 0, clock B is gated and and critical clock A actually gets disabled. This situation was found while adding fdiv_clk gates to the meson8b platform. These clocks parent clk81 critical clock, which is the mother of all peripheral clocks in this system. Because of the issue described here, the system is crashing when clk_disable_unused() is called. The situation is solved by reverting commit f8f8f1d04494 ("clk: Don't touch hardware when reparenting during registration"). To avoid breaking again the situation described in this commit description, enabling critical clock should be done before walking the orphan list. This way, a parent critical clock may not be accidentally disabled due to the CLK_OPS_PARENT_ENABLE mechanism. Fixes: f8f8f1d04494 ("clk: Don't touch hardware when reparenting during registration") Cc: Stephen Boyd Cc: Shawn Guo Cc: Dong Aisheng Signed-off-by: Jerome Brunet Tested-by: Marek Szyprowski Tested-by: Heiko Stuebner Signed-off-by: Michael Turquette Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 097b0db43cbd..0cdb8550729d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2437,23 +2437,38 @@ static int __clk_core_init(struct clk_core *core) rate = 0; core->rate = core->req_rate = rate; + /* + * Enable CLK_IS_CRITICAL clocks so newly added critical clocks + * don't get accidentally disabled when walking the orphan tree and + * reparenting clocks + */ + if (core->flags & CLK_IS_CRITICAL) { + unsigned long flags; + + clk_core_prepare(core); + + flags = clk_enable_lock(); + clk_core_enable(core); + clk_enable_unlock(flags); + } + /* * walk the list of orphan clocks and reparent any that newly finds a * parent. */ hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { struct clk_core *parent = __clk_init_parent(orphan); - unsigned long flags; /* - * we could call __clk_set_parent, but that would result in a - * redundant call to the .set_rate op, if it exists + * We need to use __clk_set_parent_before() and _after() to + * to properly migrate any prepare/enable count of the orphan + * clock. This is important for CLK_IS_CRITICAL clocks, which + * are enabled during init but might not have a parent yet. */ if (parent) { /* update the clk tree topology */ - flags = clk_enable_lock(); - clk_reparent(orphan, parent); - clk_enable_unlock(flags); + __clk_set_parent_before(orphan, parent); + __clk_set_parent_after(orphan, parent, NULL); __clk_recalc_accuracies(orphan); __clk_recalc_rates(orphan, 0); } @@ -2470,16 +2485,6 @@ static int __clk_core_init(struct clk_core *core) if (core->ops->init) core->ops->init(core->hw); - if (core->flags & CLK_IS_CRITICAL) { - unsigned long flags; - - clk_core_prepare(core); - - flags = clk_enable_lock(); - clk_core_enable(core); - clk_enable_unlock(flags); - } - kref_init(&core->ref); out: clk_prepare_unlock(); -- cgit v1.2.3 From e3fb6525c99c2ac9940953f421e4e7d1e354b0e6 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 13 Mar 2018 11:43:23 +0200 Subject: RDMA/ucma: Fix access to non-initialized CM_ID object commit 7688f2c3bbf55e52388e37ac5d63ca471a7712e1 upstream. The attempt to join multicast group without ensuring that CMA device exists will lead to the following crash reported by syzkaller. [ 64.076794] BUG: KASAN: null-ptr-deref in rdma_join_multicast+0x26e/0x12c0 [ 64.076797] Read of size 8 at addr 00000000000000b0 by task join/691 [ 64.076797] [ 64.076800] CPU: 1 PID: 691 Comm: join Not tainted 4.16.0-rc1-00219-gb97853b65b93 #23 [ 64.076802] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-proj4 [ 64.076803] Call Trace: [ 64.076809] dump_stack+0x5c/0x77 [ 64.076817] kasan_report+0x163/0x380 [ 64.085859] ? rdma_join_multicast+0x26e/0x12c0 [ 64.086634] rdma_join_multicast+0x26e/0x12c0 [ 64.087370] ? rdma_disconnect+0xf0/0xf0 [ 64.088579] ? __radix_tree_replace+0xc3/0x110 [ 64.089132] ? node_tag_clear+0x81/0xb0 [ 64.089606] ? idr_alloc_u32+0x12e/0x1a0 [ 64.090517] ? __fprop_inc_percpu_max+0x150/0x150 [ 64.091768] ? tracing_record_taskinfo+0x10/0xc0 [ 64.092340] ? idr_alloc+0x76/0xc0 [ 64.092951] ? idr_alloc_u32+0x1a0/0x1a0 [ 64.093632] ? ucma_process_join+0x23d/0x460 [ 64.094510] ucma_process_join+0x23d/0x460 [ 64.095199] ? ucma_migrate_id+0x440/0x440 [ 64.095696] ? futex_wake+0x10b/0x2a0 [ 64.096159] ucma_join_multicast+0x88/0xe0 [ 64.096660] ? ucma_process_join+0x460/0x460 [ 64.097540] ? _copy_from_user+0x5e/0x90 [ 64.098017] ucma_write+0x174/0x1f0 [ 64.098640] ? ucma_resolve_route+0xf0/0xf0 [ 64.099343] ? rb_erase_cached+0x6c7/0x7f0 [ 64.099839] __vfs_write+0xc4/0x350 [ 64.100622] ? perf_syscall_enter+0xe4/0x5f0 [ 64.101335] ? kernel_read+0xa0/0xa0 [ 64.103525] ? perf_sched_cb_inc+0xc0/0xc0 [ 64.105510] ? syscall_exit_register+0x2a0/0x2a0 [ 64.107359] ? __switch_to+0x351/0x640 [ 64.109285] ? fsnotify+0x899/0x8f0 [ 64.111610] ? fsnotify_unmount_inodes+0x170/0x170 [ 64.113876] ? __fsnotify_update_child_dentry_flags+0x30/0x30 [ 64.115813] ? ring_buffer_record_is_on+0xd/0x20 [ 64.117824] ? __fget+0xa8/0xf0 [ 64.119869] vfs_write+0xf7/0x280 [ 64.122001] SyS_write+0xa1/0x120 [ 64.124213] ? SyS_read+0x120/0x120 [ 64.126644] ? SyS_read+0x120/0x120 [ 64.128563] do_syscall_64+0xeb/0x250 [ 64.130732] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 64.132984] RIP: 0033:0x7f5c994ade99 [ 64.135699] RSP: 002b:00007f5c99b97d98 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 64.138740] RAX: ffffffffffffffda RBX: 00000000200001e4 RCX: 00007f5c994ade99 [ 64.141056] RDX: 00000000000000a0 RSI: 00000000200001c0 RDI: 0000000000000015 [ 64.143536] RBP: 00007f5c99b97ec0 R08: 0000000000000000 R09: 0000000000000000 [ 64.146017] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5c99b97fc0 [ 64.148608] R13: 0000000000000000 R14: 00007fff660e1c40 R15: 00007f5c99b989c0 [ 64.151060] [ 64.153703] Disabling lock debugging due to kernel taint [ 64.156032] BUG: unable to handle kernel NULL pointer dereference at 00000000000000b0 [ 64.159066] IP: rdma_join_multicast+0x26e/0x12c0 [ 64.161451] PGD 80000001d0298067 P4D 80000001d0298067 PUD 1dea39067 PMD 0 [ 64.164442] Oops: 0000 [#1] SMP KASAN PTI [ 64.166817] CPU: 1 PID: 691 Comm: join Tainted: G B 4.16.0-rc1-00219-gb97853b65b93 #23 [ 64.170004] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-proj4 [ 64.174985] RIP: 0010:rdma_join_multicast+0x26e/0x12c0 [ 64.177246] RSP: 0018:ffff8801c8207860 EFLAGS: 00010282 [ 64.179901] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff94789522 [ 64.183344] RDX: 1ffffffff2d50fa5 RSI: 0000000000000297 RDI: 0000000000000297 [ 64.186237] RBP: ffff8801c8207a50 R08: 0000000000000000 R09: ffffed0039040ea7 [ 64.189328] R10: 0000000000000001 R11: ffffed0039040ea6 R12: 0000000000000000 [ 64.192634] R13: 0000000000000000 R14: ffff8801e2022800 R15: ffff8801d4ac2400 [ 64.196105] FS: 00007f5c99b98700(0000) GS:ffff8801e5d00000(0000) knlGS:0000000000000000 [ 64.199211] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 64.202046] CR2: 00000000000000b0 CR3: 00000001d1c48004 CR4: 00000000003606a0 [ 64.205032] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 64.208221] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 64.211554] Call Trace: [ 64.213464] ? rdma_disconnect+0xf0/0xf0 [ 64.216124] ? __radix_tree_replace+0xc3/0x110 [ 64.219337] ? node_tag_clear+0x81/0xb0 [ 64.222140] ? idr_alloc_u32+0x12e/0x1a0 [ 64.224422] ? __fprop_inc_percpu_max+0x150/0x150 [ 64.226588] ? tracing_record_taskinfo+0x10/0xc0 [ 64.229763] ? idr_alloc+0x76/0xc0 [ 64.232186] ? idr_alloc_u32+0x1a0/0x1a0 [ 64.234505] ? ucma_process_join+0x23d/0x460 [ 64.237024] ucma_process_join+0x23d/0x460 [ 64.240076] ? ucma_migrate_id+0x440/0x440 [ 64.243284] ? futex_wake+0x10b/0x2a0 [ 64.245302] ucma_join_multicast+0x88/0xe0 [ 64.247783] ? ucma_process_join+0x460/0x460 [ 64.250841] ? _copy_from_user+0x5e/0x90 [ 64.253878] ucma_write+0x174/0x1f0 [ 64.257008] ? ucma_resolve_route+0xf0/0xf0 [ 64.259877] ? rb_erase_cached+0x6c7/0x7f0 [ 64.262746] __vfs_write+0xc4/0x350 [ 64.265537] ? perf_syscall_enter+0xe4/0x5f0 [ 64.267792] ? kernel_read+0xa0/0xa0 [ 64.270358] ? perf_sched_cb_inc+0xc0/0xc0 [ 64.272575] ? syscall_exit_register+0x2a0/0x2a0 [ 64.275367] ? __switch_to+0x351/0x640 [ 64.277700] ? fsnotify+0x899/0x8f0 [ 64.280530] ? fsnotify_unmount_inodes+0x170/0x170 [ 64.283156] ? __fsnotify_update_child_dentry_flags+0x30/0x30 [ 64.286182] ? ring_buffer_record_is_on+0xd/0x20 [ 64.288749] ? __fget+0xa8/0xf0 [ 64.291136] vfs_write+0xf7/0x280 [ 64.292972] SyS_write+0xa1/0x120 [ 64.294965] ? SyS_read+0x120/0x120 [ 64.297474] ? SyS_read+0x120/0x120 [ 64.299751] do_syscall_64+0xeb/0x250 [ 64.301826] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 64.304352] RIP: 0033:0x7f5c994ade99 [ 64.306711] RSP: 002b:00007f5c99b97d98 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 64.309577] RAX: ffffffffffffffda RBX: 00000000200001e4 RCX: 00007f5c994ade99 [ 64.312334] RDX: 00000000000000a0 RSI: 00000000200001c0 RDI: 0000000000000015 [ 64.315783] RBP: 00007f5c99b97ec0 R08: 0000000000000000 R09: 0000000000000000 [ 64.318365] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5c99b97fc0 [ 64.320980] R13: 0000000000000000 R14: 00007fff660e1c40 R15: 00007f5c99b989c0 [ 64.323515] Code: e8 e8 79 08 ff 4c 89 ff 45 0f b6 a7 b8 01 00 00 e8 68 7c 08 ff 49 8b 1f 4d 89 e5 49 c1 e4 04 48 8 [ 64.330753] RIP: rdma_join_multicast+0x26e/0x12c0 RSP: ffff8801c8207860 [ 64.332979] CR2: 00000000000000b0 [ 64.335550] ---[ end trace 0c00c17a408849c1 ]--- Reported-by: Fixes: c8f6a362bf3e ("RDMA/cma: Add multicast communication support") Signed-off-by: Leon Romanovsky Reviewed-by: Sean Hefty Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/cma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index de3d08c24715..cbe5324c4331 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4039,6 +4039,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, struct cma_multicast *mc; int ret; + if (!id->device) + return -EINVAL; + id_priv = container_of(id, struct rdma_id_private, id); if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) && !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED)) -- cgit v1.2.3 From 805cbd500ee258f8c8e5c0c709389fffd70994eb Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 13 Mar 2018 18:37:27 +0200 Subject: RDMA/ucma: Don't allow join attempts for unsupported AF family commit 0c81ffc60d5280991773d17e84bda605387148b1 upstream. Users can provide garbage while calling to ucma_join_ip_multicast(), it will indirectly cause to rdma_addr_size() return 0, making the call to ucma_process_join(), which had the right checks, but it is better to check the input as early as possible. The following crash from syzkaller revealed it. kernel BUG at lib/string.c:1052! invalid opcode: 0000 [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 0 PID: 4113 Comm: syz-executor0 Not tainted 4.16.0-rc5+ #261 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:fortify_panic+0x13/0x20 lib/string.c:1051 RSP: 0018:ffff8801ca81f8f0 EFLAGS: 00010286 RAX: 0000000000000022 RBX: 1ffff10039503f23 RCX: 0000000000000000 RDX: 0000000000000022 RSI: 1ffff10039503ed3 RDI: ffffed0039503f12 RBP: ffff8801ca81f8f0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000006 R11: 0000000000000000 R12: ffff8801ca81f998 R13: ffff8801ca81f938 R14: ffff8801ca81fa58 R15: 000000000000fa00 FS: 0000000000000000(0000) GS:ffff8801db200000(0063) knlGS:000000000a12a900 CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 CR2: 0000000008138024 CR3: 00000001cbb58004 CR4: 00000000001606f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: memcpy include/linux/string.h:344 [inline] ucma_join_ip_multicast+0x36b/0x3b0 drivers/infiniband/core/ucma.c:1421 ucma_write+0x2d6/0x3d0 drivers/infiniband/core/ucma.c:1633 __vfs_write+0xef/0x970 fs/read_write.c:480 vfs_write+0x189/0x510 fs/read_write.c:544 SYSC_write fs/read_write.c:589 [inline] SyS_write+0xef/0x220 fs/read_write.c:581 do_syscall_32_irqs_on arch/x86/entry/common.c:330 [inline] do_fast_syscall_32+0x3ec/0xf9f arch/x86/entry/common.c:392 entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139 RIP: 0023:0xf7f9ec99 RSP: 002b:00000000ff8172cc EFLAGS: 00000282 ORIG_RAX: 0000000000000004 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000020000100 RDX: 0000000000000063 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 Code: 08 5b 41 5c 41 5d 41 5e 41 5f 5d c3 0f 0b 48 89 df e8 42 2c e3 fb eb de 55 48 89 fe 48 c7 c7 80 75 98 86 48 89 e5 e8 85 95 94 fb <0f> 0b 90 90 90 90 90 90 90 90 90 90 90 55 48 89 e5 41 57 41 56 RIP: fortify_panic+0x13/0x20 lib/string.c:1051 RSP: ffff8801ca81f8f0 Fixes: 5bc2b7b397b0 ("RDMA/ucma: Allow user space to specify AF_IB when joining multicast") Reported-by: Signed-off-by: Leon Romanovsky Reviewed-by: Sean Hefty Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6840d3c5cd64..017a09ceba3f 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1330,7 +1330,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, return -ENOSPC; addr = (struct sockaddr *) &cmd->addr; - if (!cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr))) + if (cmd->addr_size != rdma_addr_size(addr)) return -EINVAL; if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER) @@ -1398,6 +1398,9 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file, join_cmd.uid = cmd.uid; join_cmd.id = cmd.id; join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); + if (!join_cmd.addr_size) + return -EINVAL; + join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER; memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); @@ -1413,6 +1416,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; + if (!rdma_addr_size((struct sockaddr *)&cmd.addr)) + return -EINVAL; + return ucma_process_join(file, &cmd, out_len); } -- cgit v1.2.3 From 8dd5c0c47332c67a04830e3842d4d6282f1824fd Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Tue, 24 Jan 2017 03:27:24 +0100 Subject: usb: gadget: f_hid: fix: Move IN request allocation to set_alt() commit 749494b6bdbbaf0899aa1c62a1ad74cd747bce47 upstream. Since commit: ba1582f22231 ("usb: gadget: f_hid: use alloc_ep_req()") we cannot allocate any requests in bind() as we check if we should align request buffer based on endpoint descriptor which is assigned in set_alt(). Allocating request in bind() function causes a NULL pointer dereference. This commit moves allocation of IN request from bind() to set_alt() to prevent this issue. Fixes: ba1582f22231 ("usb: gadget: f_hid: use alloc_ep_req()") Cc: stable@vger.kernel.org Tested-by: David Lechner Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi Cc: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_hid.c | 89 ++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index b6d4b484c51a..5815120c0402 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -284,6 +284,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, size_t count, loff_t *offp) { struct f_hidg *hidg = file->private_data; + struct usb_request *req; unsigned long flags; ssize_t status = -ENOMEM; @@ -293,7 +294,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, spin_lock_irqsave(&hidg->write_spinlock, flags); #define WRITE_COND (!hidg->write_pending) - +try_again: /* write queue */ while (!WRITE_COND) { spin_unlock_irqrestore(&hidg->write_spinlock, flags); @@ -308,6 +309,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, } hidg->write_pending = 1; + req = hidg->req; count = min_t(unsigned, count, hidg->report_length); spin_unlock_irqrestore(&hidg->write_spinlock, flags); @@ -320,24 +322,38 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, goto release_write_pending; } - hidg->req->status = 0; - hidg->req->zero = 0; - hidg->req->length = count; - hidg->req->complete = f_hidg_req_complete; - hidg->req->context = hidg; + spin_lock_irqsave(&hidg->write_spinlock, flags); + + /* we our function has been disabled by host */ + if (!hidg->req) { + free_ep_req(hidg->in_ep, hidg->req); + /* + * TODO + * Should we fail with error here? + */ + goto try_again; + } + + req->status = 0; + req->zero = 0; + req->length = count; + req->complete = f_hidg_req_complete; + req->context = hidg; status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); if (status < 0) { ERROR(hidg->func.config->cdev, "usb_ep_queue error on int endpoint %zd\n", status); - goto release_write_pending; + goto release_write_pending_unlocked; } else { status = count; } + spin_unlock_irqrestore(&hidg->write_spinlock, flags); return status; release_write_pending: spin_lock_irqsave(&hidg->write_spinlock, flags); +release_write_pending_unlocked: hidg->write_pending = 0; spin_unlock_irqrestore(&hidg->write_spinlock, flags); @@ -541,12 +557,23 @@ static void hidg_disable(struct usb_function *f) kfree(list); } spin_unlock_irqrestore(&hidg->read_spinlock, flags); + + spin_lock_irqsave(&hidg->write_spinlock, flags); + if (!hidg->write_pending) { + free_ep_req(hidg->in_ep, hidg->req); + hidg->write_pending = 1; + } + + hidg->req = NULL; + spin_unlock_irqrestore(&hidg->write_spinlock, flags); } static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct usb_composite_dev *cdev = f->config->cdev; struct f_hidg *hidg = func_to_hidg(f); + struct usb_request *req_in = NULL; + unsigned long flags; int i, status = 0; VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); @@ -567,6 +594,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; } hidg->in_ep->driver_data = hidg; + + req_in = hidg_alloc_ep_req(hidg->in_ep, hidg->report_length); + if (!req_in) { + status = -ENOMEM; + goto disable_ep_in; + } } @@ -578,12 +611,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) hidg->out_ep); if (status) { ERROR(cdev, "config_ep_by_speed FAILED!\n"); - goto fail; + goto free_req_in; } status = usb_ep_enable(hidg->out_ep); if (status < 0) { ERROR(cdev, "Enable OUT endpoint FAILED!\n"); - goto fail; + goto free_req_in; } hidg->out_ep->driver_data = hidg; @@ -599,17 +632,37 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) req->context = hidg; status = usb_ep_queue(hidg->out_ep, req, GFP_ATOMIC); - if (status) + if (status) { ERROR(cdev, "%s queue req --> %d\n", hidg->out_ep->name, status); + free_ep_req(hidg->out_ep, req); + } } else { - usb_ep_disable(hidg->out_ep); status = -ENOMEM; - goto fail; + goto disable_out_ep; } } } + if (hidg->in_ep != NULL) { + spin_lock_irqsave(&hidg->write_spinlock, flags); + hidg->req = req_in; + hidg->write_pending = 0; + spin_unlock_irqrestore(&hidg->write_spinlock, flags); + + wake_up(&hidg->write_queue); + } + return 0; +disable_out_ep: + usb_ep_disable(hidg->out_ep); +free_req_in: + if (req_in) + free_ep_req(hidg->in_ep, req_in); + +disable_ep_in: + if (hidg->in_ep) + usb_ep_disable(hidg->in_ep); + fail: return status; } @@ -658,12 +711,6 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) goto fail; hidg->out_ep = ep; - /* preallocate request and buffer */ - status = -ENOMEM; - hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length); - if (!hidg->req) - goto fail; - /* set descriptor dynamic values */ hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; @@ -690,6 +737,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) goto fail; spin_lock_init(&hidg->write_spinlock); + hidg->write_pending = 1; + hidg->req = NULL; spin_lock_init(&hidg->read_spinlock); init_waitqueue_head(&hidg->write_queue); init_waitqueue_head(&hidg->read_queue); @@ -954,10 +1003,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) device_destroy(hidg_class, MKDEV(major, hidg->minor)); cdev_del(&hidg->cdev); - /* disable/free request and end point */ - usb_ep_disable(hidg->in_ep); - free_ep_req(hidg->in_ep, hidg->req); - usb_free_all_descriptors(f); } -- cgit v1.2.3 From 055c49dcf10fe7db6087037abb87728e7dc84192 Mon Sep 17 00:00:00 2001 From: Michael Nosthoff Date: Fri, 9 Mar 2018 10:02:45 +0100 Subject: iio: st_pressure: st_accel: pass correct platform data to init commit 8b438686a001db64c21782d04ef68111e53c45d9 upstream. Commit 7383d44b added a pointer pdata which get set to the default platform_data when non was defined in the device. But it did not pass this pointer to the st_sensors_init_sensor call but still used the maybe uninitialized platform_data from dev. This breaks initialization when no platform_data is given and the optional st,drdy-int-pin devicetree option is not set. This commit fixes this. Cc: stable@vger.kernel.org Fixes: 7383d44b ("iio: st_pressure: st_accel: Initialise sensor platform data properly") Signed-off-by: Michael Nosthoff Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/accel/st_accel_core.c | 2 +- drivers/iio/pressure/st_pressure_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index fe94415a0bc7..32cd64c2ee06 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -858,7 +858,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) if (!pdata) pdata = (struct st_sensors_platform_data *)&default_accel_pdata; - err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); + err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) goto st_accel_power_off; diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index bec60299b6ec..3458418d88bc 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -678,7 +678,7 @@ int st_press_common_probe(struct iio_dev *indio_dev) if (!pdata && press_data->sensor_settings->drdy_irq.addr) pdata = (struct st_sensors_platform_data *)&default_press_pdata; - err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); + err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) goto st_press_power_off; -- cgit v1.2.3 From d8963938399a4b066448dd2a8dd100fb4e91fef8 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Wed, 14 Mar 2018 22:30:51 +0300 Subject: mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs commit 47b7de2f6c18f75d1f2716efe752cba43f32a626 upstream. It was found that in IDMAC mode after soft-reset driver switches to PIO mode. That's what happens in case of DTO timeout overflow calculation failure: 1. soft-reset is called 2. driver restarts dma 3. descriptors states are checked, one of descriptor is owned by the IDMAC. 4. driver can't use DMA and then switches to PIO mode. Failure was already fixed in: https://www.spinics.net/lists/linux-mmc/msg48125.html. Behaviour while soft-reset is not something we except or even want to happen. So we switch from dw_mci_idmac_reset to dw_mci_idmac_init, so descriptors are cleaned before starting dma. And while at it explicitly zero des0 which otherwise might contain garbage as being allocated by dmam_alloc_coherent(). Signed-off-by: Evgeniy Didin Cc: Jaehoon Chung Cc: Ulf Hansson Cc: Andy Shevchenko Cc: Jisheng Zhang Cc: Shawn Lin Cc: Alexey Brodkin Cc: Eugeniy Paltsev Cc: linux-snps-arc@lists.infradead.org Cc: # 4.4+ Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/dw_mmc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index f81f4175f49a..d382dbd44635 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -490,6 +490,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) (sizeof(struct idmac_desc_64addr) * (i + 1))) >> 32; /* Initialize reserved and buffer size fields to "0" */ + p->des0 = 0; p->des1 = 0; p->des2 = 0; p->des3 = 0; @@ -512,6 +513,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) i++, p++) { p->des3 = cpu_to_le32(host->sg_dma + (sizeof(struct idmac_desc) * (i + 1))); + p->des0 = 0; p->des1 = 0; } @@ -2878,8 +2880,8 @@ static bool dw_mci_reset(struct dw_mci *host) } if (host->use_dma == TRANS_MODE_IDMAC) - /* It is also recommended that we reset and reprogram idmac */ - dw_mci_idmac_reset(host); + /* It is also required that we reinit idmac */ + dw_mci_idmac_init(host); ret = true; -- cgit v1.2.3 From d2327a25e43a7843d65f5bab3daeb833c5caf63f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 2 Mar 2018 11:36:33 +0100 Subject: PCI: Add function 1 DMA alias quirk for Highpoint RocketRAID 644L commit 1903be8222b7c278ca897c129ce477c1dd6403a8 upstream. The Highpoint RocketRAID 644L uses a Marvel 88SE9235 controller, as with other Marvel controllers this needs a function 1 DMA alias quirk. Note the RocketRAID 642L uses the same Marvel 88SE9235 controller and already is listed with a function 1 DMA alias quirk. Cc: stable@vger.kernel.org BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1534106 Signed-off-by: Hans de Goede Acked-by: Bjorn Helgaas Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 4c9fb8b323e8..fb177dc576d6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3877,6 +3877,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230, quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, quirk_dma_func1_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645, + quirk_dma_func1_alias); /* https://bugs.gentoo.org/show_bug.cgi?id=497630 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB388_ESD, -- cgit v1.2.3 From 3ba5143bbbed8bd0ab2ee85a46f1165ff3039232 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 2 Mar 2018 11:36:32 +0100 Subject: ahci: Add PCI-id for the Highpoint Rocketraid 644L card commit 28b2182dad43f6f8fcbd167539a26714fd12bd64 upstream. Like the Highpoint Rocketraid 642L and cards using a Marvel 88SE9235 controller in general, this RAID card also supports AHCI mode and short of a custom driver, this is the only way to make it work under Linux. Note that even though the card is called to 644L, it has a product-id of 0x0645. Cc: stable@vger.kernel.org BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1534106 Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Acked-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ahci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9b46ef4c851e..4d4b5f607b81 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -539,7 +539,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230), .driver_data = board_ahci_yes_fbs }, - { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), + { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */ + .driver_data = board_ahci_yes_fbs }, + { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */ .driver_data = board_ahci_yes_fbs }, /* Promise */ -- cgit v1.2.3 From beb9ece1db9cabbe01b297e7df2e4d6769dad8bc Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 8 Feb 2018 14:43:35 +0100 Subject: clk: bcm2835: Fix ana->maskX definitions commit 49012d1bf5f78782d398adb984a080a88ba42965 upstream. ana->maskX values are already '~'-ed in bcm2835_pll_set_rate(). Remove the '~' in the definition to fix ANA setup. Note that this commit fixes a long standing bug preventing one from using an HDMI display if it's plugged after the FW has booted Linux. This is because PLLH is used by the HDMI encoder to generate the pixel clock. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Cc: Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/bcm/clk-bcm2835.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 2acaa77ad482..48e7040adb63 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -401,17 +401,17 @@ struct bcm2835_pll_ana_bits { static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { .mask0 = 0, .set0 = 0, - .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), + .mask1 = A2W_PLL_KI_MASK | A2W_PLL_KP_MASK, .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), - .mask3 = (u32)~A2W_PLL_KA_MASK, + .mask3 = A2W_PLL_KA_MASK, .set3 = (2 << A2W_PLL_KA_SHIFT), .fb_prediv_mask = BIT(14), }; static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { - .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), + .mask0 = A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK, .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), - .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), + .mask1 = A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK, .set1 = (6 << A2W_PLLH_KP_SHIFT), .mask3 = 0, .set3 = 0, -- cgit v1.2.3 From 8f0dd27b3db01e7785038ea9a711f210067ee6ae Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 8 Feb 2018 14:43:36 +0100 Subject: clk: bcm2835: Protect sections updating shared registers commit 7997f3b2df751aab0b8e60149b226a32966c41ac upstream. CM_PLLx and A2W_XOSC_CTRL registers are accessed by different clock handlers and must be accessed with ->regs_lock held. Update the sections where this protection is missing. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Cc: Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/bcm/clk-bcm2835.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 48e7040adb63..abdc149941e2 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -566,8 +566,10 @@ static int bcm2835_pll_on(struct clk_hw *hw) ~A2W_PLL_CTRL_PWRDN); /* Take the PLL out of reset. */ + spin_lock(&cprman->regs_lock); cprman_write(cprman, data->cm_ctrl_reg, cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST); + spin_unlock(&cprman->regs_lock); /* Wait for the PLL to lock. */ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); @@ -644,9 +646,11 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, } /* Unmask the reference clock from the oscillator. */ + spin_lock(&cprman->regs_lock); cprman_write(cprman, A2W_XOSC_CTRL, cprman_read(cprman, A2W_XOSC_CTRL) | data->reference_enable_mask); + spin_unlock(&cprman->regs_lock); if (do_ana_setup_first) bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana); -- cgit v1.2.3 From bdbd9153899061cc9aacfc376b26a2224850c61a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 17 Feb 2018 21:05:04 +0800 Subject: clk: sunxi-ng: a31: Fix CLK_OUT_* clock ops commit 5682e268350f9eccdbb04006605c1b7068a7b323 upstream. When support for the A31/A31s CCU was first added, the clock ops for the CLK_OUT_* clocks was set to the wrong type. The clocks are MP-type, but the ops was set for div (M) clocks. This went unnoticed until now. This was because while they are different clocks, their data structures aligned in a way that ccu_div_ops would access the second ccu_div_internal and ccu_mux_internal structures, which were valid, if not incorrect. Furthermore, the use of these CLK_OUT_* was for feeding a precise 32.768 kHz clock signal to the WiFi chip. This was achievable by using the parent with the same clock rate and no divider. So the incorrect divider setting did not affect this usage. Commit 946797aa3f08 ("clk: sunxi-ng: Support fixed post-dividers on MP style clocks") added a new field to the ccu_mp structure, which broke the aforementioned alignment. Now the system crashes as div_ops tries to look up a nonexistent table. Reported-by: Philipp Rossak Tested-by: Philipp Rossak Fixes: c6e6c96d8fa6 ("clk: sunxi-ng: Add A31/A31s clocks") Cc: Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Greg Kroah-Hartman --- drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 9fe0939c1273..6ea5401e6881 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -750,7 +750,7 @@ static struct ccu_mp out_a_clk = { .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("out-a", clk_out_parents, - &ccu_div_ops, + &ccu_mp_ops, 0), }, }; @@ -771,7 +771,7 @@ static struct ccu_mp out_b_clk = { .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("out-b", clk_out_parents, - &ccu_div_ops, + &ccu_mp_ops, 0), }, }; @@ -792,7 +792,7 @@ static struct ccu_mp out_c_clk = { .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("out-c", clk_out_parents, - &ccu_div_ops, + &ccu_mp_ops, 0), }, }; -- cgit v1.2.3 From dd62bc3058313ef183aeb22d9de2297cb486dd8d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Mar 2018 17:02:34 +0100 Subject: Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174 commit f44cb4b19ed40b655c2d422c9021ab2c2625adb6 upstream. The Atheros 1525/QCA6174 BT doesn't seem working properly on the recent kernels, as it tries to load a wrong firmware ar3k/AthrBT_0x00000200.dfu and it fails. This seems to have been a problem for some time, and the known workaround is to apply BTUSB_QCA_ROM quirk instead of BTUSB_ATH3012. The device in question is: T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=03 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=3004 Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Bugzilla: http://bugzilla.opensuse.org/show_bug.cgi?id=1082504 Reported-by: Ivan Levshin Tested-by: Ivan Levshin Cc: Signed-off-by: Takashi Iwai Signed-off-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/btusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3257647d4f74..f8ba5c714df5 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -217,7 +217,6 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, @@ -250,6 +249,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, /* QCA ROME chipset */ + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, -- cgit v1.2.3 From 85f0fec12c58509b0e3717ad07427aa508a2d869 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 3 Feb 2018 20:30:56 -0800 Subject: libata: fix length validation of ATAPI-relayed SCSI commands commit 058f58e235cbe03e923b30ea7c49995a46a8725f upstream. syzkaller reported a crash in ata_bmdma_fill_sg() when writing to /dev/sg1. The immediate cause was that the ATA command's scatterlist was not DMA-mapped, which causes 'pi - 1' to underflow, resulting in a write to 'qc->ap->bmdma_prd[0xffffffff]'. Strangely though, the flag ATA_QCFLAG_DMAMAP was set in qc->flags. The root cause is that when __ata_scsi_queuecmd() is preparing to relay a SCSI command to an ATAPI device, it doesn't correctly validate the CDB length before copying it into the 16-byte buffer 'cdb' in 'struct ata_queued_cmd'. Namely, it validates the fixed CDB length expected based on the SCSI opcode but not the actual CDB length, which can be larger due to the use of the SG_NEXT_CMD_LEN ioctl. Since 'flags' is the next member in ata_queued_cmd, a buffer overflow corrupts it. Fix it by requiring that the actual CDB length be <= 16 (ATAPI_CDB_LEN). [Really it seems the length should be required to be <= dev->cdb_len, but the current behavior seems to have been intentionally introduced by commit 607126c2a21c ("libata-scsi: be tolerant of 12-byte ATAPI commands in 16-byte CDBs") to work around a userspace bug in mplayer. Probably the workaround is no longer needed (mplayer was fixed in 2007), but continuing to allow lengths to up 16 appears harmless for now.] Here's a reproducer that works in QEMU when /dev/sg1 refers to the CD-ROM drive that qemu-system-x86_64 creates by default: #include #include #include #define SG_NEXT_CMD_LEN 0x2283 int main() { char buf[53] = { [36] = 0x7e, [52] = 0x02 }; int fd = open("/dev/sg1", O_RDWR); ioctl(fd, SG_NEXT_CMD_LEN, &(int){ 17 }); write(fd, buf, sizeof(buf)); } The crash was: BUG: unable to handle kernel paging request at ffff8cb97db37ffc IP: ata_bmdma_fill_sg drivers/ata/libata-sff.c:2623 [inline] IP: ata_bmdma_qc_prep+0xa4/0xc0 drivers/ata/libata-sff.c:2727 PGD fb6c067 P4D fb6c067 PUD 0 Oops: 0002 [#1] SMP CPU: 1 PID: 150 Comm: syz_ata_bmdma_q Not tainted 4.15.0-next-20180202 #99 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014 [...] Call Trace: ata_qc_issue+0x100/0x1d0 drivers/ata/libata-core.c:5421 ata_scsi_translate+0xc9/0x1a0 drivers/ata/libata-scsi.c:2024 __ata_scsi_queuecmd drivers/ata/libata-scsi.c:4326 [inline] ata_scsi_queuecmd+0x8c/0x210 drivers/ata/libata-scsi.c:4375 scsi_dispatch_cmd+0xa2/0xe0 drivers/scsi/scsi_lib.c:1727 scsi_request_fn+0x24c/0x530 drivers/scsi/scsi_lib.c:1865 __blk_run_queue_uncond block/blk-core.c:412 [inline] __blk_run_queue+0x3a/0x60 block/blk-core.c:432 blk_execute_rq_nowait+0x93/0xc0 block/blk-exec.c:78 sg_common_write.isra.7+0x272/0x5a0 drivers/scsi/sg.c:806 sg_write+0x1ef/0x340 drivers/scsi/sg.c:677 __vfs_write+0x31/0x160 fs/read_write.c:480 vfs_write+0xa7/0x160 fs/read_write.c:544 SYSC_write fs/read_write.c:589 [inline] SyS_write+0x4d/0xc0 fs/read_write.c:581 do_syscall_64+0x5e/0x110 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x21/0x86 Fixes: 607126c2a21c ("libata-scsi: be tolerant of 12-byte ATAPI commands in 16-byte CDBs") Reported-by: syzbot+1ff6f9fcc3c35f1c72a95e26528c8e7e3276e4da@syzkaller.appspotmail.com Cc: # v2.6.24+ Signed-off-by: Eric Biggers Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3e10e8f6f6a..64c8f9f46ddb 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4177,7 +4177,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { /* relay SCSI command to ATAPI device */ int len = COMMAND_SIZE(scsi_op); - if (unlikely(len > scmd->cmd_len || len > dev->cdb_len)) + if (unlikely(len > scmd->cmd_len || + len > dev->cdb_len || + scmd->cmd_len > ATAPI_CDB_LEN)) goto bad_cdb_len; xlat_func = atapi_xlat; -- cgit v1.2.3 From 195c71dc031bed7890e39d9571d8f9e2acdb6a5b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 3 Feb 2018 20:33:27 -0800 Subject: libata: remove WARN() for DMA or PIO command without data commit 9173e5e80729c8434b8d27531527c5245f4a5594 upstream. syzkaller hit a WARN() in ata_qc_issue() when writing to /dev/sg0. This happened because it issued a READ_6 command with no data buffer. Just remove the WARN(), as it doesn't appear indicate a kernel bug. The expected behavior is to fail the command, which the code does. Here's a reproducer that works in QEMU when /dev/sg0 refers to a disk of the default type ("82371SB PIIX3 IDE"): #include #include int main() { char buf[42] = { [36] = 0x8 /* READ_6 */ }; write(open("/dev/sg0", O_RDWR), buf, sizeof(buf)); } Fixes: f92a26365a72 ("libata: change ATA_QCFLAG_DMAMAP semantics") Reported-by: syzbot+f7b556d1766502a69d85071d2ff08bd87be53d0f@syzkaller.appspotmail.com Cc: # v2.6.25+ Signed-off-by: Eric Biggers Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index aee39524375c..233040a3f1ad 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5265,8 +5265,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) * We guarantee to LLDs that they will have at least one * non-zero sg if the command is a data command. */ - if (WARN_ON_ONCE(ata_is_data(prot) && - (!qc->sg || !qc->n_elem || !qc->nbytes))) + if (ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)) goto sys_err; if (ata_is_dma(prot) || (ata_is_pio(prot) && -- cgit v1.2.3 From 8b8524d75697da34116c3fd42103b67f69f3dcc8 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 3 Feb 2018 20:33:51 -0800 Subject: libata: don't try to pass through NCQ commands to non-NCQ devices commit 2c1ec6fda2d07044cda922ee25337cf5d4b429b3 upstream. syzkaller hit a WARN() in ata_bmdma_qc_issue() when writing to /dev/sg0. This happened because it issued an ATA pass-through command (ATA_16) where the protocol field indicated that NCQ should be used -- but the device did not support NCQ. We could just remove the WARN() from libata-sff.c, but the real problem seems to be that the SCSI -> ATA translation code passes through NCQ commands without verifying that the device actually supports NCQ. Fix this by adding the appropriate check to ata_scsi_pass_thru(). Here's reproducer that works in QEMU when /dev/sg0 refers to a disk of the default type ("82371SB PIIX3 IDE"): #include #include int main() { char buf[53] = { 0 }; buf[36] = 0x85; /* ATA_16 */ buf[37] = (12 << 1); /* FPDMA */ buf[38] = 0x1; /* Has data */ buf[51] = 0xC8; /* ATA_CMD_READ */ write(open("/dev/sg0", O_RDWR), buf, sizeof(buf)); } Fixes: ee7fb331c3ac ("libata: add support for NCQ commands for SG interface") Reported-by: syzbot+2f69ca28df61bdfc77cd36af2e789850355a221e@syzkaller.appspotmail.com Cc: # v4.4+ Signed-off-by: Eric Biggers Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-scsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 64c8f9f46ddb..9babbc845750 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3226,6 +3226,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) goto invalid_fld; } + /* We may not issue NCQ commands to devices not supporting NCQ */ + if (ata_is_ncq(tf->protocol) && !ata_ncq_enabled(dev)) { + fp = 1; + goto invalid_fld; + } + /* sanity check for pio multi commands */ if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) { fp = 1; -- cgit v1.2.3 From a9f062b850db21be39afb2cf22b8eca42ec1e314 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Feb 2018 10:48:20 +0100 Subject: libata: Apply NOLPM quirk to Crucial MX100 512GB SSDs commit 9c7be59fc519af9081c46c48f06f2b8fadf55ad8 upstream. Various people have reported the Crucial MX100 512GB model not working with LPM set to min_power. I've now received a report that it also does not work with the new med_power_with_dipm level. It does work with medium_power, but that has no measurable power-savings and given the amount of people being bitten by the other levels not working, this commit just disables LPM altogether. Note all reporters of this have either the 512GB model (max capacity), or are not specifying their SSD's size. So for now this quirk assumes this is a problem with the 512GB model only. Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=89261 Buglink: https://github.com/linrunner/TLP/issues/84 Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 233040a3f1ad..6b90bf756c7d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4403,6 +4403,11 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + /* The 512GB version of the MX100 has both queued TRIM and LPM issues */ + { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NOLPM, }, + /* devices that don't properly handle queued TRIM commands */ { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, -- cgit v1.2.3 From 2bcfcae486246875cfb9835cee24955fbfc0c17a Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sun, 18 Feb 2018 22:17:09 +0800 Subject: libata: disable LPM for Crucial BX100 SSD 500GB drive commit b17e5729a630d8326a48ec34ef02e6b4464a6aef upstream. After Laptop Mode Tools starts to use min_power for LPM, a user found out Crucial BX100 SSD can't get mounted. Crucial BX100 SSD 500GB drive don't work well with min_power. This also happens to med_power_with_dipm. So let's disable LPM for Crucial BX100 SSD 500GB drive. BugLink: https://bugs.launchpad.net/bugs/1726930 Signed-off-by: Kai-Heng Feng Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6b90bf756c7d..ac35d5738ba9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4403,6 +4403,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + /* Crucial BX100 SSD 500GB has broken LPM support */ + { "CT500BX100SSD1", "MU02", ATA_HORKAGE_NOLPM }, + /* The 512GB version of the MX100 has both queued TRIM and LPM issues */ { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM | -- cgit v1.2.3 From db4a121a8939ec1d24efe38e3405dc9776c6b925 Mon Sep 17 00:00:00 2001 From: Ju Hyung Park Date: Sun, 11 Mar 2018 02:28:35 +0900 Subject: libata: Enable queued TRIM for Samsung SSD 860 commit ca6bfcb2f6d9deab3924bf901e73622a94900473 upstream. Samsung explicitly states that queued TRIM is supported for Linux with 860 PRO and 860 EVO. Make the previous blacklist to cover only 840 and 850 series. Signed-off-by: Park Ju Hyung Reviewed-by: Martin K. Petersen Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ac35d5738ba9..1f4810ea33c5 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4422,7 +4422,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, - { "Samsung SSD 8*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + { "Samsung SSD 840*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, -- cgit v1.2.3 From a7262d24ab62e92728b7c3fbbd85b718a81ce865 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Mar 2018 16:33:58 +0100 Subject: libata: Apply NOLPM quirk to Crucial M500 480 and 960GB SSDs commit 62ac3f7305470e3f52f159de448bc1a771717e88 upstream. There have been reports of the Crucial M500 480GB model not working with LPM set to min_power / med_power_with_dipm level. It has not been tested with medium_power, but that typically has no measurable power-savings. Note the reporters Crucial_CT480M500SSD3 has a firmware version of MU03 and there is a MU05 update available, but that update does not mention any LPM fixes in its changelog, so the quirk matches all firmware versions. In my experience the LPM problems with (older) Crucial SSDs seem to be limited to higher capacity versions of the SSDs (different firmware?), so this commit adds a NOLPM quirk for the 480 and 960GB versions of the M500, to avoid LPM causing issues with these SSDs. Cc: stable@vger.kernel.org Reported-and-tested-by: Martin Steigerwald Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1f4810ea33c5..cf84a52ed20e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4411,6 +4411,14 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM, }, + /* 480GB+ M500 SSDs have both queued TRIM and LPM issues */ + { "Crucial_CT480M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NOLPM, }, + { "Crucial_CT960M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NOLPM, }, + /* devices that don't properly handle queued TRIM commands */ { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, -- cgit v1.2.3 From ed57941c84c4d8c5d30998c3832e0d20deaf0cfe Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Mar 2018 16:33:59 +0100 Subject: libata: Make Crucial BX100 500GB LPM quirk apply to all firmware versions commit 3bf7b5d6d017c27e0d3b160aafb35a8e7cfeda1f upstream. Commit b17e5729a630 ("libata: disable LPM for Crucial BX100 SSD 500GB drive"), introduced a ATA_HORKAGE_NOLPM quirk for Crucial BX100 500GB SSDs but limited this to the MU02 firmware version, according to: http://www.crucial.com/usa/en/support-ssd-firmware MU02 is the last version, so there are no newer possibly fixed versions and if the MU02 version has broken LPM then the MU01 almost certainly also has broken LPM, so this commit changes the quirk to apply to all firmware versions. Fixes: b17e5729a630 ("libata: disable LPM for Crucial BX100 SSD 500GB...") Cc: stable@vger.kernel.org Cc: Kai-Heng Feng Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cf84a52ed20e..b41d1a7b7c9d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4404,7 +4404,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* Crucial BX100 SSD 500GB has broken LPM support */ - { "CT500BX100SSD1", "MU02", ATA_HORKAGE_NOLPM }, + { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, /* The 512GB version of the MX100 has both queued TRIM and LPM issues */ { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | -- cgit v1.2.3 From 8d7a2a6d455cea5b80b584a6df147191ba0043ad Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Mar 2018 16:34:00 +0100 Subject: libata: Modify quirks for MX100 to limit NCQ_TRIM quirk to MU01 version commit d418ff56b8f2d2b296daafa8da151fe27689b757 upstream. When commit 9c7be59fc519af ("libata: Apply NOLPM quirk to Crucial MX100 512GB SSDs") was added it inherited the ATA_HORKAGE_NO_NCQ_TRIM quirk from the existing "Crucial_CT*MX100*" entry, but that entry sets model_rev to "MU01", where as the entry adding the NOLPM quirk sets it to NULL. This means that after this commit we no apply the NO_NCQ_TRIM quirk to all "Crucial_CT512MX100*" SSDs even if they have the fixed "MU02" firmware. This commit splits the "Crucial_CT512MX100*" quirk into 2 quirks, one for the "MU01" firmware and one for all other firmware versions, so that we once again only apply the NO_NCQ_TRIM quirk to the "MU01" firmware version. Fixes: 9c7be59fc519af ("libata: Apply NOLPM quirk to ... MX100 512GB SSDs") Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b41d1a7b7c9d..e08c09fa5da0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4406,10 +4406,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Crucial BX100 SSD 500GB has broken LPM support */ { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, - /* The 512GB version of the MX100 has both queued TRIM and LPM issues */ - { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */ + { "Crucial_CT512MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM, }, + /* 512GB MX100 with newer firmware has only LPM issues */ + { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NOLPM, }, /* 480GB+ M500 SSDs have both queued TRIM and LPM issues */ { "Crucial_CT480M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | -- cgit v1.2.3 From f0c88241d3526f9de39970e006a49d9c66650ab3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 21 Mar 2018 10:18:38 +0100 Subject: drm/vmwgfx: Fix a destoy-while-held mutex problem. commit 73a88250b70954a8f27c2444e1c2411bba3c29d9 upstream. When validating legacy surfaces, the backup bo might be destroyed at surface validate time. However, the kms resource validation code may have the bo reserved, so we will destroy a locked mutex. While there shouldn't be any other users of that mutex when it is destroyed, it causes a lock leak and thus throws a lockdep error. Fix this by having the kms resource validation code hold a reference to the bo while we have it reserved. We do this by introducing a validation context which might come in handy when the kms code is extended to validate multiple resources or buffers. Cc: Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul Reviewed-by: Sinclair Yeh Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 28 +++++++++++++++++++--------- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 12 +++++++++--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 5 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 5 +++-- 4 files changed, 34 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index bf28ccc150df..87086af42114 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -27,7 +27,6 @@ #include "vmwgfx_kms.h" - /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) @@ -1933,9 +1932,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, * Helper to be used if an error forces the caller to undo the actions of * vmw_kms_helper_resource_prepare. */ -void vmw_kms_helper_resource_revert(struct vmw_resource *res) +void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx) { - vmw_kms_helper_buffer_revert(res->backup); + struct vmw_resource *res = ctx->res; + + vmw_kms_helper_buffer_revert(ctx->buf); + vmw_dmabuf_unreference(&ctx->buf); vmw_resource_unreserve(res, false, NULL, 0); mutex_unlock(&res->dev_priv->cmdbuf_mutex); } @@ -1952,10 +1954,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res) * interrupted by a signal. */ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, - bool interruptible) + bool interruptible, + struct vmw_validation_ctx *ctx) { int ret = 0; + ctx->buf = NULL; + ctx->res = res; + if (interruptible) ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex); else @@ -1974,6 +1980,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, res->dev_priv->has_mob); if (ret) goto out_unreserve; + + ctx->buf = vmw_dmabuf_reference(res->backup); } ret = vmw_resource_validate(res); if (ret) @@ -1981,7 +1989,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, return 0; out_revert: - vmw_kms_helper_buffer_revert(res->backup); + vmw_kms_helper_buffer_revert(ctx->buf); out_unreserve: vmw_resource_unreserve(res, false, NULL, 0); out_unlock: @@ -1997,11 +2005,13 @@ out_unlock: * @out_fence: Optional pointer to a fence pointer. If non-NULL, a * ref-counted fence pointer is returned here. */ -void vmw_kms_helper_resource_finish(struct vmw_resource *res, - struct vmw_fence_obj **out_fence) +void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, + struct vmw_fence_obj **out_fence) { - if (res->backup || out_fence) - vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup, + struct vmw_resource *res = ctx->res; + + if (ctx->buf || out_fence) + vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, out_fence, NULL); vmw_resource_unreserve(res, false, NULL, 0); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index ff4803c107bc..2dd05395e98b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -183,6 +183,11 @@ struct vmw_display_unit { int set_gui_y; }; +struct vmw_validation_ctx { + struct vmw_resource *res; + struct vmw_dma_buffer *buf; +}; + #define vmw_crtc_to_du(x) \ container_of(x, struct vmw_display_unit, crtc) #define vmw_connector_to_du(x) \ @@ -233,9 +238,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, struct drm_vmw_fence_rep __user * user_fence_rep); int vmw_kms_helper_resource_prepare(struct vmw_resource *res, - bool interruptible); -void vmw_kms_helper_resource_revert(struct vmw_resource *res); -void vmw_kms_helper_resource_finish(struct vmw_resource *res, + bool interruptible, + struct vmw_validation_ctx *ctx); +void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx); +void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, struct vmw_fence_obj **out_fence); int vmw_kms_readback(struct vmw_private *dev_priv, struct drm_file *file_priv, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index f42359084adc..a6ca2185f5b0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -753,12 +753,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer_surface *vfbs = container_of(framebuffer, typeof(*vfbs), base); struct vmw_kms_sou_surface_dirty sdirty; + struct vmw_validation_ctx ctx; int ret; if (!srf) srf = &vfbs->surface->res; - ret = vmw_kms_helper_resource_prepare(srf, true); + ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); if (ret) return ret; @@ -777,7 +778,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips, dest_x, dest_y, num_clips, inc, &sdirty.base); - vmw_kms_helper_resource_finish(srf, out_fence); + vmw_kms_helper_resource_finish(&ctx, out_fence); return ret; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 94ad8d2acf9a..8b914504b857 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -977,12 +977,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer_surface *vfbs = container_of(framebuffer, typeof(*vfbs), base); struct vmw_stdu_dirty sdirty; + struct vmw_validation_ctx ctx; int ret; if (!srf) srf = &vfbs->surface->res; - ret = vmw_kms_helper_resource_prepare(srf, true); + ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); if (ret) return ret; @@ -1005,7 +1006,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, dest_x, dest_y, num_clips, inc, &sdirty.base); out_finish: - vmw_kms_helper_resource_finish(srf, out_fence); + vmw_kms_helper_resource_finish(&ctx, out_fence); return ret; } -- cgit v1.2.3 From e664e6d66380d53e5e468d0f1318df4516a3be25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Mar 2018 18:14:04 +0100 Subject: drm/radeon: Don't turn off DP sink when disconnected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2681bc79eeb640562c932007bfebbbdc55bf6a7d upstream. Turning off the sink in this case causes various issues, because userspace expects it to stay on until it turns it off explicitly. Instead, turn the sink off and back on when a display is connected again. This dance seems necessary for link training to work correctly. Bugzilla: https://bugs.freedesktop.org/105308 Cc: stable@vger.kernel.org Reviewed-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_connectors.c | 31 ++++++++++++------------------ 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index af0d7fd5706b..f416f5c2e8e9 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -90,25 +90,18 @@ void radeon_connector_hotplug(struct drm_connector *connector) /* don't do anything if sink is not display port, i.e., * passive dp->(dvi|hdmi) adaptor */ - if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { - int saved_dpms = connector->dpms; - /* Only turn off the display if it's physically disconnected */ - if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } else if (radeon_dp_needs_link_train(radeon_connector)) { - /* Don't try to start link training before we - * have the dpcd */ - if (!radeon_dp_getdpcd(radeon_connector)) - return; - - /* set it to OFF so that drm_helper_connector_dpms() - * won't return immediately since the current state - * is ON at this point. - */ - connector->dpms = DRM_MODE_DPMS_OFF; - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - connector->dpms = saved_dpms; + if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT && + radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && + radeon_dp_needs_link_train(radeon_connector)) { + /* Don't start link training before we have the DPCD */ + if (!radeon_dp_getdpcd(radeon_connector)) + return; + + /* Turn the connector off and back on immediately, which + * will trigger link training + */ + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } } } -- cgit v1.2.3 From 4ac9ab4f5f45d1ad0585c7bfa9ccff43b9984045 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 Mar 2018 16:45:53 +0100 Subject: drm: udl: Properly check framebuffer mmap offsets commit 3b82a4db8eaccce735dffd50b4d4e1578099b8e8 upstream. The memmap options sent to the udl framebuffer driver were not being checked for all sets of possible crazy values. Fix this up by properly bounding the allowed values. Reported-by: Eyal Itkin Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180321154553.GA18454@kroah.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/udl/udl_fb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 611b6b9bb3cb..67ea2ce03a23 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -158,10 +158,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long offset; unsigned long page, pos; - if (offset + size > info->fix.smem_len) + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + + offset = vma->vm_pgoff << PAGE_SHIFT; + + if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) return -EINVAL; pos = (unsigned long)info->fix.smem_start + offset; -- cgit v1.2.3 From f33db316d0f531f18659a240ffeda9d910446370 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 15 Mar 2018 19:49:14 -0700 Subject: acpi, numa: fix pxm to online numa node associations commit dc9e0a9347e932e3fd3cd03e7ff241022ed6ea8a upstream. Commit 99759869faf1 "acpi: Add acpi_map_pxm_to_online_node()" added support for mapping a given proximity to its nearest, by SLIT distance, online node. However, it sometimes returns unexpected results due to the fact that it switches from comparing the PXM node to the last node that was closer than the current max. for_each_online_node(n) { dist = node_distance(node, n); if (dist < min_dist) { min_dist = dist; node = n; <---- from this point we're using the wrong node for node_distance() Fixes: 99759869faf1 ("acpi: Add acpi_map_pxm_to_online_node()") Cc: Reviewed-by: Toshi Kani Acked-by: Rafael J. Wysocki > Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/numa.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index ce3a7a16f03f..17b518cb787c 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -103,25 +103,27 @@ int acpi_map_pxm_to_node(int pxm) */ int acpi_map_pxm_to_online_node(int pxm) { - int node, n, dist, min_dist; + int node, min_node; node = acpi_map_pxm_to_node(pxm); if (node == NUMA_NO_NODE) node = 0; + min_node = node; if (!node_online(node)) { - min_dist = INT_MAX; + int min_dist = INT_MAX, dist, n; + for_each_online_node(n) { dist = node_distance(node, n); if (dist < min_dist) { min_dist = dist; - node = n; + min_node = n; } } } - return node; + return min_node; } EXPORT_SYMBOL(acpi_map_pxm_to_online_node); -- cgit v1.2.3 From d0826ba87dedab9abd3f2628cc9fbee3f413bd4f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Mar 2018 14:51:49 +0100 Subject: ACPI / watchdog: Fix off-by-one error at resource assignment commit b1abf6fc49829d89660c961fafe3f90f3d843c55 upstream. The resource allocation in WDAT watchdog has off-one-by error, it sets one byte more than the actual end address. This may eventually lead to unexpected resource conflicts. Fixes: 058dfc767008 (ACPI / watchdog: Add support for WDAT hardware watchdog) Cc: 4.9+ # 4.9+ Signed-off-by: Takashi Iwai Acked-by: Mika Westerberg Acked-by: Guenter Roeck Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpi_watchdog.c | 4 ++-- drivers/watchdog/wdat_wdt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 13caebd679f5..ce8fc680785b 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -74,10 +74,10 @@ void __init acpi_watchdog_init(void) res.start = gas->address; if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { res.flags = IORESOURCE_MEM; - res.end = res.start + ALIGN(gas->access_width, 4); + res.end = res.start + ALIGN(gas->access_width, 4) - 1; } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { res.flags = IORESOURCE_IO; - res.end = res.start + gas->access_width; + res.end = res.start + gas->access_width - 1; } else { pr_warn("Unsupported address space: %u\n", gas->space_id); diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c index 6d1fbda0f461..0da9943d405f 100644 --- a/drivers/watchdog/wdat_wdt.c +++ b/drivers/watchdog/wdat_wdt.c @@ -392,7 +392,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) memset(&r, 0, sizeof(r)); r.start = gas->address; - r.end = r.start + gas->access_width; + r.end = r.start + gas->access_width - 1; if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { r.flags = IORESOURCE_MEM; } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { -- cgit v1.2.3 From 6fa877d2aca8da2f597c3a97355f7b4d8690dc1e Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Mon, 5 Mar 2018 16:56:13 -0700 Subject: libnvdimm, {btt, blk}: do integrity setup before add_disk() commit 3ffb0ba9b567a8efb9a04ed3d1ec15ff333ada22 upstream. Prior to 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk") we needed to temporarily add a zero-capacity disk before registering for blk-integrity. But adding a zero-capacity disk caused the partition table scanning to bail early, and this resulted in partitions not coming up after a probe of the BTT or blk namespaces. We can now register for integrity before the disk has been added, and this fixes the rescan problems. Fixes: 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk") Reported-by: Dariusz Dokupil Cc: Signed-off-by: Vishal Verma Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/blk.c | 3 +-- drivers/nvdimm/btt.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c index 9faaa9694d87..77db9795510f 100644 --- a/drivers/nvdimm/blk.c +++ b/drivers/nvdimm/blk.c @@ -286,8 +286,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) disk->queue = q; disk->flags = GENHD_FL_EXT_DEVT; nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name); - set_capacity(disk, 0); - device_add_disk(dev, disk); if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk)) return -ENOMEM; @@ -300,6 +298,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) } set_capacity(disk, available_disk_size >> SECTOR_SHIFT); + device_add_disk(dev, disk); revalidate_disk(disk); return 0; } diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 7121453ec047..0c46ada027cf 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c @@ -1392,8 +1392,6 @@ static int btt_blk_init(struct btt *btt) queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue); btt->btt_queue->queuedata = btt; - set_capacity(btt->btt_disk, 0); - device_add_disk(&btt->nd_btt->dev, btt->btt_disk); if (btt_meta_size(btt)) { int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt)); @@ -1405,6 +1403,7 @@ static int btt_blk_init(struct btt *btt) } } set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9); + device_add_disk(&btt->nd_btt->dev, btt->btt_disk); btt->nd_btt->size = btt->nlba * (u64)btt->sector_size; revalidate_disk(btt->btt_disk); -- cgit v1.2.3 From 0a9be1b13232aa76c5561513415029da4e513f75 Mon Sep 17 00:00:00 2001 From: Arend Van Spriel Date: Wed, 28 Feb 2018 21:15:20 +0100 Subject: brcmfmac: fix P2P_DEVICE ethernet address generation commit 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b upstream. The firmware has a requirement that the P2P_DEVICE address should be different from the address of the primary interface. When not specified by user-space, the driver generates the MAC address for the P2P_DEVICE interface using the MAC address of the primary interface and setting the locally administered bit. However, the MAC address of the primary interface may already have that bit set causing the creation of the P2P_DEVICE interface to fail with -EBUSY. Fix this by using a random address instead to determine the P2P_DEVICE address. Cc: stable@vger.kernel.org # 3.10.y Reported-by: Hans de Goede Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 24 ++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 85d949e03f79..f78d91b69287 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac) * @dev_addr: optional device address. * * P2P needs mac addresses for P2P device and interface. If no device - * address it specified, these are derived from the primary net device, ie. - * the permanent ethernet address of the device. + * address it specified, these are derived from a random ethernet + * address. */ static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) { - struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; - bool local_admin = false; + bool random_addr = false; - if (!dev_addr || is_zero_ether_addr(dev_addr)) { - dev_addr = pri_ifp->mac_addr; - local_admin = true; - } + if (!dev_addr || is_zero_ether_addr(dev_addr)) + random_addr = true; - /* Generate the P2P Device Address. This consists of the device's - * primary MAC address with the locally administered bit set. + /* Generate the P2P Device Address obtaining a random ethernet + * address with the locally administered bit set. */ - memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); - if (local_admin) - p2p->dev_addr[0] |= 0x02; + if (random_addr) + eth_random_addr(p2p->dev_addr); + else + memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); /* Generate the P2P Interface Address. If the discovery and connection * BSSCFGs need to simultaneously co-exist, then this address must be -- cgit v1.2.3 From 0e17fddb648afe74a4fc94789b7b70cf854e8903 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 22 Feb 2018 14:28:59 -0600 Subject: rtlwifi: rtl8723be: Fix loss of signal commit 78dc897b7ee67205423dbbc6b56be49fb18d15b5 upstream. In commit c713fb071edc ("rtlwifi: rtl8821ae: Fix connection lost problem correctly") a problem in rtl8821ae that caused loss of signal was fixed. That same problem has now been reported for rtl8723be. Accordingly, the ASPM L1 latency has been increased from 0 to 7 to fix the instability. Signed-off-by: Larry Finger Cc: Stable Tested-by: James Cameron Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index aba60c3145c5..618e509e75d6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -1125,7 +1125,8 @@ static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw) /* Configuration Space offset 0x70f BIT7 is used to control L0S */ tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f); - _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7)); + _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) | + ASPM_L1_LATENCY << 3); /* Configuration Space offset 0x719 Bit3 is for L1 * BIT4 is for clock request -- cgit v1.2.3 From 9eab80eded7bb767f2f0770b3380e6affd3dc2c5 Mon Sep 17 00:00:00 2001 From: OuYang ZhiZhong Date: Sun, 11 Mar 2018 15:59:07 +0800 Subject: mtdchar: fix usage of mtd_ooblayout_ecc() commit 6de564939e14327148e31ddcf769e34105176447 upstream. Section was not properly computed. The value of OOB region definition is always ECC section 0 information in the OOB area, but we want to get all the ECC bytes information, so we should call mtd_ooblayout_ecc(mtd, section++, &oobregion) until it returns -ERANGE. Fixes: c2b78452a9db ("mtd: use mtd_ooblayout_xxx() helpers where appropriate") Cc: Signed-off-by: OuYang ZhiZhong Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtdchar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 2a47a3f0e730..b4092eab53ac 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -487,7 +487,7 @@ static int shrink_ecclayout(struct mtd_info *mtd, for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) { u32 eccpos; - ret = mtd_ooblayout_ecc(mtd, section, &oobregion); + ret = mtd_ooblayout_ecc(mtd, section++, &oobregion); if (ret < 0) { if (ret != -ERANGE) return ret; @@ -534,7 +534,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to) for (i = 0; i < ARRAY_SIZE(to->eccpos);) { u32 eccpos; - ret = mtd_ooblayout_ecc(mtd, section, &oobregion); + ret = mtd_ooblayout_ecc(mtd, section++, &oobregion); if (ret < 0) { if (ret != -ERANGE) return ret; -- cgit v1.2.3 From 9b5dd849509b3df53d0b98eac79d86cdeb54ef2c Mon Sep 17 00:00:00 2001 From: Jagdish Gediya Date: Wed, 21 Mar 2018 04:31:36 +0530 Subject: mtd: nand: fsl_ifc: Fix nand waitfunc return value commit fa8e6d58c5bc260f4369c6699683d69695daed0a upstream. As per the IFC hardware manual, Most significant 2 bytes in nand_fsr register are the outcome of NAND READ STATUS command. So status value need to be shifted and aligned as per the nand framework requirement. Fixes: 82771882d960 ("NAND Machine support for Integrated Flash Controller") Cc: stable@vger.kernel.org # v3.18+ Signed-off-by: Jagdish Gediya Reviewed-by: Prabhakar Kushwaha Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/fsl_ifc_nand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index f8f12ccc6471..a4d78c57b1e1 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -656,6 +656,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; u32 nand_fsr; + int status; /* Use READ_STATUS command, but wait for the device to be ready */ ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | @@ -670,12 +671,12 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) fsl_ifc_run_command(mtd); nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr); - + status = nand_fsr >> 24; /* * The chip always seems to report that it is * write-protected, even when it is not. */ - return nand_fsr | NAND_STATUS_WP; + return status | NAND_STATUS_WP; } static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, -- cgit v1.2.3 From eca95cb6b47a4190d3cf110d51ba186eb40e3a44 Mon Sep 17 00:00:00 2001 From: Jagdish Gediya Date: Wed, 21 Mar 2018 05:51:46 +0530 Subject: mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0 commit 843c3a59997f18060848b8632607dd04781b52d1 upstream. Number of ECC status registers i.e. (ECCSTATx) has been increased in IFC version 2.0.0 due to increase in SRAM size. This is causing eccstat array to over flow. So, replace eccstat array with u32 variable to make it fail-safe and independent of number of ECC status registers or SRAM size. Fixes: bccb06c353af ("mtd: nand: ifc: update bufnum mask for ver >= 2.0.0") Cc: stable@vger.kernel.org # 3.18+ Signed-off-by: Prabhakar Kushwaha Signed-off-by: Jagdish Gediya Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/fsl_ifc_nand.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index a4d78c57b1e1..97e6f37a742e 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -201,14 +201,9 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum) /* returns nonzero if entire page is blank */ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, - u32 *eccstat, unsigned int bufnum) + u32 eccstat, unsigned int bufnum) { - u32 reg = eccstat[bufnum / 4]; - int errors; - - errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; - - return errors; + return (eccstat >> ((3 - bufnum % 4) * 8)) & 15; } /* @@ -221,7 +216,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; - u32 eccstat[4]; + u32 eccstat; int i; /* set the chip select for NAND Transaction */ @@ -256,8 +251,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) if (nctrl->eccread) { int errors; int bufnum = nctrl->page & priv->bufnum_mask; - int sector = bufnum * chip->ecc.steps; - int sector_end = sector + chip->ecc.steps - 1; + int sector_start = bufnum * chip->ecc.steps; + int sector_end = sector_start + chip->ecc.steps - 1; __be32 *eccstat_regs; if (ctrl->version >= FSL_IFC_VERSION_2_0_0) @@ -265,10 +260,12 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) else eccstat_regs = ifc->ifc_nand.v1_nand_eccstat; - for (i = sector / 4; i <= sector_end / 4; i++) - eccstat[i] = ifc_in32(&eccstat_regs[i]); + eccstat = ifc_in32(&eccstat_regs[sector_start / 4]); + + for (i = sector_start; i <= sector_end; i++) { + if (i != sector_start && !(i % 4)) + eccstat = ifc_in32(&eccstat_regs[i / 4]); - for (i = sector; i <= sector_end; i++) { errors = check_read_ecc(mtd, ctrl, eccstat, i); if (errors == 15) { -- cgit v1.2.3 From 4d9ed68855f0844af153d70424e9e6160fe6f61c Mon Sep 17 00:00:00 2001 From: Jagdish Gediya Date: Thu, 22 Mar 2018 01:08:10 +0530 Subject: mtd: nand: fsl_ifc: Read ECCSTAT0 and ECCSTAT1 registers for IFC 2.0 commit 6b00c35138b404be98b85f4a703be594cbed501c upstream. Due to missing information in Hardware manual, current implementation doesn't read ECCSTAT0 and ECCSTAT1 registers for IFC 2.0. Add support to read ECCSTAT0 and ECCSTAT1 registers during ecccheck for IFC 2.0. Fixes: 656441478ed5 ("mtd: nand: ifc: Fix location of eccstat registers for IFC V1.0") Cc: stable@vger.kernel.org # v3.18+ Signed-off-by: Jagdish Gediya Reviewed-by: Prabhakar Kushwaha Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/fsl_ifc_nand.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 97e6f37a742e..2f6b55229d5b 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -255,11 +255,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) int sector_end = sector_start + chip->ecc.steps - 1; __be32 *eccstat_regs; - if (ctrl->version >= FSL_IFC_VERSION_2_0_0) - eccstat_regs = ifc->ifc_nand.v2_nand_eccstat; - else - eccstat_regs = ifc->ifc_nand.v1_nand_eccstat; - + eccstat_regs = ifc->ifc_nand.nand_eccstat; eccstat = ifc_in32(&eccstat_regs[sector_start / 4]); for (i = sector_start; i <= sector_end; i++) { -- cgit v1.2.3 From a452b356c58cdec58ff3a628be725755b0715540 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 1 Mar 2018 19:34:00 +0100 Subject: can: ifi: Repair the error handling commit 880dd464b4304583c557c4e5f5ecebfd55d232b1 upstream. The new version of the IFI CANFD core has significantly less complex error state indication logic. In particular, the warning/error state bits are no longer all over the place, but are all present in the STATUS register. Moreover, there is a new IRQ register bit indicating transition between error states (active/warning/passive/busoff). This patch makes use of this bit to weed out the obscure selective INTERRUPT register clearing, which was used to carry over the error state indication into the poll function. While at it, this patch fixes the handling of the ACTIVE state, since the hardware provides indication of the core being in ACTIVE state and that in turn fixes the state transition indication toward userspace. Finally, register reads in the poll function are moved to the matching subfunctions since those are also no longer needed in the poll function. Signed-off-by: Marek Vasut Cc: Heiko Schocher Cc: Markus Marb Cc: Marc Kleine-Budde Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/ifi_canfd/ifi_canfd.c | 64 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index c06ef438f23f..acfa7bfb98af 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -30,6 +30,7 @@ #define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2) #define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3) #define IFI_CANFD_STCMD_BUSOFF BIT(4) +#define IFI_CANFD_STCMD_ERROR_WARNING BIT(5) #define IFI_CANFD_STCMD_BUSMONITOR BIT(16) #define IFI_CANFD_STCMD_LOOPBACK BIT(18) #define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24) @@ -52,7 +53,10 @@ #define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13) #define IFI_CANFD_INTERRUPT 0xc +#define IFI_CANFD_INTERRUPT_ERROR_BUSOFF BIT(0) #define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1) +#define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG BIT(2) +#define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC BIT(3) #define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10) #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16) #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22) @@ -61,6 +65,10 @@ #define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31)) #define IFI_CANFD_IRQMASK 0x10 +#define IFI_CANFD_IRQMASK_ERROR_BUSOFF BIT(0) +#define IFI_CANFD_IRQMASK_ERROR_WARNING BIT(1) +#define IFI_CANFD_IRQMASK_ERROR_STATE_CHG BIT(2) +#define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC BIT(3) #define IFI_CANFD_IRQMASK_SET_ERR BIT(7) #define IFI_CANFD_IRQMASK_SET_TS BIT(15) #define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16) @@ -220,7 +228,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable) if (enable) { enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY | - IFI_CANFD_IRQMASK_RXFIFO_NEMPTY; + IFI_CANFD_IRQMASK_RXFIFO_NEMPTY | + IFI_CANFD_IRQMASK_ERROR_STATE_CHG | + IFI_CANFD_IRQMASK_ERROR_WARNING | + IFI_CANFD_IRQMASK_ERROR_BUSOFF; if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER; } @@ -361,12 +372,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev) return 1; } -static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr) +static int ifi_canfd_handle_lec_err(struct net_device *ndev) { struct ifi_canfd_priv *priv = netdev_priv(ndev); struct net_device_stats *stats = &ndev->stats; struct can_frame *cf; struct sk_buff *skb; + u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST | IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST | IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST | @@ -449,6 +461,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, switch (new_state) { case CAN_STATE_ERROR_ACTIVE: + /* error active state */ + priv->can.can_stats.error_warning++; + priv->can.state = CAN_STATE_ERROR_ACTIVE; + break; + case CAN_STATE_ERROR_WARNING: /* error warning state */ priv->can.can_stats.error_warning++; priv->can.state = CAN_STATE_ERROR_WARNING; @@ -477,7 +494,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, ifi_canfd_get_berr_counter(ndev, &bec); switch (new_state) { - case CAN_STATE_ERROR_ACTIVE: + case CAN_STATE_ERROR_WARNING: /* error warning state */ cf->can_id |= CAN_ERR_CRTL; cf->data[1] = (bec.txerr > bec.rxerr) ? @@ -510,22 +527,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, return 1; } -static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd) +static int ifi_canfd_handle_state_errors(struct net_device *ndev) { struct ifi_canfd_priv *priv = netdev_priv(ndev); + u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); int work_done = 0; - u32 isr; - /* - * The ErrWarn condition is a little special, since the bit is - * located in the INTERRUPT register instead of STCMD register. - */ - isr = readl(priv->base + IFI_CANFD_INTERRUPT); - if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING) && + if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) && + (priv->can.state != CAN_STATE_ERROR_ACTIVE)) { + netdev_dbg(ndev, "Error, entered active state\n"); + work_done += ifi_canfd_handle_state_change(ndev, + CAN_STATE_ERROR_ACTIVE); + } + + if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING) && (priv->can.state != CAN_STATE_ERROR_WARNING)) { - /* Clear the interrupt */ - writel(IFI_CANFD_INTERRUPT_ERROR_WARNING, - priv->base + IFI_CANFD_INTERRUPT); netdev_dbg(ndev, "Error, entered warning state\n"); work_done += ifi_canfd_handle_state_change(ndev, CAN_STATE_ERROR_WARNING); @@ -552,18 +568,11 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota) { struct net_device *ndev = napi->dev; struct ifi_canfd_priv *priv = netdev_priv(ndev); - const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE | - IFI_CANFD_STCMD_BUSOFF; - int work_done = 0; - - u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); - u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); + int work_done = 0; /* Handle bus state changes */ - if ((stcmd & stcmd_state_mask) || - ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) == 0)) - work_done += ifi_canfd_handle_state_errors(ndev, stcmd); + work_done += ifi_canfd_handle_state_errors(ndev); /* Handle lost messages on RX */ if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW) @@ -571,7 +580,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota) /* Handle lec errors on the bus */ if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) - work_done += ifi_canfd_handle_lec_err(ndev, errctr); + work_done += ifi_canfd_handle_lec_err(ndev); /* Handle normal messages on RX */ if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY)) @@ -592,12 +601,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id) struct net_device_stats *stats = &ndev->stats; const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY | IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER | + IFI_CANFD_INTERRUPT_ERROR_COUNTER | + IFI_CANFD_INTERRUPT_ERROR_STATE_CHG | IFI_CANFD_INTERRUPT_ERROR_WARNING | - IFI_CANFD_INTERRUPT_ERROR_COUNTER; + IFI_CANFD_INTERRUPT_ERROR_BUSOFF; const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY | IFI_CANFD_INTERRUPT_TXFIFO_REMOVE; - const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ | - IFI_CANFD_INTERRUPT_ERROR_WARNING)); + const u32 clr_irq_mask = ~((u32)IFI_CANFD_INTERRUPT_SET_IRQ); u32 isr; isr = readl(priv->base + IFI_CANFD_INTERRUPT); -- cgit v1.2.3 From 6e400b460a92fd662548edd23d819fd5cc11b208 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 5 Mar 2018 21:29:52 +0100 Subject: can: ifi: Check core revision upon probe commit 591d65d5b15496af8d05e252bc1da611c66c0b79 upstream. Older versions of the core are not compatible with the driver due to various intrusive fixes of the core. Read out the VER register, check the core revision bitfield and verify if the core in use is new enough (rev 2.1 or newer) to work correctly with this driver. Signed-off-by: Marek Vasut Cc: Heiko Schocher Cc: Markus Marb Cc: Marc Kleine-Budde Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/ifi_canfd/ifi_canfd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index acfa7bfb98af..6c676403f823 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -144,6 +144,8 @@ #define IFI_CANFD_SYSCLOCK 0x50 #define IFI_CANFD_VER 0x54 +#define IFI_CANFD_VER_REV_MASK 0xff +#define IFI_CANFD_VER_REV_MIN_SUPPORTED 0x15 #define IFI_CANFD_IP_ID 0x58 #define IFI_CANFD_IP_ID_VALUE 0xD073CAFD @@ -943,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) struct resource *res; void __iomem *addr; int irq, ret; - u32 id; + u32 id, rev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); addr = devm_ioremap_resource(dev, res); @@ -957,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) return -EINVAL; } + rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK; + if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) { + dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n", + rev, IFI_CANFD_VER_REV_MIN_SUPPORTED); + return -EINVAL; + } + ndev = alloc_candev(sizeof(*priv), 1); if (!ndev) return -ENOMEM; -- cgit v1.2.3 From 01a303d27a9c5fc80d7bdf2f2961e9ad14b608dc Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Wed, 14 Mar 2018 11:52:56 +0000 Subject: can: cc770: Fix stalls on rt-linux, remove redundant IRQ ack commit f4353daf4905c0099fd25fa742e2ffd4a4bab26a upstream. This has been reported to cause stalls on rt-linux. Suggested-by: Richard Weinberger Tested-by: Richard Weinberger Signed-off-by: Andri Yngvason Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/cc770/cc770.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 1e37313054f3..9fed163262e0 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c @@ -447,15 +447,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_bytes += dlc; - - /* - * HM: We had some cases of repeated IRQs so make sure the - * INT is acknowledged I know it's already further up, but - * doing again fixed the issue - */ - cc770_write_reg(priv, msgobj[mo].ctrl0, - MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); - return NETDEV_TX_OK; } @@ -684,12 +675,6 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o) /* Nothing more to send, switch off interrupts */ cc770_write_reg(priv, msgobj[mo].ctrl0, MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); - /* - * We had some cases of repeated IRQ so make sure the - * INT is acknowledged - */ - cc770_write_reg(priv, msgobj[mo].ctrl0, - MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); stats->tx_packets++; can_get_echo_skb(dev, 0); -- cgit v1.2.3 From 5fdbcc3d6db6f17ec43ef200353208a3a9cf7234 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Wed, 14 Mar 2018 11:52:57 +0000 Subject: can: cc770: Fix queue stall & dropped RTR reply commit 746201235b3f876792099079f4c6fea941d76183 upstream. While waiting for the TX object to send an RTR, an external message with a matching id can overwrite the TX data. In this case we must call the rx routine and then try transmitting the message that was overwritten again. The queue was being stalled because the RX event did not generate an interrupt to wake up the queue again and the TX event did not happen because the TXRQST flag is reset by the chip when new data is received. According to the CC770 datasheet the id of a message object should not be changed while the MSGVAL bit is set. This has been fixed by resetting the MSGVAL bit before modifying the object in the transmit function and setting it after. It is not enough to set & reset CPUUPD. It is important to keep the MSGVAL bit reset while the message object is being modified. Otherwise, during RTR transmission, a frame with matching id could trigger an rx-interrupt, which would cause a race condition between the interrupt routine and the transmit function. Signed-off-by: Andri Yngvason Tested-by: Richard Weinberger Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/cc770/cc770.c | 94 ++++++++++++++++++++++++++++++------------- drivers/net/can/cc770/cc770.h | 2 + 2 files changed, 68 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 9fed163262e0..2743d82d4424 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c @@ -390,37 +390,23 @@ static int cc770_get_berr_counter(const struct net_device *dev, return 0; } -static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) +static void cc770_tx(struct net_device *dev, int mo) { struct cc770_priv *priv = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct can_frame *cf = (struct can_frame *)skb->data; - unsigned int mo = obj2msgobj(CC770_OBJ_TX); + struct can_frame *cf = (struct can_frame *)priv->tx_skb->data; u8 dlc, rtr; u32 id; int i; - if (can_dropped_invalid_skb(dev, skb)) - return NETDEV_TX_OK; - - if ((cc770_read_reg(priv, - msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { - netdev_err(dev, "TX register is still occupied!\n"); - return NETDEV_TX_BUSY; - } - - netif_stop_queue(dev); - dlc = cf->can_dlc; id = cf->can_id; - if (cf->can_id & CAN_RTR_FLAG) - rtr = 0; - else - rtr = MSGCFG_DIR; + rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR; + + cc770_write_reg(priv, msgobj[mo].ctrl0, + MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); cc770_write_reg(priv, msgobj[mo].ctrl1, RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES); - cc770_write_reg(priv, msgobj[mo].ctrl0, - MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES); + if (id & CAN_EFF_FLAG) { id &= CAN_EFF_MASK; cc770_write_reg(priv, msgobj[mo].config, @@ -439,13 +425,30 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < dlc; i++) cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]); - /* Store echo skb before starting the transfer */ - can_put_echo_skb(skb, dev, 0); - cc770_write_reg(priv, msgobj[mo].ctrl1, - RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); + RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); + cc770_write_reg(priv, msgobj[mo].ctrl0, + MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC); +} + +static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct cc770_priv *priv = netdev_priv(dev); + unsigned int mo = obj2msgobj(CC770_OBJ_TX); + + if (can_dropped_invalid_skb(dev, skb)) + return NETDEV_TX_OK; - stats->tx_bytes += dlc; + netif_stop_queue(dev); + + if ((cc770_read_reg(priv, + msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { + netdev_err(dev, "TX register is still occupied!\n"); + return NETDEV_TX_BUSY; + } + + priv->tx_skb = skb; + cc770_tx(dev, mo); return NETDEV_TX_OK; } @@ -671,13 +674,47 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o) struct cc770_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; unsigned int mo = obj2msgobj(o); + struct can_frame *cf; + u8 ctrl1; + + ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); - /* Nothing more to send, switch off interrupts */ cc770_write_reg(priv, msgobj[mo].ctrl0, MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); + cc770_write_reg(priv, msgobj[mo].ctrl1, + RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES); - stats->tx_packets++; + if (unlikely(!priv->tx_skb)) { + netdev_err(dev, "missing tx skb in tx interrupt\n"); + return; + } + + if (unlikely(ctrl1 & MSGLST_SET)) { + stats->rx_over_errors++; + stats->rx_errors++; + } + + /* When the CC770 is sending an RTR message and it receives a regular + * message that matches the id of the RTR message, it will overwrite the + * outgoing message in the TX register. When this happens we must + * process the received message and try to transmit the outgoing skb + * again. + */ + if (unlikely(ctrl1 & NEWDAT_SET)) { + cc770_rx(dev, mo, ctrl1); + cc770_tx(dev, mo); + return; + } + + can_put_echo_skb(priv->tx_skb, dev, 0); can_get_echo_skb(dev, 0); + + cf = (struct can_frame *)priv->tx_skb->data; + stats->tx_bytes += cf->can_dlc; + stats->tx_packets++; + + priv->tx_skb = NULL; + netif_wake_queue(dev); } @@ -789,6 +826,7 @@ struct net_device *alloc_cc770dev(int sizeof_priv) priv->can.do_set_bittiming = cc770_set_bittiming; priv->can.do_set_mode = cc770_set_mode; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + priv->tx_skb = NULL; memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags)); diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h index a1739db98d91..95752e1d1283 100644 --- a/drivers/net/can/cc770/cc770.h +++ b/drivers/net/can/cc770/cc770.h @@ -193,6 +193,8 @@ struct cc770_priv { u8 cpu_interface; /* CPU interface register */ u8 clkout; /* Clock out register */ u8 bus_config; /* Bus conffiguration register */ + + struct sk_buff *tx_skb; }; struct net_device *alloc_cc770dev(int sizeof_priv); -- cgit v1.2.3 From 101a72edd98d2f87d112f21f81f796f584f1bd58 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Thu, 15 Mar 2018 18:23:17 +0000 Subject: can: cc770: Fix use after free in cc770_tx_interrupt() commit 9ffd7503944ec7c0ef41c3245d1306c221aef2be upstream. This fixes use after free introduced by the last cc770 patch. Signed-off-by: Andri Yngvason Fixes: 746201235b3f ("can: cc770: Fix queue stall & dropped RTR reply") Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/cc770/cc770.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 2743d82d4424..6da69af103e6 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c @@ -706,13 +706,12 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o) return; } - can_put_echo_skb(priv->tx_skb, dev, 0); - can_get_echo_skb(dev, 0); - cf = (struct can_frame *)priv->tx_skb->data; stats->tx_bytes += cf->can_dlc; stats->tx_packets++; + can_put_echo_skb(priv->tx_skb, dev, 0); + can_get_echo_skb(dev, 0); priv->tx_skb = NULL; netif_wake_queue(dev); -- cgit v1.2.3 From 7c28067736a24a19e0d646fea510357228e95910 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 24 Mar 2018 10:43:26 +0100 Subject: tty: vt: fix up tabstops properly commit f1869a890cdedb92a3fab969db5d0fd982850273 upstream. Tabs on a console with long lines do not wrap properly, so correctly account for the line length when computing the tab placement location. Reported-by: James Holderness Signed-off-by: Greg Kroah-Hartman Cc: stable Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index ce2c3c6349d4..68c7bb0b7991 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1727,7 +1727,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) default_attr(vc); update_attr(vc); - vc->vc_tab_stop[0] = 0x01010100; + vc->vc_tab_stop[0] = vc->vc_tab_stop[1] = vc->vc_tab_stop[2] = vc->vc_tab_stop[3] = @@ -1771,7 +1771,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) vc->vc_pos -= (vc->vc_x << 1); while (vc->vc_x < vc->vc_cols - 1) { vc->vc_x++; - if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31))) + if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31))) break; } vc->vc_pos += (vc->vc_x << 1); @@ -1831,7 +1831,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) lf(vc); return; case 'H': - vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31)); + vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31)); return; case 'Z': respond_ID(tty); @@ -2024,7 +2024,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) return; case 'g': if (!vc->vc_par[0]) - vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31)); + vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31)); else if (vc->vc_par[0] == 3) { vc->vc_tab_stop[0] = vc->vc_tab_stop[1] = -- cgit v1.2.3 From 1e0fc7dba23d8ecf8baee8ccf8440503f7013221 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Tue, 5 Sep 2017 20:25:25 +0000 Subject: staging: lustre: ptlrpc: kfree used instead of kvfree commit c3eec59659cf25916647d2178c541302bb4822ad upstream. rq_reqbuf is allocated using kvmalloc() but released in one occasion using kfree() instead of kvfree(). The issue was found using grep based on a similar bug. Fixes: d7e09d0397e8 ("add Lustre file system client support") Fixes: ee0ec1946ec2 ("lustre: ptlrpc: Replace uses of OBD_{ALLOC,FREE}_LARGE") Cc: Peng Tao Cc: Oleg Drokin Cc: James Simmons Signed-off-by: Nadav Amit Signed-off-by: Andreas Dilger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c index a7416cd9ac71..7b0587d8b176 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -838,7 +838,7 @@ void sptlrpc_request_out_callback(struct ptlrpc_request *req) if (req->rq_pool || !req->rq_reqbuf) return; - kfree(req->rq_reqbuf); + kvfree(req->rq_reqbuf); req->rq_reqbuf = NULL; req->rq_reqbuf_len = 0; } -- cgit v1.2.3 From 6505dd1f7f55b180439c15d788bc5dea244a4781 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Wed, 10 May 2017 09:53:40 +0200 Subject: scsi: sg: don't return bogus Sg_requests commit 48ae8484e9fc324b4968d33c585e54bc98e44d61 upstream. If the list search in sg_get_rq_mark() fails to find a valid request, we return a bogus element. This then can later lead to a GPF in sg_remove_scat(). So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the list search doesn't find a valid request. Signed-off-by: Johannes Thumshirn Reported-by: Andrey Konovalov Cc: Hannes Reinecke Cc: Christoph Hellwig Cc: Doug Gilbert Reviewed-by: Hannes Reinecke Acked-by: Doug Gilbert Signed-off-by: Martin K. Petersen Cc: Tony Battersby Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7592ac8514d2..f61b37109e5c 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2064,11 +2064,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id) if ((1 == resp->done) && (!resp->sg_io_owned) && ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { resp->done = 2; /* guard against other readers */ - break; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return resp; } } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); - return resp; + return NULL; } /* always adds to end of list */ -- cgit v1.2.3 From fe3627f6761c40a408d426488fb638bc3c6a8ab7 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Tue, 20 Mar 2018 16:49:26 +0100 Subject: ppp: avoid loop in xmit recursion detection code [ Upstream commit 6d066734e9f09cdea4a3b9cb76136db3f29cfb02 ] We already detect situations where a PPP channel sends packets back to its upper PPP device. While this is enough to avoid deadlocking on xmit locks, this doesn't prevent packets from looping between the channel and the unit. The problem is that ppp_start_xmit() enqueues packets in ppp->file.xq before checking for xmit recursion. Therefore, __ppp_xmit_process() might dequeue a packet from ppp->file.xq and send it on the channel which, in turn, loops it back on the unit. Then ppp_start_xmit() queues the packet back to ppp->file.xq and __ppp_xmit_process() picks it up and sends it again through the channel. Therefore, the packet will loop between __ppp_xmit_process() and ppp_start_xmit() until some other part of the xmit path drops it. For L2TP, we rapidly fill the skb's headroom and pppol2tp_xmit() drops the packet after a few iterations. But PPTP reallocates the headroom if necessary, letting the loop run and exhaust the machine resources (as reported in https://bugzilla.kernel.org/show_bug.cgi?id=199109). Fix this by letting __ppp_xmit_process() enqueue the skb to ppp->file.xq, so that we can check for recursion before adding it to the queue. Now ppp_xmit_process() can drop the packet when recursion is detected. __ppp_channel_push() is a bit special. It calls __ppp_xmit_process() without having any actual packet to send. This is used by ppp_output_wakeup() to re-enable transmission on the parent unit (for implementations like ppp_async.c, where the .start_xmit() function might not consume the skb, leaving it in ppp->xmit_pending and disabling transmission). Therefore, __ppp_xmit_process() needs to handle the case where skb is NULL, dequeuing as many packets as possible from ppp->file.xq. Reported-by: xu heng Fixes: 55454a565836 ("ppp: avoid dealock on recursive xmit") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ppp/ppp_generic.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 114457921890..1e4969d90f1a 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -255,7 +255,7 @@ struct ppp_net { /* Prototypes. */ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, struct file *file, unsigned int cmd, unsigned long arg); -static void ppp_xmit_process(struct ppp *ppp); +static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb); static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); static void ppp_push(struct ppp *ppp); static void ppp_channel_push(struct channel *pch); @@ -511,13 +511,12 @@ static ssize_t ppp_write(struct file *file, const char __user *buf, goto out; } - skb_queue_tail(&pf->xq, skb); - switch (pf->kind) { case INTERFACE: - ppp_xmit_process(PF_TO_PPP(pf)); + ppp_xmit_process(PF_TO_PPP(pf), skb); break; case CHANNEL: + skb_queue_tail(&pf->xq, skb); ppp_channel_push(PF_TO_CHANNEL(pf)); break; } @@ -1261,8 +1260,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) put_unaligned_be16(proto, pp); skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev))); - skb_queue_tail(&ppp->file.xq, skb); - ppp_xmit_process(ppp); + ppp_xmit_process(ppp, skb); + return NETDEV_TX_OK; outf: @@ -1416,13 +1415,14 @@ static void ppp_setup(struct net_device *dev) */ /* Called to do any work queued up on the transmit side that can now be done */ -static void __ppp_xmit_process(struct ppp *ppp) +static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb) { - struct sk_buff *skb; - ppp_xmit_lock(ppp); if (!ppp->closing) { ppp_push(ppp); + + if (skb) + skb_queue_tail(&ppp->file.xq, skb); while (!ppp->xmit_pending && (skb = skb_dequeue(&ppp->file.xq))) ppp_send_frame(ppp, skb); @@ -1436,7 +1436,7 @@ static void __ppp_xmit_process(struct ppp *ppp) ppp_xmit_unlock(ppp); } -static void ppp_xmit_process(struct ppp *ppp) +static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb) { local_bh_disable(); @@ -1444,7 +1444,7 @@ static void ppp_xmit_process(struct ppp *ppp) goto err; (*this_cpu_ptr(ppp->xmit_recursion))++; - __ppp_xmit_process(ppp); + __ppp_xmit_process(ppp, skb); (*this_cpu_ptr(ppp->xmit_recursion))--; local_bh_enable(); @@ -1454,6 +1454,8 @@ static void ppp_xmit_process(struct ppp *ppp) err: local_bh_enable(); + kfree_skb(skb); + if (net_ratelimit()) netdev_err(ppp->dev, "recursion detected\n"); } @@ -1938,7 +1940,7 @@ static void __ppp_channel_push(struct channel *pch) if (skb_queue_empty(&pch->file.xq)) { ppp = pch->ppp; if (ppp) - __ppp_xmit_process(ppp); + __ppp_xmit_process(ppp, NULL); } } -- cgit v1.2.3 From e9f83a8b4aaba8f458c244c7455f8a4ea31e8a28 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 18 Mar 2018 23:59:36 +0100 Subject: net: ethernet: arc: Fix a potential memory leak if an optional regulator is deferred [ Upstream commit 00777fac28ba3e126b9e63e789a613e8bd2cab25 ] If the optional regulator is deferred, we must release some resources. They will be re-allocated when the probe function will be called again. Fixes: 6eacf31139bf ("ethernet: arc: Add support for Rockchip SoC layer device tree bindings") Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/arc/emac_rockchip.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index c6163874e4e7..c770ca37c9b2 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -169,8 +169,10 @@ static int emac_rockchip_probe(struct platform_device *pdev) /* Optional regulator for PHY */ priv->regulator = devm_regulator_get_optional(dev, "phy"); if (IS_ERR(priv->regulator)) { - if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) { + err = -EPROBE_DEFER; + goto out_clk_disable; + } dev_err(dev, "no regulator found\n"); priv->regulator = NULL; } -- cgit v1.2.3 From 1f7a395708b3b061109440f23e42de683a0bcdbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?= Date: Fri, 16 Mar 2018 00:56:01 +0800 Subject: net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f9db50691db4a7d860fce985f080bb3fc23a7ede ] According to AM335x TRM[1] 14.3.6.2, AM437x TRM[2] 15.3.6.2 and DRA7 TRM[3] 24.11.4.8.7.3.3, in-band mode in EXT_EN(bit18) register is only available when PHY is configured in RGMII mode with 10Mbps speed. It will cause some networking issues without RGMII mode, such as carrier sense errors and low throughput. TI also mentioned this issue in their forum[4]. This patch adds the check mechanism for PHY interface with RGMII interface type, the in-band mode can only be set in RGMII mode with 10Mbps speed. References: [1]: https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf [2]: http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf [3]: http://www.ti.com/lit/ug/spruic2b/spruic2b.pdf [4]: https://e2e.ti.com/support/arm/sitara_arm/f/791/p/640765/2392155 Suggested-by: Holsety Chen (陳憲輝) Signed-off-by: SZ Lin (林上智) Signed-off-by: Schuyler Patton Reviewed-by: Grygorii Strashko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ti/cpsw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 3f1971d485f3..2bd1282735b0 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -901,7 +901,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, /* set speed_in input in case RMII mode is used in 100Mbps */ if (phy->speed == 100) mac_control |= BIT(15); - else if (phy->speed == 10) + /* in band mode only works in 10Mbps RGMII mode */ + else if ((phy->speed == 10) && phy_interface_is_rgmii(phy)) mac_control |= BIT(18); /* In Band mode */ if (priv->rx_pause) -- cgit v1.2.3 From c3860a3855e4445d215279561c02a7426c344949 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 18 Mar 2018 12:49:51 -0700 Subject: net: fec: Fix unbalanced PM runtime calls [ Upstream commit a069215cf5985f3aa1bba550264907d6bd05c5f7 ] When unbinding/removing the driver, we will run into the following warnings: [ 259.655198] fec 400d1000.ethernet: 400d1000.ethernet supply phy not found, using dummy regulator [ 259.665065] fec 400d1000.ethernet: Unbalanced pm_runtime_enable! [ 259.672770] fec 400d1000.ethernet (unnamed net_device) (uninitialized): Invalid MAC address: 00:00:00:00:00:00 [ 259.683062] fec 400d1000.ethernet (unnamed net_device) (uninitialized): Using random MAC address: f2:3e:93:b7:29:c1 [ 259.696239] libphy: fec_enet_mii_bus: probed Avoid these warnings by balancing the runtime PM calls during fec_drv_remove(). Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index dd6e07c748f5..05e5b38e4891 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3533,6 +3533,8 @@ fec_drv_remove(struct platform_device *pdev) fec_enet_mii_remove(fep); if (fep->reg_phy) regulator_disable(fep->reg_phy); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(fep->phy_node); -- cgit v1.2.3 From b14031144e37fd5f53a6a4a1359d91b0210ca47f Mon Sep 17 00:00:00 2001 From: Arkadi Sharshevsky Date: Thu, 8 Mar 2018 12:42:10 +0200 Subject: team: Fix double free in error path [ Upstream commit cbcc607e18422555db569b593608aec26111cb0b ] The __send_and_alloc_skb() receives a skb ptr as a parameter but in case it fails the skb is not valid: - Send failed and released the skb internally. - Allocation failed. The current code tries to release the skb in case of failure which causes redundant freeing. Fixes: 9b00cf2d1024 ("team: implement multipart netlink messages for options transfers") Signed-off-by: Arkadi Sharshevsky Acked-by: Jiri Pirko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 26681707fc7a..a0a9c9d39f01 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -2403,7 +2403,7 @@ send_done: if (!nlh) { err = __send_and_alloc_skb(&skb, team, portid, send_func); if (err) - goto errout; + return err; goto send_done; } @@ -2688,7 +2688,7 @@ send_done: if (!nlh) { err = __send_and_alloc_skb(&skb, team, portid, send_func); if (err) - goto errout; + return err; goto send_done; } -- cgit v1.2.3 From a85c525bbff4d7467d7f0ab6fed8e2f787b073d6 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 14 Mar 2018 08:37:28 -0500 Subject: soc/fsl/qbman: fix issue in qman_delete_cgr_safe() [ Upstream commit 96f413f47677366e0ae03797409bfcc4151dbf9e ] The wait_for_completion() call in qman_delete_cgr_safe() was triggering a scheduling while atomic bug, replacing the kthread with a smp_call_function_single() call to fix it. Signed-off-by: Madalin Bucur Signed-off-by: Roy Pledge Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/soc/fsl/qbman/qman.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 119054bc922b..2caacd9d2526 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -2429,39 +2429,21 @@ struct cgr_comp { struct completion completion; }; -static int qman_delete_cgr_thread(void *p) +static void qman_delete_cgr_smp_call(void *p) { - struct cgr_comp *cgr_comp = (struct cgr_comp *)p; - int ret; - - ret = qman_delete_cgr(cgr_comp->cgr); - complete(&cgr_comp->completion); - - return ret; + qman_delete_cgr((struct qman_cgr *)p); } void qman_delete_cgr_safe(struct qman_cgr *cgr) { - struct task_struct *thread; - struct cgr_comp cgr_comp; - preempt_disable(); if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { - init_completion(&cgr_comp.completion); - cgr_comp.cgr = cgr; - thread = kthread_create(qman_delete_cgr_thread, &cgr_comp, - "cgr_del"); - - if (IS_ERR(thread)) - goto out; - - kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]); - wake_up_process(thread); - wait_for_completion(&cgr_comp.completion); + smp_call_function_single(qman_cgr_cpus[cgr->cgrid], + qman_delete_cgr_smp_call, cgr, true); preempt_enable(); return; } -out: + qman_delete_cgr(cgr); preempt_enable(); } -- cgit v1.2.3 From 4593b4c08262434e8f662f12c171a9b8c85dcec4 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 20 Mar 2018 07:59:12 +0100 Subject: s390/qeth: free netdevice when removing a card [ Upstream commit 6be687395b3124f002a653c1a50b3260222b3cd7 ] On removal, a qeth card's netdevice is currently not properly freed because the call chain looks as follows: qeth_core_remove_device(card) lx_remove_device(card) unregister_netdev(card->dev) card->dev = NULL !!! qeth_core_free_card(card) if (card->dev) !!! free_netdev(card->dev) Fix it by free'ing the netdev straight after unregistering. This also fixes the sysfs-driven layer switch case (qeth_dev_layer2_store()), where the need to free the current netdevice was not considered at all. Note that free_netdev() takes care of the netif_napi_del() for us too. Fixes: 4a71df50047f ("qeth: new qeth device driver") Signed-off-by: Julian Wiedmann Reviewed-by: Ursula Braun Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 2 -- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index cc28dda322b5..3e7d54c1437a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4989,8 +4989,6 @@ static void qeth_core_free_card(struct qeth_card *card) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_clean_channel(&card->read); qeth_clean_channel(&card->write); - if (card->dev) - free_netdev(card->dev); qeth_free_qdio_buffers(card); unregister_service_level(&card->qeth_service_level); kfree(card); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5082dfeacb95..e94e9579914e 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1057,8 +1057,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) qeth_l2_set_offline(cgdev); if (card->dev) { - netif_napi_del(&card->napi); unregister_netdev(card->dev); + free_netdev(card->dev); card->dev = NULL; } return; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index a668e6b71a29..4ca161bdc696 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3192,8 +3192,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) qeth_l3_set_offline(cgdev); if (card->dev) { - netif_napi_del(&card->napi); unregister_netdev(card->dev); + free_netdev(card->dev); card->dev = NULL; } -- cgit v1.2.3 From 9ff2636b3bbfcf4606d050fbbfa2f792ab566b93 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 20 Mar 2018 07:59:13 +0100 Subject: s390/qeth: when thread completes, wake up all waiters [ Upstream commit 1063e432bb45be209427ed3f1ca3908e4aa3c7d7 ] qeth_wait_for_threads() is potentially called by multiple users, make sure to notify all of them after qeth_clear_thread_running_bit() adjusted the thread_running_mask. With no timeout, callers would otherwise stall. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3e7d54c1437a..8b1763bf1840 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -957,7 +957,7 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread) spin_lock_irqsave(&card->thread_mask_lock, flags); card->thread_running_mask &= ~thread; spin_unlock_irqrestore(&card->thread_mask_lock, flags); - wake_up(&card->wait_q); + wake_up_all(&card->wait_q); } EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit); -- cgit v1.2.3 From 3426c365e7f92a538ec7b067134fc42839e75ca7 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 20 Mar 2018 07:59:14 +0100 Subject: s390/qeth: lock read device while queueing next buffer [ Upstream commit 17bf8c9b3d499d5168537c98b61eb7a1fcbca6c2 ] For calling ccw_device_start(), issue_next_read() needs to hold the device's ccwlock. This is satisfied for the IRQ handler path (where qeth_irq() gets called under the ccwlock), but we need explicit locking for the initial call by the MPC initialization. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 8b1763bf1840..3c44c80cc66c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -522,8 +522,7 @@ static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue) queue == card->qdio.no_in_queues - 1; } - -static int qeth_issue_next_read(struct qeth_card *card) +static int __qeth_issue_next_read(struct qeth_card *card) { int rc; struct qeth_cmd_buffer *iob; @@ -554,6 +553,17 @@ static int qeth_issue_next_read(struct qeth_card *card) return rc; } +static int qeth_issue_next_read(struct qeth_card *card) +{ + int ret; + + spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card))); + ret = __qeth_issue_next_read(card); + spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card))); + + return ret; +} + static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) { struct qeth_reply *reply; @@ -1179,7 +1189,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, return; if (channel == &card->read && channel->state == CH_STATE_UP) - qeth_issue_next_read(card); + __qeth_issue_next_read(card); iob = channel->iob; index = channel->buf_no; -- cgit v1.2.3 From 4751804da25788691602663562bbadfa5f2cb9a1 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 20 Mar 2018 07:59:15 +0100 Subject: s390/qeth: on channel error, reject further cmd requests [ Upstream commit a6c3d93963e4b333c764fde69802c3ea9eaa9d5c ] When the IRQ handler determines that one of the cmd IO channels has failed and schedules recovery, block any further cmd requests from being submitted. The request would inevitably stall, and prevent the recovery from making progress until the request times out. This sort of error was observed after Live Guest Relocation, where the pending IO on the READ channel intentionally gets terminated to kick-start recovery. Simultaneously the guest executed SIOCETHTOOL, triggering qeth to issue a QUERY CARD INFO command. The command then stalled in the inoperabel WRITE channel. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_core_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3c44c80cc66c..283416aefa56 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1171,6 +1171,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } rc = qeth_get_problem(cdev, irb); if (rc) { + card->read_or_write_problem = 1; qeth_clear_ipacmd_list(card); qeth_schedule_recovery(card); goto out; -- cgit v1.2.3 From 002f45571f6b498d417ba1dcc91bd59d386303a2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 13 Mar 2018 14:45:07 -0700 Subject: net: systemport: Rewrite __bcm_sysport_tx_reclaim() [ Upstream commit 484d802d0f2f29c335563fcac2a8facf174a1bbc ] There is no need for complex checking between the last consumed index and current consumed index, a simple subtraction will do. This also eliminates the possibility of a permanent transmit queue stall under the following conditions: - one CPU bursts ring->size worth of traffic (up to 256 buffers), to the point where we run out of free descriptors, so we stop the transmit queue at the end of bcm_sysport_xmit() - because of our locking, we have the transmit process disable interrupts which means we can be blocking the TX reclamation process - when TX reclamation finally runs, we will be computing the difference between ring->c_index (last consumed index by SW) and what the HW reports through its register - this register is masked with (ring->size - 1) = 0xff, which will lead to stripping the upper bits of the index (register is 16-bits wide) - we will be computing last_tx_cn as 0, which means there is no work to be done, and we never wake-up the transmit queue, leaving it permanently disabled A practical example is e.g: ring->c_index aka last_c_index = 12, we pushed 256 entries, HW consumer index = 268, we mask it with 0xff = 12, so last_tx_cn == 0, nothing happens. Fixes: 80105befdb4b ("net: systemport: add Broadcom SYSTEMPORT Ethernet MAC driver") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bcmsysport.c | 33 ++++++++++++++---------------- drivers/net/ethernet/broadcom/bcmsysport.h | 2 +- 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 744ed6ddaf37..91fbba58d033 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -707,37 +707,33 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, struct bcm_sysport_tx_ring *ring) { struct net_device *ndev = priv->netdev; - unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs; unsigned int pkts_compl = 0, bytes_compl = 0; + unsigned int txbds_processed = 0; struct bcm_sysport_cb *cb; + unsigned int txbds_ready; + unsigned int c_index; u32 hw_ind; /* Compute how many descriptors have been processed since last call */ hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index)); c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK; - ring->p_index = (hw_ind & RING_PROD_INDEX_MASK); - - last_c_index = ring->c_index; - num_tx_cbs = ring->size; - - c_index &= (num_tx_cbs - 1); - - if (c_index >= last_c_index) - last_tx_cn = c_index - last_c_index; - else - last_tx_cn = num_tx_cbs - last_c_index + c_index; + txbds_ready = (c_index - ring->c_index) & RING_CONS_INDEX_MASK; netif_dbg(priv, tx_done, ndev, - "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n", - ring->index, c_index, last_tx_cn, last_c_index); + "ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n", + ring->index, ring->c_index, c_index, txbds_ready); - while (last_tx_cn-- > 0) { - cb = ring->cbs + last_c_index; + while (txbds_processed < txbds_ready) { + cb = &ring->cbs[ring->clean_index]; bcm_sysport_tx_reclaim_one(priv, cb, &bytes_compl, &pkts_compl); ring->desc_count++; - last_c_index++; - last_c_index &= (num_tx_cbs - 1); + txbds_processed++; + + if (likely(ring->clean_index < ring->size - 1)) + ring->clean_index++; + else + ring->clean_index = 0; } ring->c_index = c_index; @@ -1207,6 +1203,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64); ring->index = index; ring->size = size; + ring->clean_index = 0; ring->alloc_size = ring->size; ring->desc_cpu = p; ring->desc_count = ring->size; diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index 1c82e3da69a7..07b0aaa98de0 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h @@ -638,7 +638,7 @@ struct bcm_sysport_tx_ring { unsigned int desc_count; /* Number of descriptors */ unsigned int curr_desc; /* Current descriptor */ unsigned int c_index; /* Last consumer index */ - unsigned int p_index; /* Current producer index */ + unsigned int clean_index; /* Current clean index */ struct bcm_sysport_cb *cbs; /* Transmit control blocks */ struct dma_desc *desc_cpu; /* CPU view of the descriptor */ struct bcm_sysport_priv *priv; /* private context backpointer */ -- cgit v1.2.3 From a8f4be0168d5bf0c8838ca08301ae5341208dfba Mon Sep 17 00:00:00 2001 From: Yunsheng Lin Date: Thu, 6 Jul 2017 10:22:00 +0800 Subject: net: hns: Fix a skb used after free bug commit 27463ad99f738ed93c7c8b3e2e5bc8c4853a2ff2 upstream. skb maybe freed in hns_nic_net_xmit_hw() and return NETDEV_TX_OK, which cause hns_nic_net_xmit to use a freed skb. BUG: KASAN: use-after-free in hns_nic_net_xmit_hw+0x62c/0x940... [17659.112635] alloc_debug_processing+0x18c/0x1a0 [17659.117208] __slab_alloc+0x52c/0x560 [17659.120909] kmem_cache_alloc_node+0xac/0x2c0 [17659.125309] __alloc_skb+0x6c/0x260 [17659.128837] tcp_send_ack+0x8c/0x280 [17659.132449] __tcp_ack_snd_check+0x9c/0xf0 [17659.136587] tcp_rcv_established+0x5a4/0xa70 [17659.140899] tcp_v4_do_rcv+0x27c/0x620 [17659.144687] tcp_prequeue_process+0x108/0x170 [17659.149085] tcp_recvmsg+0x940/0x1020 [17659.152787] inet_recvmsg+0x124/0x180 [17659.156488] sock_recvmsg+0x64/0x80 [17659.160012] SyS_recvfrom+0xd8/0x180 [17659.163626] __sys_trace_return+0x0/0x4 [17659.167506] INFO: Freed in kfree_skbmem+0xa0/0xb0 age=23 cpu=1 pid=13 [17659.174000] free_debug_processing+0x1d4/0x2c0 [17659.178486] __slab_free+0x240/0x390 [17659.182100] kmem_cache_free+0x24c/0x270 [17659.186062] kfree_skbmem+0xa0/0xb0 [17659.189587] __kfree_skb+0x28/0x40 [17659.193025] napi_gro_receive+0x168/0x1c0 [17659.197074] hns_nic_rx_up_pro+0x58/0x90 [17659.201038] hns_nic_rx_poll_one+0x518/0xbc0 [17659.205352] hns_nic_common_poll+0x94/0x140 [17659.209576] net_rx_action+0x458/0x5e0 [17659.213363] __do_softirq+0x1b8/0x480 [17659.217062] run_ksoftirqd+0x64/0x80 [17659.220679] smpboot_thread_fn+0x224/0x310 [17659.224821] kthread+0x150/0x170 [17659.228084] ret_from_fork+0x10/0x40 BUG: KASAN: use-after-free in hns_nic_net_xmit+0x8c/0xc0... [17751.080490] __slab_alloc+0x52c/0x560 [17751.084188] kmem_cache_alloc+0x244/0x280 [17751.088238] __build_skb+0x40/0x150 [17751.091764] build_skb+0x28/0x100 [17751.095115] __alloc_rx_skb+0x94/0x150 [17751.098900] __napi_alloc_skb+0x34/0x90 [17751.102776] hns_nic_rx_poll_one+0x180/0xbc0 [17751.107097] hns_nic_common_poll+0x94/0x140 [17751.111333] net_rx_action+0x458/0x5e0 [17751.115123] __do_softirq+0x1b8/0x480 [17751.118823] run_ksoftirqd+0x64/0x80 [17751.122437] smpboot_thread_fn+0x224/0x310 [17751.126575] kthread+0x150/0x170 [17751.129838] ret_from_fork+0x10/0x40 [17751.133454] INFO: Freed in kfree_skbmem+0xa0/0xb0 age=19 cpu=7 pid=43 [17751.139951] free_debug_processing+0x1d4/0x2c0 [17751.144436] __slab_free+0x240/0x390 [17751.148051] kmem_cache_free+0x24c/0x270 [17751.152014] kfree_skbmem+0xa0/0xb0 [17751.155543] __kfree_skb+0x28/0x40 [17751.159022] napi_gro_receive+0x168/0x1c0 [17751.163074] hns_nic_rx_up_pro+0x58/0x90 [17751.167041] hns_nic_rx_poll_one+0x518/0xbc0 [17751.171358] hns_nic_common_poll+0x94/0x140 [17751.175585] net_rx_action+0x458/0x5e0 [17751.179373] __do_softirq+0x1b8/0x480 [17751.183076] run_ksoftirqd+0x64/0x80 [17751.186691] smpboot_thread_fn+0x224/0x310 [17751.190826] kthread+0x150/0x170 [17751.194093] ret_from_fork+0x10/0x40 Fixes: 13ac695e7ea1 ("net:hns: Add support of Hip06 SoC to the Hislicon Network Subsystem") Signed-off-by: Yunsheng Lin Signed-off-by: lipeng Reported-by: Jun He Signed-off-by: David S. Miller Signed-off-by: Erick Reyes Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 22 ++++++++++------------ drivers/net/ethernet/hisilicon/hns/hns_enet.h | 6 +++--- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index a79e0a1100aa..111e1aab7d83 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -299,9 +299,9 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv, mtu); } -int hns_nic_net_xmit_hw(struct net_device *ndev, - struct sk_buff *skb, - struct hns_nic_ring_data *ring_data) +netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + struct sk_buff *skb, + struct hns_nic_ring_data *ring_data) { struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_ring *ring = ring_data->ring; @@ -360,6 +360,10 @@ int hns_nic_net_xmit_hw(struct net_device *ndev, dev_queue = netdev_get_tx_queue(ndev, skb->queue_mapping); netdev_tx_sent_queue(dev_queue, skb->len); + netif_trans_update(ndev); + ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_packets++; + wmb(); /* commit all data before submit */ assert(skb->queue_mapping < priv->ae_handle->q_num); hnae_queue_xmit(priv->ae_handle->qs[skb->queue_mapping], buf_num); @@ -1408,17 +1412,11 @@ static netdev_tx_t hns_nic_net_xmit(struct sk_buff *skb, struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); - int ret; assert(skb->queue_mapping < ndev->ae_handle->q_num); - ret = hns_nic_net_xmit_hw(ndev, skb, - &tx_ring_data(priv, skb->queue_mapping)); - if (ret == NETDEV_TX_OK) { - netif_trans_update(ndev); - ndev->stats.tx_bytes += skb->len; - ndev->stats.tx_packets++; - } - return (netdev_tx_t)ret; + + return hns_nic_net_xmit_hw(ndev, skb, + &tx_ring_data(priv, skb->queue_mapping)); } static int hns_nic_change_mtu(struct net_device *ndev, int new_mtu) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h index 5b412de350aa..7bc6a6ecd666 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h @@ -91,8 +91,8 @@ void hns_ethtool_set_ops(struct net_device *ndev); void hns_nic_net_reset(struct net_device *ndev); void hns_nic_net_reinit(struct net_device *netdev); int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h); -int hns_nic_net_xmit_hw(struct net_device *ndev, - struct sk_buff *skb, - struct hns_nic_ring_data *ring_data); +netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, + struct sk_buff *skb, + struct hns_nic_ring_data *ring_data); #endif /**__HNS_ENET_H */ -- cgit v1.2.3 From 760adf5cc0e042ad1f0cd54c267c0377d4b40b1e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 3 Mar 2018 23:29:03 +0100 Subject: mtd: jedec_probe: Fix crash in jedec_read_mfr() commit 87a73eb5b56fd6e07c8e499fe8608ef2d8912b82 upstream. It turns out that the loop where we read manufacturer jedec_read_mfd() can under some circumstances get a CFI_MFR_CONTINUATION repeatedly, making the loop go over all banks and eventually hit the end of the map and crash because of an access violation: Unable to handle kernel paging request at virtual address c4980000 pgd = (ptrval) [c4980000] *pgd=03808811, *pte=00000000, *ppte=00000000 Internal error: Oops: 7 [#1] PREEMPT ARM CPU: 0 PID: 1 Comm: swapper Not tainted 4.16.0-rc1+ #150 Hardware name: Gemini (Device Tree) PC is at jedec_probe_chip+0x6ec/0xcd0 LR is at 0x4 pc : [] lr : [<00000004>] psr: 60000013 sp : c382dd18 ip : 0000ffff fp : 00000000 r10: c0626388 r9 : 00020000 r8 : c0626340 r7 : 00000000 r6 : 00000001 r5 : c3a71afc r4 : c382dd70 r3 : 00000001 r2 : c4900000 r1 : 00000002 r0 : 00080000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 0000397f Table: 00004000 DAC: 00000053 Process swapper (pid: 1, stack limit = 0x(ptrval)) Fix this by breaking the loop with a return 0 if the offset exceeds the map size. Fixes: 5c9c11e1c47c ("[MTD] [NOR] Add support for flash chips with ID in bank other than 0") Cc: Signed-off-by: Linus Walleij Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/chips/jedec_probe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 7c0b27d132b1..b479bd81120b 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1889,6 +1889,8 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, do { uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); mask = (1 << (cfi->device_type * 8)) - 1; + if (ofs >= map->size) + return 0; result = map_read(map, base + ofs); bank++; } while ((result.x[0] & mask) == CFI_MFR_CONTINUATION); -- cgit v1.2.3 From 4d9a121dc9b3c0907bc8bc23dd5445cea1192fb3 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 14 Apr 2017 13:38:02 -0700 Subject: PCI: Make PCI_ROM_ADDRESS_MASK a 32-bit constant commit 76dc52684d0f72971d9f6cc7d5ae198061b715bd upstream. A 64-bit value is not needed since a PCI ROM address consists in 32 bits. This fixes a clang warning about "implicit conversion from 'unsigned long' to 'u32'". Also remove now unnecessary casts to u32 from __pci_read_base() and pci_std_update_resource(). Signed-off-by: Matthias Kaehlcke Signed-off-by: Bjorn Helgaas Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 2 +- drivers/pci/setup-res.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a98be6db7e93..56340abe4fc6 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -231,7 +231,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= IORESOURCE_ROM_ENABLE; l64 = l & PCI_ROM_ADDRESS_MASK; sz64 = sz & PCI_ROM_ADDRESS_MASK; - mask64 = (u32)PCI_ROM_ADDRESS_MASK; + mask64 = PCI_ROM_ADDRESS_MASK; } if (res->flags & IORESOURCE_MEM_64) { diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 4bc589ee78d0..85774b7a316a 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -63,7 +63,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) mask = (u32)PCI_BASE_ADDRESS_IO_MASK; new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; } else if (resno == PCI_ROM_RESOURCE) { - mask = (u32)PCI_ROM_ADDRESS_MASK; + mask = PCI_ROM_ADDRESS_MASK; } else { mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; -- cgit v1.2.3 From 6be48fd6991f14f46f041fcd82614e3b2f5172f5 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 17 Apr 2017 11:05:03 -0700 Subject: dm ioctl: remove double parentheses commit e36215d87f301f9567c8c99fd34e6c3521a94ddf upstream. The extra pair of parantheses is not needed and causes clang to generate warnings about the DM_DEV_CREATE_CMD comparison in validate_params(). Also remove another double parentheses that doesn't cause a warning. Signed-off-by: Matthias Kaehlcke Signed-off-by: Mike Snitzer Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index a68c650aad11..b67414b5a64e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1777,12 +1777,12 @@ static int validate_params(uint cmd, struct dm_ioctl *param) cmd == DM_LIST_VERSIONS_CMD) return 0; - if ((cmd == DM_DEV_CREATE_CMD)) { + if (cmd == DM_DEV_CREATE_CMD) { if (!*param->name) { DMWARN("name not supplied when creating device"); return -EINVAL; } - } else if ((*param->uuid && *param->name)) { + } else if (*param->uuid && *param->name) { DMWARN("only supply one of name or uuid, cmd(%u)", cmd); return -EINVAL; } -- cgit v1.2.3 From b4361da43816836e2a28b266dc7ae4c12d754edb Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Sat, 24 Jun 2017 22:50:12 -0700 Subject: Input: mousedev - fix implicit conversion warning commit dae1a432ab1fe79ae53129ededeaece35a2dc14d upstream. Clang warns: drivers/input/mousedev.c:653:63: error: implicit conversion from 'int' to 'signed char' changes value from 200 to -56 [-Wconstant-conversion] client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; ~ ^~~ As the PS2 data is really a stream of bytes, let's switch to using u8 type for it, which silences this warning. Signed-off-by: Nick Desaulniers Signed-off-by: Dmitry Torokhov Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/input/mousedev.c | 62 ++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index b604564dec5c..30328e57fdda 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -15,6 +15,7 @@ #define MOUSEDEV_MINORS 31 #define MOUSEDEV_MIX 63 +#include #include #include #include @@ -103,7 +104,7 @@ struct mousedev_client { spinlock_t packet_lock; int pos_x, pos_y; - signed char ps2[6]; + u8 ps2[6]; unsigned char ready, buffer, bufsiz; unsigned char imexseq, impsseq; enum mousedev_emul mode; @@ -291,11 +292,10 @@ static void mousedev_notify_readers(struct mousedev *mousedev, } client->pos_x += packet->dx; - client->pos_x = client->pos_x < 0 ? - 0 : (client->pos_x >= xres ? xres : client->pos_x); + client->pos_x = clamp_val(client->pos_x, 0, xres); + client->pos_y += packet->dy; - client->pos_y = client->pos_y < 0 ? - 0 : (client->pos_y >= yres ? yres : client->pos_y); + client->pos_y = clamp_val(client->pos_y, 0, yres); p->dx += packet->dx; p->dy += packet->dy; @@ -571,44 +571,50 @@ static int mousedev_open(struct inode *inode, struct file *file) return error; } -static inline int mousedev_limit_delta(int delta, int limit) -{ - return delta > limit ? limit : (delta < -limit ? -limit : delta); -} - -static void mousedev_packet(struct mousedev_client *client, - signed char *ps2_data) +static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data) { struct mousedev_motion *p = &client->packets[client->tail]; + s8 dx, dy, dz; + + dx = clamp_val(p->dx, -127, 127); + p->dx -= dx; + + dy = clamp_val(p->dy, -127, 127); + p->dy -= dy; - ps2_data[0] = 0x08 | - ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); - ps2_data[1] = mousedev_limit_delta(p->dx, 127); - ps2_data[2] = mousedev_limit_delta(p->dy, 127); - p->dx -= ps2_data[1]; - p->dy -= ps2_data[2]; + ps2_data[0] = BIT(3); + ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2); + ps2_data[0] |= p->buttons & 0x07; + ps2_data[1] = dx; + ps2_data[2] = dy; switch (client->mode) { case MOUSEDEV_EMUL_EXPS: - ps2_data[3] = mousedev_limit_delta(p->dz, 7); - p->dz -= ps2_data[3]; - ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); + dz = clamp_val(p->dz, -7, 7); + p->dz -= dz; + + ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1); client->bufsiz = 4; break; case MOUSEDEV_EMUL_IMPS: - ps2_data[0] |= - ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); - ps2_data[3] = mousedev_limit_delta(p->dz, 127); - p->dz -= ps2_data[3]; + dz = clamp_val(p->dz, -127, 127); + p->dz -= dz; + + ps2_data[0] |= ((p->buttons & 0x10) >> 3) | + ((p->buttons & 0x08) >> 1); + ps2_data[3] = dz; + client->bufsiz = 4; break; case MOUSEDEV_EMUL_PS2: default: - ps2_data[0] |= - ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); p->dz = 0; + + ps2_data[0] |= ((p->buttons & 0x10) >> 3) | + ((p->buttons & 0x08) >> 1); + client->bufsiz = 3; break; } @@ -714,7 +720,7 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer, { struct mousedev_client *client = file->private_data; struct mousedev *mousedev = client->mousedev; - signed char data[sizeof(client->ps2)]; + u8 data[sizeof(client->ps2)]; int retval = 0; if (!client->ready && !client->buffer && mousedev->exist && -- cgit v1.2.3 From 17af7983691f9394e5e3619e910570f8897b5ab0 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sun, 16 Apr 2017 20:12:50 -0700 Subject: usb: gadget: remove redundant self assignment commit 8a8b161df5ce06ef5a315899f83978e765be09e8 upstream. The assignment ret = ret is redundant and can be removed. Reviewed-by: Krzysztof Opasiak Reviewed-by: Peter Chen Signed-off-by: Stefan Agner Signed-off-by: Felipe Balbi Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index e97539fc127e..7d658565b20f 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -139,10 +139,8 @@ int usb_ep_disable(struct usb_ep *ep) goto out; ret = ep->ops->disable(ep); - if (ret) { - ret = ret; + if (ret) goto out; - } ep->enabled = false; -- cgit v1.2.3 From 54af0282954055bc5f866a6a449864ca61a86282 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 1 Feb 2017 17:46:02 +0100 Subject: xgene_enet: remove bogus forward declarations commit 1f3d62090d3ba4d0c14e5271be87812fc577b197 upstream. The device match tables for both the xgene_enet driver and its phy driver have forward declarations that declare an array without a length, leading to a clang warning when they are not followed by an actual defitinition: drivers/net/ethernet/apm/xgene/../../../phy/mdio-xgene.h:135:34: warning: tentative array definition assumed to have one element drivers/net/ethernet/apm/xgene/xgene_enet_main.c:33:36: warning: tentative array definition assumed to have one element The declarations for the mdio driver are even in a header file, so they cause duplicate definitions of the tables for each file that includes them. This removes all four forward declarations and moves the actual definitions up a little, so they are in front of their first user. For the OF match tables, this means having to remove the #ifdef around them, and passing the actual structure into of_match_device(). This has no effect on the generated object code though, as the of_match_device function has an empty stub that does not evaluate its argument, and the symbol gets dropped either way. Fixes: 43b3cf6634a4 ("drivers: net: phy: xgene: Add MDIO driver") Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 50 ++++++++++++------------ drivers/net/phy/mdio-xgene.c | 50 ++++++++++++------------ drivers/net/phy/mdio-xgene.h | 4 -- 3 files changed, 48 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 651f308cdc60..fca2e428cd86 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -1680,6 +1680,30 @@ static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata) } } +#ifdef CONFIG_ACPI +static const struct acpi_device_id xgene_enet_acpi_match[] = { + { "APMC0D05", XGENE_ENET1}, + { "APMC0D30", XGENE_ENET1}, + { "APMC0D31", XGENE_ENET1}, + { "APMC0D3F", XGENE_ENET1}, + { "APMC0D26", XGENE_ENET2}, + { "APMC0D25", XGENE_ENET2}, + { } +}; +MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); +#endif + +static const struct of_device_id xgene_enet_of_match[] = { + {.compatible = "apm,xgene-enet", .data = (void *)XGENE_ENET1}, + {.compatible = "apm,xgene1-sgenet", .data = (void *)XGENE_ENET1}, + {.compatible = "apm,xgene1-xgenet", .data = (void *)XGENE_ENET1}, + {.compatible = "apm,xgene2-sgenet", .data = (void *)XGENE_ENET2}, + {.compatible = "apm,xgene2-xgenet", .data = (void *)XGENE_ENET2}, + {}, +}; + +MODULE_DEVICE_TABLE(of, xgene_enet_of_match); + static int xgene_enet_probe(struct platform_device *pdev) { struct net_device *ndev; @@ -1826,32 +1850,6 @@ static void xgene_enet_shutdown(struct platform_device *pdev) xgene_enet_remove(pdev); } -#ifdef CONFIG_ACPI -static const struct acpi_device_id xgene_enet_acpi_match[] = { - { "APMC0D05", XGENE_ENET1}, - { "APMC0D30", XGENE_ENET1}, - { "APMC0D31", XGENE_ENET1}, - { "APMC0D3F", XGENE_ENET1}, - { "APMC0D26", XGENE_ENET2}, - { "APMC0D25", XGENE_ENET2}, - { } -}; -MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); -#endif - -#ifdef CONFIG_OF -static const struct of_device_id xgene_enet_of_match[] = { - {.compatible = "apm,xgene-enet", .data = (void *)XGENE_ENET1}, - {.compatible = "apm,xgene1-sgenet", .data = (void *)XGENE_ENET1}, - {.compatible = "apm,xgene1-xgenet", .data = (void *)XGENE_ENET1}, - {.compatible = "apm,xgene2-sgenet", .data = (void *)XGENE_ENET2}, - {.compatible = "apm,xgene2-xgenet", .data = (void *)XGENE_ENET2}, - {}, -}; - -MODULE_DEVICE_TABLE(of, xgene_enet_of_match); -#endif - static struct platform_driver xgene_enet_driver = { .driver = { .name = "xgene-enet", diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index 39be3b82608f..20fbcc9c4687 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c @@ -314,6 +314,30 @@ static acpi_status acpi_register_phy(acpi_handle handle, u32 lvl, } #endif +static const struct of_device_id xgene_mdio_of_match[] = { + { + .compatible = "apm,xgene-mdio-rgmii", + .data = (void *)XGENE_MDIO_RGMII + }, + { + .compatible = "apm,xgene-mdio-xfi", + .data = (void *)XGENE_MDIO_XFI + }, + {}, +}; +MODULE_DEVICE_TABLE(of, xgene_mdio_of_match); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id xgene_mdio_acpi_match[] = { + { "APMC0D65", XGENE_MDIO_RGMII }, + { "APMC0D66", XGENE_MDIO_XFI }, + { } +}; + +MODULE_DEVICE_TABLE(acpi, xgene_mdio_acpi_match); +#endif + + static int xgene_mdio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -439,32 +463,6 @@ static int xgene_mdio_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF -static const struct of_device_id xgene_mdio_of_match[] = { - { - .compatible = "apm,xgene-mdio-rgmii", - .data = (void *)XGENE_MDIO_RGMII - }, - { - .compatible = "apm,xgene-mdio-xfi", - .data = (void *)XGENE_MDIO_XFI - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, xgene_mdio_of_match); -#endif - -#ifdef CONFIG_ACPI -static const struct acpi_device_id xgene_mdio_acpi_match[] = { - { "APMC0D65", XGENE_MDIO_RGMII }, - { "APMC0D66", XGENE_MDIO_XFI }, - { } -}; - -MODULE_DEVICE_TABLE(acpi, xgene_mdio_acpi_match); -#endif - static struct platform_driver xgene_mdio_driver = { .driver = { .name = "xgene-mdio", diff --git a/drivers/net/phy/mdio-xgene.h b/drivers/net/phy/mdio-xgene.h index 354241b53c1d..594a11d42401 100644 --- a/drivers/net/phy/mdio-xgene.h +++ b/drivers/net/phy/mdio-xgene.h @@ -132,10 +132,6 @@ static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src) #define GET_BIT(field, src) \ xgene_enet_get_field_value(field ## _POS, 1, src) -static const struct of_device_id xgene_mdio_of_match[]; -#ifdef CONFIG_ACPI -static const struct acpi_device_id xgene_mdio_acpi_match[]; -#endif int xgene_mdio_rgmii_read(struct mii_bus *bus, int phy_id, int reg); int xgene_mdio_rgmii_write(struct mii_bus *bus, int phy_id, int reg, u16 data); struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr); -- cgit v1.2.3 From e6061c11c3b5a8f1bba97bfe3cd1af5f95cfca95 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 8 Feb 2017 13:58:43 -0500 Subject: HID: sony: Use LED_CORE_SUSPENDRESUME commit 765a1077c85e5f2efcc43582f80caf43a052e903 upstream. The LED subsystem provides the LED_CORE_SUSPENDRESUME flag to handle automatically turning off and restoring the state of device LEDs during suspend/resume. Use this flag instead of saving and restoring the state locally. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina Cc: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-sony.c | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b0bb99a821bd..1b1dccd37fbd 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1056,7 +1056,6 @@ struct sony_sc { u8 battery_charging; u8 battery_capacity; u8 led_state[MAX_LEDS]; - u8 resume_led_state[MAX_LEDS]; u8 led_delay_on[MAX_LEDS]; u8 led_delay_off[MAX_LEDS]; u8 led_count; @@ -1793,6 +1792,7 @@ static int sony_leds_init(struct sony_sc *sc) led->name = name; led->brightness = sc->led_state[n]; led->max_brightness = max_brightness[n]; + led->flags = LED_CORE_SUSPENDRESUME; led->brightness_get = sony_led_get_brightness; led->brightness_set = sony_led_set_brightness; @@ -2509,47 +2509,32 @@ static void sony_remove(struct hid_device *hdev) static int sony_suspend(struct hid_device *hdev, pm_message_t message) { - /* - * On suspend save the current LED state, - * stop running force-feedback and blank the LEDS. - */ - if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { - struct sony_sc *sc = hid_get_drvdata(hdev); - #ifdef CONFIG_SONY_FF - sc->left = sc->right = 0; -#endif - memcpy(sc->resume_led_state, sc->led_state, - sizeof(sc->resume_led_state)); - memset(sc->led_state, 0, sizeof(sc->led_state)); + /* On suspend stop any running force-feedback events */ + if (SONY_FF_SUPPORT) { + struct sony_sc *sc = hid_get_drvdata(hdev); + sc->left = sc->right = 0; sony_send_output_report(sc); } +#endif return 0; } static int sony_resume(struct hid_device *hdev) { - /* Restore the state of controller LEDs on resume */ - if (SONY_LED_SUPPORT) { - struct sony_sc *sc = hid_get_drvdata(hdev); - - memcpy(sc->led_state, sc->resume_led_state, - sizeof(sc->led_state)); - - /* - * The Sixaxis and navigation controllers on USB need to be - * reinitialized on resume or they won't behave properly. - */ - if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || - (sc->quirks & NAVIGATION_CONTROLLER_USB)) { - sixaxis_set_operational_usb(sc->hdev); - sc->defer_initialization = 1; - } + struct sony_sc *sc = hid_get_drvdata(hdev); - sony_set_leds(sc); + /* + * The Sixaxis and navigation controllers on USB need to be + * reinitialized on resume or they won't behave properly. + */ + if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || + (sc->quirks & NAVIGATION_CONTROLLER_USB)) { + sixaxis_set_operational_usb(sc->hdev); + sc->defer_initialization = 1; } return 0; -- cgit v1.2.3 From 510d52da02ae6c8ebaa8c760bde50f141906ac87 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Thu, 15 Mar 2018 15:33:02 +0200 Subject: RDMA/ucma: Check AF family prior resolving address commit 2975d5de6428ff6d9317e9948f0968f7d42e5d74 upstream. Garbage supplied by user will cause to UCMA module provide zero memory size for memcpy(), because it wasn't checked, it will produce unpredictable results in rdma_resolve_addr(). [ 42.873814] BUG: KASAN: null-ptr-deref in rdma_resolve_addr+0xc8/0xfb0 [ 42.874816] Write of size 28 at addr 00000000000000a0 by task resaddr/1044 [ 42.876765] [ 42.876960] CPU: 1 PID: 1044 Comm: resaddr Not tainted 4.16.0-rc1-00057-gaa56a5293d7e #34 [ 42.877840] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 [ 42.879691] Call Trace: [ 42.880236] dump_stack+0x5c/0x77 [ 42.880664] kasan_report+0x163/0x380 [ 42.881354] ? rdma_resolve_addr+0xc8/0xfb0 [ 42.881864] memcpy+0x34/0x50 [ 42.882692] rdma_resolve_addr+0xc8/0xfb0 [ 42.883366] ? deref_stack_reg+0x88/0xd0 [ 42.883856] ? vsnprintf+0x31a/0x770 [ 42.884686] ? rdma_bind_addr+0xc40/0xc40 [ 42.885327] ? num_to_str+0x130/0x130 [ 42.885773] ? deref_stack_reg+0x88/0xd0 [ 42.886217] ? __read_once_size_nocheck.constprop.6+0x10/0x10 [ 42.887698] ? unwind_get_return_address_ptr+0x50/0x50 [ 42.888302] ? replace_slot+0x147/0x170 [ 42.889176] ? delete_node+0x12c/0x340 [ 42.890223] ? __radix_tree_lookup+0xa9/0x160 [ 42.891196] ? ucma_resolve_ip+0xb7/0x110 [ 42.891917] ucma_resolve_ip+0xb7/0x110 [ 42.893003] ? ucma_resolve_addr+0x190/0x190 [ 42.893531] ? _copy_from_user+0x5e/0x90 [ 42.894204] ucma_write+0x174/0x1f0 [ 42.895162] ? ucma_resolve_route+0xf0/0xf0 [ 42.896309] ? dequeue_task_fair+0x67e/0xd90 [ 42.897192] ? put_prev_entity+0x7d/0x170 [ 42.897870] ? ring_buffer_record_is_on+0xd/0x20 [ 42.898439] ? tracing_record_taskinfo_skip+0x20/0x50 [ 42.899686] __vfs_write+0xc4/0x350 [ 42.900142] ? kernel_read+0xa0/0xa0 [ 42.900602] ? firmware_map_remove+0xdf/0xdf [ 42.901135] ? do_task_dead+0x5d/0x60 [ 42.901598] ? do_exit+0xcc6/0x1220 [ 42.902789] ? __fget+0xa8/0xf0 [ 42.903190] vfs_write+0xf7/0x280 [ 42.903600] SyS_write+0xa1/0x120 [ 42.904206] ? SyS_read+0x120/0x120 [ 42.905710] ? compat_start_thread+0x60/0x60 [ 42.906423] ? SyS_read+0x120/0x120 [ 42.908716] do_syscall_64+0xeb/0x250 [ 42.910760] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 42.912735] RIP: 0033:0x7f138b0afe99 [ 42.914734] RSP: 002b:00007f138b799e98 EFLAGS: 00000287 ORIG_RAX: 0000000000000001 [ 42.917134] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f138b0afe99 [ 42.919487] RDX: 000000000000002e RSI: 0000000020000c40 RDI: 0000000000000004 [ 42.922393] RBP: 00007f138b799ec0 R08: 00007f138b79a700 R09: 0000000000000000 [ 42.925266] R10: 00007f138b79a700 R11: 0000000000000287 R12: 00007f138b799fc0 [ 42.927570] R13: 0000000000000000 R14: 00007ffdbae757c0 R15: 00007f138b79a9c0 [ 42.930047] [ 42.932681] Disabling lock debugging due to kernel taint [ 42.934795] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0 [ 42.936939] IP: memcpy_erms+0x6/0x10 [ 42.938864] PGD 80000001bea92067 P4D 80000001bea92067 PUD 1bea96067 PMD 0 [ 42.941576] Oops: 0002 [#1] SMP KASAN PTI [ 42.943952] CPU: 1 PID: 1044 Comm: resaddr Tainted: G B 4.16.0-rc1-00057-gaa56a5293d7e #34 [ 42.946964] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 [ 42.952336] RIP: 0010:memcpy_erms+0x6/0x10 [ 42.954707] RSP: 0018:ffff8801c8b479c8 EFLAGS: 00010286 [ 42.957227] RAX: 00000000000000a0 RBX: ffff8801c8b47ba0 RCX: 000000000000001c [ 42.960543] RDX: 000000000000001c RSI: ffff8801c8b47bbc RDI: 00000000000000a0 [ 42.963867] RBP: ffff8801c8b47b60 R08: 0000000000000000 R09: ffffed0039168ed1 [ 42.967303] R10: 0000000000000001 R11: ffffed0039168ed0 R12: ffff8801c8b47bbc [ 42.970685] R13: 00000000000000a0 R14: 1ffff10039168f4a R15: 0000000000000000 [ 42.973631] FS: 00007f138b79a700(0000) GS:ffff8801e5d00000(0000) knlGS:0000000000000000 [ 42.976831] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 42.979239] CR2: 00000000000000a0 CR3: 00000001be908002 CR4: 00000000003606a0 [ 42.982060] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 42.984877] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 42.988033] Call Trace: [ 42.990487] rdma_resolve_addr+0xc8/0xfb0 [ 42.993202] ? deref_stack_reg+0x88/0xd0 [ 42.996055] ? vsnprintf+0x31a/0x770 [ 42.998707] ? rdma_bind_addr+0xc40/0xc40 [ 43.000985] ? num_to_str+0x130/0x130 [ 43.003410] ? deref_stack_reg+0x88/0xd0 [ 43.006302] ? __read_once_size_nocheck.constprop.6+0x10/0x10 [ 43.008780] ? unwind_get_return_address_ptr+0x50/0x50 [ 43.011178] ? replace_slot+0x147/0x170 [ 43.013517] ? delete_node+0x12c/0x340 [ 43.016019] ? __radix_tree_lookup+0xa9/0x160 [ 43.018755] ? ucma_resolve_ip+0xb7/0x110 [ 43.021270] ucma_resolve_ip+0xb7/0x110 [ 43.023968] ? ucma_resolve_addr+0x190/0x190 [ 43.026312] ? _copy_from_user+0x5e/0x90 [ 43.029384] ucma_write+0x174/0x1f0 [ 43.031861] ? ucma_resolve_route+0xf0/0xf0 [ 43.034782] ? dequeue_task_fair+0x67e/0xd90 [ 43.037483] ? put_prev_entity+0x7d/0x170 [ 43.040215] ? ring_buffer_record_is_on+0xd/0x20 [ 43.042990] ? tracing_record_taskinfo_skip+0x20/0x50 [ 43.045595] __vfs_write+0xc4/0x350 [ 43.048624] ? kernel_read+0xa0/0xa0 [ 43.051604] ? firmware_map_remove+0xdf/0xdf [ 43.055379] ? do_task_dead+0x5d/0x60 [ 43.058000] ? do_exit+0xcc6/0x1220 [ 43.060783] ? __fget+0xa8/0xf0 [ 43.063133] vfs_write+0xf7/0x280 [ 43.065677] SyS_write+0xa1/0x120 [ 43.068647] ? SyS_read+0x120/0x120 [ 43.071179] ? compat_start_thread+0x60/0x60 [ 43.074025] ? SyS_read+0x120/0x120 [ 43.076705] do_syscall_64+0xeb/0x250 [ 43.079006] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 43.081606] RIP: 0033:0x7f138b0afe99 [ 43.083679] RSP: 002b:00007f138b799e98 EFLAGS: 00000287 ORIG_RAX: 0000000000000001 [ 43.086802] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f138b0afe99 [ 43.089989] RDX: 000000000000002e RSI: 0000000020000c40 RDI: 0000000000000004 [ 43.092866] RBP: 00007f138b799ec0 R08: 00007f138b79a700 R09: 0000000000000000 [ 43.096233] R10: 00007f138b79a700 R11: 0000000000000287 R12: 00007f138b799fc0 [ 43.098913] R13: 0000000000000000 R14: 00007ffdbae757c0 R15: 00007f138b79a9c0 [ 43.101809] Code: 90 90 90 90 90 eb 1e 0f 1f 00 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38 [ 43.107950] RIP: memcpy_erms+0x6/0x10 RSP: ffff8801c8b479c8 Reported-by: Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Signed-off-by: Leon Romanovsky Reviewed-by: Sean Hefty Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 017a09ceba3f..6b8bb3af9b40 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -662,19 +662,23 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, int in_len, int out_len) { struct rdma_ucm_resolve_ip cmd; + struct sockaddr *src, *dst; struct ucma_context *ctx; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; + src = (struct sockaddr *) &cmd.src_addr; + dst = (struct sockaddr *) &cmd.dst_addr; + if (!rdma_addr_size(src) || !rdma_addr_size(dst)) + return -EINVAL; + ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); - ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, - (struct sockaddr *) &cmd.dst_addr, - cmd.timeout_ms); + ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); ucma_put_ctx(ctx); return ret; } -- cgit v1.2.3 From a7d0333a87b3a9b68c9d4351fbd9e0f76f6ac913 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Mon, 19 Mar 2018 14:20:15 +0200 Subject: RDMA/ucma: Fix use-after-free access in ucma_close commit ed65a4dc22083e73bac599ded6a262318cad7baf upstream. The error in ucma_create_id() left ctx in the list of contexts belong to ucma file descriptor. The attempt to close this file descriptor causes to use-after-free accesses while iterating over such list. Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Reported-by: Signed-off-by: Leon Romanovsky Reviewed-by: Sean Hefty Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6b8bb3af9b40..4a42a95be601 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -495,6 +495,9 @@ err1: mutex_lock(&mut); idr_remove(&ctx_idr, ctx->id); mutex_unlock(&mut); + mutex_lock(&file->mut); + list_del(&ctx->list); + mutex_unlock(&file->mut); kfree(ctx); return ret; } -- cgit v1.2.3 From a6cd10d9940282804d45a139bc14ccf93bd34769 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 20 Mar 2018 17:05:13 +0200 Subject: RDMA/ucma: Ensure that CM_ID exists prior to access it commit e8980d67d6017c8eee8f9c35f782c4bd68e004c9 upstream. Prior to access UCMA commands, the context should be initialized and connected to CM_ID with ucma_create_id(). In case user skips this step, he can provide non-valid ctx without CM_ID and cause to multiple NULL dereferences. Also there are situations where the create_id can be raced with other user access, ensure that the context is only shared to other threads once it is fully initialized to avoid the races. [ 109.088108] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 [ 109.090315] IP: ucma_connect+0x138/0x1d0 [ 109.092595] PGD 80000001dc02d067 P4D 80000001dc02d067 PUD 1da9ef067 PMD 0 [ 109.095384] Oops: 0000 [#1] SMP KASAN PTI [ 109.097834] CPU: 0 PID: 663 Comm: uclose Tainted: G B 4.16.0-rc1-00062-g2975d5de6428 #45 [ 109.100816] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 [ 109.105943] RIP: 0010:ucma_connect+0x138/0x1d0 [ 109.108850] RSP: 0018:ffff8801c8567a80 EFLAGS: 00010246 [ 109.111484] RAX: 0000000000000000 RBX: 1ffff100390acf50 RCX: ffffffff9d7812e2 [ 109.114496] RDX: 1ffffffff3f507a5 RSI: 0000000000000297 RDI: 0000000000000297 [ 109.117490] RBP: ffff8801daa15600 R08: 0000000000000000 R09: ffffed00390aceeb [ 109.120429] R10: 0000000000000001 R11: ffffed00390aceea R12: 0000000000000000 [ 109.123318] R13: 0000000000000120 R14: ffff8801de6459c0 R15: 0000000000000118 [ 109.126221] FS: 00007fabb68d6700(0000) GS:ffff8801e5c00000(0000) knlGS:0000000000000000 [ 109.129468] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 109.132523] CR2: 0000000000000020 CR3: 00000001d45d8003 CR4: 00000000003606b0 [ 109.135573] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 109.138716] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 109.142057] Call Trace: [ 109.144160] ? ucma_listen+0x110/0x110 [ 109.146386] ? wake_up_q+0x59/0x90 [ 109.148853] ? futex_wake+0x10b/0x2a0 [ 109.151297] ? save_stack+0x89/0xb0 [ 109.153489] ? _copy_from_user+0x5e/0x90 [ 109.155500] ucma_write+0x174/0x1f0 [ 109.157933] ? ucma_resolve_route+0xf0/0xf0 [ 109.160389] ? __mod_node_page_state+0x1d/0x80 [ 109.162706] __vfs_write+0xc4/0x350 [ 109.164911] ? kernel_read+0xa0/0xa0 [ 109.167121] ? path_openat+0x1b10/0x1b10 [ 109.169355] ? fsnotify+0x899/0x8f0 [ 109.171567] ? fsnotify_unmount_inodes+0x170/0x170 [ 109.174145] ? __fget+0xa8/0xf0 [ 109.177110] vfs_write+0xf7/0x280 [ 109.179532] SyS_write+0xa1/0x120 [ 109.181885] ? SyS_read+0x120/0x120 [ 109.184482] ? compat_start_thread+0x60/0x60 [ 109.187124] ? SyS_read+0x120/0x120 [ 109.189548] do_syscall_64+0xeb/0x250 [ 109.192178] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 109.194725] RIP: 0033:0x7fabb61ebe99 [ 109.197040] RSP: 002b:00007fabb68d5e98 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 109.200294] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fabb61ebe99 [ 109.203399] RDX: 0000000000000120 RSI: 00000000200001c0 RDI: 0000000000000004 [ 109.206548] RBP: 00007fabb68d5ec0 R08: 0000000000000000 R09: 0000000000000000 [ 109.209902] R10: 0000000000000000 R11: 0000000000000202 R12: 00007fabb68d5fc0 [ 109.213327] R13: 0000000000000000 R14: 00007fff40ab2430 R15: 00007fabb68d69c0 [ 109.216613] Code: 88 44 24 2c 0f b6 84 24 6e 01 00 00 88 44 24 2d 0f b6 84 24 69 01 00 00 88 44 24 2e 8b 44 24 60 89 44 24 30 e8 da f6 06 ff 31 c0 <66> 41 83 7c 24 20 1b 75 04 8b 44 24 64 48 8d 74 24 20 4c 89 e7 [ 109.223602] RIP: ucma_connect+0x138/0x1d0 RSP: ffff8801c8567a80 [ 109.226256] CR2: 0000000000000020 Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Reported-by: Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 4a42a95be601..0ef2f6a3b8df 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -132,7 +132,7 @@ static inline struct ucma_context *_ucma_find_context(int id, ctx = idr_find(&ctx_idr, id); if (!ctx) ctx = ERR_PTR(-ENOENT); - else if (ctx->file != file) + else if (ctx->file != file || !ctx->cm_id) ctx = ERR_PTR(-EINVAL); return ctx; } @@ -454,6 +454,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, struct rdma_ucm_create_id cmd; struct rdma_ucm_create_id_resp resp; struct ucma_context *ctx; + struct rdma_cm_id *cm_id; enum ib_qp_type qp_type; int ret; @@ -474,10 +475,10 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, return -ENOMEM; ctx->uid = cmd.uid; - ctx->cm_id = rdma_create_id(current->nsproxy->net_ns, - ucma_event_handler, ctx, cmd.ps, qp_type); - if (IS_ERR(ctx->cm_id)) { - ret = PTR_ERR(ctx->cm_id); + cm_id = rdma_create_id(current->nsproxy->net_ns, + ucma_event_handler, ctx, cmd.ps, qp_type); + if (IS_ERR(cm_id)) { + ret = PTR_ERR(cm_id); goto err1; } @@ -487,10 +488,12 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, ret = -EFAULT; goto err2; } + + ctx->cm_id = cm_id; return 0; err2: - rdma_destroy_id(ctx->cm_id); + rdma_destroy_id(cm_id); err1: mutex_lock(&mut); idr_remove(&ctx_idr, ctx->id); -- cgit v1.2.3 From 269f3734f20cf1ffe97f54db5e822a381b6994b7 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Sun, 25 Mar 2018 11:23:55 +0300 Subject: RDMA/ucma: Check that device is connected prior to access it commit 4b658d1bbc16605330694bb3ef2570c465ef383d upstream. Add missing check that device is connected prior to access it. [ 55.358652] BUG: KASAN: null-ptr-deref in rdma_init_qp_attr+0x4a/0x2c0 [ 55.359389] Read of size 8 at addr 00000000000000b0 by task qp/618 [ 55.360255] [ 55.360432] CPU: 1 PID: 618 Comm: qp Not tainted 4.16.0-rc1-00071-gcaf61b1b8b88 #91 [ 55.361693] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 [ 55.363264] Call Trace: [ 55.363833] dump_stack+0x5c/0x77 [ 55.364215] kasan_report+0x163/0x380 [ 55.364610] ? rdma_init_qp_attr+0x4a/0x2c0 [ 55.365238] rdma_init_qp_attr+0x4a/0x2c0 [ 55.366410] ucma_init_qp_attr+0x111/0x200 [ 55.366846] ? ucma_notify+0xf0/0xf0 [ 55.367405] ? _get_random_bytes+0xea/0x1b0 [ 55.367846] ? urandom_read+0x2f0/0x2f0 [ 55.368436] ? kmem_cache_alloc_trace+0xd2/0x1e0 [ 55.369104] ? refcount_inc_not_zero+0x9/0x60 [ 55.369583] ? refcount_inc+0x5/0x30 [ 55.370155] ? rdma_create_id+0x215/0x240 [ 55.370937] ? _copy_to_user+0x4f/0x60 [ 55.371620] ? mem_cgroup_commit_charge+0x1f5/0x290 [ 55.372127] ? _copy_from_user+0x5e/0x90 [ 55.372720] ucma_write+0x174/0x1f0 [ 55.373090] ? ucma_close_id+0x40/0x40 [ 55.373805] ? __lru_cache_add+0xa8/0xd0 [ 55.374403] __vfs_write+0xc4/0x350 [ 55.374774] ? kernel_read+0xa0/0xa0 [ 55.375173] ? fsnotify+0x899/0x8f0 [ 55.375544] ? fsnotify_unmount_inodes+0x170/0x170 [ 55.376689] ? __fsnotify_update_child_dentry_flags+0x30/0x30 [ 55.377522] ? handle_mm_fault+0x174/0x320 [ 55.378169] vfs_write+0xf7/0x280 [ 55.378864] SyS_write+0xa1/0x120 [ 55.379270] ? SyS_read+0x120/0x120 [ 55.379643] ? mm_fault_error+0x180/0x180 [ 55.380071] ? task_work_run+0x7d/0xd0 [ 55.380910] ? __task_pid_nr_ns+0x120/0x140 [ 55.381366] ? SyS_read+0x120/0x120 [ 55.381739] do_syscall_64+0xeb/0x250 [ 55.382143] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 55.382841] RIP: 0033:0x7fc2ef803e99 [ 55.383227] RSP: 002b:00007fffcc5f3be8 EFLAGS: 00000217 ORIG_RAX: 0000000000000001 [ 55.384173] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc2ef803e99 [ 55.386145] RDX: 0000000000000057 RSI: 0000000020000080 RDI: 0000000000000003 [ 55.388418] RBP: 00007fffcc5f3c00 R08: 0000000000000000 R09: 0000000000000000 [ 55.390542] R10: 0000000000000000 R11: 0000000000000217 R12: 0000000000400480 [ 55.392916] R13: 00007fffcc5f3cf0 R14: 0000000000000000 R15: 0000000000000000 [ 55.521088] Code: e5 4d 1e ff 48 89 df 44 0f b6 b3 b8 01 00 00 e8 65 50 1e ff 4c 8b 2b 49 8d bd b0 00 00 00 e8 56 50 1e ff 41 0f b6 c6 48 c1 e0 04 <49> 03 85 b0 00 00 00 48 8d 78 08 48 89 04 24 e8 3a 4f 1e ff 48 [ 55.525980] RIP: rdma_init_qp_attr+0x52/0x2c0 RSP: ffff8801e2c2f9d8 [ 55.532648] CR2: 00000000000000b0 [ 55.534396] ---[ end trace 70cee64090251c0b ]--- Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Fixes: d541e45500bd ("IB/core: Convert ah_attr from OPA to IB when copying to user") Reported-by: Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 0ef2f6a3b8df..dd0c5037c9cf 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1156,6 +1156,11 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); + if (!ctx->cm_id->device) { + ret = -EINVAL; + goto out; + } + resp.qp_attr_mask = 0; memset(&qp_attr, 0, sizeof qp_attr); qp_attr.qp_state = cmd.qp_state; -- cgit v1.2.3 From 5eaa1b1e089708c1afab79bca3950fe93e7c3b35 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Sun, 25 Mar 2018 11:39:05 +0300 Subject: RDMA/ucma: Check that device exists prior to accessing it commit c8d3bcbfc5eab3f01cf373d039af725f3b488813 upstream. Ensure that device exists prior to accessing its properties. Reported-by: Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index dd0c5037c9cf..307d6f577900 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1317,7 +1317,7 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, { struct rdma_ucm_notify cmd; struct ucma_context *ctx; - int ret; + int ret = -EINVAL; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; @@ -1326,7 +1326,9 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx); - ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event); + if (ctx->cm_id->device) + ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event); + ucma_put_ctx(ctx); return ret; } -- cgit v1.2.3 From d0253af4a15b81f7f9d033917c3fd64b65df0154 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 28 Mar 2018 11:27:22 -0700 Subject: RDMA/ucma: Introduce safer rdma_addr_size() variants commit 84652aefb347297aa08e91e283adf7b18f77c2d5 upstream. There are several places in the ucma ABI where userspace can pass in a sockaddr but set the address family to AF_IB. When that happens, rdma_addr_size() will return a size bigger than sizeof struct sockaddr_in6, and the ucma kernel code might end up copying past the end of a buffer not sized for a struct sockaddr_ib. Fix this by introducing new variants int rdma_addr_size_in6(struct sockaddr_in6 *addr); int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr); that are type-safe for the types used in the ucma ABI and return 0 if the size computed is bigger than the size of the type passed in. We can use these new variants to check what size userspace has passed in before copying any addresses. Reported-by: Signed-off-by: Roland Dreier Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/addr.c | 16 ++++++++++++++++ drivers/infiniband/core/ucma.c | 34 +++++++++++++++++----------------- 2 files changed, 33 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index fb4ce0394ac7..978b8d94f9a4 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -209,6 +209,22 @@ int rdma_addr_size(struct sockaddr *addr) } EXPORT_SYMBOL(rdma_addr_size); +int rdma_addr_size_in6(struct sockaddr_in6 *addr) +{ + int ret = rdma_addr_size((struct sockaddr *) addr); + + return ret <= sizeof(*addr) ? ret : 0; +} +EXPORT_SYMBOL(rdma_addr_size_in6); + +int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr) +{ + int ret = rdma_addr_size((struct sockaddr *) addr); + + return ret <= sizeof(*addr) ? ret : 0; +} +EXPORT_SYMBOL(rdma_addr_size_kss); + static struct rdma_addr_client self; void rdma_addr_register_client(struct rdma_addr_client *client) diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 307d6f577900..4d732810f6fc 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -630,6 +630,9 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; + if (!rdma_addr_size_in6(&cmd.addr)) + return -EINVAL; + ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -643,22 +646,21 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf, int in_len, int out_len) { struct rdma_ucm_bind cmd; - struct sockaddr *addr; struct ucma_context *ctx; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - addr = (struct sockaddr *) &cmd.addr; - if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr))) + if (cmd.reserved || !cmd.addr_size || + cmd.addr_size != rdma_addr_size_kss(&cmd.addr)) return -EINVAL; ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); - ret = rdma_bind_addr(ctx->cm_id, addr); + ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); ucma_put_ctx(ctx); return ret; } @@ -668,23 +670,22 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, int in_len, int out_len) { struct rdma_ucm_resolve_ip cmd; - struct sockaddr *src, *dst; struct ucma_context *ctx; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - src = (struct sockaddr *) &cmd.src_addr; - dst = (struct sockaddr *) &cmd.dst_addr; - if (!rdma_addr_size(src) || !rdma_addr_size(dst)) + if (!rdma_addr_size_in6(&cmd.src_addr) || + !rdma_addr_size_in6(&cmd.dst_addr)) return -EINVAL; ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); - ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); + ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, + (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); ucma_put_ctx(ctx); return ret; } @@ -694,24 +695,23 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file, int in_len, int out_len) { struct rdma_ucm_resolve_addr cmd; - struct sockaddr *src, *dst; struct ucma_context *ctx; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - src = (struct sockaddr *) &cmd.src_addr; - dst = (struct sockaddr *) &cmd.dst_addr; - if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) || - !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst))) + if (cmd.reserved || + (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) || + !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr))) return -EINVAL; ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); - ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); + ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, + (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); ucma_put_ctx(ctx); return ret; } @@ -1414,7 +1414,7 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file, join_cmd.response = cmd.response; join_cmd.uid = cmd.uid; join_cmd.id = cmd.id; - join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); + join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr); if (!join_cmd.addr_size) return -EINVAL; @@ -1433,7 +1433,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - if (!rdma_addr_size((struct sockaddr *)&cmd.addr)) + if (!rdma_addr_size_kss(&cmd.addr)) return -EINVAL; return ucma_process_join(file, &cmd, out_len); -- cgit v1.2.3 From cfde23842ab214e3de39beb7e68970c502e849e8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 5 Jul 2017 10:30:56 +0200 Subject: scsi: virtio_scsi: always read VPD pages for multiqueue too commit a680f1d463aeaeb00d22af257a56e111967c2f18 upstream. Multi-queue virtio-scsi uses a different scsi_host_template struct. Add the .device_alloc field there, too. Fixes: 25d1d50e23275e141e3a3fe06c25a99f4c4bf4e0 Cc: stable@vger.kernel.org Cc: David Gibson Signed-off-by: Paolo Bonzini Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Martin K. Petersen Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/virtio_scsi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 8f4adc1d9588..cbc8e9388268 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -819,6 +819,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .change_queue_depth = virtscsi_change_queue_depth, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .slave_alloc = virtscsi_device_alloc, .can_queue = 1024, .dma_boundary = UINT_MAX, -- cgit v1.2.3 From 7e59524527a5ce0cbca047f3ad0fb8f7997713fe Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 23 Oct 2017 14:32:48 -0700 Subject: usb: dwc2: Improve gadget state disconnection handling commit d2471d4a24dfbff5e463d382e2c6fec7d7e25a09 upstream. In the earlier commit dad3f793f20f ("usb: dwc2: Make sure we disconnect the gadget state"), I was trying to fix up the fact that we somehow weren't disconnecting the gadget state, so that when the OTG port was plugged in the second time we would get warnings about the state tracking being wrong. (This seems to be due to a quirk of the HiKey board where we do not ever get any otg interrupts, particularly the session end detected signal. Instead we only see status change interrupt.) The fix there was somewhat simple, as it just made sure to call dwc2_hsotg_disconnect() before we connected things up in OTG mode, ensuring the state handling didn't throw errors. But in looking at a different issue I was seeing with UDC state handling, I realized that it would be much better to call dwc2_hsotg_disconnect when we get the state change signal moving to host mode. Thus, this patch removes the earlier disconnect call I added and moves it (and the needed locking) to the host mode transition. Cc: Wei Xu Cc: Guodong Xu Cc: Amit Pundir Cc: YongQin Liu Cc: John Youn Cc: Minas Harutyunyan Cc: Douglas Anderson Cc: Chen Yu Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Acked-by: Minas Harutyunyan Tested-by: Minas Harutyunyan Signed-off-by: John Stultz Signed-off-by: Felipe Balbi Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/hcd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index dfc0566bb155..919a32153060 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3220,7 +3220,6 @@ static void dwc2_conn_id_status_change(struct work_struct *work) dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); spin_lock_irqsave(&hsotg->lock, flags); - dwc2_hsotg_disconnect(hsotg); dwc2_hsotg_core_init_disconnected(hsotg, false); spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hsotg_core_connect(hsotg); @@ -3238,8 +3237,12 @@ static void dwc2_conn_id_status_change(struct work_struct *work) if (count > 250) dev_err(hsotg->dev, "Connection id status change timed out\n"); - hsotg->op_state = OTG_STATE_A_HOST; + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_hsotg_disconnect(hsotg); + spin_unlock_irqrestore(&hsotg->lock, flags); + + hsotg->op_state = OTG_STATE_A_HOST; /* Initialize the Core for Host mode */ dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); -- cgit v1.2.3 From 04e624e76153d65541a062d82b851e95b3eae581 Mon Sep 17 00:00:00 2001 From: Major Hayden Date: Fri, 23 Feb 2018 14:29:54 -0600 Subject: USB: serial: ftdi_sio: add RT Systems VX-8 cable commit 9608e5c0f079390473b484ef92334dfd3431bb89 upstream. This patch adds a device ID for the RT Systems cable used to program Yaesu VX-8R/VX-8DR handheld radios. It uses the main FTDI VID instead of the common RT Systems VID. Signed-off-by: Major Hayden Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0c743e4cca1e..d7e1273352c4 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -773,6 +773,7 @@ static const struct usb_device_id id_table_combined[] = { .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) }, + { USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 543d2801632b..a154b922ede8 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -922,6 +922,9 @@ /* * RT Systems programming cables for various ham radios */ +/* This device uses the VID of FTDI */ +#define RTSYSTEMS_USB_VX8_PID 0x9e50 /* USB-VX8 USB to 7 pin modular plug for Yaesu VX-8 radio */ + #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_USB_S03_PID 0x9001 /* RTS-03 USB to Serial Adapter */ #define RTSYSTEMS_USB_59_PID 0x9e50 /* USB-59 USB to 8 pin plug */ -- cgit v1.2.3 From 6424b64c8a6dcf505242b18286dce5d0931c6ee4 Mon Sep 17 00:00:00 2001 From: Clemens Werther Date: Fri, 16 Mar 2018 10:20:46 +0100 Subject: USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator commit 6555ad13a01952c16485c82a52ad1f3e07e34b3a upstream. Add device id for Harman FirmwareHubEmulator to make the device auto-detectable by the driver. Signed-off-by: Clemens Werther Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d7e1273352c4..71cbc6890ac4 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -936,6 +936,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_FHE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index a154b922ede8..76a10b222ff9 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1443,6 +1443,12 @@ */ #define FTDI_CINTERION_MC55I_PID 0xA951 +/* + * Product: FirmwareHubEmulator + * Manufacturer: Harman Becker Automotive Systems + */ +#define FTDI_FHE_PID 0xA9A0 + /* * Product: Comet Caller ID decoder * Manufacturer: Crucible Technologies -- cgit v1.2.3 From f213d151e8927d3486a0a21e7031179a358e52bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 6 Mar 2018 09:32:43 +0100 Subject: USB: serial: cp210x: add ELDAT Easywave RX09 id commit 1f1e82f74c0947e40144688c9e36abe4b3999f49 upstream. Add device id for ELDAT Easywave RX09 tranceiver. Reported-by: Jan Jansen Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 3178d8afb3e6..cab80acace4e 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -152,6 +152,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ + { USB_DEVICE(0x155A, 0x1006) }, /* ELDAT Easywave RX09 */ { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ -- cgit v1.2.3 From 666dc4c8378f77b9815fd8b317339f22025bcc3c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 27 Feb 2018 16:21:05 +0000 Subject: mei: remove dev_err message on an unsupported ioctl commit bb0829a741792b56c908d7745bc0b2b540293bcc upstream. Currently the driver spams the kernel log on unsupported ioctls which is unnecessary as the ioctl returns -ENOIOCTLCMD to indicate this anyway. I suspect this was originally for debugging purposes but it really is not required so remove it. Signed-off-by: Colin Ian King Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 41f318631c6d..60f5a8ded8dd 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -551,7 +551,6 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) break; default: - dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); rets = -ENOIOCTLCMD; } -- cgit v1.2.3 From 50cd7759a34104c3acb510e644355d4ae8010851 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 8 Jan 2018 09:21:07 -0500 Subject: media: usbtv: prevent double free in error case commit 50e7044535537b2a54c7ab798cd34c7f6d900bd2 upstream. Quoting the original report: It looks like there is a double-free vulnerability in Linux usbtv driver on an error path of usbtv_probe function. When audio registration fails, usbtv_video_free function ends up freeing usbtv data structure, which gets freed the second time under usbtv_video_fail label. usbtv_audio_fail: usbtv_video_free(usbtv); => v4l2_device_put(&usbtv->v4l2_dev); => v4l2_device_put => kref_put => v4l2_device_release => usbtv_release (CALLBACK) => kfree(usbtv) (1st time) usbtv_video_fail: usb_set_intfdata(intf, NULL); usb_put_dev(usbtv->udev); kfree(usbtv); (2nd time) So, as we have refcounting, use it Reported-by: Yavuz, Tuba Signed-off-by: Oliver Neukum CC: stable@vger.kernel.org Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/usbtv/usbtv-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 0324633ede42..e56a49a5e8b1 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -109,6 +109,8 @@ static int usbtv_probe(struct usb_interface *intf, return 0; usbtv_audio_fail: + /* we must not free at this point */ + usb_get_dev(usbtv->udev); usbtv_video_free(usbtv); usbtv_video_fail: -- cgit v1.2.3 From 5104b330e75be2fafd65e4affdd2c70691677817 Mon Sep 17 00:00:00 2001 From: Alexander Gerasiov Date: Sun, 4 Feb 2018 02:50:22 +0300 Subject: parport_pc: Add support for WCH CH382L PCI-E single parallel port card. commit 823f7923833c6cc2b16e601546d607dcfb368004 upstream. WCH CH382L is a PCI-E adapter with 1 parallel port. It is similair to CH382 but serial ports are not soldered on board. Detected as Serial controller: Device 1c00:3050 (rev 10) (prog-if 05 [16850]) Signed-off-by: Alexander Gerasiov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_pc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 78530d1714dc..bdce0679674c 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2646,6 +2646,7 @@ enum parport_pc_pci_cards { netmos_9901, netmos_9865, quatech_sppxp100, + wch_ch382l, }; @@ -2708,6 +2709,7 @@ static struct parport_pc_pci { /* netmos_9901 */ { 1, { { 0, -1 }, } }, /* netmos_9865 */ { 1, { { 0, -1 }, } }, /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, + /* wch_ch382l */ { 1, { { 2, -1 }, } }, }; static const struct pci_device_id parport_pc_pci_tbl[] = { @@ -2797,6 +2799,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, + /* WCH CH382L PCI-E single parallel port card */ + { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); -- cgit v1.2.3 From baa392b075f84359c79264a2482be434313ba25d Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Thu, 15 Mar 2018 10:25:44 +0000 Subject: staging: comedi: ni_mio_common: ack ai fifo error interrupts. commit e1d9fc04c41840a4688ef6ce90b6dcca157ea4d7 upstream. Ack ai fifo error interrupts in interrupt handler to clear interrupt after fifo overflow. It should prevent lock-ups after the ai fifo overflows. Cc: # v4.2+ Signed-off-by: Frank Mori Hess Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index a574885ffba9..18c5312f7886 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1284,6 +1284,8 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) ack |= NISTC_INTA_ACK_AI_START; if (a_status & NISTC_AI_STATUS1_STOP) ack |= NISTC_INTA_ACK_AI_STOP; + if (a_status & NISTC_AI_STATUS1_OVER) + ack |= NISTC_INTA_ACK_AI_ERR; if (ack) ni_stc_writew(dev, ack, NISTC_INTA_ACK_REG); } -- cgit v1.2.3 From 61981aa00364a3b52c217a3150038ecebc5abdec Mon Sep 17 00:00:00 2001 From: Masaki Ota Date: Mon, 29 Jan 2018 14:36:54 -0800 Subject: Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370 commit 567b9b549cfa1cbc202762ae97b5385c29ade1e3 upstream. The primary interface for the touchpad device in Thinkpad L570 is SMBus, so ALPS overlooked PS2 interface Firmware setting of TrackStick, and shipped with TrackStick otp bit is disabled. The address 0xD7 contains device number information, so we can identify the device by checking this value, but to access it we need to enable Command mode, and then re-enable the device. Devices shipped in Thinkpad L570 report either 0x0C or 0x1D as device numbers, if we see them we assume that the devices are DualPoints. The same issue exists on Dell Latitude 7370. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196929 Fixes: 646580f793 ("Input: ALPS - fix multi-touch decoding on SS4 plus touchpads") Signed-off-by: Masaki Ota Tested-by: Aaron Ma Tested-by: Jonathan Liu Tested-by: Jaak Ristioja Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/alps.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index af83d2e34913..a8a96def0ba2 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2538,13 +2538,31 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4], } static int alps_update_dual_info_ss4_v2(unsigned char otp[][4], - struct alps_data *priv) + struct alps_data *priv, + struct psmouse *psmouse) { bool is_dual = false; + int reg_val = 0; + struct ps2dev *ps2dev = &psmouse->ps2dev; - if (IS_SS4PLUS_DEV(priv->dev_id)) + if (IS_SS4PLUS_DEV(priv->dev_id)) { is_dual = (otp[0][0] >> 4) & 0x01; + if (!is_dual) { + /* For support TrackStick of Thinkpad L/E series */ + if (alps_exit_command_mode(psmouse) == 0 && + alps_enter_command_mode(psmouse) == 0) { + reg_val = alps_command_mode_read_reg(psmouse, + 0xD7); + } + alps_exit_command_mode(psmouse); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); + + if (reg_val == 0x0C || reg_val == 0x1D) + is_dual = true; + } + } + if (is_dual) priv->flags |= ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE; @@ -2567,7 +2585,7 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, alps_update_btn_info_ss4_v2(otp, priv); - alps_update_dual_info_ss4_v2(otp, priv); + alps_update_dual_info_ss4_v2(otp, priv, psmouse); return 0; } -- cgit v1.2.3 From 8f00faad73188d1a4d628658bbc47aafeee2f495 Mon Sep 17 00:00:00 2001 From: Dennis Wassenberg Date: Thu, 8 Mar 2018 15:32:09 -0800 Subject: Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list commit b56af54ac78c54a519d82813836f305d7f76ef27 upstream. Reset i8042 before probing because of insufficient BIOS initialisation of the i8042 serial controller. This makes Synaptics touchpad detection possible. Without resetting the Synaptics touchpad is not detected because there are always NACK messages from AUX port. Signed-off-by: Dennis Wassenberg Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index d1051e3ce819..c92fb8532fed 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -692,6 +692,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "20046"), }, }, + { + /* Lenovo ThinkPad L460 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), + }, + }, { /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ .matches = { -- cgit v1.2.3 From 8f662f40fce81d7a5d7f0a14f6e0ab4a01321cc2 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 3 Apr 2018 10:24:34 -0700 Subject: Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad commit 04bb1719c4de94700056241d4c0fe3c1413f5aff upstream. The touch sensor buttons on Sony VAIO VGN-CS series laptops (e.g. VGN-CS31S) are a separate PS/2 device. As the MUX is disabled for all VAIO machines by the nomux blacklist, the data from touch sensor buttons and touchpad are combined. The protocol used by the buttons is probably similar to the touchpad protocol (both are Synaptics) so both devices get enabled. The controller combines the data, creating a mess which results in random button clicks, touchpad stopping working and lost sync error messages: psmouse serio1: TouchPad at isa0060/serio1/input0 lost sync at byte 4 psmouse serio1: TouchPad at isa0060/serio1/input0 lost sync at byte 1 psmouse serio1: TouchPad at isa0060/serio1/input0 lost sync at byte 1 psmouse serio1: TouchPad at isa0060/serio1/input0 lost sync at byte 1 psmouse serio1: TouchPad at isa0060/serio1/input0 lost sync at byte 1 psmouse serio1: issuing reconnect request Add a new i8042_dmi_forcemux_table whitelist with VGN-CS. With MUX enabled, touch sensor buttons are detected as separate device (and left disabled as there's currently no driver), fixing all touchpad problems. Signed-off-by: Ondrej Zary Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/serio/i8042-x86ia64io.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index c92fb8532fed..e484ea2dc787 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -530,6 +530,20 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { { } }; +static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = { + { + /* + * Sony Vaio VGN-CS series require MUX or the touch sensor + * buttons will disturb touchpad operation + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), + }, + }, + { } +}; + /* * On some Asus laptops, just running self tests cause problems. */ @@ -1230,6 +1244,9 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_nomux_table)) i8042_nomux = true; + if (dmi_check_system(i8042_dmi_forcemux_table)) + i8042_nomux = false; + if (dmi_check_system(i8042_dmi_notimeout_table)) i8042_notimeout = true; -- cgit v1.2.3 From 4d2e98ce445b10b2f1f4f44ff096a6a9381726e1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 29 Jan 2018 17:08:21 -0500 Subject: vt: change SGR 21 to follow the standards commit 65d9982d7e523a1a8e7c9af012da0d166f72fc56 upstream. ECMA-48 [1] (aka ISO 6429) has defined SGR 21 as "doubly underlined" since at least March 1984. The Linux kernel has treated it as SGR 22 "normal intensity" since it was added in Linux-0.96b in June 1992. Before that, it was simply ignored. Other terminal emulators have either ignored it, or treat it as double underline now. xterm for example added support in its 304 release (May 2014) [2] where it was previously ignoring it. Changing this behavior shouldn't be an issue: - It isn't a named capability in ncurses's terminfo database, so no script is using libtinfo/libcurses to look this up, or using tput to query & output the right sequence. - Any script assuming SGR 21 will reset intensity in all terminals already do not work correctly on non-Linux VTs (including running under screen/tmux/etc...). - If someone has written a script that only runs in the Linux VT, and they're using SGR 21 (instead of SGR 22), the output should still be readable. imo it's important to change this as the Linux VT's non-conformance is sometimes used as an argument for other terminal emulators to not implement SGR 21 at all, or do so incorrectly. [1]: https://www.ecma-international.org/publications/standards/Ecma-048.htm [2]: https://github.com/ThomasDickey/xterm-snapshots/commit/2fd29cb98d214cb536bcafbee00bc73b3f1eeb9d Signed-off-by: Mike Frysinger Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 68c7bb0b7991..9e1ac58e269e 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1354,6 +1354,11 @@ static void csi_m(struct vc_data *vc) case 3: vc->vc_italic = 1; break; + case 21: + /* + * No console drivers support double underline, so + * convert it to a single underline. + */ case 4: vc->vc_underline = 1; break; @@ -1389,7 +1394,6 @@ static void csi_m(struct vc_data *vc) vc->vc_disp_ctrl = 1; vc->vc_toggle_meta = 1; break; - case 21: case 22: vc->vc_intensity = 1; break; -- cgit v1.2.3 From 4e4321c232c75230bd1579eba6c5b3f54571328d Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Thu, 6 Apr 2017 09:12:18 +0800 Subject: md/raid10: reset the 'first' at the end of loop commit 6f287ca6046edd34ed83aafb7f9033c9c2e809e2 upstream. We need to set "first = 0' at the end of rdev_for_each loop, so we can get the array's min_offset_diff correctly otherwise min_offset_diff just means the last rdev's offset diff. [only the first chunk, due to b506335e5d2b ("md/raid10: skip spare disk as 'first' disk") being already applied - gregkh] Suggested-by: NeilBrown Signed-off-by: Guoqing Jiang Reviewed-by: NeilBrown Signed-off-by: Shaohua Li Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid10.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 18a4271bf569..6a7b9b1dcfe3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3681,6 +3681,7 @@ static int raid10_run(struct mddev *mddev) if (blk_queue_discard(bdev_get_queue(rdev->bdev))) discard_supported = true; + first = 0; } if (mddev->queue) { -- cgit v1.2.3 From 83216cbbfda8c7091fffa8260e4436355f1d49a7 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 15 Mar 2018 17:54:20 +0100 Subject: net: hns: Fix ethtool private flags commit d61d263c8d82db7c4404a29ebc29674b1c0c05c9 upstream. The driver implementation returns support for private flags, while no private flags are present. When asked for the number of private flags it returns the number of statistic flag names. Fix this by returning EOPNOTSUPP for not implemented ethtool flags. Signed-off-by: Matthias Brugger Signed-off-by: David S. Miller Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 34b5e699a1d5..02a03bccde7b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -671,7 +671,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data) static int hns_gmac_get_sset_count(int stringset) { - if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) + if (stringset == ETH_SS_STATS) return ARRAY_SIZE(g_gmac_stats_string); return 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index 4ecb809785f9..6ea872287307 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb) int hns_ppe_get_sset_count(int stringset) { - if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) + if (stringset == ETH_SS_STATS) return ETH_PPE_STATIC_NUM; return 0; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index fbbbbffd58dc..f3be9ac47bfb 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -798,7 +798,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data) */ int hns_rcb_get_ring_sset_count(int stringset) { - if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) + if (stringset == ETH_SS_STATS) return HNS_RING_STATIC_REG_NUM; return 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 86a496d71995..6be0cae44e9b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -1017,8 +1017,10 @@ int hns_get_sset_count(struct net_device *netdev, int stringset) cnt--; return cnt; - } else { + } else if (stringset == ETH_SS_STATS) { return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset)); + } else { + return -EOPNOTSUPP; } } -- cgit v1.2.3 From 182ab70f61d18ed231ab4357bb2059a2be27f257 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Apr 2018 09:08:12 +0200 Subject: Revert "spi: bcm-qspi: shut up warning about cfi header inclusion" This reverts commit c30e6636ce101fd61331092c490b9d9c55b2d143. Florian writes: Sorry for noticing so late, but this appears to be bogus, there is no MTD_NORFLASH symbol being defined in 4.9, in fact I can't find this Kconfig symbol in any kernel version, so this effectively results in the driver no longer being selectable, so this sure does silence the warning. It's not good to just disable a whole driver :( So let's revert the patch for now, Arnd can work on a better build fix... Reported-by: Florian Fainelli Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/spi/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 0e7415f6d093..b7995474148c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -156,7 +156,6 @@ config SPI_BCM63XX_HSSPI config SPI_BCM_QSPI tristate "Broadcom BSPI and MSPI controller support" depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || COMPILE_TEST - depends on MTD_NORFLASH default ARCH_BCM_IPROC help Enables support for the Broadcom SPI flash and MSPI controller. -- cgit v1.2.3 From 39639c49bc5046b3279d8dd400defb5d32884ff3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Apr 2018 09:28:46 +0200 Subject: Revert "mtip32xx: use runtime tag to initialize command header" This reverts commit db54facd56a40e7766bf7f7cda1ae138e72a691c which was commit a4e84aae8139aca9fbfbced1f45c51ca81b57488 upstream. Ben writes: MQ IO schedulers were introduced in 4.11, so this shouldn't be needed in older branches. It also causes a performance regression (fixed upstream). Please revert this for 4.4 and 4.9. So let's revert it! Reported-by: Ben Hutchings Cc: Ming Lei Cc: Jens Axboe Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/block/mtip32xx/mtip32xx.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index b86273fdf48e..3cfd879267b2 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -169,25 +169,6 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev) return false; /* device present */ } -/* we have to use runtime tag to setup command header */ -static void mtip_init_cmd_header(struct request *rq) -{ - struct driver_data *dd = rq->q->queuedata; - struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); - u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; - - /* Point the command headers at the command tables. */ - cmd->command_header = dd->port->command_list + - (sizeof(struct mtip_cmd_hdr) * rq->tag); - cmd->command_header_dma = dd->port->command_list_dma + - (sizeof(struct mtip_cmd_hdr) * rq->tag); - - if (host_cap_64) - cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); - - cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); -} - static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) { struct request *rq; @@ -199,9 +180,6 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) if (IS_ERR(rq)) return NULL; - /* Internal cmd isn't submitted via .queue_rq */ - mtip_init_cmd_header(rq); - return blk_mq_rq_to_pdu(rq); } @@ -3833,8 +3811,6 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq = bd->rq; int ret; - mtip_init_cmd_header(rq); - if (unlikely(mtip_check_unal_depth(hctx, rq))) return BLK_MQ_RQ_QUEUE_BUSY; @@ -3866,6 +3842,7 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, { struct driver_data *dd = data; struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); + u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; /* * For flush requests, request_idx starts at the end of the @@ -3882,6 +3859,17 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, memset(cmd->command, 0, CMD_DMA_ALLOC_SZ); + /* Point the command headers at the command tables. */ + cmd->command_header = dd->port->command_list + + (sizeof(struct mtip_cmd_hdr) * request_idx); + cmd->command_header_dma = dd->port->command_list_dma + + (sizeof(struct mtip_cmd_hdr) * request_idx); + + if (host_cap_64) + cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); + + cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); + sg_init_table(cmd->sg, MTIP_MAX_SG); return 0; } -- cgit v1.2.3 From bf7eb32f77e2b509942feff4bdf124a962e3ab52 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Apr 2018 10:18:25 +0200 Subject: spi: davinci: fix up dma_mapping_error() incorrect patch commit aabb797b4c1204b2e8518538b2616e476f2bac92, which is commit c5a2a394835f473ae23931eda5066d3771d7b2f8 upstream had an error in it. Ben writes: The '!' needs to be deleted. This appears to have been fixed upstream by: commit 8aedbf580d21121d2a032e4c8ea12d8d2d85e275 Author: Fabien Parent Date: Thu Feb 23 19:01:56 2017 +0100 spi: davinci: Use SPI framework to handle DMA mapping which is not suitable for stable. So I'm just fixing this up directly. Reported-by: Ben Hutchings Cc: Kevin Hilman Cc: Mark Brown Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-davinci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 02fb96797ac8..0d8f43a17edb 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -646,7 +646,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) buf = t->rx_buf; t->rx_dma = dma_map_single(&spi->dev, buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(&spi->dev, !t->rx_dma)) { + if (dma_mapping_error(&spi->dev, t->rx_dma)) { ret = -EFAULT; goto err_rx_map; } -- cgit v1.2.3 From ddeedda6e71c5919adae5419297fb27a622128b4 Mon Sep 17 00:00:00 2001 From: "sudarsana.kalluru@cavium.com" Date: Thu, 4 May 2017 08:15:04 -0700 Subject: qed: Fix overriding of supported autoneg value. [ Upstream commit 34f9199ce7b7e5c641b96e928bd60e086bf7f278 ] Driver currently uses advertised-autoneg value to populate the supported-autoneg field. When advertised field is updated, user gets the same value for supported field. Supported-autoneg value need to be populated from the link capabilities value returned by the MFW. Signed-off-by: Sudarsana Reddy Kalluru Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 3 +++ drivers/net/ethernet/qlogic/qed/qed_main.c | 6 +++++- drivers/net/ethernet/qlogic/qed/qed_mcp.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index afe5e57d9acb..9a6adbd9ed34 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -1628,6 +1628,9 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) DP_NOTICE(p_hwfn, "Unknown Speed in 0x%08x\n", link_temp); } + p_hwfn->mcp_info->link_capabilities.default_speed_autoneg = + link->speed.autoneg; + link_temp &= NVM_CFG1_PORT_DRV_FLOW_CONTROL_MASK; link_temp >>= NVM_CFG1_PORT_DRV_FLOW_CONTROL_OFFSET; link->pause.autoneg = !!(link_temp & diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index dba3fbe4800e..0b949c6d83fc 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1240,7 +1240,7 @@ static void qed_fill_link(struct qed_hwfn *hwfn, /* TODO - at the moment assume supported and advertised speed equal */ if_link->supported_caps = QED_LM_FIBRE_BIT; - if (params.speed.autoneg) + if (link_caps.default_speed_autoneg) if_link->supported_caps |= QED_LM_Autoneg_BIT; if (params.pause.autoneg || (params.pause.forced_rx && params.pause.forced_tx)) @@ -1250,6 +1250,10 @@ static void qed_fill_link(struct qed_hwfn *hwfn, if_link->supported_caps |= QED_LM_Pause_BIT; if_link->advertised_caps = if_link->supported_caps; + if (params.speed.autoneg) + if_link->advertised_caps |= QED_LM_Autoneg_BIT; + else + if_link->advertised_caps &= ~QED_LM_Autoneg_BIT; if (params.speed.advertised_speeds & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) if_link->advertised_caps |= QED_LM_1000baseT_Half_BIT | diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index dff520ed069b..7b7a84d2c839 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -35,6 +35,7 @@ struct qed_mcp_link_params { struct qed_mcp_link_capabilities { u32 speed_capabilities; + bool default_speed_autoneg; }; struct qed_mcp_link_state { -- cgit v1.2.3 From beaf445bdd0677d45032aa082faa8dc106526bd5 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Fri, 28 Apr 2017 12:41:02 -0500 Subject: md/raid5: make use of spin_lock_irq over local_irq_disable + spin_lock [ Upstream commit 3d05f3aed5d721c2c77d20288c29ab26c6193ed5 ] On mainline, there is no functional difference, just less code, and symmetric lock/unlock paths. On PREEMPT_RT builds, this fixes the following warning, seen by Alexander GQ Gerasiov, due to the sleeping nature of spinlocks. BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:993 in_atomic(): 0, irqs_disabled(): 1, pid: 58, name: kworker/u12:1 CPU: 5 PID: 58 Comm: kworker/u12:1 Tainted: G W 4.9.20-rt16-stand6-686 #1 Hardware name: Supermicro SYS-5027R-WRF/X9SRW-F, BIOS 3.2a 10/28/2015 Workqueue: writeback wb_workfn (flush-253:0) Call Trace: dump_stack+0x47/0x68 ? migrate_enable+0x4a/0xf0 ___might_sleep+0x101/0x180 rt_spin_lock+0x17/0x40 add_stripe_bio+0x4e3/0x6c0 [raid456] ? preempt_count_add+0x42/0xb0 raid5_make_request+0x737/0xdd0 [raid456] Reported-by: Alexander GQ Gerasiov Tested-by: Alexander GQ Gerasiov Signed-off-by: Julia Cartwright Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid5.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 4493be50fc6a..86ba7851e881 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -110,8 +110,7 @@ static inline void unlock_device_hash_lock(struct r5conf *conf, int hash) static inline void lock_all_device_hash_locks_irq(struct r5conf *conf) { int i; - local_irq_disable(); - spin_lock(conf->hash_locks); + spin_lock_irq(conf->hash_locks); for (i = 1; i < NR_STRIPE_HASH_LOCKS; i++) spin_lock_nest_lock(conf->hash_locks + i, conf->hash_locks); spin_lock(&conf->device_lock); @@ -121,9 +120,9 @@ static inline void unlock_all_device_hash_locks_irq(struct r5conf *conf) { int i; spin_unlock(&conf->device_lock); - for (i = NR_STRIPE_HASH_LOCKS; i; i--) - spin_unlock(conf->hash_locks + i - 1); - local_irq_enable(); + for (i = NR_STRIPE_HASH_LOCKS - 1; i; i--) + spin_unlock(conf->hash_locks + i); + spin_unlock_irq(conf->hash_locks); } /* bio's attached to a stripe+device for I/O are linked together in bi_sector @@ -732,12 +731,11 @@ static bool is_full_stripe_write(struct stripe_head *sh) static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) { - local_irq_disable(); if (sh1 > sh2) { - spin_lock(&sh2->stripe_lock); + spin_lock_irq(&sh2->stripe_lock); spin_lock_nested(&sh1->stripe_lock, 1); } else { - spin_lock(&sh1->stripe_lock); + spin_lock_irq(&sh1->stripe_lock); spin_lock_nested(&sh2->stripe_lock, 1); } } @@ -745,8 +743,7 @@ static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) { spin_unlock(&sh1->stripe_lock); - spin_unlock(&sh2->stripe_lock); - local_irq_enable(); + spin_unlock_irq(&sh2->stripe_lock); } /* Only freshly new full stripe normal write stripe can be added to a batch list */ -- cgit v1.2.3 From d36d6e43078a6ccc1e984534f292e19ab2733935 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 13:43:24 +0800 Subject: rtc: snvs: fix an incorrect check of return value [ Upstream commit 758929005f06f954b7e1c87a1c9fdb44157b228f ] Function devm_regmap_init_mmio() returns an ERR_PTR on error. However, in function snvs_rtc_probe() its return value is checked against NULL. This patch fixes it by checking the return value with IS_ERR(). Signed-off-by: Pan Bian Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-snvs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 0f11c2a228e3..a753ef9c1459 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -257,7 +257,7 @@ static int snvs_rtc_probe(struct platform_device *pdev) of_property_read_u32(pdev->dev.of_node, "offset", &data->offset); } - if (!data->regmap) { + if (IS_ERR(data->regmap)) { dev_err(&pdev->dev, "Can't find snvs syscon\n"); return -ENODEV; } -- cgit v1.2.3 From f9800a1f5797c48ab9de6488077a869a59061470 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 4 May 2017 15:50:53 -0700 Subject: IB/srpt: Fix abort handling [ Upstream commit 55d694275f41a1c0eef4ef49044ff29bc3999490 ] Let the target core check the CMD_T_ABORTED flag instead of the SRP target driver. Hence remove the transport_check_aborted_status() call. Since state == SRPT_STATE_CMD_RSP_SENT is something that really should not happen, do not try to recover if srpt_queue_response() is called for an I/O context that is in that state. This patch is a bug fix because the srpt_abort_cmd() call is misplaced - if that function is called from srpt_queue_response() it should either be called before the command state is changed or after the response has been sent. Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke Cc: Doug Ledford Cc: Christoph Hellwig Cc: Andy Grover Cc: David Disseldorp Signed-off-by: Nicholas Bellinger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/srpt/ib_srpt.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 29ab814693fc..860bb59f6326 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2292,12 +2292,8 @@ static void srpt_queue_response(struct se_cmd *cmd) } spin_unlock_irqrestore(&ioctx->spinlock, flags); - if (unlikely(transport_check_aborted_status(&ioctx->cmd, false) - || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) { - atomic_inc(&ch->req_lim_delta); - srpt_abort_cmd(ioctx); + if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) return; - } /* For read commands, transfer the data to the initiator. */ if (ioctx->cmd.data_direction == DMA_FROM_DEVICE && -- cgit v1.2.3 From 84284968156340dce4e942b1cebea66c3d4f8146 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 4 May 2017 15:50:54 -0700 Subject: IB/srpt: Avoid that aborting a command triggers a kernel warning [ Upstream commit bd2c52d733f126ff75f99c537a27655b2db07e28 ] Avoid that the following warning is triggered: WARNING: CPU: 10 PID: 166 at ../drivers/infiniband/ulp/srpt/ib_srpt.c:2674 srpt_release_cmd+0x139/0x140 [ib_srpt] CPU: 10 PID: 166 Comm: kworker/u24:8 Not tainted 4.9.4-1-default #1 Workqueue: tmr-fileio target_tmr_work [target_core_mod] Call Trace: [] dump_stack+0x63/0x83 [] __warn+0xcb/0xf0 [] warn_slowpath_null+0x1d/0x20 [] srpt_release_cmd+0x139/0x140 [ib_srpt] [] target_release_cmd_kref+0xb7/0x120 [target_core_mod] [] target_put_sess_cmd+0x2f/0x60 [target_core_mod] [] core_tmr_lun_reset+0x340/0x790 [target_core_mod] [] target_tmr_work+0xe6/0x140 [target_core_mod] [] process_one_work+0x1f3/0x4d0 [] worker_thread+0x48/0x4e0 [] ? process_one_work+0x4d0/0x4d0 [] kthread+0xca/0xe0 [] ? kthread_park+0x60/0x60 [] ret_from_fork+0x25/0x30 Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke Cc: Doug Ledford Cc: Christoph Hellwig Cc: David Disseldorp Signed-off-by: Nicholas Bellinger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 860bb59f6326..876f438aa048 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2666,7 +2666,8 @@ static void srpt_release_cmd(struct se_cmd *se_cmd) struct srpt_rdma_ch *ch = ioctx->ch; unsigned long flags; - WARN_ON(ioctx->state != SRPT_STATE_DONE); + WARN_ON_ONCE(ioctx->state != SRPT_STATE_DONE && + !(ioctx->cmd.transport_state & CMD_T_ABORTED)); if (ioctx->n_rw_ctx) { srpt_free_rw_ctxs(ch, ioctx); -- cgit v1.2.3 From 68e356469b2ecdfc4777c3329753183cc40a9227 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 5 May 2017 15:25:32 -0700 Subject: bna: Avoid reading past end of buffer [ Upstream commit 9e4eb1ce472fbf7b007f23c88ec11c37265e401c ] Using memcpy() from a string that is shorter than the length copied means the destination buffer is being filled with arbitrary data from the kernel rodata segment. Instead, use strncpy() which will fill the trailing bytes with zeros. This was found with the future CONFIG_FORTIFY_SOURCE feature. Cc: Daniel Micay Signed-off-by: Kees Cook Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/brocade/bna/bfa_ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 0f6811860ad5..a36e38676640 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -2845,7 +2845,7 @@ bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) { - memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); + strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); } static void -- cgit v1.2.3 From 694fb34bebb6de95eb1293b2ca190edf7a909f18 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 5 May 2017 15:34:34 -0700 Subject: qlge: Avoid reading past end of buffer [ Upstream commit df5303a8aa9a0a6934f4cea7427f1edf771f21c2 ] Using memcpy() from a string that is shorter than the length copied means the destination buffer is being filled with arbitrary data from the kernel rodata segment. Instead, use strncpy() which will fill the trailing bytes with zeros. This was found with the future CONFIG_FORTIFY_SOURCE feature. Cc: Daniel Micay Signed-off-by: Kees Cook Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qlge/qlge_dbg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c index be258d90de9e..e3223f2fe2ff 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c @@ -765,7 +765,7 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump) sizeof(struct mpi_coredump_global_header); mpi_coredump->mpi_global_header.imageSize = sizeof(struct ql_mpi_coredump); - memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", + strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", sizeof(mpi_coredump->mpi_global_header.idString)); /* Get generic NIC reg dump */ @@ -1255,7 +1255,7 @@ static void ql_gen_reg_dump(struct ql_adapter *qdev, sizeof(struct mpi_coredump_global_header); mpi_coredump->mpi_global_header.imageSize = sizeof(struct ql_reg_dump); - memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", + strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", sizeof(mpi_coredump->mpi_global_header.idString)); -- cgit v1.2.3 From 0d84e3b5a64ac3405a103e579d8a903fad916798 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 Apr 2017 13:44:11 +0200 Subject: ubi: fastmap: Fix slab corruption [ Upstream commit 8a1435880f452430b41374d27ac4a33e7bd381ea ] Booting with UBI fastmap and SLUB debugging enabled results in the following splats. The problem is that ubi_scan_fastmap() moves the fastmap blocks from the scan_ai (allocated in scan_fast()) to the ai allocated in ubi_attach(). This results in two problems: - When the scan_ai is freed, aebs which were allocated from its slab cache are still in use. - When the other ai is being destroyed in destroy_ai(), the arguments to kmem_cache_free() call are incorrect since aebs on its ->fastmap list were allocated with a slab cache from a differnt ai. Fix this by making a copy of the aebs in ubi_scan_fastmap() instead of moving them. ============================================================================= BUG ubi_aeb_slab_cache (Not tainted): Objects remaining in ubi_aeb_slab_cache on __kmem_cache_shutdown() ----------------------------------------------------------------------------- INFO: Slab 0xbfd2da3c objects=17 used=1 fp=0xb33d7748 flags=0x40000080 CPU: 1 PID: 118 Comm: ubiattach Tainted: G B 4.9.15 #3 [<80111910>] (unwind_backtrace) from [<8010d498>] (show_stack+0x18/0x1c) [<8010d498>] (show_stack) from [<804a3274>] (dump_stack+0xb4/0xe0) [<804a3274>] (dump_stack) from [<8026c47c>] (slab_err+0x78/0x88) [<8026c47c>] (slab_err) from [<802735bc>] (__kmem_cache_shutdown+0x180/0x3e0) [<802735bc>] (__kmem_cache_shutdown) from [<8024e13c>] (shutdown_cache+0x1c/0x60) [<8024e13c>] (shutdown_cache) from [<8024ed64>] (kmem_cache_destroy+0x19c/0x20c) [<8024ed64>] (kmem_cache_destroy) from [<8057cc14>] (destroy_ai+0x1dc/0x1e8) [<8057cc14>] (destroy_ai) from [<8057f04c>] (ubi_attach+0x3f4/0x450) [<8057f04c>] (ubi_attach) from [<8056fe70>] (ubi_attach_mtd_dev+0x60c/0xff8) [<8056fe70>] (ubi_attach_mtd_dev) from [<80571d78>] (ctrl_cdev_ioctl+0x110/0x2b8) [<80571d78>] (ctrl_cdev_ioctl) from [<8029c77c>] (do_vfs_ioctl+0xac/0xa00) [<8029c77c>] (do_vfs_ioctl) from [<8029d10c>] (SyS_ioctl+0x3c/0x64) [<8029d10c>] (SyS_ioctl) from [<80108860>] (ret_fast_syscall+0x0/0x1c) INFO: Object 0xb33d7e88 @offset=3720 INFO: Allocated in scan_peb+0x608/0x81c age=72 cpu=1 pid=118 kmem_cache_alloc+0x3b0/0x43c scan_peb+0x608/0x81c ubi_attach+0x124/0x450 ubi_attach_mtd_dev+0x60c/0xff8 ctrl_cdev_ioctl+0x110/0x2b8 do_vfs_ioctl+0xac/0xa00 SyS_ioctl+0x3c/0x64 ret_fast_syscall+0x0/0x1c kmem_cache_destroy ubi_aeb_slab_cache: Slab cache still has objects CPU: 1 PID: 118 Comm: ubiattach Tainted: G B 4.9.15 #3 [<80111910>] (unwind_backtrace) from [<8010d498>] (show_stack+0x18/0x1c) [<8010d498>] (show_stack) from [<804a3274>] (dump_stack+0xb4/0xe0) [<804a3274>] (dump_stack) from [<8024ed80>] (kmem_cache_destroy+0x1b8/0x20c) [<8024ed80>] (kmem_cache_destroy) from [<8057cc14>] (destroy_ai+0x1dc/0x1e8) [<8057cc14>] (destroy_ai) from [<8057f04c>] (ubi_attach+0x3f4/0x450) [<8057f04c>] (ubi_attach) from [<8056fe70>] (ubi_attach_mtd_dev+0x60c/0xff8) [<8056fe70>] (ubi_attach_mtd_dev) from [<80571d78>] (ctrl_cdev_ioctl+0x110/0x2b8) [<80571d78>] (ctrl_cdev_ioctl) from [<8029c77c>] (do_vfs_ioctl+0xac/0xa00) [<8029c77c>] (do_vfs_ioctl) from [<8029d10c>] (SyS_ioctl+0x3c/0x64) [<8029d10c>] (SyS_ioctl) from [<80108860>] (ret_fast_syscall+0x0/0x1c) cache_from_obj: Wrong slab cache. ubi_aeb_slab_cache but object is from ubi_aeb_slab_cache ------------[ cut here ]------------ WARNING: CPU: 1 PID: 118 at mm/slab.h:354 kmem_cache_free+0x39c/0x450 Modules linked in: CPU: 1 PID: 118 Comm: ubiattach Tainted: G B 4.9.15 #3 [<80111910>] (unwind_backtrace) from [<8010d498>] (show_stack+0x18/0x1c) [<8010d498>] (show_stack) from [<804a3274>] (dump_stack+0xb4/0xe0) [<804a3274>] (dump_stack) from [<80120e40>] (__warn+0xf4/0x10c) [<80120e40>] (__warn) from [<80120f20>] (warn_slowpath_null+0x28/0x30) [<80120f20>] (warn_slowpath_null) from [<80271fe0>] (kmem_cache_free+0x39c/0x450) [<80271fe0>] (kmem_cache_free) from [<8057cb88>] (destroy_ai+0x150/0x1e8) [<8057cb88>] (destroy_ai) from [<8057ef1c>] (ubi_attach+0x2c4/0x450) [<8057ef1c>] (ubi_attach) from [<8056fe70>] (ubi_attach_mtd_dev+0x60c/0xff8) [<8056fe70>] (ubi_attach_mtd_dev) from [<80571d78>] (ctrl_cdev_ioctl+0x110/0x2b8) [<80571d78>] (ctrl_cdev_ioctl) from [<8029c77c>] (do_vfs_ioctl+0xac/0xa00) [<8029c77c>] (do_vfs_ioctl) from [<8029d10c>] (SyS_ioctl+0x3c/0x64) [<8029d10c>] (SyS_ioctl) from [<80108860>] (ret_fast_syscall+0x0/0x1c) ---[ end trace 2bd8396277fd0a0b ]--- ============================================================================= BUG ubi_aeb_slab_cache (Tainted: G B W ): page slab pointer corrupt. ----------------------------------------------------------------------------- INFO: Allocated in scan_peb+0x608/0x81c age=104 cpu=1 pid=118 kmem_cache_alloc+0x3b0/0x43c scan_peb+0x608/0x81c ubi_attach+0x124/0x450 ubi_attach_mtd_dev+0x60c/0xff8 ctrl_cdev_ioctl+0x110/0x2b8 do_vfs_ioctl+0xac/0xa00 SyS_ioctl+0x3c/0x64 ret_fast_syscall+0x0/0x1c INFO: Slab 0xbfd2da3c objects=17 used=1 fp=0xb33d7748 flags=0x40000081 INFO: Object 0xb33d7e88 @offset=3720 fp=0xb33d7da0 Redzone b33d7e80: cc cc cc cc cc cc cc cc ........ Object b33d7e88: 02 00 00 00 01 00 00 00 00 f0 ff 7f ff ff ff ff ................ Object b33d7e98: 00 00 00 00 00 00 00 00 bd 16 00 00 00 00 00 00 ................ Object b33d7ea8: 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ Redzone b33d7eb8: cc cc cc cc .... Padding b33d7f60: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ CPU: 1 PID: 118 Comm: ubiattach Tainted: G B W 4.9.15 #3 [<80111910>] (unwind_backtrace) from [<8010d498>] (show_stack+0x18/0x1c) [<8010d498>] (show_stack) from [<804a3274>] (dump_stack+0xb4/0xe0) [<804a3274>] (dump_stack) from [<80271770>] (free_debug_processing+0x320/0x3c4) [<80271770>] (free_debug_processing) from [<80271ad0>] (__slab_free+0x2bc/0x430) [<80271ad0>] (__slab_free) from [<80272024>] (kmem_cache_free+0x3e0/0x450) [<80272024>] (kmem_cache_free) from [<8057cb88>] (destroy_ai+0x150/0x1e8) [<8057cb88>] (destroy_ai) from [<8057ef1c>] (ubi_attach+0x2c4/0x450) [<8057ef1c>] (ubi_attach) from [<8056fe70>] (ubi_attach_mtd_dev+0x60c/0xff8) [<8056fe70>] (ubi_attach_mtd_dev) from [<80571d78>] (ctrl_cdev_ioctl+0x110/0x2b8) [<80571d78>] (ctrl_cdev_ioctl) from [<8029c77c>] (do_vfs_ioctl+0xac/0xa00) [<8029c77c>] (do_vfs_ioctl) from [<8029d10c>] (SyS_ioctl+0x3c/0x64) [<8029d10c>] (SyS_ioctl) from [<80108860>] (ret_fast_syscall+0x0/0x1c) FIX ubi_aeb_slab_cache: Object at 0xb33d7e88 not freed Signed-off-by: Rabin Vincent Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/fastmap.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index c1f5c29e458e..b44c8d348e78 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -828,6 +828,24 @@ static int find_fm_anchor(struct ubi_attach_info *ai) return ret; } +static struct ubi_ainf_peb *clone_aeb(struct ubi_attach_info *ai, + struct ubi_ainf_peb *old) +{ + struct ubi_ainf_peb *new; + + new = ubi_alloc_aeb(ai, old->pnum, old->ec); + if (!new) + return NULL; + + new->vol_id = old->vol_id; + new->sqnum = old->sqnum; + new->lnum = old->lnum; + new->scrub = old->scrub; + new->copy_flag = old->copy_flag; + + return new; +} + /** * ubi_scan_fastmap - scan the fastmap. * @ubi: UBI device object @@ -847,7 +865,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, struct ubi_vid_hdr *vh; struct ubi_ec_hdr *ech; struct ubi_fastmap_layout *fm; - struct ubi_ainf_peb *tmp_aeb, *aeb; + struct ubi_ainf_peb *aeb; int i, used_blocks, pnum, fm_anchor, ret = 0; size_t fm_size; __be32 crc, tmp_crc; @@ -857,9 +875,16 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, if (fm_anchor < 0) return UBI_NO_FASTMAP; - /* Move all (possible) fastmap blocks into our new attach structure. */ - list_for_each_entry_safe(aeb, tmp_aeb, &scan_ai->fastmap, u.list) - list_move_tail(&aeb->u.list, &ai->fastmap); + /* Copy all (possible) fastmap blocks into our new attach structure. */ + list_for_each_entry(aeb, &scan_ai->fastmap, u.list) { + struct ubi_ainf_peb *new; + + new = clone_aeb(ai, aeb); + if (!new) + return -ENOMEM; + + list_add(&new->u.list, &ai->fastmap); + } down_write(&ubi->fm_protect); memset(ubi->fm_buf, 0, ubi->fm_size); -- cgit v1.2.3 From ad741ccdd88e8ab7d42f44509280abe5f615a1cf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 5 May 2017 08:33:24 +0300 Subject: ipmi_ssif: unlock on allocation failure [ Upstream commit cf9806f32ef63b745f2486e0dbb2ac21f4ca44f0 ] We should unlock and re-enable IRQs if this allocation fails. Fixes: 259307074bfc ("ipmi: Add SMBus interface driver (SSIF) ") Signed-off-by: Dan Carpenter Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_ssif.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 510fc104bcdc..f11c1c7e84c6 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -409,6 +409,7 @@ static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) msg = ipmi_alloc_smi_msg(); if (!msg) { ssif_info->ssif_state = SSIF_NORMAL; + ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -431,6 +432,7 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, msg = ipmi_alloc_smi_msg(); if (!msg) { ssif_info->ssif_state = SSIF_NORMAL; + ipmi_ssif_unlock_cond(ssif_info, flags); return; } -- cgit v1.2.3 From 2d11840e917e3f014ac4480b1a9e29977220aadf Mon Sep 17 00:00:00 2001 From: Jim Baxter Date: Mon, 8 May 2017 13:49:57 +0100 Subject: net: cdc_ncm: Fix TX zero padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit aeca3a77b1e0ed06a095933b89c86aed007383eb ] The zero padding that is added to NTB's does not zero the memory correctly. This is because the skb_put modifies the value of skb_out->len which results in the memset command not setting any memory to zero as (ctx->tx_max - skb_out->len) == 0. I have resolved this by storing the size of the memory to be zeroed before the skb_put and using this in the memset call. Signed-off-by: Jim Baxter Reviewed-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ncm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index dc6d3b0a0be8..feb61eaffe32 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1118,6 +1118,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) u16 n = 0, index, ndplen; u8 ready2send = 0; u32 delayed_ndp_size; + size_t padding_count; /* When our NDP gets written in cdc_ncm_ndp(), then skb_out->len gets updated * accordingly. Otherwise, we should check here. @@ -1274,11 +1275,13 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) * a ZLP after full sized NTBs. */ if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && - skb_out->len > ctx->min_tx_pkt) - memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, - ctx->tx_max - skb_out->len); - else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0) + skb_out->len > ctx->min_tx_pkt) { + padding_count = ctx->tx_max - skb_out->len; + memset(skb_put(skb_out, padding_count), 0, padding_count); + } else if (skb_out->len < ctx->tx_max && + (skb_out->len % dev->maxpacket) == 0) { *skb_put(skb_out, 1) = 0; /* force short packet */ + } /* set final frame length */ nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; -- cgit v1.2.3 From 988ef9c8c29ccc9949a18b599df463ebd653daef Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 8 May 2017 14:21:21 -0500 Subject: net: ethernet: ti: cpsw: adjust cpsw fifos depth for fullduplex flow control [ Upstream commit 48f5bccc60675f8426a6159935e8636a1fd89f56 ] When users set flow control using ethtool the bits are set properly in the CPGMAC_SL MACCONTROL register, but the FIFO depth in the respective Port n Maximum FIFO Blocks (Pn_MAX_BLKS) registers remains set to the minimum size reset value. When receive flow control is enabled on a port, the port's associated FIFO block allocation must be adjusted. The port RX allocation must increase to accommodate the flow control runout. The TRM recommends numbers of 5 or 6. Hence, apply required Port FIFO configuration to Pn_MAX_BLKS.Pn_TX_MAX_BLKS=0xF and Pn_MAX_BLKS.Pn_RX_MAX_BLKS=0x5 during interface initialization. Cc: Schuyler Patton Signed-off-by: Grygorii Strashko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ti/cpsw.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 2bd1282735b0..552de9c490c6 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -282,6 +282,10 @@ struct cpsw_ss_regs { /* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */ #define CPSW_V1_SEQ_ID_OFS_SHIFT 16 +#define CPSW_MAX_BLKS_TX 15 +#define CPSW_MAX_BLKS_TX_SHIFT 4 +#define CPSW_MAX_BLKS_RX 5 + struct cpsw_host_regs { u32 max_blks; u32 blk_cnt; @@ -1160,11 +1164,23 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) switch (cpsw->version) { case CPSW_VERSION_1: slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP); + /* Increase RX FIFO size to 5 for supporting fullduplex + * flow control mode + */ + slave_write(slave, + (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | + CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS); break; case CPSW_VERSION_2: case CPSW_VERSION_3: case CPSW_VERSION_4: slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP); + /* Increase RX FIFO size to 5 for supporting fullduplex + * flow control mode + */ + slave_write(slave, + (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | + CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS); break; } -- cgit v1.2.3 From a90e9ee704b291125d0dda967e14a3340567afab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 8 May 2017 15:55:14 -0700 Subject: drivers/misc/vmw_vmci/vmci_queue_pair.c: fix a couple integer overflow tests [ Upstream commit 146180c052a00172f4dc08eaade836fd02f61fb5 ] The "DIV_ROUND_UP(size, PAGE_SIZE)" operation can overflow if "size" is more than ULLONG_MAX - PAGE_SIZE. Link: http://lkml.kernel.org/r/20170322111950.GA11279@mwanda Signed-off-by: Dan Carpenter Cc: Jorgen Hansen Cc: Masahiro Yamada Cc: Michal Hocko Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_queue_pair.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index f84a4275ca29..f735ab4ba84e 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -298,8 +298,11 @@ static void *qp_alloc_queue(u64 size, u32 flags) size_t pas_size; size_t vas_size; size_t queue_size = sizeof(*queue) + sizeof(*queue->kernel_if); - const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; + u64 num_pages; + if (size > SIZE_MAX - PAGE_SIZE) + return NULL; + num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; if (num_pages > (SIZE_MAX - queue_size) / (sizeof(*queue->kernel_if->u.g.pas) + @@ -624,9 +627,12 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size) { struct vmci_queue *queue; size_t queue_page_size; - const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; + u64 num_pages; const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if)); + if (size > SIZE_MAX - PAGE_SIZE) + return NULL; + num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; if (num_pages > (SIZE_MAX - queue_size) / sizeof(*queue->kernel_if->u.h.page)) return NULL; -- cgit v1.2.3 From ae1b31453e6e59bc68f11ba6efb2effc3d3b6b1a Mon Sep 17 00:00:00 2001 From: Talat Batheesh Date: Tue, 9 May 2017 14:45:23 +0300 Subject: net/mlx4_en: Avoid adding steering rules with invalid ring [ Upstream commit 89c557687a32c294e9d25670a96e9287c09f2d5f ] Inserting steering rules with illegal ring is an invalid operation, block it. Fixes: 820672812f82 ('net/mlx4_en: Manage flow steering rules with ethtool') Signed-off-by: Talat Batheesh Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index bdda17d2ea0f..674246b189c2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1520,6 +1520,11 @@ static int mlx4_en_flow_replace(struct net_device *dev, qpn = priv->drop_qp.qpn; else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); + if (qpn < priv->rss_map.base_qpn || + qpn >= priv->rss_map.base_qpn + priv->rx_ring_num) { + en_warn(priv, "rxnfc: QP (0x%x) doesn't exist\n", qpn); + return -EINVAL; + } } else { if (cmd->fs.ring_cookie >= priv->rx_ring_num) { en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist\n", -- cgit v1.2.3 From 408719afbc61e388b1dc311d96a85e5d5e6e8f39 Mon Sep 17 00:00:00 2001 From: Ram Amrani Date: Tue, 9 May 2017 15:07:50 +0300 Subject: qed: Correct doorbell configuration for !4Kb pages [ Upstream commit a82dadbce47395747824971db08a128130786fdc ] When configuring the doorbell DPI address, driver aligns the start address to 4KB [HW-pages] instead of host PAGE_SIZE. As a result, RoCE applications might receive addresses which are unaligned to pages [when PAGE_SIZE > 4KB], which is a security risk. Fixes: 51ff17251c9c ("qed: Add support for RoCE hw init") Signed-off-by: Ram Amrani Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 9a6adbd9ed34..d02313770fc2 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -850,7 +850,7 @@ qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) NULL) + qed_cxt_get_proto_cid_count(p_hwfn, PROTOCOLID_ETH, NULL); - norm_regsize = roundup(QED_PF_DEMS_SIZE * non_pwm_conn, 4096); + norm_regsize = roundup(QED_PF_DEMS_SIZE * non_pwm_conn, PAGE_SIZE); min_addr_reg1 = norm_regsize / 4096; pwm_regsize = db_bar_size - norm_regsize; -- cgit v1.2.3 From 485c108e820d217a9ca597841d6e5667fa8c5e05 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 9 May 2017 15:40:38 +0200 Subject: net: qca_spi: Fix alignment issues in rx path [ Upstream commit 8d66c30b12ed3cb533696dea8b9a9eadd5da426a ] The qca_spi driver causes alignment issues on ARM devices. So fix this by using netdev_alloc_skb_ip_align(). Signed-off-by: Stefan Wahren Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qualcomm/qca_spi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 6e2add979471..8bbb55f31909 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -296,8 +296,9 @@ qcaspi_receive(struct qcaspi *qca) /* Allocate rx SKB if we don't have one available. */ if (!qca->rx_skb) { - qca->rx_skb = netdev_alloc_skb(net_dev, - net_dev->mtu + VLAN_ETH_HLEN); + qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, + net_dev->mtu + + VLAN_ETH_HLEN); if (!qca->rx_skb) { netdev_dbg(net_dev, "out of RX resources\n"); qca->stats.out_of_mem++; @@ -377,7 +378,7 @@ qcaspi_receive(struct qcaspi *qca) qca->rx_skb, qca->rx_skb->dev); qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; netif_rx_ni(qca->rx_skb); - qca->rx_skb = netdev_alloc_skb(net_dev, + qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, net_dev->mtu + VLAN_ETH_HLEN); if (!qca->rx_skb) { netdev_dbg(net_dev, "out of RX resources\n"); @@ -759,7 +760,8 @@ qcaspi_netdev_init(struct net_device *dev) if (!qca->rx_buffer) return -ENOBUFS; - qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN); + qca->rx_skb = netdev_alloc_skb_ip_align(dev, qca->net_dev->mtu + + VLAN_ETH_HLEN); if (!qca->rx_skb) { kfree(qca->rx_buffer); netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n"); -- cgit v1.2.3 From 014c8ea230972d327bb685d7d53cb7d7ff06b172 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 9 May 2017 17:19:42 +0100 Subject: netxen_nic: set rcode to the return status from the call to netxen_issue_cmd [ Upstream commit 0fe20fafd1791f993806d417048213ec57b81045 ] Currently rcode is being initialized to NX_RCODE_SUCCESS and later it is checked to see if it is not NX_RCODE_SUCCESS which is never true. It appears that there is an unintentional missing assignment of rcode from the return of the call to netxen_issue_cmd() that was dropped in an earlier fix, so add it in. Detected by CoverityScan, CID#401900 ("Logically dead code") Fixes: 2dcd5d95ad6b2 ("netxen_nic: fix cdrp race condition") Signed-off-by: Colin Ian King Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index b8d5270359cd..e30676515529 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c @@ -247,7 +247,7 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) cmd.req.arg3 = 0; if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) - netxen_issue_cmd(adapter, &cmd); + rcode = netxen_issue_cmd(adapter, &cmd); if (rcode != NX_RCODE_SUCCESS) return -EIO; -- cgit v1.2.3 From fdf3b78df4d24933df840a27e7bf836b7b6042a3 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Wed, 10 May 2017 11:20:27 -0400 Subject: mdio: mux: Correct mdio_mux_init error path issues [ Upstream commit b60161668199ac62011c024adc9e66713b9554e7 ] There is a potential unnecessary refcount decrement on error path of put_device(&pb->mii_bus->dev), as it is possible to avoid the of_mdio_find_bus() call if mux_bus is specified by the calling function. The same put_device() is not called in the error path if the devm_kzalloc of pb fails. This caused the variable used in the put_device() to be changed, as the pb pointer was obviously not set up. There is an unnecessary of_node_get() on child_bus_node if the of_mdiobus_register() is successful, as the for_each_available_child_of_node() automatically increments this. Thus the refcount on this node will always be +1 more than it should be. There is no of_node_put() on child_bus_node if the of_mdiobus_register() call fails. Finally, it is lacking devm_kfree() of pb in the error path. While this might not be technically necessary, it was present in other parts of the function. So, I am adding it where necessary to make it uniform. Signed-off-by: Jon Mason Fixes: f20e6657a875 ("mdio: mux: Enhanced MDIO mux framework for integrated multiplexers") Fixes: 0ca2997d1452 ("netdev/of/phy: Add MDIO bus multiplexer support.") Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/mdio-mux.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 963838d4fac1..6943c5ece44a 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c @@ -122,10 +122,9 @@ int mdio_mux_init(struct device *dev, pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL); if (pb == NULL) { ret_val = -ENOMEM; - goto err_parent_bus; + goto err_pb_kz; } - pb->switch_data = data; pb->switch_fn = switch_fn; pb->current_child = -1; @@ -154,6 +153,7 @@ int mdio_mux_init(struct device *dev, cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { ret_val = -ENOMEM; + devm_kfree(dev, cb); of_node_put(child_bus_node); break; } @@ -169,8 +169,8 @@ int mdio_mux_init(struct device *dev, if (r) { mdiobus_free(cb->mii_bus); devm_kfree(dev, cb); + of_node_put(child_bus_node); } else { - of_node_get(child_bus_node); cb->next = pb->children; pb->children = cb; } @@ -181,9 +181,11 @@ int mdio_mux_init(struct device *dev, return 0; } + devm_kfree(dev, pb); +err_pb_kz: /* balance the reference of_mdio_find_bus() took */ - put_device(&pb->mii_bus->dev); - + if (!mux_bus) + put_device(&parent_bus->dev); err_parent_bus: of_node_put(parent_bus_node); return ret_val; -- cgit v1.2.3 From 97e885c7d1c806ec9d602644cb9c6eee094b25a1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 19 Dec 2014 12:57:49 -0800 Subject: Input: elan_i2c - check if device is there before really probing [ Upstream commit c5928551fd41b2eecdad78fa2be2a4a13ed5fde9 ] Before trying to properly initialize the touchpad and generate bunch of errors, let's first see it there is anything at the given address. If we get error, fail silently with -ENXIO. Reviewed-by: Guenter Roeck Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/elan_i2c_core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index c9d491bc85e0..3851d5715772 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1082,6 +1082,13 @@ static int elan_probe(struct i2c_client *client, return error; } + /* Make sure there is something at this address */ + error = i2c_smbus_read_byte(client); + if (error < 0) { + dev_dbg(&client->dev, "nothing at this address: %d\n", error); + return -ENXIO; + } + /* Initialize the touchpad. */ error = elan_initialize(data); if (error) -- cgit v1.2.3 From e0709814a17f0eeed84fa593f7a3057aa38cba56 Mon Sep 17 00:00:00 2001 From: KT Liao Date: Mon, 12 Dec 2016 11:03:42 -0800 Subject: Input: elantech - force relative mode on a certain module [ Upstream commit d899520b0431e70279bfb5066ecb6dc91d0b7072 ] One of Elan modules with sample version is 0x74 and hw_version is 0x03 has a bug in absolute mode implementation, so let it run in default PS/2 relative mode. Signed-off-by: KT Liao Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/elantech.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 59603a5728f7..c519c0b09568 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1711,6 +1711,17 @@ int elantech_init(struct psmouse *psmouse) etd->samples[0], etd->samples[1], etd->samples[2]); } + if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) { + /* + * This module has a bug which makes absolute mode + * unusable, so let's abort so we'll be using standard + * PS/2 protocol. + */ + psmouse_info(psmouse, + "absolute mode broken, forcing standard PS/2 protocol\n"); + goto init_fail; + } + if (elantech_set_absolute_mode(psmouse)) { psmouse_err(psmouse, "failed to put touchpad into absolute mode.\n"); -- cgit v1.2.3 From 3a743c429f47a204a7b3bb0972daa4ad960c9088 Mon Sep 17 00:00:00 2001 From: MaJun Date: Fri, 12 May 2017 11:55:28 +0800 Subject: irqchip/mbigen: Fix the clear register offset calculation [ Upstream commit 9459a04b6a5a09967eec94a1b66f0a74312819d9 ] The register array offset for clearing an interrupt is calculated by: offset = (hwirq - RESERVED_IRQ_PER_MBIGEN_CHIP) / 32; This is wrong because the clear register array includes the reserved interrupts. So the clear operation ends up in the wrong register. This went unnoticed so far, because the hardware clears the real bit through a timeout mechanism when the hardware is configured in debug mode. That debug mode was enabled on early generations of the hardware, so the problem was papered over. On newer hardware with updated firmware the debug mode was disabled, so the bits did not get cleared which causes the system to malfunction. Remove the subtraction of RESERVED_IRQ_PER_MBIGEN_CHIP, so the correct register is accessed. [ tglx: Rewrote changelog ] Fixes: a6c2f87b8820 ("irqchip/mbigen: Implement the mbigen irq chip operation functions") Signed-off-by: MaJun Signed-off-by: Hanjun Guo Acked-by: Marc Zyngier Cc: Kefeng Wang Cc: linuxarm@huawei.com Cc: Wei Yongjun Link: http://lkml.kernel.org/r/1494561328-39514-4-git-send-email-guohanjun@huawei.com Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-mbigen.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index 03b79b061d24..05d87f60d929 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -105,10 +105,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, u32 *mask, u32 *addr) { - unsigned int ofst; - - hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP; - ofst = hwirq / 32 * 4; + unsigned int ofst = (hwirq / 32) * 4; *mask = 1 << (hwirq % 32); *addr = ofst + REG_MBIGEN_CLEAR_OFFSET; -- cgit v1.2.3 From 00b475072e4942036b1992fc0c9ab39cd84d1c9e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 12 May 2017 12:00:01 -0400 Subject: vmxnet3: ensure that adapter is in proper state during force_close [ Upstream commit 1c4d5f51a812a82de97beee24f48ed05c65ebda5 ] There are several paths in vmxnet3, where settings changes cause the adapter to be brought down and back up (vmxnet3_set_ringparam among them). Should part of the reset operation fail, these paths call vmxnet3_force_close, which enables all napi instances prior to calling dev_close (with the expectation that vmxnet3_close will then properly disable them again). However, vmxnet3_force_close neglects to clear VMXNET3_STATE_BIT_QUIESCED prior to calling dev_close. As a result vmxnet3_quiesce_dev (called from vmxnet3_close), returns early, and leaves all the napi instances in a enabled state while the device itself is closed. If a device in this state is activated again, napi_enable will be called on already enabled napi_instances, leading to a BUG halt. The fix is to simply enausre that the QUIESCED bit is cleared in vmxnet3_force_close to allow quesence to be completed properly on close. Signed-off-by: Neil Horman CC: Shrikrishna Khare CC: "VMware, Inc." CC: "David S. Miller" Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/vmxnet3/vmxnet3_drv.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 4afba17e2403..f809eed0343c 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2962,6 +2962,11 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter) /* we need to enable NAPI, otherwise dev_close will deadlock */ for (i = 0; i < adapter->num_rx_queues; i++) napi_enable(&adapter->rx_queue[i].napi); + /* + * Need to clear the quiesce bit to ensure that vmxnet3_close + * can quiesce the device properly + */ + clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); dev_close(adapter->netdev); } -- cgit v1.2.3 From 95fbdbb60501bbc2bf5ae8d0736199714925ccd1 Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 29 Mar 2017 17:29:09 -0700 Subject: bus: brcmstb_gisb: Use register offsets with writes too [ Upstream commit 856c7ccb9ce7a061f04bdf586f649cb93654e294 ] This commit corrects the bug introduced in commit f80835875d3d ("bus: brcmstb_gisb: Look up register offsets in a table") such that gisb_write() translates the register enumeration into an offset from the base address for writes as well as reads. Fixes: f80835875d3d ("bus: brcmstb_gisb: Look up register offsets in a table") Signed-off-by: Doug Berger Acked-by: Gregory Fong Signed-off-by: Florian Fainelli Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bus/brcmstb_gisb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index 72fe0a5a8bf3..a94598d0945a 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Broadcom Corporation + * Copyright (C) 2014-2017 Broadcom * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -127,9 +127,9 @@ static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) return; if (gdev->big_endian) - iowrite32be(val, gdev->base + reg); + iowrite32be(val, gdev->base + offset); else - iowrite32(val, gdev->base + reg); + iowrite32(val, gdev->base + offset); } static ssize_t gisb_arb_get_timeout(struct device *dev, -- cgit v1.2.3 From 69df2501c0902550d45f0b762788df7b9ab89bf6 Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 29 Mar 2017 17:29:10 -0700 Subject: bus: brcmstb_gisb: correct support for 64-bit address output [ Upstream commit 0c2aa0e4b308815e877601845c1a89913f9bd2b9 ] The GISB bus can support addresses beyond 32-bits. So this commit corrects support for reading a captured 64-bit address into a 64-bit variable by obtaining the high bits from the ARB_ERR_CAP_HI_ADDR register (when present) and then outputting the full 64-bit value. It also removes unused definitions. Fixes: 44127b771d9c ("bus: add Broadcom GISB bus arbiter timeout/error handler") Signed-off-by: Doug Berger Acked-by: Gregory Fong Signed-off-by: Florian Fainelli Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/bus/brcmstb_gisb.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index a94598d0945a..017c37b9c7c1 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -37,8 +37,6 @@ #define ARB_ERR_CAP_CLEAR (1 << 0) #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) #define ARB_ERR_CAP_STATUS_TEA (1 << 11) -#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2) -#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c #define ARB_ERR_CAP_STATUS_WRITE (1 << 1) #define ARB_ERR_CAP_STATUS_VALID (1 << 0) @@ -47,7 +45,6 @@ enum { ARB_ERR_CAP_CLR, ARB_ERR_CAP_HI_ADDR, ARB_ERR_CAP_ADDR, - ARB_ERR_CAP_DATA, ARB_ERR_CAP_STATUS, ARB_ERR_CAP_MASTER, }; @@ -57,7 +54,6 @@ static const int gisb_offsets_bcm7038[] = { [ARB_ERR_CAP_CLR] = 0x0c4, [ARB_ERR_CAP_HI_ADDR] = -1, [ARB_ERR_CAP_ADDR] = 0x0c8, - [ARB_ERR_CAP_DATA] = 0x0cc, [ARB_ERR_CAP_STATUS] = 0x0d0, [ARB_ERR_CAP_MASTER] = -1, }; @@ -67,7 +63,6 @@ static const int gisb_offsets_bcm7400[] = { [ARB_ERR_CAP_CLR] = 0x0c8, [ARB_ERR_CAP_HI_ADDR] = -1, [ARB_ERR_CAP_ADDR] = 0x0cc, - [ARB_ERR_CAP_DATA] = 0x0d0, [ARB_ERR_CAP_STATUS] = 0x0d4, [ARB_ERR_CAP_MASTER] = 0x0d8, }; @@ -77,7 +72,6 @@ static const int gisb_offsets_bcm7435[] = { [ARB_ERR_CAP_CLR] = 0x168, [ARB_ERR_CAP_HI_ADDR] = -1, [ARB_ERR_CAP_ADDR] = 0x16c, - [ARB_ERR_CAP_DATA] = 0x170, [ARB_ERR_CAP_STATUS] = 0x174, [ARB_ERR_CAP_MASTER] = 0x178, }; @@ -87,7 +81,6 @@ static const int gisb_offsets_bcm7445[] = { [ARB_ERR_CAP_CLR] = 0x7e4, [ARB_ERR_CAP_HI_ADDR] = 0x7e8, [ARB_ERR_CAP_ADDR] = 0x7ec, - [ARB_ERR_CAP_DATA] = 0x7f0, [ARB_ERR_CAP_STATUS] = 0x7f4, [ARB_ERR_CAP_MASTER] = 0x7f8, }; @@ -109,9 +102,13 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) { int offset = gdev->gisb_offsets[reg]; - /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */ - if (offset == -1) - return 1; + if (offset < 0) { + /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */ + if (reg == ARB_ERR_CAP_MASTER) + return 1; + else + return 0; + } if (gdev->big_endian) return ioread32be(gdev->base + offset); @@ -119,6 +116,16 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) return ioread32(gdev->base + offset); } +static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev) +{ + u64 value; + + value = gisb_read(gdev, ARB_ERR_CAP_ADDR); + value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32; + + return value; +} + static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) { int offset = gdev->gisb_offsets[reg]; @@ -185,7 +192,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, const char *reason) { u32 cap_status; - unsigned long arb_addr; + u64 arb_addr; u32 master; const char *m_name; char m_fmt[11]; @@ -197,10 +204,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, return 1; /* Read the address and master */ - arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff; -#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) - arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32; -#endif + arb_addr = gisb_read_address(gdev); master = gisb_read(gdev, ARB_ERR_CAP_MASTER); m_name = brcmstb_gisb_master_to_str(gdev, master); @@ -209,7 +213,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, m_name = m_fmt; } - pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n", + pr_crit("%s: %s at 0x%llx [%c %s], core: %s\n", __func__, reason, arb_addr, cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R', cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "", -- cgit v1.2.3 From d6701d258d3c916aca4515c9d32dc7340b0e22b4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 10 May 2017 22:40:06 +0300 Subject: PowerCap: Fix an error code in powercap_register_zone() [ Upstream commit 216c4e9db4c9d1d2a382b42880442dc632cd47d9 ] In the current code we accidentally return the successful result from idr_alloc() instead of a negative error pointer. The caller is looking for an error pointer and so it treats the returned value as a valid pointer. This one might be a bit serious because if it lets people get around the kernel's protection for remapping NULL. I'm not sure. Fixes: 75d2364ea0ca (PowerCap: Add class driver) Signed-off-by: Dan Carpenter Reviewed-by: Srinivas Pandruvada Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/powercap/powercap_sys.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 14bde0db8c24..5b10b50f8686 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -538,6 +538,7 @@ struct powercap_zone *powercap_register_zone( power_zone->id = result; idr_init(&power_zone->idr); + result = -ENOMEM; power_zone->name = kstrdup(name, GFP_KERNEL); if (!power_zone->name) goto err_name_alloc; -- cgit v1.2.3 From c5eb48c6331d8773d707facbb8950f8fd7ef1682 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 14 May 2017 10:43:55 +0200 Subject: iio: pressure: zpa2326: report interrupted case as failure [ Upstream commit e7215fe4d51e69c9d2608ad0c409d48e844d0adc ] If the timeout-case prints a warning message then probably the interrupted case should also. Further, wait_for_completion_interruptible_timeout() returns long not int. Fixes: commit 03b262f2bbf4 ("iio:pressure: initial zpa2326 barometer support") Signed-off-by: Nicholas Mc Guire Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/pressure/zpa2326.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index 19d2eb46fda6..2a4a62ebfd8d 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -871,12 +871,13 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, { int ret; unsigned int val; + long timeout; zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt"); - ret = wait_for_completion_interruptible_timeout( + timeout = wait_for_completion_interruptible_timeout( &private->data_ready, ZPA2326_CONVERSION_JIFFIES); - if (ret > 0) + if (timeout > 0) /* * Interrupt handler completed before timeout: return operation * status. @@ -886,13 +887,16 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, /* Clear all interrupts just to be sure. */ regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val); - if (!ret) + if (!timeout) { /* Timed out. */ + zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)", + timeout); ret = -ETIME; - - if (ret != -ERESTARTSYS) - zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)", - ret); + } else if (timeout < 0) { + zpa2326_warn(indio_dev, + "wait for one shot interrupt cancelled"); + ret = -ERESTARTSYS; + } return ret; } -- cgit v1.2.3 From c019b6ef720f2fbc612969e817090be9f1b8865a Mon Sep 17 00:00:00 2001 From: Andrea della Porta Date: Sat, 29 Apr 2017 07:30:23 +0100 Subject: staging: wlan-ng: prism2mgmt.c: fixed a double endian conversion before calling hfa384x_drvr_setconfig16, also fixes relative sparse warning [ Upstream commit dea20579a69ab68cdca6adf79bb7c0c162eb9b72 ] staging: wlan-ng: prism2mgmt.c: This patches fixes a double endian conversion. cpu_to_le16() was called twice first in prism2mgmt_scan and again inside hfa384x_drvr_setconfig16() for the same variable, hence it was swapped twice. Incidentally, it also fixed the following sparse warning: drivers/staging/wlan-ng/prism2mgmt.c:173:30: warning: incorrect type in assignment (different base types) drivers/staging/wlan-ng/prism2mgmt.c:173:30: expected unsigned short [unsigned] [usertype] word drivers/staging/wlan-ng/prism2mgmt.c:173:30: got restricted __le16 [usertype] Unfortunately, only compile tested. Signed-off-by: Andrea della Porta Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index 170de1c9eac4..f815f9d5045f 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -169,7 +169,7 @@ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) hw->ident_sta_fw.variant) > HFA384x_FIRMWARE_VERSION(1, 5, 0)) { if (msg->scantype.data != P80211ENUM_scantype_active) - word = cpu_to_le16(msg->maxchanneltime.data); + word = msg->maxchanneltime.data; else word = 0; -- cgit v1.2.3 From 0babe22bda12dee55de6a3ba306cdb925db12923 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 29 Mar 2017 17:22:44 +0200 Subject: clk: renesas: rcar-gen2: Fix PLL0 on R-Car V2H and E2 [ Upstream commit b7c563c489e94417efbad68d057ea5d2030ae44c ] R-Car V2H and E2 do not have the PLL0CR register, but use a fixed multiplier (depending on mode pins) and divider. This corrects the clock rate of "pll0" (PLL0 VCO after post divider) on R-Car V2H and E2 from 1.5 GHz to 1 GHz. Inspired by Sergei Shtylyov's work for the common R-Car Gen2 and RZ/G Clock Pulse Generator support core. Fixes: 7c4163aae3d8e5b9 ("ARM: dts: r8a7792: initial SoC device tree") Fixes: 0dce5454d5c25858 ("ARM: shmobile: Initial r8a7794 SoC device tree") Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/renesas/clk-rcar-gen2.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 00e6aba4b9c0..c55d5fe116d6 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -271,11 +271,14 @@ struct cpg_pll_config { unsigned int extal_div; unsigned int pll1_mult; unsigned int pll3_mult; + unsigned int pll0_mult; /* For R-Car V2H and E2 only */ }; static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { - { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, - { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, + { 1, 208, 106, 200 }, { 1, 208, 88, 200 }, + { 1, 156, 80, 150 }, { 1, 156, 66, 150 }, + { 2, 240, 122, 230 }, { 2, 240, 102, 230 }, + { 2, 208, 106, 200 }, { 2, 208, 88, 200 }, }; /* SDHI divisors */ @@ -297,6 +300,12 @@ static const struct clk_div_table cpg_sd01_div_table[] = { static u32 cpg_mode __initdata; +static const char * const pll0_mult_match[] = { + "renesas,r8a7792-cpg-clocks", + "renesas,r8a7794-cpg-clocks", + NULL +}; + static struct clk * __init rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, const struct cpg_pll_config *config, @@ -317,9 +326,15 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, * clock implementation and we currently have no need to change * the multiplier value. */ - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + if (of_device_compatible_match(np, pll0_mult_match)) { + /* R-Car V2H and E2 do not have PLL0CR */ + mult = config->pll0_mult; + div = 3; + } else { + u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + mult = ((value >> 24) & ((1 << 7) - 1)) + 1; + } parent_name = "main"; - mult = ((value >> 24) & ((1 << 7) - 1)) + 1; } else if (!strcmp(name, "pll1")) { parent_name = "main"; mult = config->pll1_mult / 2; -- cgit v1.2.3 From 3743e05f5d4084d0d08a1490118a4996080def87 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sun, 7 May 2017 07:16:30 +0200 Subject: i2c: mux: reg: put away the parent i2c adapter on probe failure [ Upstream commit 68118e0e73aa3a6291c8b9eb1ee708e05f110cea ] It is only prudent to let go of resources that are not used. Fixes: b3fdd32799d8 ("i2c: mux: Add register-based mux i2c-mux-reg") Signed-off-by: Peter Rosin Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/muxes/i2c-mux-reg.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c index c6a90b4a9c62..91b10afc8c34 100644 --- a/drivers/i2c/muxes/i2c-mux-reg.c +++ b/drivers/i2c/muxes/i2c-mux-reg.c @@ -196,20 +196,25 @@ static int i2c_mux_reg_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mux->data.reg_size = resource_size(res); mux->data.reg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(mux->data.reg)) - return PTR_ERR(mux->data.reg); + if (IS_ERR(mux->data.reg)) { + ret = PTR_ERR(mux->data.reg); + goto err_put_parent; + } } if (mux->data.reg_size != 4 && mux->data.reg_size != 2 && mux->data.reg_size != 1) { dev_err(&pdev->dev, "Invalid register size\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put_parent; } muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0, i2c_mux_reg_select, NULL); - if (!muxc) - return -ENOMEM; + if (!muxc) { + ret = -ENOMEM; + goto err_put_parent; + } muxc->priv = mux; platform_set_drvdata(pdev, muxc); @@ -235,6 +240,8 @@ static int i2c_mux_reg_probe(struct platform_device *pdev) add_adapter_failed: i2c_mux_del_adapters(muxc); +err_put_parent: + i2c_put_adapter(parent); return ret; } -- cgit v1.2.3 From 6c9b7010fba9585ad21d26a7eeaca666be3008d8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 12 May 2017 22:54:23 +0800 Subject: mdio: mux: fix device_node_continue.cocci warnings [ Upstream commit 8c977f5a856a7276450ddf3a7b57b4a8815b63f9 ] Device node iterators put the previous value of the index variable, so an explicit put causes a double put. In particular, of_mdiobus_register can fail before doing anything interesting, so one could view it as a no-op from the reference count point of view. Generated by: scripts/coccinelle/iterators/device_node_continue.cocci CC: Jon Mason Signed-off-by: Julia Lawall Signed-off-by: Fengguang Wu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/mdio-mux.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 6943c5ece44a..599ce24c514f 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c @@ -169,7 +169,6 @@ int mdio_mux_init(struct device *dev, if (r) { mdiobus_free(cb->mii_bus); devm_kfree(dev, cb); - of_node_put(child_bus_node); } else { cb->next = pb->children; pb->children = cb; -- cgit v1.2.3 From 04030f5931b40e9c627b5fea9ac515d5e3d827c3 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 13:55:13 +0800 Subject: usb: dwc3: keystone: check return value [ Upstream commit 018047a1dba7636e1f7fdae2cc290a528991d648 ] Function devm_clk_get() returns an ERR_PTR when it fails. However, in function kdwc3_probe(), its return value is not checked, which may result in a bad memory access bug. This patch fixes the bug. Signed-off-by: Pan Bian Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-keystone.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 72664700b8a2..12ee23f53cdd 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -107,6 +107,10 @@ static int kdwc3_probe(struct platform_device *pdev) return PTR_ERR(kdwc->usbss); kdwc->clk = devm_clk_get(kdwc->dev, "usb"); + if (IS_ERR(kdwc->clk)) { + dev_err(kdwc->dev, "unable to get usb clock\n"); + return PTR_ERR(kdwc->clk); + } error = clk_prepare_enable(kdwc->clk); if (error < 0) { -- cgit v1.2.3 From 088c77a8005bf839bbf3ae2882a48dd87cf2a4c4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 16 May 2017 14:06:12 +0200 Subject: ata: libahci: properly propagate return value of platform_get_irq() [ Upstream commit c034640a32f8456018d9c8c83799ead683046b95 ] When platform_get_irq() fails, it returns an error code, which libahci_platform and replaces it by -EINVAL. This commit fixes that by propagating the error code. It fixes the situation where platform_get_irq() returns -EPROBE_DEFER because the interrupt controller is not available yet, and generally looks like the right thing to do. We pay attention to not show the "no irq" message when we are in an EPROBE_DEFER situation, because the driver probing will be retried later on, once the interrupt controller becomes available to provide the interrupt. Signed-off-by: Thomas Petazzoni Reviewed-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libahci_platform.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index aaa761b9081c..cd2eab6aa92e 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -514,8 +514,9 @@ int ahci_platform_init_host(struct platform_device *pdev, irq = platform_get_irq(pdev, 0); if (irq <= 0) { - dev_err(dev, "no irq\n"); - return -EINVAL; + if (irq != -EPROBE_DEFER) + dev_err(dev, "no irq\n"); + return irq; } hpriv->irq = irq; -- cgit v1.2.3 From 4cc339e66447d8bee92a7f8ecbc23d8aa517fba1 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 9 May 2017 18:58:24 -0500 Subject: uio: fix incorrect memory leak cleanup [ Upstream commit 0d83539092ddb1ab79b4d65bccb866bf07ea2ccd ] Commit 75f0aef6220d ("uio: fix memory leak") has fixed up some memory leaks during the failure paths of the addition of uio attributes, but still is not correct entirely. A kobject_uevent() failure still needs a kobject_put() and the kobject container structure allocation failure before the kobject_init() doesn't need a kobject_put(). Fix this properly. Fixes: 75f0aef6220d ("uio: fix memory leak") Signed-off-by: Suman Anna Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index fba021f5736a..208bc52fc84d 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -279,7 +279,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) { ret = -ENOMEM; - goto err_map_kobj; + goto err_map; } kobject_init(&map->kobj, &map_attr_type); map->mem = mem; @@ -289,7 +289,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) goto err_map_kobj; ret = kobject_uevent(&map->kobj, KOBJ_ADD); if (ret) - goto err_map; + goto err_map_kobj; } for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) { @@ -308,7 +308,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) portio = kzalloc(sizeof(*portio), GFP_KERNEL); if (!portio) { ret = -ENOMEM; - goto err_portio_kobj; + goto err_portio; } kobject_init(&portio->kobj, &portio_attr_type); portio->port = port; @@ -319,7 +319,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) goto err_portio_kobj; ret = kobject_uevent(&portio->kobj, KOBJ_ADD); if (ret) - goto err_portio; + goto err_portio_kobj; } return 0; -- cgit v1.2.3 From d84a1c8e3228cf43d2dea63e480a0dd230a663dd Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 26 Apr 2017 16:59:34 +0800 Subject: usb: chipidea: properly handle host or gadget initialization failure [ Upstream commit c4a0bbbdb7f6e3c37fa6deb3ef28c5ed99da6175 ] If ci_hdrc_host_init() or ci_hdrc_gadget_init() returns error and the error != -ENXIO, as Peter pointed out, "it stands for initialization for host or gadget has failed", so we'd better return failure rather continue. And before destroying the otg, i.e ci_hdrc_otg_destroy(ci), we should also check ci->roles[CI_ROLE_GADGET]. Signed-off-by: Jisheng Zhang Signed-off-by: Peter Chen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 6e0d614a8075..64c6af2c8559 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -839,7 +839,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci) { ci_hdrc_gadget_destroy(ci); ci_hdrc_host_destroy(ci); - if (ci->is_otg) + if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) ci_hdrc_otg_destroy(ci); } @@ -939,27 +939,35 @@ static int ci_hdrc_probe(struct platform_device *pdev) /* initialize role(s) before the interrupt is requested */ if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { ret = ci_hdrc_host_init(ci); - if (ret) - dev_info(dev, "doesn't support host\n"); + if (ret) { + if (ret == -ENXIO) + dev_info(dev, "doesn't support host\n"); + else + goto deinit_phy; + } } if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) { ret = ci_hdrc_gadget_init(ci); - if (ret) - dev_info(dev, "doesn't support gadget\n"); + if (ret) { + if (ret == -ENXIO) + dev_info(dev, "doesn't support gadget\n"); + else + goto deinit_host; + } } if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { dev_err(dev, "no supported roles\n"); ret = -ENODEV; - goto deinit_phy; + goto deinit_gadget; } if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) { ret = ci_hdrc_otg_init(ci); if (ret) { dev_err(dev, "init otg fails, ret = %d\n", ret); - goto stop; + goto deinit_gadget; } } @@ -1024,7 +1032,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) ci_extcon_unregister(ci); stop: - ci_role_destroy(ci); + if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) + ci_hdrc_otg_destroy(ci); +deinit_gadget: + ci_hdrc_gadget_destroy(ci); +deinit_host: + ci_hdrc_host_destroy(ci); deinit_phy: ci_usb_phy_exit(ci); -- cgit v1.2.3 From c3231c038ae7dc4e3c3647ec7c1903744303549c Mon Sep 17 00:00:00 2001 From: Petr Cvek Date: Mon, 24 Apr 2017 22:51:58 -0300 Subject: pxa_camera: fix module remove codepath for v4l2 clock [ Upstream commit e3b4d10cc057522353c4a02f2f90dca6a52e006f ] The conversion from soc_camera omitted a correct handling of the clock gating for a sensor. When the pxa_camera driver module was removed it tried to unregister clk, but this caused a similar warning: WARNING: CPU: 0 PID: 6740 at drivers/media/v4l2-core/v4l2-clk.c:278 v4l2_clk_unregister(): Refusing to unregister ref-counted 0-0030 clock! The clock was at time still refcounted by the sensor driver. Before the removing of the pxa_camera the clock must be dropped by the sensor driver. This should be triggered by v4l2_async_notifier_unregister() call which removes sensor driver module too, calls unbind() function and then tries to probe sensor driver again. Inside unbind() we can safely unregister the v4l2 clock as the sensor driver got removed. The original v4l2_clk_unregister() should be put inside test as the clock can be already unregistered from unbind(). If there was not any bound sensor the clock is still present. The codepath is practically a copy from the old soc_camera. The bug was tested with a pxa_camera+ov9640 combination during the conversion of the ov9640 from the soc_camera. Signed-off-by: Petr Cvek Tested-by: Robert Jarzmik Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/pxa_camera.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index c12209c701d3..390d708c807a 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2169,6 +2169,12 @@ static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier, pxa_dma_stop_channels(pcdev); pxa_camera_destroy_formats(pcdev); + + if (pcdev->mclk_clk) { + v4l2_clk_unregister(pcdev->mclk_clk); + pcdev->mclk_clk = NULL; + } + video_unregister_device(&pcdev->vdev); pcdev->sensor = NULL; @@ -2495,7 +2501,13 @@ static int pxa_camera_remove(struct platform_device *pdev) dma_release_channel(pcdev->dma_chans[1]); dma_release_channel(pcdev->dma_chans[2]); - v4l2_clk_unregister(pcdev->mclk_clk); + v4l2_async_notifier_unregister(&pcdev->notifier); + + if (pcdev->mclk_clk) { + v4l2_clk_unregister(pcdev->mclk_clk); + pcdev->mclk_clk = NULL; + } + v4l2_device_unregister(&pcdev->v4l2_dev); dev_info(&pdev->dev, "PXA Camera driver unloaded\n"); -- cgit v1.2.3 From 651688ba685a9079c3ec9dfa5fa72936594e7f2d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 16 May 2017 11:47:42 -0400 Subject: USB: ene_usb6250: fix first command execution [ Upstream commit 4b309f1c4972c8f09e03ac64fc63510dbf5591a4 ] In the ene_usb6250 sub-driver for usb-storage, the ene_transport() routine is supposed to initialize the driver before executing the current command, if the initialization has not already been performed. However, a bug in the routine causes it to skip the command after doing the initialization. Also, the routine does not return an appropriate error code if either the initialization or the command fails. As a result of the first bug, the first command (a SCSI INQUIRY) is not carried out. The results can be seen in the system log, in the form of a warning message and empty or garbage INQUIRY data: Apr 18 22:40:08 notebook2 kernel: scsi host6: scsi scan: INQUIRY result too short (5), using 36 Apr 18 22:40:08 notebook2 kernel: scsi 6:0:0:0: Direct-Access PQ: 0 ANSI: 0 This patch fixes both errors. Signed-off-by: Alan Stern Reported-and-tested-by: Andreas Hartmann Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/ene_ub6250.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 4340b4925daa..4199fe563c71 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -2295,21 +2295,22 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) { - int result = 0; + int result = USB_STOR_XFER_GOOD; struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); /*US_DEBUG(usb_stor_show_command(us, srb)); */ scsi_set_resid(srb, 0); - if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) { + if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) result = ene_init(us); - } else { + if (result == USB_STOR_XFER_GOOD) { + result = USB_STOR_TRANSPORT_ERROR; if (info->SD_Status.Ready) result = sd_scsi_irp(us, srb); if (info->MS_Status.Ready) result = ms_scsi_irp(us, srb); } - return 0; + return result; } static struct scsi_host_template ene_ub6250_host_template; -- cgit v1.2.3 From c85669ef1e34371658bf17021ad139a44fea43b1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 16 May 2017 11:47:52 -0400 Subject: USB: ene_usb6250: fix SCSI residue overwriting [ Upstream commit aa18c4b6e0e39bfb00af48734ec24bc189ac9909 ] In the ene_usb6250 sub-driver for usb-storage, the SCSI residue is not reported correctly. The residue is initialized to 0, but this value is overwritten whenever the driver sends firmware to the card reader before performing the current command. As a result, a valid READ or WRITE operation appears to have failed, causing the SCSI core to retry the command multiple times and eventually fail. This patch fixes the problem by resetting the SCSI residue to 0 after sending firmware to the device. Signed-off-by: Alan Stern Reported-and-tested-by: Andreas Hartmann Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/ene_ub6250.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 4199fe563c71..4d6eb48b2c45 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -1942,6 +1942,8 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) bcb->CDB[0] = 0xEF; result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); + if (us->srb != NULL) + scsi_set_resid(us->srb, 0); info->BIN_FLAG = flag; kfree(buf); -- cgit v1.2.3 From 65db56497574362f0f57f18f1f7ac8ff03926d17 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Sat, 22 Apr 2017 18:37:19 +0530 Subject: serial: 8250: omap: Disable DMA for console UART [ Upstream commit 84b40e3b57eef1417479c00490dd4c9f6e5ffdbc ] Kernel always writes log messages to console via serial8250_console_write()->serial8250_console_putchar() which directly accesses UART_TX register _without_ using DMA. But, if other processes like systemd using same UART port, then these writes are handled by a different code flow using 8250_omap driver where there is provision to use DMA. It seems that it is possible that both DMA and CPU might simultaneously put data to UART FIFO and lead to potential loss of data due to FIFO overflow and weird data corruption. This happens when both kernel console and userspace tries to write simultaneously to the same UART port. Therefore, disable DMA on kernel console port to avoid potential race between CPU and DMA. Signed-off-by: Vignesh R Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index da31159a03ec..e8b34f16ba2c 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -613,6 +613,10 @@ static int omap_8250_startup(struct uart_port *port) up->lsr_saved_flags = 0; up->msr_saved_flags = 0; + /* Disable DMA for console UART */ + if (uart_console(port)) + up->dma = NULL; + if (up->dma) { ret = serial8250_request_dma(up); if (ret) { -- cgit v1.2.3 From 13b9c31db4f2627920328f7010ed6a3bcb958e60 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Apr 2017 20:15:35 +0200 Subject: serial: sh-sci: Fix race condition causing garbage during shutdown [ Upstream commit 1cf4a7efdc71cab84c42cfea7200608711ea954f ] If DMA is enabled and used, a burst of old data may be seen on the serial console during "poweroff" or "reboot". uart_flush_buffer() clears the circular buffer, but sci_port.tx_dma_len is not reset. This leads to a circular buffer overflow, dumping (UART_XMIT_SIZE - sci_port.tx_dma_len) bytes. To fix this, add a .flush_buffer() callback that resets sci_port.tx_dma_len. Inspired by commit 31ca2c63fdc0aee7 ("tty/serial: atmel: fix race condition (TX+DMA)"). Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a55c94dfefd2..107f0d194ac5 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1545,7 +1545,16 @@ static void sci_free_dma(struct uart_port *port) if (s->chan_rx) sci_rx_dma_release(s, false); } -#else + +static void sci_flush_buffer(struct uart_port *port) +{ + /* + * In uart_flush_buffer(), the xmit circular buffer has just been + * cleared, so we have to reset tx_dma_len accordingly. + */ + to_sci_port(port)->tx_dma_len = 0; +} +#else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma(struct uart_port *port) { } @@ -1553,7 +1562,9 @@ static inline void sci_request_dma(struct uart_port *port) static inline void sci_free_dma(struct uart_port *port) { } -#endif + +#define sci_flush_buffer NULL +#endif /* !CONFIG_SERIAL_SH_SCI_DMA */ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) { @@ -2551,6 +2562,7 @@ static const struct uart_ops sci_uart_ops = { .break_ctl = sci_break_ctl, .startup = sci_startup, .shutdown = sci_shutdown, + .flush_buffer = sci_flush_buffer, .set_termios = sci_set_termios, .pm = sci_pm, .type = sci_type, -- cgit v1.2.3 From f74050ed6ba48d032e130e462e24c87fb627bd38 Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Wed, 17 May 2017 17:24:33 +0200 Subject: net/wan/fsl_ucc_hdlc: fix unitialized variable warnings [ Upstream commit 66bb144bd9096dd5268ef736ba769b8b6f4ef100 ] This fixes the following compiler warnings: drivers/net/wan/fsl_ucc_hdlc.c: In function 'ucc_hdlc_poll': warning: 'skb' may be used uninitialized in this function [-Wmaybe-uninitialized] skb->mac_header = skb->data - skb->head; and drivers/net/wan/fsl_ucc_hdlc.c: In function 'ucc_hdlc_probe': drivers/net/wan/fsl_ucc_hdlc.c:1127:3: warning: 'utdm' may be used uninitialized in this function [-Wmaybe-uninitialized] kfree(utdm); Signed-off-by: Holger Brunck Cc: Zhao Qiang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/fsl_ucc_hdlc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 65647533b401..4c49410c3a1b 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -454,7 +454,7 @@ static int hdlc_tx_done(struct ucc_hdlc_private *priv) static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit) { struct net_device *dev = priv->ndev; - struct sk_buff *skb; + struct sk_buff *skb = NULL; hdlc_device *hdlc = dev_to_hdlc(dev); struct qe_bd *bd; u32 bd_status; @@ -1002,7 +1002,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct ucc_hdlc_private *uhdlc_priv = NULL; struct ucc_tdm_info *ut_info; - struct ucc_tdm *utdm; + struct ucc_tdm *utdm = NULL; struct resource res; struct net_device *dev; hdlc_device *hdlc; -- cgit v1.2.3 From 6b3a9354cd0b2dae4d2d3e19e63173e30eec74d7 Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Wed, 17 May 2017 17:24:35 +0200 Subject: net/wan/fsl_ucc_hdlc: fix incorrect memory allocation [ Upstream commit 5b8aad93c52bdda6a731cab8497998cfa0f2df07 ] We need space for the struct qe_bd and not for a pointer to this struct. Signed-off-by: Holger Brunck Cc: Zhao Qiang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/fsl_ucc_hdlc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 4c49410c3a1b..dcd5ff43a946 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -137,7 +137,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) priv->tx_ring_size = TX_BD_RING_LEN; /* Alloc Rx BD */ priv->rx_bd_base = dma_alloc_coherent(priv->dev, - RX_BD_RING_LEN * sizeof(struct qe_bd *), + RX_BD_RING_LEN * sizeof(struct qe_bd), &priv->dma_rx_bd, GFP_KERNEL); if (!priv->rx_bd_base) { @@ -148,7 +148,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) /* Alloc Tx BD */ priv->tx_bd_base = dma_alloc_coherent(priv->dev, - TX_BD_RING_LEN * sizeof(struct qe_bd *), + TX_BD_RING_LEN * sizeof(struct qe_bd), &priv->dma_tx_bd, GFP_KERNEL); if (!priv->tx_bd_base) { @@ -295,11 +295,11 @@ free_ucc_pram: qe_muram_free(priv->ucc_pram_offset); free_tx_bd: dma_free_coherent(priv->dev, - TX_BD_RING_LEN * sizeof(struct qe_bd *), + TX_BD_RING_LEN * sizeof(struct qe_bd), priv->tx_bd_base, priv->dma_tx_bd); free_rx_bd: dma_free_coherent(priv->dev, - RX_BD_RING_LEN * sizeof(struct qe_bd *), + RX_BD_RING_LEN * sizeof(struct qe_bd), priv->rx_bd_base, priv->dma_rx_bd); free_uccf: ucc_fast_free(priv->uccf); @@ -688,7 +688,7 @@ static void uhdlc_memclean(struct ucc_hdlc_private *priv) if (priv->rx_bd_base) { dma_free_coherent(priv->dev, - RX_BD_RING_LEN * sizeof(struct qe_bd *), + RX_BD_RING_LEN * sizeof(struct qe_bd), priv->rx_bd_base, priv->dma_rx_bd); priv->rx_bd_base = NULL; @@ -697,7 +697,7 @@ static void uhdlc_memclean(struct ucc_hdlc_private *priv) if (priv->tx_bd_base) { dma_free_coherent(priv->dev, - TX_BD_RING_LEN * sizeof(struct qe_bd *), + TX_BD_RING_LEN * sizeof(struct qe_bd), priv->tx_bd_base, priv->dma_tx_bd); priv->tx_bd_base = NULL; -- cgit v1.2.3 From eed386e2e286f1d187b293b84ab53d0740b549c3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 May 2017 15:01:34 +0200 Subject: sh_eth: Use platform device for printing before register_netdev() [ Upstream commit 5f5c5449acad0cd3322e53e1ac68c044483b0aa5 ] The MDIO initialization failure message is printed using the network device, before it has been registered, leading to: (null): failed to initialise MDIO Use the platform device instead to fix this: sh-eth ee700000.ethernet: failed to initialise MDIO Fixes: daacf03f0bbfefee ("sh_eth: Register MDIO bus before registering the network device") Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/renesas/sh_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index b6816ae00b7a..c8fd99b3ca29 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -3133,7 +3133,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) /* MDIO bus init */ ret = sh_mdio_init(mdp, pd); if (ret) { - dev_err(&ndev->dev, "failed to initialise MDIO\n"); + dev_err(&pdev->dev, "failed to initialise MDIO\n"); goto out_release; } -- cgit v1.2.3 From c8799579ff4b1970c519ab664dffca1e9d1198de Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Thu, 18 May 2017 13:03:52 +0200 Subject: mlxsw: spectrum: Avoid possible NULL pointer dereference [ Upstream commit c0e01eac7ada785fdeaea1ae5476ec1cf3b00374 ] In case we got an FDB notification for a port that doesn't exist we execute an FDB entry delete to prevent it from re-appearing the next time we poll for notifications. If the operation failed we would trigger a NULL pointer dereference as 'mlxsw_sp_port' is NULL. Fix it by reporting the error using the underlying bus device instead. Fixes: 12f1501e7511 ("mlxsw: spectrum: remove FDB entry in case we get unknown object notification") Signed-off-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index bea9ae31a769..60e1edcbe573 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -1448,8 +1448,7 @@ do_fdb_op: err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, adding, true); if (err) { - if (net_ratelimit()) - netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n"); + dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n"); return; } @@ -1509,8 +1508,7 @@ do_fdb_op: err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid, adding, true); if (err) { - if (net_ratelimit()) - netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n"); + dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n"); return; } -- cgit v1.2.3 From 2fb42f008bb8540ef0f12250e7c44508fd795824 Mon Sep 17 00:00:00 2001 From: Varun Prakash Date: Wed, 17 May 2017 20:30:43 +0530 Subject: scsi: csiostor: fix use after free in csio_hw_use_fwconfig() [ Upstream commit a351e40b6de550049423a26f7ded7b639e363d89 ] mbp pointer is passed to csio_hw_validate_caps() so call mempool_free() after calling csio_hw_validate_caps(). Signed-off-by: Varun Prakash Fixes: 541c571fa2fd ("csiostor:Use firmware version from cxgb4/t4fw_version.h") Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/csiostor/csio_hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 622bdabc8894..dab195f04da7 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -1769,7 +1769,6 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) goto bye; } - mempool_free(mbp, hw->mb_mempool); if (finicsum != cfcsum) { csio_warn(hw, "Config File checksum mismatch: csum=%#x, computed=%#x\n", @@ -1780,6 +1779,10 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) rv = csio_hw_validate_caps(hw, mbp); if (rv != 0) goto bye; + + mempool_free(mbp, hw->mb_mempool); + mbp = NULL; + /* * Note that we're operating with parameters * not supplied by the driver, rather than from hard-wired -- cgit v1.2.3 From acf6bfef15fac288f68e1b9a1e63f8b5fee5771b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 3 May 2017 15:26:00 +0100 Subject: ath5k: fix memory leak on buf on failed eeprom read [ Upstream commit 8fed6823e06e43ee9cf7c0ffecec2f9111ce6201 ] The AR5K_EEPROM_READ macro returns with -EIO if a read error occurs causing a memory leak on the allocated buffer buf. Fix this by explicitly calling ath5k_hw_nvram_read and exiting on the via the freebuf label that performs the necessary free'ing of buf when a read error occurs. Detected by CoverityScan, CID#1248782 ("Resource Leak") Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath5k/debug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 4f8d9ed04f5e..4a1054408f1a 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -939,7 +939,10 @@ static int open_file_eeprom(struct inode *inode, struct file *file) } for (i = 0; i < eesize; ++i) { - AR5K_EEPROM_READ(i, val); + if (!ath5k_hw_nvram_read(ah, i, &val)) { + ret = -EIO; + goto freebuf; + } buf[i] = val; } -- cgit v1.2.3 From a1aeeacc646dc2e576512988b7f721751c0373ef Mon Sep 17 00:00:00 2001 From: Nikita Yushchenko Date: Fri, 19 May 2017 17:48:00 +0300 Subject: iio: hi8435: avoid garbage event at first enable [ Upstream commit ee19ac340c5fdfd89c6348be4563453c61ab54a9 ] Currently, driver generates events for channels if new reading differs from previous one. This "previous value" is initialized to zero, which results into event if value is constant-one. Fix that by initializing "previous value" by reading at event enable time. This provides reliable sequence for userspace: - enable event, - AFTER THAT read current value, - AFTER THAT each event will correspond to change. Signed-off-by: Nikita Yushchenko Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/hi8435.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index 678e8c7ea763..52b2dcf1d942 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -121,10 +121,21 @@ static int hi8435_write_event_config(struct iio_dev *idev, enum iio_event_direction dir, int state) { struct hi8435_priv *priv = iio_priv(idev); + int ret; + u32 tmp; + + if (state) { + ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp); + if (ret < 0) + return ret; + if (tmp & BIT(chan->channel)) + priv->event_prev_val |= BIT(chan->channel); + else + priv->event_prev_val &= ~BIT(chan->channel); - priv->event_scan_mask &= ~BIT(chan->channel); - if (state) priv->event_scan_mask |= BIT(chan->channel); + } else + priv->event_scan_mask &= ~BIT(chan->channel); return 0; } -- cgit v1.2.3 From e187c0c9104db9271afa0c2b63c403ace286b93d Mon Sep 17 00:00:00 2001 From: Nikita Yushchenko Date: Fri, 19 May 2017 17:48:02 +0300 Subject: iio: hi8435: cleanup reset gpio [ Upstream commit 61305664a542f874283f74bf0b27ddb31f5045d7 ] Reset GPIO is active low. Currently driver uses gpiod_set_value(1) to clean reset, which depends on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality. This fixes driver to use _raw version of gpiod_set_value() to enforce active-low semantics despite of what's written in device tree. Allowing device tree to override that only opens possibility for errors and does not add any value. Additionally, use _cansleep version to make things work with i2c-gpio and other sleeping gpio drivers. Signed-off-by: Nikita Yushchenko Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/hi8435.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index 52b2dcf1d942..fec696ec3fd1 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -453,13 +453,15 @@ static int hi8435_probe(struct spi_device *spi) priv->spi = spi; reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW); - if (IS_ERR(reset_gpio)) { - /* chip s/w reset if h/w reset failed */ + if (!IS_ERR(reset_gpio)) { + /* need >=100ns low pulse to reset chip */ + gpiod_set_raw_value_cansleep(reset_gpio, 0); + udelay(1); + gpiod_set_raw_value_cansleep(reset_gpio, 1); + } else { + /* s/w reset chip if h/w reset is not available */ hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST); hi8435_writeb(priv, HI8435_CTRL_REG, 0); - } else { - udelay(5); - gpiod_set_value(reset_gpio, 1); } spi_set_drvdata(spi, idev); -- cgit v1.2.3 From 691b03605d23f49888e1743467362b6bb730942a Mon Sep 17 00:00:00 2001 From: Mikko Koivunen Date: Thu, 18 May 2017 15:12:50 +0300 Subject: iio: light: rpr0521 poweroff for probe fails [ Upstream commit 12d74949133e2450533894ea01ce0c56646ce006 ] Set sensor measurement off after probe fail in pm_runtime_set_active() or iio_device_register(). Without this change sensor measurement stays on even though probe fails on these calls. This is maybe rare case, but causes constant power drain without any benefits when it happens. Power drain is 20-500uA, typically 180uA. Signed-off-by: Mikko Koivunen Acked-by: Daniel Baluta Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/light/rpr0521.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index 7de0f397194b..d23cf7759ee7 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -510,13 +510,26 @@ static int rpr0521_probe(struct i2c_client *client, ret = pm_runtime_set_active(&client->dev); if (ret < 0) - return ret; + goto err_poweroff; pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - return iio_device_register(indio_dev); + ret = iio_device_register(indio_dev); + if (ret) + goto err_pm_disable; + + return 0; + +err_pm_disable: + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); +err_poweroff: + rpr0521_poweroff(data); + + return ret; } static int rpr0521_remove(struct i2c_client *client) -- cgit v1.2.3 From 03858f5f7ad86a1b8332e4a3329b7757c34da30c Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Tue, 16 May 2017 14:01:25 +0800 Subject: md-cluster: fix potential lock issue in add_new_disk [ Upstream commit 2dffdc0724004f38f5e39907747b53e4b0d80e59 ] The add_new_disk returns with communication locked if __sendmsg returns failure, fix it with call unlock_comm before return. Reported-by: Dan Carpenter CC: Goldwyn Rodrigues Signed-off-by: Guoqing Jiang Signed-off-by: Shaohua Li Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/md-cluster.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index ba7edcdd09ce..fcc2b5746a9f 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1122,8 +1122,10 @@ static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev) cmsg.raid_slot = cpu_to_le32(rdev->desc_nr); lock_comm(cinfo); ret = __sendmsg(cinfo, &cmsg); - if (ret) + if (ret) { + unlock_comm(cinfo); return ret; + } cinfo->no_new_dev_lockres->flags |= DLM_LKF_NOQUEUE; ret = dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_EX); cinfo->no_new_dev_lockres->flags &= ~DLM_LKF_NOQUEUE; -- cgit v1.2.3 From 87aa297871ee0d05d45648ba647cb0ea0485884c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 5 May 2017 15:38:41 -0700 Subject: ray_cs: Avoid reading past end of buffer [ Upstream commit e48d661eb13f2f83861428f001c567fdb3f317e8 ] Using memcpy() from a buffer that is shorter than the length copied means the destination buffer is being filled with arbitrary data from the kernel rodata segment. In this case, the source was made longer, since it did not match the destination structure size. Additionally removes a needless cast. This was found with the future CONFIG_FORTIFY_SOURCE feature. Cc: Daniel Micay Signed-off-by: Kees Cook Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ray_cs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0881ba8535f4..c78abfc7bd96 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -247,7 +247,10 @@ static const UCHAR b4_default_startup_parms[] = { 0x04, 0x08, /* Noise gain, limit offset */ 0x28, 0x28, /* det rssi, med busy offsets */ 7, /* det sync thresh */ - 0, 2, 2 /* test mode, min, max */ + 0, 2, 2, /* test mode, min, max */ + 0, /* rx/tx delay */ + 0, 0, 0, 0, 0, 0, /* current BSS id */ + 0 /* hop set */ }; /*===========================================================================*/ @@ -598,7 +601,7 @@ static void init_startup_params(ray_dev_t *local) * a_beacon_period = hops a_beacon_period = KuS *//* 64ms = 010000 */ if (local->fw_ver == 0x55) { - memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms, + memcpy(&local->sparm.b4, b4_default_startup_parms, sizeof(struct b4_startup_params)); /* Translate sane kus input values to old build 4/5 format */ /* i = hop time in uS truncated to 3 bytes */ -- cgit v1.2.3 From 69f4dd14771cad36c38640ff3f5c537bc6b97762 Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Mon, 22 May 2017 09:31:15 +0200 Subject: net/wan/fsl_ucc_hdlc: fix muram allocation error [ Upstream commit 85deed56032b6c98b541895bfda9bdd74f6ed987 ] sizeof(priv->ucc_pram) is 4 as it is the size of a pointer, but we want to reserve space for the struct ucc_hdlc_param. Signed-off-by: Holger Brunck Cc: Zhao Qiang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/fsl_ucc_hdlc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index dcd5ff43a946..a8bd68f252e9 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -158,7 +158,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) } /* Alloc parameter ram for ucc hdlc */ - priv->ucc_pram_offset = qe_muram_alloc(sizeof(priv->ucc_pram), + priv->ucc_pram_offset = qe_muram_alloc(sizeof(struct ucc_hdlc_param), ALIGNMENT_OF_UCC_HDLC_PRAM); if (priv->ucc_pram_offset < 0) { -- cgit v1.2.3 From 1a53869c4c3406d841093c8e5e0649e5f6de80ac Mon Sep 17 00:00:00 2001 From: Tin Huynh Date: Mon, 22 May 2017 16:19:20 +0700 Subject: leds: pca955x: Correct I2C Functionality [ Upstream commit aace34c0bb8ea3c8bdcec865b6a4be4db0a68e33 ] The driver checks an incorrect flag of functionality of adapter. When a driver requires i2c_smbus_read_byte_data and i2c_smbus_write_byte_data, it should check I2C_FUNC_SMBUS_BYTE_DATA instead I2C_FUNC_I2C. This patch fixes the problem. Signed-off-by: Tin Huynh Signed-off-by: Jacek Anaszewski Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/leds/leds-pca955x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 840401ae9a4e..f6726484a8a1 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -266,7 +266,7 @@ static int pca955x_probe(struct i2c_client *client, "slave address 0x%02x\n", id->name, chip->bits, client->addr); - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; if (pdata) { -- cgit v1.2.3 From 72185b9770fc588bc277e4e5336e9cdf7c42ad45 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 13 May 2017 14:39:53 +0200 Subject: gpio: crystalcove: Do not write regular gpio registers for virtual GPIOs [ Upstream commit 9a752b4c9ab924033bfdb8784c680d50b2bd5684 ] The Crystal Cove PMIC has 16 real GPIOs but the ACPI code for devices with this PMIC may address up to 95 GPIOs, these extra GPIOs are called virtual GPIOs and are used by the ACPI code as a method of accessing various non GPIO bits of PMIC. Commit dcdc3018d635 ("gpio: crystalcove: support virtual GPIO") added dummy support for these to avoid a bunch of ACPI errors, but instead of ignoring writes / reads to them by doing: if (gpio >= CRYSTALCOVE_GPIO_NUM) return 0; It accidentally introduced the following wrong check: if (gpio > CRYSTALCOVE_VGPIO_NUM) return 0; Which means that attempts by the ACPI code to access these gpios causes some arbitrary gpio to get touched through for example GPIO1P0CTLO + gpionr % 8. Since we do support input/output (but not interrupts) on the 0x5e virtual GPIO, this commit makes to_reg return -ENOTSUPP for unsupported virtual GPIOs so as to not have to check for (gpio >= CRYSTALCOVE_GPIO_NUM && gpio != 0x5e) everywhere and to make it easier to add support for more virtual GPIOs in the future. It then adds a check for to_reg returning an error to all callers where this may happen fixing the ACPI code accessing virtual GPIOs accidentally causing changes to real GPIOs. Fixes: dcdc3018d635 ("gpio: crystalcove: support virtual GPIO") Cc: Aaron Lu Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-crystalcove.c | 54 +++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 7c446d118cd6..1d87b0718d3a 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -90,8 +90,18 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) { int reg; - if (gpio == 94) - return GPIOPANELCTL; + if (gpio >= CRYSTALCOVE_GPIO_NUM) { + /* + * Virtual GPIO called from ACPI, for now we only support + * the panel ctl. + */ + switch (gpio) { + case 0x5e: + return GPIOPANELCTL; + default: + return -EOPNOTSUPP; + } + } if (reg_type == CTRL_IN) { if (gpio < 8) @@ -130,36 +140,36 @@ static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio) static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); + int reg = to_reg(gpio, CTRL_OUT); - if (gpio > CRYSTALCOVE_VGPIO_NUM) + if (reg < 0) return 0; - return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), - CTLO_INPUT_SET); + return regmap_write(cg->regmap, reg, CTLO_INPUT_SET); } static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, int value) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); + int reg = to_reg(gpio, CTRL_OUT); - if (gpio > CRYSTALCOVE_VGPIO_NUM) + if (reg < 0) return 0; - return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), - CTLO_OUTPUT_SET | value); + return regmap_write(cg->regmap, reg, CTLO_OUTPUT_SET | value); } static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); - int ret; unsigned int val; + int ret, reg = to_reg(gpio, CTRL_IN); - if (gpio > CRYSTALCOVE_VGPIO_NUM) + if (reg < 0) return 0; - ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); + ret = regmap_read(cg->regmap, reg, &val); if (ret) return ret; @@ -170,14 +180,15 @@ static void crystalcove_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); + int reg = to_reg(gpio, CTRL_OUT); - if (gpio > CRYSTALCOVE_VGPIO_NUM) + if (reg < 0) return; if (value) - regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); + regmap_update_bits(cg->regmap, reg, 1, 1); else - regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 0); + regmap_update_bits(cg->regmap, reg, 1, 0); } static int crystalcove_irq_type(struct irq_data *data, unsigned type) @@ -185,6 +196,9 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned type) struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); + if (data->hwirq >= CRYSTALCOVE_GPIO_NUM) + return 0; + switch (type) { case IRQ_TYPE_NONE: cg->intcnt_value = CTLI_INTCNT_DIS; @@ -235,8 +249,10 @@ static void crystalcove_irq_unmask(struct irq_data *data) struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); - cg->set_irq_mask = false; - cg->update |= UPDATE_IRQ_MASK; + if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { + cg->set_irq_mask = false; + cg->update |= UPDATE_IRQ_MASK; + } } static void crystalcove_irq_mask(struct irq_data *data) @@ -244,8 +260,10 @@ static void crystalcove_irq_mask(struct irq_data *data) struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); - cg->set_irq_mask = true; - cg->update |= UPDATE_IRQ_MASK; + if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { + cg->set_irq_mask = true; + cg->update |= UPDATE_IRQ_MASK; + } } static struct irq_chip crystalcove_irqchip = { -- cgit v1.2.3 From 2c582b6bac13e495d6c14fdd1f866b93ff90cddc Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Thu, 18 May 2017 13:34:43 +0300 Subject: net/mlx5: Tolerate irq_set_affinity_hint() failures [ Upstream commit b665d98edc9ab295169be2fc5bb4e89a46de0a1a ] Add tolerance to failures of irq_set_affinity_hint(). Its role is to give hints that optimizes performance, and should not block the driver load. In non-SMP systems, functionality is not available as there is a single core, and all these calls definitely fail. Hence, do not call the function and avoid the warning prints. Fixes: db058a186f98 ("net/mlx5_core: Set irq affinity hints") Signed-off-by: Tariq Toukan Cc: kernel-team@fb.com Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 981cd1d84a5b..935e62635f12 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -548,7 +548,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) struct mlx5_priv *priv = &mdev->priv; struct msix_entry *msix = priv->msix_arr; int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector; - int err; if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); @@ -558,18 +557,12 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), priv->irq_info[i].mask); - err = irq_set_affinity_hint(irq, priv->irq_info[i].mask); - if (err) { - mlx5_core_warn(mdev, "irq_set_affinity_hint failed,irq 0x%.4x", - irq); - goto err_clear_mask; - } +#ifdef CONFIG_SMP + if (irq_set_affinity_hint(irq, priv->irq_info[i].mask)) + mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); +#endif return 0; - -err_clear_mask: - free_cpumask_var(priv->irq_info[i].mask); - return err; } static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) -- cgit v1.2.3 From 5cddd2f34166ecf24710728458539c024c905fdd Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Wed, 24 May 2017 14:09:44 +0200 Subject: scsi: bnx2fc: fix race condition in bnx2fc_get_host_stats() [ Upstream commit c2dd893a3b0772d1c680e109b9d5715d7f73022b ] If multiple tasks attempt to read the stats, it may happen that the start_req_done completion is re-initialized while still being used by another task, causing a list corruption. This patch fixes the bug by adding a mutex to serialize the calls to bnx2fc_get_host_stats(). WARNING: at lib/list_debug.c:48 list_del+0x6e/0xa0() (Not tainted) Hardware name: PowerEdge R820 list_del corruption. prev->next should be ffff882035627d90, but was ffff884069541588 Pid: 40267, comm: perl Not tainted 2.6.32-642.3.1.el6.x86_64 #1 Call Trace: [] ? warn_slowpath_common+0x91/0xe0 [] ? warn_slowpath_fmt+0x46/0x60 [] ? list_del+0x6e/0xa0 [] ? wait_for_common+0x14d/0x180 [] ? default_wake_function+0x0/0x20 [] ? wait_for_completion_timeout+0x13/0x20 [] ? bnx2fc_get_host_stats+0xa1/0x280 [bnx2fc] [] ? fc_stat_show+0x90/0xc0 [scsi_transport_fc] [] ? show_fcstat_tx_frames+0x16/0x20 [scsi_transport_fc] [] ? dev_attr_show+0x27/0x50 [] ? __get_free_pages+0xe/0x50 [] ? sysfs_read_file+0x111/0x200 [] ? vfs_read+0xb5/0x1a0 [] ? fget_light_pos+0x16/0x50 [] ? sys_read+0x51/0xb0 [] ? __audit_syscall_exit+0x25e/0x290 [] ? system_call_fastpath+0x16/0x1b Signed-off-by: Maurizio Lombardi Acked-by: Chad Dupuis Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/bnx2fc/bnx2fc.h | 1 + drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index fdd4eb4e41b2..e58786f797d9 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -191,6 +191,7 @@ struct bnx2fc_hba { struct bnx2fc_cmd_mgr *cmd_mgr; spinlock_t hba_lock; struct mutex hba_mutex; + struct mutex hba_stats_mutex; unsigned long adapter_state; #define ADAPTER_STATE_UP 0 #define ADAPTER_STATE_GOING_DOWN 1 diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index f9ddb6156f14..bee7d37367ca 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -670,15 +670,17 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) if (!fw_stats) return NULL; + mutex_lock(&hba->hba_stats_mutex); + bnx2fc_stats = fc_get_host_stats(shost); init_completion(&hba->stat_req_done); if (bnx2fc_send_stat_req(hba)) - return bnx2fc_stats; + goto unlock_stats_mutex; rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ)); if (!rc) { BNX2FC_HBA_DBG(lport, "FW stat req timed out\n"); - return bnx2fc_stats; + goto unlock_stats_mutex; } BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt); bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt; @@ -700,6 +702,9 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) memcpy(&hba->prev_stats, hba->stats_buffer, sizeof(struct fcoe_statistics_params)); + +unlock_stats_mutex: + mutex_unlock(&hba->hba_stats_mutex); return bnx2fc_stats; } @@ -1348,6 +1353,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) } spin_lock_init(&hba->hba_lock); mutex_init(&hba->hba_mutex); + mutex_init(&hba->hba_stats_mutex); hba->cnic = cnic; -- cgit v1.2.3 From a1df375ca4962c8b1bbcc0dc38de53a0da782cdd Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Sun, 30 Apr 2017 19:49:21 +1200 Subject: fix race in drivers/char/random.c:get_reg() [ Upstream commit 9dfa7bba35ac08a63565d58c454dccb7e1bb0a08 ] get_reg() can be reentered on architectures with prioritized interrupts (m68k in this case), causing f->reg_index to be incremented after the range check. Out of bounds memory access past the pt_regs struct results. This will go mostly undetected unless access is beyond end of memory. Prevent the race by disabling interrupts in get_reg(). Tested on m68k (Atari Falcon, and ARAnyM emulator). Kudos to Geert Uytterhoeven for helping to trace this race. Signed-off-by: Michael Schmitz Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 08d1dd58c0d2..23f3fb45ff07 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1115,12 +1115,16 @@ static void add_interrupt_bench(cycles_t start) static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) { __u32 *ptr = (__u32 *) regs; + unsigned long flags; if (regs == NULL) return 0; + local_irq_save(flags); if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) f->reg_idx = 0; - return *(ptr + f->reg_idx++); + ptr += f->reg_idx++; + local_irq_restore(flags); + return *ptr; } void add_interrupt_randomness(int irq, int irq_flags) -- cgit v1.2.3 From 969eeef39863b6435ed80da16a2325ceb4137ae6 Mon Sep 17 00:00:00 2001 From: KT Liao Date: Thu, 25 May 2017 10:06:21 -0700 Subject: Input: elan_i2c - clear INT before resetting controller [ Upstream commit 4b3c7dbbfff0673e8a89575414b864d8b001d3bb ] Some old touchpad FWs need to have interrupt cleared before issuing reset command after updating firmware. We clear interrupt by attempting to read full report from the controller, and discarding any data read. Signed-off-by: KT Liao Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/elan_i2c_i2c.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c index a679e56c44cd..765879dcaf85 100644 --- a/drivers/input/mouse/elan_i2c_i2c.c +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -557,7 +557,14 @@ static int elan_i2c_finish_fw_update(struct i2c_client *client, long ret; int error; int len; - u8 buffer[ETP_I2C_INF_LENGTH]; + u8 buffer[ETP_I2C_REPORT_LEN]; + + len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN); + if (len != ETP_I2C_REPORT_LEN) { + error = len < 0 ? len : -EIO; + dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n", + error, len); + } reinit_completion(completion); enable_irq(client->irq); -- cgit v1.2.3 From 1a6906e7f50d84272849549a26e985c4d6e581bd Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 24 May 2017 19:45:17 -0700 Subject: bonding: Don't update slave->link until ready to commit [ Upstream commit 797a93647a48d6cb8a20641a86a71713a947f786 ] In the loadbalance arp monitoring scheme, when a slave link change is detected, the slave->link is immediately updated and slave_state_changed is set. Later down the function, the rtnl_lock is acquired and the changes are committed, updating the bond link state. However, the acquisition of the rtnl_lock can fail. The next time the monitor runs, since slave->link is already updated, it determines that link is unchanged. This results in the bond link state permanently out of sync with the slave link. This patch modifies bond_loadbalance_arp_mon() to handle link changes identical to bond_ab_arp_{inspect/commit}(). The new link state is maintained in slave->new_link until we're ready to commit at which point it's copied into slave->link. NOTE: miimon_{inspect/commit}() has a more complex state machine requiring the use of the bond_{propose,commit}_link_state() functions which maintains the intermediate state in slave->link_new_state. The arp monitors don't require that. Testing: This bug is very easy to reproduce with the following steps. 1. In a loop, toggle a slave link of a bond slave interface. 2. In a separate loop, do ifconfig up/down of an unrelated interface to create contention for rtnl_lock. Within a few iterations, the bond link goes out of sync with the slave link. Signed-off-by: Nithin Nayak Sujir Cc: Mahesh Bandewar Cc: Jay Vosburgh Acked-by: Mahesh Bandewar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4907c9b57565..fb1141f7f6b5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2605,11 +2605,13 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) bond_for_each_slave_rcu(bond, slave, iter) { unsigned long trans_start = dev_trans_start(slave->dev); + slave->new_link = BOND_LINK_NOCHANGE; + if (slave->link != BOND_LINK_UP) { if (bond_time_in_interval(bond, trans_start, 1) && bond_time_in_interval(bond, slave->last_rx, 1)) { - slave->link = BOND_LINK_UP; + slave->new_link = BOND_LINK_UP; slave_state_changed = 1; /* primary_slave has no meaning in round-robin @@ -2636,7 +2638,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) if (!bond_time_in_interval(bond, trans_start, 2) || !bond_time_in_interval(bond, slave->last_rx, 2)) { - slave->link = BOND_LINK_DOWN; + slave->new_link = BOND_LINK_DOWN; slave_state_changed = 1; if (slave->link_failure_count < UINT_MAX) @@ -2667,6 +2669,11 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) if (!rtnl_trylock()) goto re_arm; + bond_for_each_slave(bond, slave, iter) { + if (slave->new_link != BOND_LINK_NOCHANGE) + slave->link = slave->new_link; + } + if (slave_state_changed) { bond_slave_state_change(bond); if (BOND_MODE(bond) == BOND_MODE_XOR) -- cgit v1.2.3 From a435a0ceadae59f839e0d4a47b771d68418e682b Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 8 May 2017 14:34:57 -0600 Subject: drm/msm: Take the mutex before calling msm_gem_new_impl [ Upstream commit 90dd57de4a043f642179b1323a31ca3ced826611 ] Amongst its other duties, msm_gem_new_impl adds the newly created GEM object to the shared inactive list which may also be actively modifiying the list during submission. All the paths to modify the list are protected by the mutex except for the one through msm_gem_import which can end up causing list corruption. Signed-off-by: Jordan Crouse [add extra WARN_ON(!mutex_is_locked(&dev->struct_mutex))] Signed-off-by: Rob Clark Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/msm/msm_gem.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 797d1f8340b9..7145127513c4 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -770,6 +770,8 @@ static int msm_gem_new_impl(struct drm_device *dev, unsigned sz; bool use_vram = false; + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + switch (flags & MSM_BO_CACHE_MASK) { case MSM_BO_UNCACHED: case MSM_BO_CACHED: @@ -863,7 +865,11 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, size = PAGE_ALIGN(dmabuf->size); + /* Take mutex so we can modify the inactive list in msm_gem_new_impl */ + mutex_lock(&dev->struct_mutex); ret = msm_gem_new_impl(dev, size, MSM_BO_WC, dmabuf->resv, &obj); + mutex_unlock(&dev->struct_mutex); + if (ret) goto fail; -- cgit v1.2.3 From ff2620e356e393ba475b0550c85477b2658b4515 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Fri, 22 Dec 2017 09:46:59 -0600 Subject: i40iw: Fix sequence number for the first partial FPDU [ Upstream commit df8b13a1b23356d01dfc4647a5629cdb0f4ce566 ] Partial FPDU processing is broken as the sequence number for the first partial FPDU is wrong due to incorrect Q2 buffer offset. The offset should be 64 rather than 16. Fixes: 786c6adb3a94 ("i40iw: add puda code") Signed-off-by: Shiraz Saleem Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/i40iw/i40iw_d.h | 1 + drivers/infiniband/hw/i40iw/i40iw_puda.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index d1328a697750..8ce599e1639c 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -86,6 +86,7 @@ #define RDMA_OPCODE_MASK 0x0f #define RDMA_READ_REQ_OPCODE 1 #define Q2_BAD_FRAME_OFFSET 72 +#define Q2_FPSN_OFFSET 64 #define CQE_MAJOR_DRV 0x8000 #define I40IW_TERM_SENT 0x01 diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index c62d354f7810..3ed49146d73c 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -1320,7 +1320,7 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq, u32 *hw_host_ctx = (u32 *)qp->hw_host_ctx; u32 rcv_wnd = hw_host_ctx[23]; /* first partial seq # in q2 */ - u32 fps = qp->q2_buf[16]; + u32 fps = *(u32 *)(qp->q2_buf + Q2_FPSN_OFFSET); struct list_head *rxlist = &pfpdu->rxlist; struct list_head *plist; -- cgit v1.2.3 From 11c7a4b5ac947bd2dc01b9874948e1359fc1e065 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Fri, 22 Dec 2017 09:46:56 -0600 Subject: i40iw: Correct Q1/XF object count equation [ Upstream commit fe99afd1febd74e0ef1fed7e3283f09effe1f4f0 ] Lower Inbound RDMA Read Queue (Q1) object count by a factor of 2 as it is incorrectly doubled. Also, round up Q1 and Transmit FIFO (XF) object count to power of 2 to satisfy hardware requirement. Fixes: 86dbcd0f12e9 ("i40iw: add file to handle cqp calls") Signed-off-by: Shiraz Saleem Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index 2c4b4d072d6a..3b973cba8975 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -3644,8 +3644,10 @@ enum i40iw_status_code i40iw_config_fpm_values(struct i40iw_sc_dev *dev, u32 qp_ hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].cnt = 1; hmc_info->hmc_obj[I40IW_HMC_IW_MR].cnt = mrwanted; - hmc_info->hmc_obj[I40IW_HMC_IW_XF].cnt = I40IW_MAX_WQ_ENTRIES * qpwanted; - hmc_info->hmc_obj[I40IW_HMC_IW_Q1].cnt = 4 * I40IW_MAX_IRD_SIZE * qpwanted; + hmc_info->hmc_obj[I40IW_HMC_IW_XF].cnt = + roundup_pow_of_two(I40IW_MAX_WQ_ENTRIES * qpwanted); + hmc_info->hmc_obj[I40IW_HMC_IW_Q1].cnt = + roundup_pow_of_two(2 * I40IW_MAX_IRD_SIZE * qpwanted); hmc_info->hmc_obj[I40IW_HMC_IW_XFFL].cnt = hmc_info->hmc_obj[I40IW_HMC_IW_XF].cnt / hmc_fpm_misc->xf_block_size; hmc_info->hmc_obj[I40IW_HMC_IW_Q1FL].cnt = -- cgit v1.2.3 From 8e50e9d66e872c7bb5a31d71afe44a089e81143c Mon Sep 17 00:00:00 2001 From: Yi Zeng Date: Tue, 26 Dec 2017 19:22:26 +0800 Subject: thermal: power_allocator: fix one race condition issue for thermal_instances list [ Upstream commit a5de11d67dcd268b8d0beb73dc374de5e97f0caf ] When invoking allow_maximum_power and traverse tz->thermal_instances, we should grab thermal_zone_device->lock to avoid race condition. For example, during the system reboot, if the mali GPU device implements device shutdown callback and unregister GPU devfreq cooling device, the deleted list head may be accessed to cause panic, as the following log shows: [ 33.551070] c3 25 (kworker/3:0) Unable to handle kernel paging request at virtual address dead000000000070 [ 33.566708] c3 25 (kworker/3:0) pgd = ffffffc0ed290000 [ 33.572071] c3 25 (kworker/3:0) [dead000000000070] *pgd=00000001ed292003, *pud=00000001ed292003, *pmd=0000000000000000 [ 33.581515] c3 25 (kworker/3:0) Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 33.599761] c3 25 (kworker/3:0) CPU: 3 PID: 25 Comm: kworker/3:0 Not tainted 4.4.35+ #912 [ 33.614137] c3 25 (kworker/3:0) Workqueue: events_freezable thermal_zone_device_check [ 33.620245] c3 25 (kworker/3:0) task: ffffffc0f32e4200 ti: ffffffc0f32f0000 task.ti: ffffffc0f32f0000 [ 33.629466] c3 25 (kworker/3:0) PC is at power_allocator_throttle+0x7c8/0x8a4 [ 33.636609] c3 25 (kworker/3:0) LR is at power_allocator_throttle+0x808/0x8a4 [ 33.643742] c3 25 (kworker/3:0) pc : [] lr : [] pstate: 20000145 [ 33.652874] c3 25 (kworker/3:0) sp : ffffffc0f32f3bb0 [ 34.468519] c3 25 (kworker/3:0) Process kworker/3:0 (pid: 25, stack limit = 0xffffffc0f32f0020) [ 34.477220] c3 25 (kworker/3:0) Stack: (0xffffffc0f32f3bb0 to 0xffffffc0f32f4000) [ 34.819822] c3 25 (kworker/3:0) Call trace: [ 34.824021] c3 25 (kworker/3:0) Exception stack(0xffffffc0f32f39c0 to 0xffffffc0f32f3af0) [ 34.924993] c3 25 (kworker/3:0) [] power_allocator_throttle+0x7c8/0x8a4 [ 34.933184] c3 25 (kworker/3:0) [] handle_thermal_trip.part.25+0x70/0x224 [ 34.941545] c3 25 (kworker/3:0) [] thermal_zone_device_update+0xc0/0x20c [ 34.949818] c3 25 (kworker/3:0) [] thermal_zone_device_check+0x20/0x2c [ 34.957924] c3 25 (kworker/3:0) [] process_one_work+0x168/0x458 [ 34.965414] c3 25 (kworker/3:0) [] worker_thread+0x13c/0x4b4 [ 34.972650] c3 25 (kworker/3:0) [] kthread+0xe8/0xfc [ 34.979187] c3 25 (kworker/3:0) [] ret_from_fork+0x10/0x40 [ 34.986244] c3 25 (kworker/3:0) Code: f9405e73 eb1302bf d102e273 54ffc460 (b9402a61) [ 34.994339] c3 25 (kworker/3:0) ---[ end trace 32057901e3b7e1db ]--- Signed-off-by: Yi Zeng Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/power_allocator.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c index b4d3116cfdaf..3055f9a12a17 100644 --- a/drivers/thermal/power_allocator.c +++ b/drivers/thermal/power_allocator.c @@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + mutex_lock(&tz->lock); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { if ((instance->trip != params->trip_max_desired_temperature) || (!cdev_is_power_actor(instance->cdev))) @@ -534,6 +535,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) mutex_unlock(&instance->cdev->lock); thermal_cdev_update(instance->cdev); } + mutex_unlock(&tz->lock); } /** -- cgit v1.2.3 From 2fb63a4c948be910a0f2696d6fecdb481ae1887c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 23 Dec 2017 19:41:47 +0100 Subject: ACPI / video: Default lcd_only to true on Win8-ready and newer machines [ Upstream commit 5928c281524fe451114e04f1dfa11246a37e859f ] We're seeing a lot of bogus backlight interfaces on newer machines without a LCD such as desktops, servers and HDMI sticks. This causes userspace to show a non-functional brightness slider in e.g. the GNOME3 system menu, which is undesirable. And, in general, we should simply just not register a non functional backlight interface. Checking the LCD flag causes the bogus acpi_video backlight interfaces to go away (on the machines this was tested on). This change sets the lcd_only option by default on any machines which are Win8-ready, to fix this. This is not entirely without a risk of regressions, but video_detect.c already prefers native-backlight interfaces over the acpi_video one on Win8-ready machines, calling acpi_video_unregister_backlight() as soon as a native interface shows up. This is done because the ACPI backlight interface often is broken on Win8-ready machines, because win8 does not seem to actually use it. So in practice we already end up not registering the ACPI backlight interface on (most) Win8-ready machines with a LCD panel, thus this change does not change anything for (most) machines with a LCD panel and on machines without a LCD panel we actually don't want to register any backlight interfaces. This has been tested on the following machines and fixes a bogus backlight interface showing up there: - Desktop with an Asrock B150M Pro4S/D3 m.b. using i5-6500 builtin gfx - Intel Compute Stick STK1AW32SC - Meegopad T08 HDMI stick Bogus backlight interfaces have also been reported on: - Desktop with Asus H87I-Plus m.b. - Desktop with ASRock B75M-ITX m.b. - Desktop with Gigabyte Z87-D3HP m.b. - Dell PowerEdge T20 desktop Link: https://bugzilla.redhat.com/show_bug.cgi?id=1097436 Link: https://bugzilla.redhat.com/show_bug.cgi?id=1133327 Link: https://bugzilla.redhat.com/show_bug.cgi?id=1133329 Link: https://bugzilla.redhat.com/show_bug.cgi?id=1133646 Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpi_video.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index c5557d070954..94e04c9de12b 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -87,8 +87,8 @@ MODULE_PARM_DESC(report_key_events, static bool device_id_scheme = false; module_param(device_id_scheme, bool, 0444); -static bool only_lcd = false; -module_param(only_lcd, bool, 0444); +static int only_lcd = -1; +module_param(only_lcd, int, 0444); static int register_count; static DEFINE_MUTEX(register_count_mutex); @@ -2082,6 +2082,16 @@ int acpi_video_register(void) goto leave; } + /* + * We're seeing a lot of bogus backlight interfaces on newer machines + * without a LCD such as desktops, servers and HDMI sticks. Checking + * the lcd flag fixes this, so enable this on any machines which are + * win8 ready (where we also prefer the native backlight driver, so + * normally the acpi_video code should not register there anyways). + */ + if (only_lcd == -1) + only_lcd = acpi_osi_is_win8(); + dmi_check_system(video_dmi_table); ret = acpi_bus_register_driver(&acpi_video_bus); -- cgit v1.2.3 From 9e156f310a88848b7692c41c3cfcdbfeb1c05e7a Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Thu, 28 Dec 2017 16:26:11 +0200 Subject: net/mlx4_en: Change default QoS settings [ Upstream commit a42b63c1ac1986f17f71bc91a6b0aaa14d4dae71 ] Change the default mapping between TC and TCG as follows: Prio | TC/TCG | from to | (set by FW) (set by SW) ---------+----------------------------------- 0 | 0/0 0/7 1 | 1/0 0/6 2 | 2/0 0/5 3 | 3/0 0/4 4 | 4/0 0/3 5 | 5/0 0/2 6 | 6/0 0/1 7 | 7/0 0/0 These new settings cause that a pause frame for any prio stops traffic for all prios. Fixes: 564c274c3df0 ("net/mlx4_en: DCB QoS support") Signed-off-by: Moni Shoua Signed-off-by: Maor Gottlieb Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 5 +++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 7 +++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 3 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index b04760a5034b..d98827adec9b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c @@ -310,6 +310,7 @@ static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets) } switch (ets->tc_tsa[i]) { + case IEEE_8021QAZ_TSA_VENDOR: case IEEE_8021QAZ_TSA_STRICT: break; case IEEE_8021QAZ_TSA_ETS: @@ -347,6 +348,10 @@ static int mlx4_en_config_port_scheduler(struct mlx4_en_priv *priv, /* higher TC means higher priority => lower pg */ for (i = IEEE_8021QAZ_MAX_TCS - 1; i >= 0; i--) { switch (ets->tc_tsa[i]) { + case IEEE_8021QAZ_TSA_VENDOR: + pg[i] = MLX4_EN_TC_VENDOR; + tc_tx_bw[i] = MLX4_EN_BW_MAX; + break; case IEEE_8021QAZ_TSA_STRICT: pg[i] = num_strict++; tc_tx_bw[i] = MLX4_EN_BW_MAX; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index d223e7cb68ba..0160c93de6d3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -3125,6 +3125,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->msg_enable = MLX4_EN_MSG_LEVEL; #ifdef CONFIG_MLX4_EN_DCB if (!mlx4_is_slave(priv->mdev->dev)) { + u8 prio; + + for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; ++prio) { + priv->ets.prio_tc[prio] = prio; + priv->ets.tc_tsa[prio] = IEEE_8021QAZ_TSA_VENDOR; + } + priv->dcbx_cap = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; priv->flags |= MLX4_EN_DCB_ENABLED; diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index df0f39611c5e..18f221d8a04d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -472,6 +472,7 @@ struct mlx4_en_frag_info { #define MLX4_EN_BW_MIN 1 #define MLX4_EN_BW_MAX 100 /* Utilize 100% of the line */ +#define MLX4_EN_TC_VENDOR 0 #define MLX4_EN_TC_ETS 7 enum dcb_pfc_type { -- cgit v1.2.3 From 715f7e3efef0227865162b00d13321431be7962f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 6 Dec 2017 14:20:15 -0600 Subject: PM / devfreq: Fix potential NULL pointer dereference in governor_store [ Upstream commit 63f1e05f7fe9ca509c60154d6a833abf96eecdc9 ] df->governor is being dereferenced before it is null checked, hence there is a potential null pointer dereference. Notice that df->governor is being null checked at line 1004: if (df->governor) {, which implies it might be null. Fix this by null checking df->governor before dereferencing it. Addresses-Coverity-ID: 1401988 ("Dereference before null check") Fixes: bcf23c79c4e4 ("PM / devfreq: Fix available_governor sysfs") Signed-off-by: Gustavo A. R. Silva Reviewed-by: Chanwoo Choi Signed-off-by: MyungJoo Ham Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/devfreq/devfreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 9e5674c5a07b..db70cee71caa 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -943,7 +943,8 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, if (df->governor == governor) { ret = 0; goto out; - } else if (df->governor->immutable || governor->immutable) { + } else if ((df->governor && df->governor->immutable) || + governor->immutable) { ret = -EINVAL; goto out; } -- cgit v1.2.3 From 8d008c0ce55c89c47d70646ae244c006abecd288 Mon Sep 17 00:00:00 2001 From: Maciej Purski Date: Wed, 22 Nov 2017 16:32:15 +0100 Subject: hwmon: (ina2xx) Make calibration register value fixed [ Upstream commit 5d389b125186cf254ad5b8015763ac07c151aea4 ] Calibration register is used for calculating current register in hardware according to datasheet: current = shunt_volt * calib_register / 2048 (ina 226) current = shunt_volt * calib_register / 4096 (ina 219) Fix calib_register value to 2048 for ina226 and 4096 for ina 219 in order to avoid truncation error and provide best precision allowed by shunt_voltage measurement. Make current scale value follow changes of shunt_resistor from sysfs as calib_register value is now fixed. Power_lsb value should also follow shunt_resistor changes as stated in datasheet: power_lsb = 25 * current_lsb (ina 226) power_lsb = 20 * current_lsb (ina 219) Signed-off-by: Maciej Purski Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/ina2xx.c | 87 +++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index b24f1d3045f0..a629f7c130f0 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -94,18 +94,20 @@ enum ina2xx_ids { ina219, ina226 }; struct ina2xx_config { u16 config_default; - int calibration_factor; + int calibration_value; int registers; int shunt_div; int bus_voltage_shift; int bus_voltage_lsb; /* uV */ - int power_lsb; /* uW */ + int power_lsb_factor; }; struct ina2xx_data { const struct ina2xx_config *config; long rshunt; + long current_lsb_uA; + long power_lsb_uW; struct mutex config_lock; struct regmap *regmap; @@ -115,21 +117,21 @@ struct ina2xx_data { static const struct ina2xx_config ina2xx_config[] = { [ina219] = { .config_default = INA219_CONFIG_DEFAULT, - .calibration_factor = 40960000, + .calibration_value = 4096, .registers = INA219_REGISTERS, .shunt_div = 100, .bus_voltage_shift = 3, .bus_voltage_lsb = 4000, - .power_lsb = 20000, + .power_lsb_factor = 20, }, [ina226] = { .config_default = INA226_CONFIG_DEFAULT, - .calibration_factor = 5120000, + .calibration_value = 2048, .registers = INA226_REGISTERS, .shunt_div = 400, .bus_voltage_shift = 0, .bus_voltage_lsb = 1250, - .power_lsb = 25000, + .power_lsb_factor = 25, }, }; @@ -168,12 +170,16 @@ static u16 ina226_interval_to_reg(int interval) return INA226_SHIFT_AVG(avg_bits); } +/* + * Calibration register is set to the best value, which eliminates + * truncation errors on calculating current register in hardware. + * According to datasheet (eq. 3) the best values are 2048 for + * ina226 and 4096 for ina219. They are hardcoded as calibration_value. + */ static int ina2xx_calibrate(struct ina2xx_data *data) { - u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor, - data->rshunt); - - return regmap_write(data->regmap, INA2XX_CALIBRATION, val); + return regmap_write(data->regmap, INA2XX_CALIBRATION, + data->config->calibration_value); } /* @@ -186,10 +192,6 @@ static int ina2xx_init(struct ina2xx_data *data) if (ret < 0) return ret; - /* - * Set current LSB to 1mA, shunt is in uOhms - * (equation 13 in datasheet). - */ return ina2xx_calibrate(data); } @@ -267,15 +269,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_POWER: - val = regval * data->config->power_lsb; + val = regval * data->power_lsb_uW; break; case INA2XX_CURRENT: - /* signed register, LSB=1mA (selected), in mA */ - val = (s16)regval; + /* signed register, result in mA */ + val = regval * data->current_lsb_uA; + val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_CALIBRATION: - val = DIV_ROUND_CLOSEST(data->config->calibration_factor, - regval); + val = regval; break; default: /* programmer goofed */ @@ -303,9 +305,32 @@ static ssize_t ina2xx_show_value(struct device *dev, ina2xx_get_value(data, attr->index, regval)); } -static ssize_t ina2xx_set_shunt(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) +/* + * In order to keep calibration register value fixed, the product + * of current_lsb and shunt_resistor should also be fixed and equal + * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order + * to keep the scale. + */ +static int ina2xx_set_shunt(struct ina2xx_data *data, long val) +{ + unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, + data->config->shunt_div); + if (val <= 0 || val > dividend) + return -EINVAL; + + mutex_lock(&data->config_lock); + data->rshunt = val; + data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); + data->power_lsb_uW = data->config->power_lsb_factor * + data->current_lsb_uA; + mutex_unlock(&data->config_lock); + + return 0; +} + +static ssize_t ina2xx_store_shunt(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) { unsigned long val; int status; @@ -315,18 +340,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev, if (status < 0) return status; - if (val == 0 || - /* Values greater than the calibration factor make no sense. */ - val > data->config->calibration_factor) - return -EINVAL; - - mutex_lock(&data->config_lock); - data->rshunt = val; - status = ina2xx_calibrate(data); - mutex_unlock(&data->config_lock); + status = ina2xx_set_shunt(data, val); if (status < 0) return status; - return count; } @@ -386,7 +402,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, /* shunt resistance */ static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, - ina2xx_show_value, ina2xx_set_shunt, + ina2xx_show_value, ina2xx_store_shunt, INA2XX_CALIBRATION); /* update interval (ina226 only) */ @@ -441,10 +457,7 @@ static int ina2xx_probe(struct i2c_client *client, val = INA2XX_RSHUNT_DEFAULT; } - if (val <= 0 || val > data->config->calibration_factor) - return -ENODEV; - - data->rshunt = val; + ina2xx_set_shunt(data, val); ina2xx_regmap_config.max_register = data->config->registers; -- cgit v1.2.3 From 1be3eb15225dc01451a4989ac13faf50116fabaf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 28 Dec 2017 09:16:47 -0500 Subject: media: videobuf2-core: don't go out of the buffer range [ Upstream commit df93dc61b0d8b19a5c9db545cf3fcc24f88dfde4 ] Currently, there's no check if an invalid buffer range is passed. However, while testing DVB memory mapped apps, I got this: videobuf2_core: VB: num_buffers -2143943680, buffer 33, index -2143943647 unable to handle kernel paging request at ffff888b773c0890 IP: __vb2_queue_alloc+0x134/0x4e0 [videobuf2_core] PGD 4142c7067 P4D 4142c7067 PUD 0 Oops: 0002 [#1] SMP Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill ecdh_generic binfmt_misc rc_dvbsky sp2 ts2020 intel_rapl x86_pkg_temp_thermal dvb_usb_dvbsky intel_powerclamp dvb_usb_v2 coretemp m88ds3103 kvm_intel i2c_mux dvb_core snd_hda_codec_hdmi crct10dif_pclmul crc32_pclmul videobuf2_vmalloc videobuf2_memops snd_hda_intel ghash_clmulni_intel videobuf2_core snd_hda_codec rc_core mei_me intel_cstate snd_hwdep snd_hda_core videodev intel_uncore snd_pcm mei media tpm_tis tpm_tis_core intel_rapl_perf tpm snd_timer lpc_ich snd soundcore kvm irqbypass libcrc32c i915 i2c_algo_bit drm_kms_helper e1000e ptp drm crc32c_intel video pps_core CPU: 3 PID: 1776 Comm: dvbv5-zap Not tainted 4.14.0+ #78 Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017 task: ffff88877c73bc80 task.stack: ffffb7c402418000 RIP: 0010:__vb2_queue_alloc+0x134/0x4e0 [videobuf2_core] RSP: 0018:ffffb7c40241bc60 EFLAGS: 00010246 RAX: 0000000080360421 RBX: 0000000000000021 RCX: 000000000000000a RDX: ffffb7c40241bcf4 RSI: ffff888780362c60 RDI: ffff888796d8e130 RBP: ffffb7c40241bcc8 R08: 0000000000000316 R09: 0000000000000004 R10: ffff888780362c00 R11: 0000000000000001 R12: 000000000002f000 R13: ffff8887758be700 R14: 0000000000021000 R15: 0000000000000001 FS: 00007f2849024740(0000) GS:ffff888796d80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff888b773c0890 CR3: 000000043beb2005 CR4: 00000000003606e0 Call Trace: vb2_core_reqbufs+0x226/0x420 [videobuf2_core] dvb_vb2_reqbufs+0x2d/0xc0 [dvb_core] dvb_dvr_do_ioctl+0x98/0x1d0 [dvb_core] dvb_usercopy+0x53/0x1b0 [dvb_core] ? dvb_demux_ioctl+0x20/0x20 [dvb_core] ? tty_ldisc_deref+0x16/0x20 ? tty_write+0x1f9/0x310 ? process_echoes+0x70/0x70 dvb_dvr_ioctl+0x15/0x20 [dvb_core] do_vfs_ioctl+0xa5/0x600 SyS_ioctl+0x79/0x90 entry_SYSCALL_64_fastpath+0x1a/0xa5 RIP: 0033:0x7f28486f7ea7 RSP: 002b:00007ffc13b2db18 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 000055b10fc06130 RCX: 00007f28486f7ea7 RDX: 00007ffc13b2db48 RSI: 00000000c0086f3c RDI: 0000000000000007 RBP: 0000000000000203 R08: 000055b10df1e02c R09: 000000000000002e R10: 0036b42415108357 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f2849062f60 R14: 00000000000001f1 R15: 00007ffc13b2da54 Code: 74 0a 60 8b 0a 48 83 c0 30 48 83 c2 04 89 48 d0 89 48 d4 48 39 f0 75 eb 41 8b 42 08 83 7d d4 01 41 c7 82 ec 01 00 00 ff ff ff ff <4d> 89 94 c5 88 00 00 00 74 14 83 c3 01 41 39 dc 0f 85 f1 fe ff RIP: __vb2_queue_alloc+0x134/0x4e0 [videobuf2_core] RSP: ffffb7c40241bc60 CR2: ffff888b773c0890 So, add a sanity check in order to prevent going past array. Signed-off-by: Mauro Carvalho Chehab Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/videobuf2-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 9ccf7f5e0e2e..4299ce06c25b 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -334,6 +334,10 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, struct vb2_buffer *vb; int ret; + /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ + num_buffers = min_t(unsigned int, num_buffers, + VB2_MAX_FRAME - q->num_buffers); + for (buffer = 0; buffer < num_buffers; ++buffer) { /* Allocate videobuf buffer structures */ vb = kzalloc(q->buf_struct_size, GFP_KERNEL); -- cgit v1.2.3 From a8cfc6d0e7ace50a81a3f4ce1b7874dacbd3e4e4 Mon Sep 17 00:00:00 2001 From: Rafael David Tinoco Date: Thu, 7 Dec 2017 19:59:13 -0200 Subject: scsi: libiscsi: Allow sd_shutdown on bad transport [ Upstream commit d754941225a7dbc61f6dd2173fa9498049f9a7ee ] If, for any reason, userland shuts down iscsi transport interfaces before proper logouts - like when logging in to LUNs manually, without logging out on server shutdown, or when automated scripts can't umount/logout from logged LUNs - kernel will hang forever on its sd_sync_cache() logic, after issuing the SYNCHRONIZE_CACHE cmd to all still existent paths. PID: 1 TASK: ffff8801a69b8000 CPU: 1 COMMAND: "systemd-shutdow" #0 [ffff8801a69c3a30] __schedule at ffffffff8183e9ee #1 [ffff8801a69c3a80] schedule at ffffffff8183f0d5 #2 [ffff8801a69c3a98] schedule_timeout at ffffffff81842199 #3 [ffff8801a69c3b40] io_schedule_timeout at ffffffff8183e604 #4 [ffff8801a69c3b70] wait_for_completion_io_timeout at ffffffff8183fc6c #5 [ffff8801a69c3bd0] blk_execute_rq at ffffffff813cfe10 #6 [ffff8801a69c3c88] scsi_execute at ffffffff815c3fc7 #7 [ffff8801a69c3cc8] scsi_execute_req_flags at ffffffff815c60fe #8 [ffff8801a69c3d30] sd_sync_cache at ffffffff815d37d7 #9 [ffff8801a69c3da8] sd_shutdown at ffffffff815d3c3c This happens because iscsi_eh_cmd_timed_out(), the transport layer timeout helper, would tell the queue timeout function (scsi_times_out) to reset the request timer over and over, until the session state is back to logged in state. Unfortunately, during server shutdown, this might never happen again. Other option would be "not to handle" the issue in the transport layer. That would trigger the error handler logic, which would also need the session state to be logged in again. Best option, for such case, is to tell upper layers that the command was handled during the transport layer error handler helper, marking it as DID_NO_CONNECT, which will allow completion and inform about the problem. After the session was marked as ISCSI_STATE_FAILED, due to the first timeout during the server shutdown phase, all subsequent cmds will fail to be queued, allowing upper logic to fail faster. Signed-off-by: Rafael David Tinoco Reviewed-by: Lee Duncan Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/libiscsi.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4abd3fce5ab6..c2b682916337 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1695,6 +1695,15 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) */ switch (session->state) { case ISCSI_STATE_FAILED: + /* + * cmds should fail during shutdown, if the session + * state is bad, allowing completion to happen + */ + if (unlikely(system_state != SYSTEM_RUNNING)) { + reason = FAILURE_SESSION_FAILED; + sc->result = DID_NO_CONNECT << 16; + break; + } case ISCSI_STATE_IN_RECOVERY: reason = FAILURE_SESSION_IN_RECOVERY; sc->result = DID_IMM_RETRY << 16; @@ -1979,6 +1988,19 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) } if (session->state != ISCSI_STATE_LOGGED_IN) { + /* + * During shutdown, if session is prematurely disconnected, + * recovery won't happen and there will be hung cmds. Not + * handling cmds would trigger EH, also bad in this case. + * Instead, handle cmd, allow completion to happen and let + * upper layer to deal with the result. + */ + if (unlikely(system_state != SYSTEM_RUNNING)) { + sc->result = DID_NO_CONNECT << 16; + ISCSI_DBG_EH(session, "sc on shutdown, handled\n"); + rc = BLK_EH_HANDLED; + goto done; + } /* * We are probably in the middle of iscsi recovery so let * that complete and handle the error. @@ -2083,7 +2105,7 @@ done: task->last_timeout = jiffies; spin_unlock(&session->frwd_lock); ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? - "timer reset" : "nh"); + "timer reset" : "shutdown or nh"); return rc; } -- cgit v1.2.3 From 388f0c8cfca271b4505fadde31d2eaecd2516cfa Mon Sep 17 00:00:00 2001 From: Chaitra P B Date: Wed, 27 Dec 2017 23:09:11 -0800 Subject: scsi: mpt3sas: Proper handling of set/clear of "ATA command pending" flag. [ Upstream commit f49d4aed1315a7b766d855f1367142e682b0cc87 ] 1. In IO path, setting of "ATA command pending" flag early before device removal, invalid device handle etc., checks causes any new commands to be always returned with SAM_STAT_BUSY and when the driver removes the drive the SML issues SYNC Cache command and that command is always returned with SAM_STAT_BUSY and thus making SYNC Cache command to requeued. 2. If the driver gets an ATA PT command for a SATA drive then the driver set "ATA command pending" flag in device specific data structure not to allow any further commands until the ATA PT command is completed. However, after setting the flag if the driver decides to return the command back to upper layers without actually issuing to the firmware (i.e., returns from qcmd failure return paths) then the corresponding flag is not cleared and this prevents the driver from sending any new commands to the drive. This patch fixes above two issues by setting of "ATA command pending" flag after checking for whether device deleted, invalid device handle, device busy with task management. And by setting "ATA command pending" flag to false in all of the qcmd failure return paths after setting the flag. Signed-off-by: Chaitra P B Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 468acab04d3d..b8589068d175 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -4065,19 +4065,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) return 0; } - /* - * Bug work around for firmware SATL handling. The loop - * is based on atomic operations and ensures consistency - * since we're lockless at this point - */ - do { - if (test_bit(0, &sas_device_priv_data->ata_command_pending)) { - scmd->result = SAM_STAT_BUSY; - scmd->scsi_done(scmd); - return 0; - } - } while (_scsih_set_satl_pending(scmd, true)); - sas_target_priv_data = sas_device_priv_data->sas_target; /* invalid device handle */ @@ -4103,6 +4090,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) sas_device_priv_data->block) return SCSI_MLQUEUE_DEVICE_BUSY; + /* + * Bug work around for firmware SATL handling. The loop + * is based on atomic operations and ensures consistency + * since we're lockless at this point + */ + do { + if (test_bit(0, &sas_device_priv_data->ata_command_pending)) { + scmd->result = SAM_STAT_BUSY; + scmd->scsi_done(scmd); + return 0; + } + } while (_scsih_set_satl_pending(scmd, true)); + if (scmd->sc_data_direction == DMA_FROM_DEVICE) mpi_control = MPI2_SCSIIO_CONTROL_READ; else if (scmd->sc_data_direction == DMA_TO_DEVICE) @@ -4124,6 +4124,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) if (!smid) { pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ioc->name, __func__); + _scsih_set_satl_pending(scmd, false); goto out; } mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); @@ -4154,6 +4155,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) if (mpi_request->DataLength) { if (ioc->build_sg_scmd(ioc, scmd, smid)) { mpt3sas_base_free_smid(ioc, smid); + _scsih_set_satl_pending(scmd, false); goto out; } } else -- cgit v1.2.3 From c979024a1bb359988dc6b50a26dd3bb0789fd54f Mon Sep 17 00:00:00 2001 From: Shanker Donthineni Date: Tue, 5 Dec 2017 13:16:21 -0600 Subject: irqchip/gic-v3: Fix the driver probe() fail due to disabled GICC entry [ Upstream commit ebe2f8718007d5a1238bb3cb8141b5bb2b4d5773 ] The ACPI specification says OS shouldn't attempt to use GICC configuration parameters if the flag ACPI_MADT_ENABLED is cleared. The ARM64-SMP code skips the disabled GICC entries but not causing any issue. However the current GICv3 driver probe bails out causing kernel panic() instead of skipping the disabled GICC interfaces. This issue happens on systems where redistributor regions are not in the always-on power domain and one of GICC interface marked with ACPI_MADT_ENABLED=0. This patch does the two things to fix the panic. - Don't return an error in gic_acpi_match_gicc() for disabled GICC entry. - No need to keep GICR region information for disabled GICC entry. Observed kernel crash on QDF2400 platform GICC entry is disabled. Kernel crash traces: Kernel panic - not syncing: No interrupt controller found. CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.13.5 #26 [] dump_backtrace+0x0/0x218 [] show_stack+0x14/0x20 [] dump_stack+0x98/0xb8 [] panic+0x118/0x26c [] init_IRQ+0x24/0x2c [] start_kernel+0x230/0x394 [] __primary_switched+0x64/0x6c ---[ end Kernel panic - not syncing: No interrupt controller found. Disabled GICC subtable example: Subtable Type : 0B [Generic Interrupt Controller] Length : 50 Reserved : 0000 CPU Interface Number : 0000003D Processor UID : 0000003D Flags (decoded below) : 00000000 Processor Enabled : 0 Performance Interrupt Trig Mode : 0 Virtual GIC Interrupt Trig Mode : 0 Parking Protocol Version : 00000000 Performance Interrupt : 00000017 Parked Address : 0000000000000000 Base Address : 0000000000000000 Virtual GIC Base Address : 0000000000000000 Hypervisor GIC Base Address : 0000000000000000 Virtual GIC Interrupt : 00000019 Redistributor Base Address : 0000FFFF88F40000 ARM MPIDR : 000000000000000D Efficiency Class : 00 Reserved : 000000 Signed-off-by: Shanker Donthineni Signed-off-by: Marc Zyngier Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-gic-v3.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index fd4a78296b48..100c80e48190 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1250,6 +1250,10 @@ gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header, u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2; void __iomem *redist_base; + /* GICC entry which has !ACPI_MADT_ENABLED is not unusable so skip */ + if (!(gicc->flags & ACPI_MADT_ENABLED)) + return 0; + redist_base = ioremap(gicc->gicr_base_address, size); if (!redist_base) return -ENOMEM; @@ -1299,6 +1303,13 @@ static int __init gic_acpi_match_gicc(struct acpi_subtable_header *header, if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) return 0; + /* + * It's perfectly valid firmware can pass disabled GICC entry, driver + * should not treat as errors, skip the entry instead of probe fail. + */ + if (!(gicc->flags & ACPI_MADT_ENABLED)) + return 0; + return -ENODEV; } -- cgit v1.2.3 From b7fe48228d816c1ad7e1e90e2bff7d09d17e6642 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 2 Jan 2018 16:26:31 +0100 Subject: ACPI: EC: Fix debugfs_create_*() usage [ Upstream commit 3522f867c13b63cf62acdf1b8ca5664c549a716a ] acpi_ec.gpe is "unsigned long", hence treating it as "u32" would expose the wrong half on big-endian 64-bit systems. Fix this by changing its type to "u32" and removing the cast, as all other code already uses u32 or sometimes even only u8. Fixes: 1195a098168fcacf (ACPI: Provide /sys/kernel/debug/ec/...) Signed-off-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/ec.c | 2 +- drivers/acpi/ec_sys.c | 2 +- drivers/acpi/internal.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index c3bcb7f5986e..307b3e28f34c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1518,7 +1518,7 @@ static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events) } acpi_handle_info(ec->handle, - "GPE=0x%lx, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", + "GPE=0x%x, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); return ret; } diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 6c7dd7af789e..dd70d6c2bca0 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -128,7 +128,7 @@ static int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) return -ENOMEM; } - if (!debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe)) + if (!debugfs_create_x32("gpe", 0444, dev_dir, &first_ec->gpe)) goto error; if (!debugfs_create_bool("use_global_lock", 0444, dev_dir, &first_ec->global_lock)) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 08b3ca0ead69..b012e94b7d9f 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -158,7 +158,7 @@ static inline void acpi_early_processor_osc(void) {} -------------------------------------------------------------------------- */ struct acpi_ec { acpi_handle handle; - unsigned long gpe; + u32 gpe; unsigned long command_addr; unsigned long data_addr; bool global_lock; -- cgit v1.2.3 From 2707d9b2f90136cfaea307198d83959ca8da815e Mon Sep 17 00:00:00 2001 From: "Pieter \\\"PoroCYon\\\" Sluys" Date: Thu, 4 Jan 2018 16:53:50 +0100 Subject: vfb: fix video mode and line_length being set when loaded [ Upstream commit 7b9faf5df0ac495a1a3d7cdb64921c179f9008ac ] Currently, when loading the vfb module, the newly created fbdev has a line_length of 0, and its video mode would be PSEUDOCOLOR regardless of color depth. (The former could be worked around by calling the FBIOPUT_VSCREENINFO ioctl with having the FBACTIVIATE_FORCE flag set.) This patch automatically sets the line_length correctly, and the video mode is derived from the bit depth now as well. Thanks to Geert Uytterhoeven for confirming the bug and helping me with the patch. Output of `fbset -i' before the patch: mode "1366x768-60" # D: 72.432 MHz, H: 47.403 kHz, V: 60.004 Hz geometry 1366 768 1366 768 32 timings 13806 120 10 14 3 32 5 rgba 8/0,8/8,8/16,8/24 endmode Frame buffer device information: Name : Virtual FB Address : 0xffffaa1405d85000 Size : 4196352 Type : PACKED PIXELS Visual : PSEUDOCOLOR XPanStep : 1 YPanStep : 1 YWrapStep : 1 LineLength : 0 <-- note this Accelerator : No After: mode "1366x768-60" # D: 72.432 MHz, H: 47.403 kHz, V: 60.004 Hz geometry 1366 768 1366 768 32 timings 13806 120 10 14 3 32 5 rgba 8/0,8/8,8/16,8/24 endmode Frame buffer device information: Name : Virtual FB Address : 0xffffaa1405d85000 Size : 4196352 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 1 YPanStep : 1 YWrapStep : 1 LineLength : 5464 Accelerator : No Signed-off-by: "Pieter \"PoroCYon\" Sluys" Reviewed-by: Geert Uytterhoeven [b.zolnierkie: minor fixups] Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/vfb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c index da653a080394..54127905bfe7 100644 --- a/drivers/video/fbdev/vfb.c +++ b/drivers/video/fbdev/vfb.c @@ -239,8 +239,23 @@ static int vfb_check_var(struct fb_var_screeninfo *var, */ static int vfb_set_par(struct fb_info *info) { + switch (info->var.bits_per_pixel) { + case 1: + info->fix.visual = FB_VISUAL_MONO01; + break; + case 8: + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + break; + case 16: + case 24: + case 32: + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + } + info->fix.line_length = get_line_length(info->var.xres_virtual, info->var.bits_per_pixel); + return 0; } @@ -450,6 +465,8 @@ static int vfb_probe(struct platform_device *dev) goto err2; platform_set_drvdata(dev, info); + vfb_set_par(info); + fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n", videomemorysize >> 10); return 0; -- cgit v1.2.3 From c5aa51c82e6ed7c203b2b8415645dfea249cc369 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Jan 2018 22:31:11 +0100 Subject: gpio: label descriptors using the device name [ Upstream commit 24e78079bf2250874e33da2e7cfbb6db72d3caf4 ] Some GPIO lines appear named "?" in the lsgpio dump due to their requesting drivers not passing a reasonable label. Most typically this happens if a device tree node just defines gpios = <...> and not foo-gpios = <...>, the former gets named "foo" and the latter gets named "?". However the struct device passed in is always valid so let's just label the GPIO with dev_name() on the device if no proper label was passed. Cc: Reported-by: Jason Kridner Reported-by: Jason Kridner Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f3c3680963b9..4f54ff45e09e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3231,7 +3231,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, return desc; } - status = gpiod_request(desc, con_id); + /* If a connection label was passed use that, else use the device name as label */ + status = gpiod_request(desc, con_id ? con_id : dev_name(dev)); if (status < 0) return ERR_PTR(status); -- cgit v1.2.3 From 5736369b54e3a4dc00592df922fbd8d739fb5be2 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 18 Dec 2017 19:57:06 -0800 Subject: IB/rdmavt: Allocate CQ memory on the correct node [ Upstream commit db9a2c6f9b6196b889b98e961cb9a37617b11ccf ] CQ allocation does not ensure that completion queue entries and the completion queue structure are allocated on the correct numa node. Fix by allocating the rvt_cq and kernel CQ entries on the device node, leaving the user CQ entries on the default local node. Also ensure CQ resizes use the correct allocator when extending a CQ. Reviewed-by: Sebastian Sanchez Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/sw/rdmavt/cq.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/sw/rdmavt/cq.c b/drivers/infiniband/sw/rdmavt/cq.c index 6d9904a4a0ab..29dc5278d7be 100644 --- a/drivers/infiniband/sw/rdmavt/cq.c +++ b/drivers/infiniband/sw/rdmavt/cq.c @@ -197,7 +197,7 @@ struct ib_cq *rvt_create_cq(struct ib_device *ibdev, return ERR_PTR(-EINVAL); /* Allocate the completion queue structure. */ - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_node(sizeof(*cq), GFP_KERNEL, rdi->dparms.node); if (!cq) return ERR_PTR(-ENOMEM); @@ -213,7 +213,9 @@ struct ib_cq *rvt_create_cq(struct ib_device *ibdev, sz += sizeof(struct ib_uverbs_wc) * (entries + 1); else sz += sizeof(struct ib_wc) * (entries + 1); - wc = vmalloc_user(sz); + wc = udata ? + vmalloc_user(sz) : + vzalloc_node(sz, rdi->dparms.node); if (!wc) { ret = ERR_PTR(-ENOMEM); goto bail_cq; @@ -368,7 +370,9 @@ int rvt_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) sz += sizeof(struct ib_uverbs_wc) * (cqe + 1); else sz += sizeof(struct ib_wc) * (cqe + 1); - wc = vmalloc_user(sz); + wc = udata ? + vmalloc_user(sz) : + vzalloc_node(sz, rdi->dparms.node); if (!wc) return -ENOMEM; -- cgit v1.2.3 From 8612220ec404743178d0d02eb29357d4739e802f Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 28 Dec 2017 09:27:41 +0100 Subject: backlight: tdo24m: Fix the SPI CS between transfers [ Upstream commit 2023b0524a6310e9ea80daf085f51c71bff9289f ] Currently the LCD display (TD035S) on the cm-x300 platform is broken and remains blank. The TD0245S specification requires that the chipselect is toggled between commands sent to the panel. This was also the purpose of the former patch of commit f64dcac0b124 ("backlight: tdo24m: ensure chip select changes between transfers"). Unfortunately, the "cs_change" field of a SPI transfer is misleading. Its true meaning is that for a SPI message holding multiple transfers, the chip select is toggled between each transfer, but for the last transfer it remains asserted. In this driver, all the SPI messages contain exactly one transfer, which means that each transfer is the last of its message, and as a consequence the chip select is never toggled. Actually, there was a second bug hidding the first one, hence the problem was not seen until v4.6. This problem was fixed by commit a52db659c79c ("spi: pxa2xx: Fix cs_change management") for PXA based boards. This fix makes the TD035S work again on a cm-x300 board. The same applies to other PXA boards, ie. corgi and tosa. Fixes: a52db659c79c ("spi: pxa2xx: Fix cs_change management") Reported-by: Andrea Adami Signed-off-by: Robert Jarzmik Acked-by: Daniel Thompson Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/backlight/corgi_lcd.c | 2 +- drivers/video/backlight/tdo24m.c | 2 +- drivers/video/backlight/tosa_lcd.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index d7c239ea3d09..f5574060f9c8 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -177,7 +177,7 @@ static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data) struct spi_message msg; struct spi_transfer xfer = { .len = 1, - .cs_change = 1, + .cs_change = 0, .tx_buf = lcd->buf, }; diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index eab1f842f9c0..e4bd63e9db6b 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c @@ -369,7 +369,7 @@ static int tdo24m_probe(struct spi_device *spi) spi_message_init(m); - x->cs_change = 1; + x->cs_change = 0; x->tx_buf = &lcd->buf[0]; spi_message_add_tail(x, m); diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index 6a41ea92737a..4dc5ee8debeb 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -49,7 +49,7 @@ static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data) struct spi_message msg; struct spi_transfer xfer = { .len = 1, - .cs_change = 1, + .cs_change = 0, .tx_buf = buf, }; -- cgit v1.2.3 From 2bc30f850f9f20ce3cfce4c9db524519b8bdcc21 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 1 Jan 2018 13:23:57 +0100 Subject: pinctrl: baytrail: Enable glitch filter for GPIOs used as interrupts [ Upstream commit 9291c65b01d1c67ebd56644cb19317ad665c44b3 ] On some systems, some PCB traces attached to GpioInts are routed in such a way that they pick up enough interference to constantly (many times per second) trigger. Enabling glitch-filtering fixes this. Signed-off-by: Hans de Goede Acked-by: Mika Westerberg Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/intel/pinctrl-baytrail.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 0a965026b134..fc5b18d3db20 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -46,6 +46,9 @@ #define BYT_TRIG_POS BIT(25) #define BYT_TRIG_LVL BIT(24) #define BYT_DEBOUNCE_EN BIT(20) +#define BYT_GLITCH_FILTER_EN BIT(19) +#define BYT_GLITCH_F_SLOW_CLK BIT(17) +#define BYT_GLITCH_F_FAST_CLK BIT(16) #define BYT_PULL_STR_SHIFT 9 #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) @@ -1579,6 +1582,9 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) */ value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + /* Enable glitch filtering */ + value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | + BYT_GLITCH_F_FAST_CLK; writel(value, reg); -- cgit v1.2.3 From c8fed0d73cad36fd01cbd4fc8c18c4307b7bf95c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 19 Dec 2017 12:33:56 +0100 Subject: rt2x00: do not pause queue unconditionally on error path [ Upstream commit 6dd80efd75ce7c2dbd9f117cf585ee2b33a42ee1 ] Pausing queue without checking threshold is racy with txdone path. Moreover we do not need pause queue on any error, but only if queue is full - in case when we send RTS frame ( other cases of almost full queue are already handled in rt2x00queue_write_tx_frame() ). Patch fixes of theoretically possible problem of pausing empty queue. Signed-off-by: Stanislaw Gruszka Tested-by: Enrico Mioso Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c index 13da95a24cf7..987c7c4f43cd 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -142,15 +142,25 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, if (!rt2x00dev->ops->hw->set_rts_threshold && (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | IEEE80211_TX_RC_USE_CTS_PROTECT))) { - if (rt2x00queue_available(queue) <= 1) - goto exit_fail; + if (rt2x00queue_available(queue) <= 1) { + /* + * Recheck for full queue under lock to avoid race + * conditions with rt2x00lib_txdone(). + */ + spin_lock(&queue->tx_lock); + if (rt2x00queue_threshold(queue)) + rt2x00queue_pause_queue(queue); + spin_unlock(&queue->tx_lock); + + goto exit_free_skb; + } if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) - goto exit_fail; + goto exit_free_skb; } if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false))) - goto exit_fail; + goto exit_free_skb; /* * Pausing queue has to be serialized with rt2x00lib_txdone(). Note @@ -164,10 +174,6 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, return; - exit_fail: - spin_lock(&queue->tx_lock); - rt2x00queue_pause_queue(queue); - spin_unlock(&queue->tx_lock); exit_free_skb: ieee80211_free_txskb(hw, skb); } -- cgit v1.2.3 From 0d9870ca5012400374c9789d91dcccb86508b63e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 26 Dec 2017 17:33:18 +0000 Subject: wl1251: check return from call to wl1251_acx_arp_ip_filter [ Upstream commit ac1181c60822292176ab96912208ec9f9819faf8 ] Currently the less than zero error check on ret is incorrect as it is checking a far earlier ret assignment rather than the return from the call to wl1251_acx_arp_ip_filter. Fix this by adding in the missing assginment. Detected by CoverityScan, CID#1164835 ("Logically dead code") Fixes: 204cc5c44fb6 ("wl1251: implement hardware ARP filtering") Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ti/wl1251/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 1c539c83e8cf..5e41bf04ef61 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -1200,8 +1200,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc; - wl1251_acx_arp_ip_filter(wl, enable, addr); - + ret = wl1251_acx_arp_ip_filter(wl, enable, addr); if (ret < 0) goto out_sleep; } -- cgit v1.2.3 From 9f47b01992e19560fcbc536d0010581dd9f17a9b Mon Sep 17 00:00:00 2001 From: Firo Yang Date: Fri, 26 May 2017 22:37:38 +0800 Subject: hdlcdrv: Fix divide by zero in hdlcdrv_ioctl [ Upstream commit fb3ce90b7d7761b6f7f28f0ff5c456ef6b5229a1 ] syszkaller fuzzer triggered a divide by zero, when set calibration through ioctl(). To fix it, test 'bitrate' if it is negative or 0, just return -EINVAL. Reported-by: Andrey Konovalov Signed-off-by: Firo Yang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/hamradio/hdlcdrv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 4bad0b894e9c..27160d1870e1 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -576,6 +576,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case HDLCDRVCTL_CALIBRATE: if(!capable(CAP_SYS_RAWIO)) return -EPERM; + if (s->par.bitrate <= 0) + return -EINVAL; if (bi.data.calibrate > INT_MAX / s->par.bitrate) return -EINVAL; s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16; -- cgit v1.2.3 From 3291bb532df5181352acfb492fc18b7110172670 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 9 May 2017 10:04:36 +0200 Subject: HID: i2c: Call acpi_device_fix_up_power for ACPI-enumerated devices [ Upstream commit f3d3eab667de62572376abb1aa26316191c39929 ] For ACPI devices which do not have a _PSC method, the ACPI subsys cannot query their initial state at boot, so these devices are assumed to have been put in D0 by the BIOS, but for touchscreens that is not always true. This commit adds a call to acpi_device_fix_up_power to explicitly put devices without a _PSC method into D0 state (for devices with a _PSC method it is a nop). Note we only need to do this on probe, after a resume the ACPI subsys knows the device is in D3 and will properly put it in D0. This fixes the SIS0817 i2c-hid touchscreen on a Peaq C1010 2-in-1 device failing to probe with a "hid_descr_cmd failed" error. Acked-by: Benjamin Tissoires Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 865e7c262322..7d6da9b43dab 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -968,6 +968,15 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, return ret < 0 && ret != -ENXIO ? ret : 0; } +static void i2c_hid_acpi_fix_up_power(struct device *dev) +{ + acpi_handle handle = ACPI_HANDLE(dev); + struct acpi_device *adev; + + if (handle && acpi_bus_get_device(handle, &adev) == 0) + acpi_device_fix_up_power(adev); +} + static const struct acpi_device_id i2c_hid_acpi_match[] = { {"ACPI0C50", 0 }, {"PNP0C50", 0 }, @@ -980,6 +989,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, { return -ENODEV; } + +static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} #endif #ifdef CONFIG_OF @@ -1082,6 +1093,8 @@ static int i2c_hid_probe(struct i2c_client *client, if (ret < 0) goto err; + i2c_hid_acpi_fix_up_power(&client->dev); + pm_runtime_get_noresume(&client->dev); pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); -- cgit v1.2.3 From 922841084a82f1356c0499a165319b780965f039 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 24 May 2017 12:09:53 +0530 Subject: dmaengine: imx-sdma: Handle return value of clk_prepare_enable [ Upstream commit fb9caf370f4d0457789d13a1a1b110a8db846e5e ] clk_prepare_enable() can fail here and we must check its return value. Signed-off-by: Arvind Yadav Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/dma/imx-sdma.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 21726a270fc4..b9c29720aeb1 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1755,19 +1755,26 @@ static int sdma_probe(struct platform_device *pdev) if (IS_ERR(sdma->clk_ahb)) return PTR_ERR(sdma->clk_ahb); - clk_prepare(sdma->clk_ipg); - clk_prepare(sdma->clk_ahb); + ret = clk_prepare(sdma->clk_ipg); + if (ret) + return ret; + + ret = clk_prepare(sdma->clk_ahb); + if (ret) + goto err_clk; ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma", sdma); if (ret) - return ret; + goto err_irq; sdma->irq = irq; sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); - if (!sdma->script_addrs) - return -ENOMEM; + if (!sdma->script_addrs) { + ret = -ENOMEM; + goto err_irq; + } /* initially no scripts available */ saddr_arr = (s32 *)sdma->script_addrs; @@ -1882,6 +1889,10 @@ err_register: dma_async_device_unregister(&sdma->dma_device); err_init: kfree(sdma->script_addrs); +err_irq: + clk_unprepare(sdma->clk_ahb); +err_clk: + clk_unprepare(sdma->clk_ipg); return ret; } @@ -1893,6 +1904,8 @@ static int sdma_remove(struct platform_device *pdev) devm_free_irq(&pdev->dev, sdma->irq, sdma); dma_async_device_unregister(&sdma->dma_device); kfree(sdma->script_addrs); + clk_unprepare(sdma->clk_ahb); + clk_unprepare(sdma->clk_ipg); /* Kill the tasklet */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct sdma_channel *sdmac = &sdma->channel[i]; -- cgit v1.2.3 From 6625fd2adc4b40418f072ac0e9a11c8f1f9ea141 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 17 May 2017 21:55:07 +0100 Subject: backlight: Report error on failure [ Upstream commit 7e715c2d9c27c23f3187454157c58cf292ed103e ] It is possible to update the backlight power and the brightness using the sysfs and on writing it either returns the count or if the callback function does not exist then returns the error code 'ENXIO'. We have a situation where the userspace client is writing to the sysfs to update the power and since the callback function exists the client receives the return value as count and considers the operation to be successful. That is correct as the write to the sysfs was successful. But there is no way to know if the actual operation was done or not. backlight_update_status() returns the error code if it fails. Pass that to the userspace client who is trying to update the power so that the client knows that the operation failed. Signed-off-by: Sudip Mukherjee Acked-by: Daniel Thompson Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/video/backlight/backlight.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 288318ad21dd..8049e7656daa 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -134,7 +134,7 @@ static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, { int rc; struct backlight_device *bd = to_backlight_device(dev); - unsigned long power; + unsigned long power, old_power; rc = kstrtoul(buf, 0, &power); if (rc) @@ -145,10 +145,16 @@ static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, if (bd->ops) { pr_debug("set power to %lu\n", power); if (bd->props.power != power) { + old_power = bd->props.power; bd->props.power = power; - backlight_update_status(bd); + rc = backlight_update_status(bd); + if (rc) + bd->props.power = old_power; + else + rc = count; + } else { + rc = count; } - rc = count; } mutex_unlock(&bd->ops_lock); @@ -176,8 +182,7 @@ int backlight_device_set_brightness(struct backlight_device *bd, else { pr_debug("set brightness to %lu\n", brightness); bd->props.brightness = brightness; - backlight_update_status(bd); - rc = 0; + rc = backlight_update_status(bd); } } mutex_unlock(&bd->ops_lock); -- cgit v1.2.3 From ecbd702dec3d9d096217b0125cbac66054bd1214 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 29 May 2017 15:00:17 +0200 Subject: net/mlx5: avoid build warning for uniprocessor [ Upstream commit f0d7ae95fff4ab444b8433f07afc4b077ef1a285 ] Building the driver with CONFIG_SMP disabled results in a harmless warning: ethernet/mellanox/mlx5/core/main.c: In function 'mlx5_irq_set_affinity_hint': ethernet/mellanox/mlx5/core/main.c:615:6: error: unused variable 'irq' [-Werror=unused-variable] It's better to express the conditional compilation using IS_ENABLED() here, as that lets the compiler see what the intented use for the variable is, and that it can be silently discarded. Fixes: b665d98edc9a ("net/mlx5: Tolerate irq_set_affinity_hint() failures") Signed-off-by: Arnd Bergmann Acked-by: Saeed Mahameed Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 935e62635f12..3c183b8c083a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -557,10 +557,9 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), priv->irq_info[i].mask); -#ifdef CONFIG_SMP - if (irq_set_affinity_hint(irq, priv->irq_info[i].mask)) + if (IS_ENABLED(CONFIG_SMP) && + irq_set_affinity_hint(irq, priv->irq_info[i].mask)) mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); -#endif return 0; } -- cgit v1.2.3 From 6cd7b51283df0615a223f527e0721be1058ae36e Mon Sep 17 00:00:00 2001 From: Arjun Vynipadath Date: Tue, 30 May 2017 18:06:06 +0530 Subject: cxgb4: FW upgrade fixes [ Upstream commit 26747211486c5bc7dd014c3caab206576e00c0d0 ] Disable FW_OK flag while flashing Firmware. This will help to fix any potential mailbox timeouts during Firmware flash. Grab new devlog parameters after Firmware restart. When we FLASH new Firmware onto an adapter, the new Firmware may have the Firmware Device Log located at a different memory address or have a different size for it. Signed-off-by: Arjun Vynipadath Signed-off-by: Casey Leedom Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 6fd3be69ff21..24d391899730 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -6185,13 +6185,18 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, if (!t4_fw_matches_chip(adap, fw_hdr)) return -EINVAL; + /* Disable FW_OK flag so that mbox commands with FW_OK flag set + * wont be sent when we are flashing FW. + */ + adap->flags &= ~FW_OK; + ret = t4_fw_halt(adap, mbox, force); if (ret < 0 && !force) - return ret; + goto out; ret = t4_load_fw(adap, fw_data, size); if (ret < 0) - return ret; + goto out; /* * Older versions of the firmware don't understand the new @@ -6202,7 +6207,17 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, * its header flags to see if it advertises the capability. */ reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0); - return t4_fw_restart(adap, mbox, reset); + ret = t4_fw_restart(adap, mbox, reset); + + /* Grab potentially new Firmware Device Log parameters so we can see + * how healthy the new Firmware is. It's okay to contact the new + * Firmware for these parameters even though, as far as it's + * concerned, we've never said "HELLO" to it ... + */ + (void)t4_init_devlog_params(adap); +out: + adap->flags |= FW_OK; + return ret; } /** -- cgit v1.2.3 From 489b11ae30afc7b1315559613b7d0abf7249dd4f Mon Sep 17 00:00:00 2001 From: Arjun Vynipadath Date: Tue, 30 May 2017 13:30:24 +0530 Subject: cxgb4: Fix netdev_features flag [ Upstream commit 90592b9a35836bacd34d92a3aba7958756b6a7c0 ] GRO is not supported by Chelsio HW when rx_csum is disabled. Update the netdev features flag when rx_csum is modified. Signed-off-by: Arjun Vynipadath Signed-off-by: Steve Wise Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 0c2a32a305bc..3ec32d7c5866 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2742,6 +2742,16 @@ static int cxgb_setup_tc(struct net_device *dev, u32 handle, __be16 proto, return -EOPNOTSUPP; } +static netdev_features_t cxgb_fix_features(struct net_device *dev, + netdev_features_t features) +{ + /* Disable GRO, if RX_CSUM is disabled */ + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_GRO; + + return features; +} + static const struct net_device_ops cxgb4_netdev_ops = { .ndo_open = cxgb_open, .ndo_stop = cxgb_close, @@ -2766,6 +2776,7 @@ static const struct net_device_ops cxgb4_netdev_ops = { #endif .ndo_set_tx_maxrate = cxgb_set_tx_maxrate, .ndo_setup_tc = cxgb_setup_tc, + .ndo_fix_features = cxgb_fix_features, }; #ifdef CONFIG_PCI_IOV -- cgit v1.2.3 From 2c90ca5c196b68b2b453d1b37cebda35d068ae89 Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Tue, 25 Apr 2017 16:45:15 +0200 Subject: rtc: m41t80: fix SQW dividers override when setting a date [ Upstream commit 0f546b058b86ea2f661cc7a6e931cee5a29959ef ] This patch is only relevant for RTC with the SQ_ALT feature which means the clock output frequency divider is stored in the weekday register. Current implementation discards the previous dividers value and clear them as soon as the time is set. Signed-off-by: Gary Bisson Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-m41t80.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 58698d21c2c3..c4ca6a385790 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -168,6 +168,7 @@ static int m41t80_get_datetime(struct i2c_client *client, /* Sets the given date and time to the real time clock. */ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) { + struct m41t80_data *clientdata = i2c_get_clientdata(client); unsigned char buf[8]; int err, flags; @@ -183,6 +184,17 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year - 100); buf[M41T80_REG_WDAY] = tm->tm_wday; + /* If the square wave output is controlled in the weekday register */ + if (clientdata->features & M41T80_FEATURE_SQ_ALT) { + int val; + + val = i2c_smbus_read_byte_data(client, M41T80_REG_WDAY); + if (val < 0) + return val; + + buf[M41T80_REG_WDAY] |= (val & 0xf0); + } + err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_SSEC, sizeof(buf), buf); if (err < 0) { -- cgit v1.2.3 From 3ac7598acbb6affbfe24dfca86a29626f268baaf Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 28 Apr 2017 16:53:16 -0700 Subject: i40evf: fix merge error in older patch [ Upstream commit 155b0f690051345deefc653774b739c786067d61 ] This patch fixes a missing line that was missed while merging, which results in a driver feature in the VF not working to enable RSS as a negotiated feature. Fixes: 43a3d9ba34c9c ("i40evf: Allow PF driver to configure RSS") Signed-off-by: Jesse Brandeburg Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index ddf478d6322b..614f93e01500 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -154,6 +154,7 @@ int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter) adapter->current_op = I40E_VIRTCHNL_OP_GET_VF_RESOURCES; adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG; caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 | + I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF | I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ | I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG | I40E_VIRTCHNL_VF_OFFLOAD_VLAN | -- cgit v1.2.3 From e1dcd000c8f4f8f1e294049d1bde596799cae83f Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Fri, 19 May 2017 15:35:09 +0530 Subject: rtc: opal: Handle disabled TPO in opal_get_tpo_time() [ Upstream commit 6dc1cf6f932bb0ea4d8f5e913a0a401ecacd2f03 ] On PowerNV platform when Timed-Power-On(TPO) is disabled, read of stored TPO yields value with all date components set to '0' inside opal_get_tpo_time(). The function opal_to_tm() then converts it to an offset from year 1900 yielding alarm-time == "1900-00-01 00:00:00". This causes problems with __rtc_read_alarm() that expecting an offset from "1970-00-01 00:00:00" and returned alarm-time results in a -ve value for time64_t. Which ultimately results in this error reported in kernel logs with a seemingly garbage value: "rtc rtc0: invalid alarm value: -2-1--1041528741 2005511117:71582844:32" We fix this by explicitly handling the case of all alarm date-time components being '0' inside opal_get_tpo_time() and returning -ENOENT in such a case. This signals generic rtc that no alarm is set and it bails out from the alarm initialization flow without reporting the above error. Signed-off-by: Vaibhav Jain Reported-by: Steve Best Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-opal.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index e4324dcf9508..aa53fceaa5e0 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -150,6 +150,16 @@ static int opal_get_tpo_time(struct device *dev, struct rtc_wkalrm *alarm) y_m_d = be32_to_cpu(__y_m_d); h_m_s_ms = ((u64)be32_to_cpu(__h_m) << 32); + + /* check if no alarm is set */ + if (y_m_d == 0 && h_m_s_ms == 0) { + pr_debug("No alarm is set\n"); + rc = -ENOENT; + goto exit; + } else { + pr_debug("Alarm set to %x %llx\n", y_m_d, h_m_s_ms); + } + opal_to_tm(y_m_d, h_m_s_ms, &alarm->time); exit: -- cgit v1.2.3 From d5cbc16656aee364a80af20a476d23bd11301225 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Fri, 19 May 2017 22:18:55 +0530 Subject: rtc: interface: Validate alarm-time before handling rollover [ Upstream commit da96aea0ed177105cb13ee83b328f6c61e061d3f ] In function __rtc_read_alarm() its possible for an alarm time-stamp to be invalid even after replacing missing components with current time-stamp. The condition 'alarm->time.tm_year < 70' will trigger this case and will cause the call to 'rtc_tm_to_time64(&alarm->time)' return a negative value for variable t_alm. While handling alarm rollover this negative t_alm (assumed to seconds offset from '1970-01-01 00:00:00') is converted back to rtc_time via rtc_time64_to_tm() which results in this error log with seemingly garbage values: "rtc rtc0: invalid alarm value: -2-1--1041528741 2005511117:71582844:32" This error was generated when the rtc driver (rtc-opal in this case) returned an alarm time-stamp of '00-00-00 00:00:00' to indicate that the alarm is disabled. Though I have submitted a separate fix for the rtc-opal driver, this issue may potentially impact other existing/future rtc drivers. To fix this issue the patch validates the alarm time-stamp just after filling up the missing datetime components and if rtc_valid_tm() still reports it to be invalid then bails out of the function without handling the rollover. Reported-by: Steve Best Signed-off-by: Vaibhav Jain Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/interface.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 6ebd42aad291..25cf3069e2e7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -227,6 +227,13 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) missing = year; } + /* Can't proceed if alarm is still invalid after replacing + * missing fields. + */ + err = rtc_valid_tm(&alarm->time); + if (err) + goto done; + /* with luck, no rollover is needed */ t_now = rtc_tm_to_time64(&now); t_alm = rtc_tm_to_time64(&alarm->time); @@ -278,9 +285,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) dev_warn(&rtc->dev, "alarm rollover not handled\n"); } -done: err = rtc_valid_tm(&alarm->time); +done: if (err) { dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", alarm->time.tm_year + 1900, alarm->time.tm_mon + 1, -- cgit v1.2.3 From 2630e187b92af7e59bbb2b9702bbc2ac42b59fec Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 30 May 2017 17:38:43 -0500 Subject: net: freescale: fix potential null pointer dereference [ Upstream commit 06d2d6431bc8d41ef5ffd8bd4b52cea9f72aed22 ] Add NULL check before dereferencing pointer _id_ in order to avoid a potential NULL pointer dereference. Addresses-Coverity-ID: 1397995 Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/fsl_pq_mdio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 446c7b374ff5..a10de1e9c157 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -381,7 +381,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) { const struct of_device_id *id = of_match_device(fsl_pq_mdio_match, &pdev->dev); - const struct fsl_pq_mdio_data *data = id->data; + const struct fsl_pq_mdio_data *data; struct device_node *np = pdev->dev.of_node; struct resource res; struct device_node *tbi; @@ -389,6 +389,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) struct mii_bus *new_bus; int err; + if (!id) { + dev_err(&pdev->dev, "Failed to match device\n"); + return -ENODEV; + } + + data = id->data; + dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible); new_bus = mdiobus_alloc_size(sizeof(*priv)); -- cgit v1.2.3 From 903ad1a90d3bda38028b2dc05af0e0e4814543f4 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 12 May 2017 16:25:30 +0200 Subject: clk: at91: fix clk-generated parenting [ Upstream commit 8e56133e5c7b7a7a97f6a92d92f664d5ecd30745 ] clk_generated_startup is called after clk_hw_register. So the first call to get_parent will not have the correct value (i.e. 0) and because this is cached, it may never be updated. Signed-off-by: Alexandre Belloni Fixes: df70aeef6083 ("clk: at91: add generated clock driver") Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/at91/clk-generated.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 4e1cd5aa69d8..70474bd97a10 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -260,13 +260,12 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, gck->lock = lock; gck->range = *range; + clk_generated_startup(gck); hw = &gck->hw; ret = clk_hw_register(NULL, &gck->hw); if (ret) { kfree(gck); hw = ERR_PTR(ret); - } else - clk_generated_startup(gck); return hw; } -- cgit v1.2.3 From 8d0c9ead6fd8d9a74c8743ab14b1ddc7c8072a49 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sat, 27 May 2017 18:09:32 +0200 Subject: drm/sun4i: Ignore the generic connectors for components [ Upstream commit 49baeb074783f5bdf770dc9fac5fbb2837190583 ] The generic connectors such as hdmi-connector doesn't have any driver in, so if they are added to the component list, we will be waiting forever for a non-existing driver to probe. Add a list of the connectors we want to ignore when building our component list. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/sun4i/sun4i_drv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 9e77fc034e0a..aad2f4a2a0ef 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -212,6 +212,11 @@ static const struct component_master_ops sun4i_drv_master_ops = { .unbind = sun4i_drv_unbind, }; +static bool sun4i_drv_node_is_connector(struct device_node *node) +{ + return of_device_is_compatible(node, "hdmi-connector"); +} + static bool sun4i_drv_node_is_frontend(struct device_node *node) { return of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || @@ -252,6 +257,13 @@ static int sun4i_drv_add_endpoints(struct device *dev, !of_device_is_available(node)) return 0; + /* + * The connectors will be the last nodes in our pipeline, we + * can just bail out. + */ + if (sun4i_drv_node_is_connector(node)) + return 0; + if (!sun4i_drv_node_is_frontend(node)) { /* Add current component */ DRM_DEBUG_DRIVER("Adding component %s\n", -- cgit v1.2.3 From 8bf4782062a0a0f6b9ca68f3f6625e1a5fe455fc Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 10 Apr 2017 10:35:17 +0200 Subject: mtd: nand: gpmi: Fix gpmi_nand_init() error path [ Upstream commit 4d02423e9afe6c46142ce98bbcaf5167316dbfbf ] The GPMI driver is wrongly assuming that nand_release() can safely be called on an uninitialized/unregistered NAND device. Add a new err_nand_cleanup label in the error path and only execute if nand_scan_tail() succeeded. Note that we now call nand_cleanup() instead of nand_release() (nand_release() is actually grouping the mtd_device_unregister() and nand_cleanup() in one call) because there's no point in trying to unregister a device that has never been registered. Signed-off-by: Boris Brezillon Reviewed-by: Marek Vasut Acked-by: Han Xu Reviewed-by: Marek Vasut Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 427039b77668..d9dab4275859 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -2047,18 +2047,20 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) ret = nand_boot_init(this); if (ret) - goto err_out; + goto err_nand_cleanup; ret = chip->scan_bbt(mtd); if (ret) - goto err_out; + goto err_nand_cleanup; ret = mtd_device_register(mtd, NULL, 0); if (ret) - goto err_out; + goto err_nand_cleanup; return 0; +err_nand_cleanup: + nand_cleanup(chip); err_out: - gpmi_nand_exit(this); + gpmi_free_dma_buffer(this); return ret; } -- cgit v1.2.3 From 2d0eb3f188e1de0fadaca05b413ea44c217fa7dd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 25 May 2017 13:50:20 +0900 Subject: mtd: nand: check ecc->total sanity in nand_scan_tail [ Upstream commit 79e0348c4e24fd1affdcf055e0269755580e0fcc ] Drivers are supposed to set correct ecc->{size,strength,bytes} before calling nand_scan_tail(), but it does not complain about ecc->total bigger than oobsize. In this case, chip->scan_bbt() crashes due to memory corruption, but it is hard to debug. It would be kind to fail it earlier with a clear message. Signed-off-by: Masahiro Yamada Signed-off-by: Boris Brezillon Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/nand_base.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a3e86e52640a..5fb45161789c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4785,6 +4785,11 @@ int nand_scan_tail(struct mtd_info *mtd) goto err_free; } ecc->total = ecc->steps * ecc->bytes; + if (ecc->total > mtd->oobsize) { + WARN(1, "Total number of ECC bytes exceeded oobsize\n"); + ret = -EINVAL; + goto err_free; + } /* * The number of bytes available for a client to place data into -- cgit v1.2.3 From 82a19094f113b8177e920a48a4bb4cd1054c3142 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 18 May 2017 17:19:28 +0100 Subject: clk: scpi: fix return type of __scpi_dvfs_round_rate [ Upstream commit 7374aec95636ca39409545eba4ef5ff3125c2346 ] The frequencies above the maximum value of signed integer(i.e. 2^31 -1) will overflow with the current code. This patch fixes the return type of __scpi_dvfs_round_rate from 'int' to 'unsigned long'. Fixes: cd52c2a4b5c4 ("clk: add support for clocks provided by SCP(System Control Processor)") Cc: Michael Turquette Cc: Stephen Boyd Signed-off-by: Sudeep Holla Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk-scpi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 96d37175d0ad..8ad458b5ad6e 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -71,15 +71,15 @@ static const struct clk_ops scpi_clk_ops = { }; /* find closest match to given frequency in OPP table */ -static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) +static long __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) { int idx; - u32 fmin = 0, fmax = ~0, ftmp; + unsigned long fmin = 0, fmax = ~0, ftmp; const struct scpi_opp *opp = clk->info->opps; for (idx = 0; idx < clk->info->count; idx++, opp++) { ftmp = opp->freq; - if (ftmp >= (u32)rate) { + if (ftmp >= rate) { if (ftmp <= fmax) fmax = ftmp; break; -- cgit v1.2.3 From df170185b8d393a047f95f1d2871192c3b414bf1 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Mon, 15 May 2017 11:58:59 +0100 Subject: clk: Fix __set_clk_rates error print-string [ Upstream commit ee177c5d6369f8e5d3e4793dce501cf4431313a1 ] When failing to set a clock the printout emitted is incorrect. "u32 rate" is formatted as %d and should be %u whereas "unsigned long clk_set_rate()" is formatted as %ld and should be %lu as per Documentation/printk-formats.txt. Fixes: 2885c3b2a3da ("clk: Show correct information when fail to set clock rate") Signed-off-by: Bryan O'Donoghue Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk-conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 674785d968a3..f02900922bbe 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -106,7 +106,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) rc = clk_set_rate(clk, rate); if (rc < 0) - pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n", + pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n", __clk_get_name(clk), rate, rc, clk_get_rate(clk)); clk_put(clk); -- cgit v1.2.3 From 00ceff917d1b5b945756579ba34482179f56ecf2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 14 Jun 2017 13:58:53 +0300 Subject: drm/amdkfd: NULL dereference involving create_process() [ Upstream commit b312b2b25b6ac9e2eb03f4ca651b33108752de3a ] We accidentally return ERR_PTR(0) which is NULL. The caller is not expecting that and it leads to an Oops. Fixes: dd59239a9862 ("amdkfd: init aperture once per process") Signed-off-by: Dan Carpenter Reviewed-by: Felix Kuehling Signed-off-by: Oded Gabbay Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ef7c8de7060e..171480bb95d0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -317,7 +317,8 @@ static struct kfd_process *create_process(const struct task_struct *thread) /* init process apertures*/ process->is_32bit_user_mode = in_compat_syscall(); - if (kfd_init_apertures(process) != 0) + err = kfd_init_apertures(process); + if (err != 0) goto err_init_apretures; return process; -- cgit v1.2.3 From a57608696560d40cfbc5d3aa486a4405e891b044 Mon Sep 17 00:00:00 2001 From: Anilkumar Kolli Date: Wed, 31 May 2017 14:21:27 +0300 Subject: ath10k: add BMI parameters to fix calibration from DT/pre-cal [ Upstream commit a9f5f287fa1d47d61dfa8b60f94831174b2ea4d0 ] QCA99X0, QCA9888, QCA9984 supports calibration data in either OTP or DT/pre-cal file. Current ath10k supports Calibration data from OTP only. If caldata is loaded from DT/pre-cal file, fetching board id and applying calibration parameters like tx power gets failed. error log: [ 15.733663] ath10k_pci 0000:01:00.0: failed to fetch board file: -2 [ 15.741474] ath10k_pci 0000:01:00.0: could not probe fw (-2) This patch adds calibration data support from DT/pre-cal file. Below parameters are used to get board id and applying calibration parameters from cal data. EEPROM[OTP] FLASH[DT/pre-cal file] Cal param 0x700 0x10000 Board id 0x10 0x8000 Tested on QCA9888 with pre-cal file. Signed-off-by: Anilkumar Kolli Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/bmi.h | 2 ++ drivers/net/wireless/ath/ath10k/core.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h index 7d3231acfb24..82bdec744055 100644 --- a/drivers/net/wireless/ath/ath10k/bmi.h +++ b/drivers/net/wireless/ath/ath10k/bmi.h @@ -83,6 +83,8 @@ enum bmi_cmd_id { #define BMI_NVRAM_SEG_NAME_SZ 16 #define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10 +#define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000 +#define BMI_PARAM_FLASH_SECTION_ALL 0x10000 #define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00 #define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10 diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 7b3017f55e3d..65ad7a130ca1 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -652,7 +652,7 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar) { u32 result, address; u8 board_id, chip_id; - int ret; + int ret, bmi_board_id_param; address = ar->hw_params.patch_load_addr; @@ -676,8 +676,13 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar) return ret; } - ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EEPROM_BOARD_ID, - &result); + if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || + ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE) + bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID; + else + bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID; + + ret = ath10k_bmi_execute(ar, address, bmi_board_id_param, &result); if (ret) { ath10k_err(ar, "could not execute otp for board id check: %d\n", ret); @@ -739,6 +744,11 @@ static int ath10k_download_and_run_otp(struct ath10k *ar) return ret; } + /* As of now pre-cal is valid for 10_4 variants */ + if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || + ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE) + bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL; + ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result); if (ret) { ath10k_err(ar, "could not execute otp (%d)\n", ret); -- cgit v1.2.3 From d78b198c02c4276ad93af106f7f38904bd45d6cb Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Thu, 1 Jun 2017 16:18:10 +0800 Subject: qlcnic: Fix a sleep-in-atomic bug in qlcnic_82xx_hw_write_wx_2M and qlcnic_82xx_hw_read_wx_2M [ Upstream commit 5ea6d691aac6c93b790f0905e3460d44cc4c449b ] The driver may sleep under a write spin lock, and the function call path is: qlcnic_82xx_hw_write_wx_2M (acquire the lock by write_lock_irqsave) crb_win_lock qlcnic_pcie_sem_lock usleep_range qlcnic_82xx_hw_read_wx_2M (acquire the lock by write_lock_irqsave) crb_win_lock qlcnic_pcie_sem_lock usleep_range To fix it, the usleep_range is replaced with udelay. Signed-off-by: Jia-Ju Bai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 509b596cf1e8..bd1ec70fb736 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) } return -EIO; } - usleep_range(1000, 1500); + udelay(1200); } if (id_reg) -- cgit v1.2.3 From 96770d43016bbb1f0491c2611f0a5e07092101f2 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Wed, 31 May 2017 15:08:25 +0800 Subject: mISDN: Fix a sleep-in-atomic bug [ Upstream commit 93818da5eed63fbc17b64080406ea53b86b23309 ] The driver may sleep under a read spin lock, and the function call path is: send_socklist (acquire the lock by read_lock) skb_copy(GFP_KERNEL) --> may sleep To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/mISDN/stack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index 9cb4b621fbc3..b92a19a594a1 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c @@ -72,7 +72,7 @@ send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb) if (sk->sk_state != MISDN_BOUND) continue; if (!cskb) - cskb = skb_copy(skb, GFP_KERNEL); + cskb = skb_copy(skb, GFP_ATOMIC); if (!cskb) { printk(KERN_WARNING "%s no skb\n", __func__); break; -- cgit v1.2.3 From d7ba3c00047dfd88fe0360a2d27169b54c88c4f1 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 31 May 2017 13:29:30 +0300 Subject: net: phy: micrel: Restore led_mode and clk_sel on resume [ Upstream commit 79e498a9c7da0737829ff864aae44df434105676 ] These bits seem to be lost after a suspend/resume cycle so just set them again. Do this by splitting the handling of these bits into a function that is also called on resume. This patch fixes ethernet suspend/resume on imx6ul-14x14-evk boards. Signed-off-by: Leonard Crestez Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/micrel.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2032a6de026b..4da73e2c37cf 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -268,23 +268,12 @@ out: return ret; } -static int kszphy_config_init(struct phy_device *phydev) +/* Some config bits need to be set again on resume, handle them here. */ +static int kszphy_config_reset(struct phy_device *phydev) { struct kszphy_priv *priv = phydev->priv; - const struct kszphy_type *type; int ret; - if (!priv) - return 0; - - type = priv->type; - - if (type->has_broadcast_disable) - kszphy_broadcast_disable(phydev); - - if (type->has_nand_tree_disable) - kszphy_nand_tree_disable(phydev); - if (priv->rmii_ref_clk_sel) { ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val); if (ret) { @@ -295,7 +284,7 @@ static int kszphy_config_init(struct phy_device *phydev) } if (priv->led_mode >= 0) - kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode); + kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode); if (phy_interrupt_is_valid(phydev)) { int ctl = phy_read(phydev, MII_BMCR); @@ -311,6 +300,25 @@ static int kszphy_config_init(struct phy_device *phydev) return 0; } +static int kszphy_config_init(struct phy_device *phydev) +{ + struct kszphy_priv *priv = phydev->priv; + const struct kszphy_type *type; + + if (!priv) + return 0; + + type = priv->type; + + if (type->has_broadcast_disable) + kszphy_broadcast_disable(phydev); + + if (type->has_nand_tree_disable) + kszphy_nand_tree_disable(phydev); + + return kszphy_config_reset(phydev); +} + static int ksz8041_config_init(struct phy_device *phydev) { struct device_node *of_node = phydev->mdio.dev.of_node; @@ -715,8 +723,14 @@ static int kszphy_suspend(struct phy_device *phydev) static int kszphy_resume(struct phy_device *phydev) { + int ret; + genphy_resume(phydev); + ret = kszphy_config_reset(phydev); + if (ret) + return ret; + /* Enable PHY Interrupts */ if (phy_interrupt_is_valid(phydev)) { phydev->interrupts = PHY_INTERRUPT_ENABLED; -- cgit v1.2.3 From 9d4aa135e44ecee5c295891aea97f86eb234ff77 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Mon, 15 May 2017 06:40:39 +0000 Subject: RDMA/iw_cxgb4: Avoid touch after free error in ARP failure handlers [ Upstream commit 1dad0ebeea1cd890b8892523f736916e245b0aef ] The patch 761e19a504af (RDMA/iw_cxgb4: Handle return value of c4iw_ofld_send() in abort_arp_failure()) from May 6, 2016 leads to the following static checker warning: drivers/infiniband/hw/cxgb4/cm.c:575 abort_arp_failure() warn: passing freed memory 'skb' Also fixes skb leak when l2t resolution fails Fixes: 761e19a504afa55 (RDMA/iw_cxgb4: Handle return value of c4iw_ofld_send() in abort_arp_failure()) Reported-by: Dan Carpenter Cc: Dan Carpenter Signed-off-by: Raju Rangoju Reviewed-by: Steve Wise Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/cxgb4/cm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 6512a555f7f8..dd18b74cd01d 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -488,6 +488,7 @@ static int _put_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); release_ep_resources(ep); + kfree_skb(skb); return 0; } @@ -498,6 +499,7 @@ static int _put_pass_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); c4iw_put_ep(&ep->parent_ep->com); release_ep_resources(ep); + kfree_skb(skb); return 0; } @@ -569,11 +571,13 @@ static void abort_arp_failure(void *handle, struct sk_buff *skb) PDBG("%s rdev %p\n", __func__, rdev); req->cmd = CPL_ABORT_NO_RST; + skb_get(skb); ret = c4iw_ofld_send(rdev, skb); if (ret) { __state_set(&ep->com, DEAD); queue_arp_failure_cpl(ep, skb, FAKE_CPL_PUT_EP_SAFE); - } + } else + kfree_skb(skb); } static int send_flowc(struct c4iw_ep *ep) -- cgit v1.2.3 From 4581de2bfa6f8aeb03cd7bd28a2a4d6246b67c51 Mon Sep 17 00:00:00 2001 From: "Steven L. Roberts" Date: Wed, 10 May 2017 10:54:12 -0500 Subject: RDMA/hfi1: fix array termination by appending NULL to attr array [ Upstream commit c4dd4b69f55abcc8dd079f8de55d9d8c2ddbefce ] This fixes a kernel panic when loading the hfi driver as a dynamic module. Signed-off-by: Steven L Roberts Reviewed-by: Leon Romanovsky Acked-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/hfi1/sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/hfi1/sysfs.c b/drivers/infiniband/hw/hfi1/sysfs.c index 919a5474e651..621b60ab74ee 100644 --- a/drivers/infiniband/hw/hfi1/sysfs.c +++ b/drivers/infiniband/hw/hfi1/sysfs.c @@ -196,7 +196,8 @@ static const struct sysfs_ops port_cc_sysfs_ops = { }; static struct attribute *port_cc_default_attributes[] = { - &cc_prescan_attr.attr + &cc_prescan_attr.attr, + NULL }; static struct kobj_type port_cc_ktype = { -- cgit v1.2.3 From 80c9698bd6a8f0385167c20eccd8d9dda25577a0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 18 May 2017 11:51:51 +0300 Subject: drm/omap: fix tiled buffer stride calculations [ Upstream commit cc8dd7661ccc2d8dc88921da8e6cc7c2fcdb0341 ] omap_gem uses page alignment for buffer stride. The related calculations are a bit off, though, as byte stride of 4096 gets aligned to 8192, instead of 4096. This patch changes the code to use DIV_ROUND_UP(), which fixes those calculations and makes them more readable. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/omapdrm/omap_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 505dee0db973..ca91651be3d4 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -195,7 +195,7 @@ static void evict_entry(struct drm_gem_object *obj, size_t size = PAGE_SIZE * n; loff_t off = mmap_offset(obj) + (entry->obj_pgoff << PAGE_SHIFT); - const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); + const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE); if (m > 1) { int i; @@ -442,7 +442,7 @@ static int fault_2d(struct drm_gem_object *obj, * into account in some of the math, so figure out virtual stride * in pages */ - const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); + const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE); /* We don't use vmf->pgoff since that has the fake offset: */ pgoff = ((unsigned long)vmf->virtual_address - -- cgit v1.2.3 From 6b3c6821f0ebb3153f05fe78f165ea000847270b Mon Sep 17 00:00:00 2001 From: Ganesh Goudar Date: Wed, 31 May 2017 19:10:21 +0530 Subject: cxgb4: fix incorrect cim_la output for T6 [ Upstream commit a97051f4553551d13e586ab3cb6ae13093a44a81 ] take care of UpDbgLaRdPtr[0-3] restriction for T6. Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 24d391899730..ebeeb3581b9c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -8088,7 +8088,16 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr) ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]); if (ret) break; - idx = (idx + 1) & UPDBGLARDPTR_M; + + /* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to + * identify the 32-bit portion of the full 312-bit data + */ + if (is_t6(adap->params.chip) && (idx & 0xf) >= 9) + idx = (idx & 0xff0) + 0x10; + else + idx++; + /* address can't exceed 0xfff */ + idx &= UPDBGLARDPTR_M; } restart: if (cfg & UPDBGLAEN_F) { -- cgit v1.2.3 From e8b356ae7876d4661aee3d307fc2dedd46aa1f42 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 31 May 2017 22:21:03 +0200 Subject: Fix serial console on SNI RM400 machines [ Upstream commit e279e6d98e0cf2c2fe008b3c29042b92f0e17b1d ] sccnxp driver doesn't get the correct uart clock rate, if CONFIG_HAVE_CLOCK is disabled. Correct usage of clk API to make it work with/without it. Fixes: 90efa75f7ab0 (serial: sccnxp: Using CLK API for getting UART clock) Suggested-by: Russell King - ARM Linux Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sccnxp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index fcf803ffad19..cdd2f942317c 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -884,14 +884,19 @@ static int sccnxp_probe(struct platform_device *pdev) clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { - if (PTR_ERR(clk) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; + ret = PTR_ERR(clk); + if (ret == -EPROBE_DEFER) goto err_out; - } + uartclk = 0; + } else { + clk_prepare_enable(clk); + uartclk = clk_get_rate(clk); + } + + if (!uartclk) { dev_notice(&pdev->dev, "Using default clock frequency\n"); uartclk = s->chip->freq_std; - } else - uartclk = clk_get_rate(clk); + } /* Check input frequency */ if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) { -- cgit v1.2.3 From 6083f1625b75a9c711ab14e95f581fc2bb8e3710 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 4 Jun 2017 04:16:25 +0200 Subject: macsec: check return value of skb_to_sgvec always [ Upstream commit cda7ea6903502af34015000e16be290a79f07638 ] Signed-off-by: Jason A. Donenfeld Cc: Sabrina Dubroca Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/macsec.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 2caac0c37059..365a48cfcbbf 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -742,7 +742,12 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, macsec_fill_iv(iv, secy->sci, pn); sg_init_table(sg, ret); - skb_to_sgvec(skb, sg, 0, skb->len); + ret = skb_to_sgvec(skb, sg, 0, skb->len); + if (unlikely(ret < 0)) { + macsec_txsa_put(tx_sa); + kfree_skb(skb); + return ERR_PTR(ret); + } if (tx_sc->encrypt) { int len = skb->len - macsec_hdr_len(sci_present) - @@ -949,7 +954,11 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, macsec_fill_iv(iv, sci, ntohl(hdr->packet_number)); sg_init_table(sg, ret); - skb_to_sgvec(skb, sg, 0, skb->len); + ret = skb_to_sgvec(skb, sg, 0, skb->len); + if (unlikely(ret < 0)) { + kfree_skb(skb); + return ERR_PTR(ret); + } if (hdr->tci_an & MACSEC_TCI_E) { /* confidentiality: ethernet + macsec header -- cgit v1.2.3 From eec6e0a4b168b26f99b91c58dc17f948deaa9d9f Mon Sep 17 00:00:00 2001 From: Talat Batheesh Date: Sun, 4 Jun 2017 14:30:07 +0300 Subject: net/mlx4: Fix the check in attaching steering rules [ Upstream commit 6dc06c08bef1c746ff8da33dab677cfbacdcad32 ] Our previous patch (cited below) introduced a regression for RAW Eth QPs. Fix it by checking if the QP number provided by user-space exists, hence allowing steering rules to be added for valid QPs only. Fixes: 89c557687a32 ("net/mlx4_en: Avoid adding steering rules with invalid ring") Reported-by: Or Gerlitz Signed-off-by: Talat Batheesh Signed-off-by: Tariq Toukan Acked-by: Or Gerlitz Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 5 ----- drivers/net/ethernet/mellanox/mlx4/mcg.c | 15 +++++++++++---- drivers/net/ethernet/mellanox/mlx4/qp.c | 13 +++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 674246b189c2..bdda17d2ea0f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1520,11 +1520,6 @@ static int mlx4_en_flow_replace(struct net_device *dev, qpn = priv->drop_qp.qpn; else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); - if (qpn < priv->rss_map.base_qpn || - qpn >= priv->rss_map.base_qpn + priv->rx_ring_num) { - en_warn(priv, "rxnfc: QP (0x%x) doesn't exist\n", qpn); - return -EINVAL; - } } else { if (cmd->fs.ring_cookie >= priv->rx_ring_num) { en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist\n", diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 1a670b681555..0710b3677464 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "mlx4.h" @@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *dev, if (IS_ERR(mailbox)) return PTR_ERR(mailbox); + if (!mlx4_qp_lookup(dev, rule->qpn)) { + mlx4_err_rule(dev, "QP doesn't exist\n", rule); + ret = -EINVAL; + goto out; + } + trans_rule_ctrl_to_hw(rule, mailbox->buf); size += sizeof(struct mlx4_net_trans_rule_hw_ctrl); list_for_each_entry(cur, &rule->list, list) { ret = parse_trans_rule(dev, cur, mailbox->buf + size); - if (ret < 0) { - mlx4_free_cmd_mailbox(dev, mailbox); - return ret; - } + if (ret < 0) + goto out; + size += ret; } @@ -1021,6 +1027,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev, } } +out: mlx4_free_cmd_mailbox(dev, mailbox); return ret; diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 6143113a7fef..99c8fc970f88 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -387,6 +387,19 @@ static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) __mlx4_qp_free_icm(dev, qpn); } +struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn) +{ + struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; + struct mlx4_qp *qp; + + spin_lock(&qp_table->lock); + + qp = __mlx4_qp_lookup(dev, qpn); + + spin_unlock(&qp_table->lock); + return qp; +} + int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp) { struct mlx4_priv *priv = mlx4_priv(dev); -- cgit v1.2.3 From 5366c5ff9e13d6362408e25ced761f3228de7b60 Mon Sep 17 00:00:00 2001 From: Ido Shamay Date: Mon, 5 Jun 2017 10:44:56 +0300 Subject: net/mlx4: Check if Granular QoS per VF has been enabled before updating QP qos_vport [ Upstream commit 269f9883fe254d109afdfc657875c456d6fabb08 ] The Granular QoS per VF feature must be enabled in FW before it can be used. Thus, the driver cannot modify a QP's qos_vport value (via the UPDATE_QP FW command) if the feature has not been enabled -- the FW returns an error if this is attempted. Fixes: 08068cd5683f ("net/mlx4: Added qos_vport QP configuration in VST mode") Signed-off-by: Ido Shamay Signed-off-by: Jack Morgenstein Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/qp.c | 6 ++++++ drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 16 +++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 99c8fc970f88..474ff36b9755 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -487,6 +487,12 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, } if (attr & MLX4_UPDATE_QP_QOS_VPORT) { + if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP)) { + mlx4_warn(dev, "Granular QoS per VF is not enabled\n"); + err = -EOPNOTSUPP; + goto out; + } + qp_mask |= 1ULL << MLX4_UPD_QP_MASK_QOS_VPP; cmd->qp_context.qos_vport = params->qos_vport; } diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1822382212ee..8fd1b1ab7d81 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -5214,6 +5214,13 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); } +static void update_qos_vpp(struct mlx4_update_qp_context *ctx, + struct mlx4_vf_immed_vlan_work *work) +{ + ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP); + ctx->qp_context.qos_vport = work->qos_vport; +} + void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) { struct mlx4_vf_immed_vlan_work *work = @@ -5328,11 +5335,10 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) qp->sched_queue & 0xC7; upd_context->qp_context.pri_path.sched_queue |= ((work->qos & 0x7) << 3); - upd_context->qp_mask |= - cpu_to_be64(1ULL << - MLX4_UPD_QP_MASK_QOS_VPP); - upd_context->qp_context.qos_vport = - work->qos_vport; + + if (dev->caps.flags2 & + MLX4_DEV_CAP_FLAG2_QOS_VPP) + update_qos_vpp(upd_context, work); } err = mlx4_cmd(dev, mailbox->dma, -- cgit v1.2.3 From fe587505e7d566982717493ddc95b935de81047c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 29 Mar 2017 10:21:09 +0300 Subject: iwlwifi: mvm: fix firmware debug restart recording [ Upstream commit addce854f164a68da9cb158e2e7e447705068549 ] When we want to stop the recording of the firmware debug and restart it later without reloading the firmware we don't need to resend the configuration that comes with host commands. Sending those commands confused the hardware and led to an NMI 0x66. Change the flow as following: * read the relevant registers (DBGC_IN_SAMPLE, DBGC_OUT_CTRL) * clear those registers * wait for the hardware to complete its write to the buffer * get the data * restore the value of those registers (to restart the recording) For early start (where the configuration is already compiled in the firmware), we don't need to set those registers after the firmware has been loaded, but only when we want to restart the recording without having restarted the firmware. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 12 +--------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 32 ++++++++++++++++++------- 4 files changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 406ef301b8ab..da8234b762bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -369,6 +369,7 @@ #define MON_DMARB_RD_DATA_ADDR (0xa03c5c) #define DBGC_IN_SAMPLE (0xa03c00) +#define DBGC_OUT_CTRL (0xa03c0c) /* enable the ID buf for read */ #define WFPM_PS_CTL_CLR 0xA0300C diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 700d244df34b..2642d8e477b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c @@ -914,14 +914,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, return 0; } -static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm) -{ - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) - iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); - else - iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1); -} - int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) { u8 *ptr; @@ -935,10 +927,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) /* EARLY START - firmware's configuration is hard coded */ if ((!mvm->fw->dbg_conf_tlv[conf_id] || !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) && - conf_id == FW_DBG_START_FROM_ALIVE) { - iwl_mvm_restart_early_start(mvm); + conf_id == FW_DBG_START_FROM_ALIVE) return 0; - } if (!mvm->fw->dbg_conf_tlv[conf_id]) return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index c60703e0c246..ed9bf8c759b4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1687,6 +1687,7 @@ void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) { mvm->ucode_loaded = false; + mvm->fw_dbg_conf = FW_DBG_INVALID; iwl_trans_stop_device(mvm->trans); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 4d35deb628bc..6d38eec3f9d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1118,21 +1118,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) mutex_lock(&mvm->mutex); - /* stop recording */ if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + /* stop recording */ iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); + + iwl_mvm_fw_error_dump(mvm); + + /* start recording again if the firmware is not crashed */ + if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) && + mvm->fw->dbg_dest_tlv) + iwl_clear_bits_prph(mvm->trans, + MON_BUFF_SAMPLE_CTL, 0x100); } else { + u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE); + u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL); + + /* stop recording */ iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); - /* wait before we collect the data till the DBGC stop */ udelay(100); - } + iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0); + /* wait before we collect the data till the DBGC stop */ + udelay(500); - iwl_mvm_fw_error_dump(mvm); + iwl_mvm_fw_error_dump(mvm); - /* start recording again if the firmware is not crashed */ - WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && - mvm->fw->dbg_dest_tlv && - iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); + /* start recording again if the firmware is not crashed */ + if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) && + mvm->fw->dbg_dest_tlv) { + iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample); + iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl); + } + } mutex_unlock(&mvm->mutex); -- cgit v1.2.3 From c3a1c5ab6ccef80768c445bc583d0b94248cda78 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Mon, 17 Apr 2017 22:37:05 +0200 Subject: watchdog: f71808e_wdt: Add F71868 support [ Upstream commit 166fbcf88fdafa02f784ec25ac64745c716b2de0 ] This adds support for watchdog part of Fintek F71868 Super I/O chip to f71808e_wdt driver. The F71868 chip is, in general, very similar to a F71869, however it has slightly different set of available reset pulse widths. Tested on MSI A55M-P33 motherboard. Signed-off-by: Maciej S. Szmigiero Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/Kconfig | 7 ++++--- drivers/watchdog/f71808e_wdt.c | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3eb58cb51e56..8f8909a668d7 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -799,11 +799,12 @@ config EBC_C384_WDT the timeout module parameter. config F71808E_WDT - tristate "Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Watchdog" + tristate "Fintek F718xx, F818xx Super I/O Watchdog" depends on X86 help - This is the driver for the hardware watchdog on the Fintek - F71808E, F71862FG, F71869, F71882FG and F71889FG Super I/O controllers. + This is the driver for the hardware watchdog on the Fintek F71808E, + F71862FG, F71868, F71869, F71882FG, F71889FG, F81865 and F81866 + Super I/O controllers. You can compile this driver directly into the kernel, or use it as a module. The module will be called f71808e_wdt. diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 1b7e9169072f..8658dba21768 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -57,6 +57,7 @@ #define SIO_F71808_ID 0x0901 /* Chipset ID */ #define SIO_F71858_ID 0x0507 /* Chipset ID */ #define SIO_F71862_ID 0x0601 /* Chipset ID */ +#define SIO_F71868_ID 0x1106 /* Chipset ID */ #define SIO_F71869_ID 0x0814 /* Chipset ID */ #define SIO_F71869A_ID 0x1007 /* Chipset ID */ #define SIO_F71882_ID 0x0541 /* Chipset ID */ @@ -101,7 +102,7 @@ MODULE_PARM_DESC(timeout, static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH; module_param(pulse_width, uint, 0); MODULE_PARM_DESC(pulse_width, - "Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms" + "Watchdog signal pulse width. 0(=level), 1, 25, 30, 125, 150, 5000 or 6000 ms" " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")"); static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN; @@ -119,13 +120,14 @@ module_param(start_withtimeout, uint, 0); MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with" " given initial timeout. Zero (default) disables this feature."); -enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg, f81865, - f81866}; +enum chips { f71808fg, f71858fg, f71862fg, f71868, f71869, f71882fg, f71889fg, + f81865, f81866}; static const char *f71808e_names[] = { "f71808fg", "f71858fg", "f71862fg", + "f71868", "f71869", "f71882fg", "f71889fg", @@ -252,16 +254,23 @@ static int watchdog_set_timeout(int timeout) static int watchdog_set_pulse_width(unsigned int pw) { int err = 0; + unsigned int t1 = 25, t2 = 125, t3 = 5000; + + if (watchdog.type == f71868) { + t1 = 30; + t2 = 150; + t3 = 6000; + } mutex_lock(&watchdog.lock); - if (pw <= 1) { + if (pw <= 1) { watchdog.pulse_val = 0; - } else if (pw <= 25) { + } else if (pw <= t1) { watchdog.pulse_val = 1; - } else if (pw <= 125) { + } else if (pw <= t2) { watchdog.pulse_val = 2; - } else if (pw <= 5000) { + } else if (pw <= t3) { watchdog.pulse_val = 3; } else { pr_err("pulse width out of range\n"); @@ -354,6 +363,7 @@ static int watchdog_start(void) goto exit_superio; break; + case f71868: case f71869: /* GPIO14 --> WDTRST# */ superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 4); @@ -792,6 +802,9 @@ static int __init f71808e_find(int sioaddr) watchdog.type = f71862fg; err = f71862fg_pin_configure(0); /* validate module parameter */ break; + case SIO_F71868_ID: + watchdog.type = f71868; + break; case SIO_F71869_ID: case SIO_F71869A_ID: watchdog.type = f71869; -- cgit v1.2.3 From 6dc9a4b33b355c4bddb994b0abf1982a798ea1f4 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Thu, 16 Mar 2017 17:26:03 +0200 Subject: iwlwifi: mvm: Fix command queue number on d0i3 flow [ Upstream commit c72c37b7f392ad7edc10b6092fa48c632ba6f4ed ] During d0i3 flow we flush all the queue except from the command queue. Currently, in this flow the command queue is hard coded to 9. In DQA the command queue number has changed from 9 to 0. Fix that. This fixes a problem in runtime PM resume flow. Fixes: 097129c9e625 ("iwlwifi: mvm: move cmd queue to be #0 in dqa mode") Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ed9bf8c759b4..2b1c691bb4b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1666,8 +1666,11 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq); */ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) { + u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE : + IWL_MVM_CMD_QUEUE; + return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) & - ~BIT(IWL_MVM_CMD_QUEUE)); + ~BIT(cmd_queue)); } static inline -- cgit v1.2.3 From 87a9c569fea9d88a5a47064a9fb6720707010114 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Mar 2017 22:00:10 +0100 Subject: iwlwifi: tt: move ucode_loaded check under mutex [ Upstream commit d9954405758a0cbbe258d9b4d4dc12a06fa48a28 ] The ucode_loaded check should be under the mutex, since it can otherwise change state after we looked at it and before we got the mutex. Fix that. Fixes: 5c89e7bc557e ("iwlwifi: mvm: add registration to cooling device") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index bec7d9c46087..c5203568a47a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -790,11 +790,13 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev, struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata); int ret; - if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) - return -EIO; - mutex_lock(&mvm->mutex); + if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) { + ret = -EIO; + goto unlock; + } + if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) { ret = -EINVAL; goto unlock; -- cgit v1.2.3 From 9345b98879420bde44fa448ad8d9d04e47d18835 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 24 Mar 2017 11:01:45 +0200 Subject: iwlwifi: pcie: only use d0i3 in suspend/resume if system_pm is set to d0i3 [ Upstream commit e4c49c4937951de1cdbe35572ade40c948dec1e1 ] We only need to handle d0i3 entry and exit during suspend resume if system_pm is set to IWL_PLAT_PM_MODE_D0I3, otherwise d0i3 entry failures will cause suspend to fail. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=194791 Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 10ef44e8ecd5..fe32de252e6b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2824,7 +2824,8 @@ static struct iwl_trans_dump_data #ifdef CONFIG_PM_SLEEP static int iwl_trans_pcie_suspend(struct iwl_trans *trans) { - if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3) + if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && + (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) return iwl_pci_fw_enter_d0i3(trans); return 0; @@ -2832,7 +2833,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) static void iwl_trans_pcie_resume(struct iwl_trans *trans) { - if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3) + if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && + (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) iwl_pci_fw_exit_d0i3(trans); } #endif /* CONFIG_PM_SLEEP */ -- cgit v1.2.3 From 9d85c2a32c413be3e37b39337a927a8872ebb4a5 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 25 Apr 2017 10:18:10 +0300 Subject: iwlwifi: fix min API version for 7265D, 3168, 8000 and 8265 [ Upstream commit 15098803d38778070b8edfa5a3d5fc4fef10d0a1 ] In a previous commit, we removed support for API versions earlier than 22 for these NICs. By mistake, the *_UCODE_API_MIN definitions were set to 17. Fix that. Fixes: 4b87e5af638b ("iwlwifi: remove support for fw older than -17 and -22") Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/iwl-7000.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/iwl-8000.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c index d4b73dedf89b..b35adbca7a5d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c @@ -79,8 +79,8 @@ /* Lowest firmware API version supported */ #define IWL7260_UCODE_API_MIN 17 #define IWL7265_UCODE_API_MIN 17 -#define IWL7265D_UCODE_API_MIN 17 -#define IWL3168_UCODE_API_MIN 20 +#define IWL7265D_UCODE_API_MIN 22 +#define IWL3168_UCODE_API_MIN 22 /* NVM versions */ #define IWL7260_NVM_VERSION 0x0a1d diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index 8d3e53fac1da..20d08ddb4388 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c @@ -74,8 +74,8 @@ #define IWL8265_UCODE_API_MAX 26 /* Lowest firmware API version supported */ -#define IWL8000_UCODE_API_MIN 17 -#define IWL8265_UCODE_API_MIN 20 +#define IWL8000_UCODE_API_MIN 22 +#define IWL8265_UCODE_API_MIN 22 /* NVM versions */ #define IWL8000_NVM_VERSION 0x0a1d -- cgit v1.2.3 From 5b81fa9664ca252010ddfcffb7d61bde3642c966 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Wed, 3 May 2017 10:28:50 -0700 Subject: e1000e: fix race condition around skb_tstamp_tx() [ Upstream commit 5012863b7347866764c4a4e58b62fb05346b0d06 ] The e1000e driver and related hardware has a limitation on Tx PTP packets which requires we limit to timestamping a single packet at once. We do this by verifying that we never request a new Tx timestamp while we still have a tx_hwtstamp_skb pointer. Unfortunately the driver suffers from a race condition around this. The tx_hwtstamp_skb pointer is not set to NULL until after skb_tstamp_tx() is called. This function notifies the stack and applications of a new timestamp. Even a well behaved application that only sends a new request when the first one is finished might be woken up and possibly send a packet before we can free the timestamp in the driver again. The result is that we needlessly ignore some Tx timestamp requests in this corner case. Fix this by assigning the tx_hwtstamp_skb pointer prior to calling skb_tstamp_tx() and use a temporary pointer to hold the timestamped skb until that function finishes. This ensures that the application is not woken up until the driver is ready to begin timestamping a new packet. This ensures that well behaved applications do not accidentally race with condition to skip Tx timestamps. Obviously an application which sends multiple Tx timestamp requests at once will still only timestamp one packet at a time. Unfortunately there is nothing we can do about this. Reported-by: David Mirabito Signed-off-by: Jacob Keller Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000e/netdev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 528a926dd979..64a0c61435c7 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1182,6 +1182,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work) struct e1000_hw *hw = &adapter->hw; if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) { + struct sk_buff *skb = adapter->tx_hwtstamp_skb; struct skb_shared_hwtstamps shhwtstamps; u64 txstmp; @@ -1190,9 +1191,14 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work) e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp); - skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps); - dev_kfree_skb_any(adapter->tx_hwtstamp_skb); + /* Clear the global tx_hwtstamp_skb pointer and force writes + * prior to notifying the stack of a Tx timestamp. + */ adapter->tx_hwtstamp_skb = NULL; + wmb(); /* force write prior to skb_tstamp_tx */ + + skb_tstamp_tx(skb, &shhwtstamps); + dev_kfree_skb_any(skb); } else if (time_after(jiffies, adapter->tx_hwtstamp_start + adapter->tx_timeout_factor * HZ)) { dev_kfree_skb_any(adapter->tx_hwtstamp_skb); -- cgit v1.2.3 From f07ce2798efa11713d032513096f1912f2b1916f Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Wed, 3 May 2017 10:28:52 -0700 Subject: igb: fix race condition with PTP_TX_IN_PROGRESS bits [ Upstream commit 4ccdc013b0ae04755a8f7905e0525955d52a77d0 ] Hardware related to the igb driver has a limitation of only handling one Tx timestamp at a time. Thus, the driver uses a state bit lock to enforce that only one timestamp request is honored at a time. Unfortunately this suffers from a simple race condition. The bit lock is not cleared until after skb_tstamp_tx() is called notifying the stack of a new Tx timestamp. Even a well behaved application which sends only one timestamp request at once and waits for a response might wake up and send a new packet before the bit lock is cleared. This results in needlessly dropping some Tx timestamp requests. We can fix this by unlocking the state bit as soon as we read the Timestamp register, as this is the first point at which it is safe to unlock. To avoid issues with the skb pointer, we'll use a copy of the pointer and set the global variable in the driver structure to NULL first. This ensures that the next timestamp request does not modify our local copy of the skb pointer. This ensures that well behaved applications do not accidentally race with the unlock bit. Obviously an application which sends multiple Tx timestamp requests at once will still only timestamp one packet at a time. Unfortunately there is nothing we can do about this. Reported-by: David Mirabito Signed-off-by: Jacob Keller Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/igb/igb_ptp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index a7895c4cbcc3..9eb9b68f8935 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -721,6 +721,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter) **/ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) { + struct sk_buff *skb = adapter->ptp_tx_skb; struct e1000_hw *hw = &adapter->hw; struct skb_shared_hwtstamps shhwtstamps; u64 regval; @@ -748,10 +749,17 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) shhwtstamps.hwtstamp = ktime_add_ns(shhwtstamps.hwtstamp, adjust); - skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps); - dev_kfree_skb_any(adapter->ptp_tx_skb); + /* Clear the lock early before calling skb_tstamp_tx so that + * applications are not woken up before the lock bit is clear. We use + * a copy of the skb pointer to ensure other threads can't change it + * while we're notifying the stack. + */ adapter->ptp_tx_skb = NULL; clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); + + /* Notify the stack and free the skb after we've unlocked */ + skb_tstamp_tx(skb, &shhwtstamps); + dev_kfree_skb_any(skb); } /** -- cgit v1.2.3 From 20c29d92ce653c216e1adb892bcb04846871d537 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 5 May 2017 08:34:58 +0300 Subject: cxl: Unlock on error in probe [ Upstream commit 58d876fa7181f2f393190c1d32c056b5a9d34aa2 ] We should unlock if get_cxl_adapter() fails. Fixes: 594ff7d067ca ("cxl: Support to flash a new image on the adapter from a guest") Signed-off-by: Dan Carpenter Acked-by: Frederic Barrat Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cxl/flash.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cxl/flash.c b/drivers/misc/cxl/flash.c index c63d61e17d56..381a9a166f93 100644 --- a/drivers/misc/cxl/flash.c +++ b/drivers/misc/cxl/flash.c @@ -401,8 +401,10 @@ static int device_open(struct inode *inode, struct file *file) if (down_interruptible(&sem) != 0) return -EPERM; - if (!(adapter = get_cxl_adapter(adapter_num))) - return -ENODEV; + if (!(adapter = get_cxl_adapter(adapter_num))) { + rc = -ENODEV; + goto err_unlock; + } file->private_data = adapter; continue_token = 0; @@ -446,6 +448,8 @@ err1: free_page((unsigned long) le); err: put_device(&adapter->dev); +err_unlock: + up(&sem); return rc; } -- cgit v1.2.3 From 7c484e3bcf10c9a83e78fe77fc3d4d0b8074b12c Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 23 Apr 2017 10:06:36 -0300 Subject: cx25840: fix unchecked return values [ Upstream commit 35378ce143071c2a6bad4b59a000e9b9f8f6ea67 ] In functions cx25840_initialize(), cx231xx_initialize(), and cx23885_initialize(), the return value of create_singlethread_workqueue() is used without validation. This may result in NULL dereference and cause kernel crash. This patch fixes it. Signed-off-by: Pan Bian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/cx25840/cx25840-core.c | 36 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 142ae28803bb..d558ed3e59c6 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -420,11 +420,13 @@ static void cx25840_initialize(struct i2c_client *client) INIT_WORK(&state->fw_work, cx25840_work_handler); init_waitqueue_head(&state->fw_wait); q = create_singlethread_workqueue("cx25840_fw"); - prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); - queue_work(q, &state->fw_work); - schedule(); - finish_wait(&state->fw_wait, &wait); - destroy_workqueue(q); + if (q) { + prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); + queue_work(q, &state->fw_work); + schedule(); + finish_wait(&state->fw_wait, &wait); + destroy_workqueue(q); + } /* 6. */ cx25840_write(client, 0x115, 0x8c); @@ -634,11 +636,13 @@ static void cx23885_initialize(struct i2c_client *client) INIT_WORK(&state->fw_work, cx25840_work_handler); init_waitqueue_head(&state->fw_wait); q = create_singlethread_workqueue("cx25840_fw"); - prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); - queue_work(q, &state->fw_work); - schedule(); - finish_wait(&state->fw_wait, &wait); - destroy_workqueue(q); + if (q) { + prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); + queue_work(q, &state->fw_work); + schedule(); + finish_wait(&state->fw_wait, &wait); + destroy_workqueue(q); + } /* Call the cx23888 specific std setup func, we no longer rely on * the generic cx24840 func. @@ -752,11 +756,13 @@ static void cx231xx_initialize(struct i2c_client *client) INIT_WORK(&state->fw_work, cx25840_work_handler); init_waitqueue_head(&state->fw_wait); q = create_singlethread_workqueue("cx25840_fw"); - prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); - queue_work(q, &state->fw_work); - schedule(); - finish_wait(&state->fw_wait, &wait); - destroy_workqueue(q); + if (q) { + prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); + queue_work(q, &state->fw_work); + schedule(); + finish_wait(&state->fw_wait, &wait); + destroy_workqueue(q); + } cx25840_std_setup(client); -- cgit v1.2.3 From 085da766de30ca002dc226fb9d90f58b58e73312 Mon Sep 17 00:00:00 2001 From: A Sun Date: Sun, 26 Mar 2017 15:33:07 -0300 Subject: mceusb: sporadic RX truncation corruption fix [ Upstream commit 8e175b22e8640bf3a58e071af54190b909e4a944 ] Intermittent RX truncation and loss of IR received data. This resulted in receive stream synchronization errors where driver attempted to incorrectly parse IR data (eg 0x90 below) as command response. [ 3969.139898] mceusb 1-1.2:1.0: processed IR data [ 3969.151315] mceusb 1-1.2:1.0: rx data: 00 90 (length=2) [ 3969.151321] mceusb 1-1.2:1.0: Unknown command 0x00 0x90 [ 3969.151336] mceusb 1-1.2:1.0: rx data: 98 0a 8d 0a 8e 0a 8e 0a 8e 0a 8e 0a 9a 0a 8e 0a 0b 3a 8e 00 80 41 59 00 00 (length=25) [ 3969.151341] mceusb 1-1.2:1.0: Raw IR data, 24 pulse/space samples [ 3969.151348] mceusb 1-1.2:1.0: Storing space with duration 500000 Bug trigger appears to be normal, but heavy, IR receiver use. Signed-off-by: A Sun Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/rc/mceusb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index db525cdfac88..d9f88a4a96bd 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1381,8 +1381,13 @@ static int mceusb_dev_probe(struct usb_interface *intf, goto rc_dev_fail; /* wire up inbound data handler */ - usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, - mceusb_dev_recv, ir, ep_in->bInterval); + if (usb_endpoint_xfer_int(ep_in)) + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, + mceusb_dev_recv, ir, ep_in->bInterval); + else + usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, + mceusb_dev_recv, ir); + ir->urb_in->transfer_dma = ir->dma_in; ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -- cgit v1.2.3 From e9399672360e6ecdcb6a9ebfe88e156922d1694c Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 5 Jun 2017 12:22:55 +0100 Subject: net: phy: avoid genphy_aneg_done() for PHYs without clause 22 support [ Upstream commit 41408ad519f7a2a1c5229e61f2a97f4df1b61adc ] Avoid calling genphy_aneg_done() for PHYs that do not implement the Clause 22 register set. Clause 45 PHYs may implement the Clause 22 register set along with the Clause 22 extension MMD. Hence, we can't simply block access to the Clause 22 functions based on the PHY being a Clause 45 PHY. Signed-off-by: Russell King Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/phy.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e2d9ca60e467..4d217649c8b1 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -148,6 +148,12 @@ static inline int phy_aneg_done(struct phy_device *phydev) if (phydev->drv->aneg_done) return phydev->drv->aneg_done(phydev); + /* Avoid genphy_aneg_done() if the Clause 45 PHY does not + * implement Clause 22 registers + */ + if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) + return -EINVAL; + return genphy_aneg_done(phydev); } -- cgit v1.2.3 From 383f15ee34fb21137a6486162132f79fc049cb3e Mon Sep 17 00:00:00 2001 From: Rakesh Pandit Date: Mon, 5 Jun 2017 14:43:11 +0300 Subject: nvme-pci: fix multiple ctrl removal scheduling [ Upstream commit 82b057caefaff2a891f821a617d939f46e03e844 ] Commit c5f6ce97c1210 tries to address multiple resets but fails as work_busy doesn't involve any synchronization and can fail. This is reproducible easily as can be seen by WARNING below which is triggered with line: WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING) Allowing multiple resets can result in multiple controller removal as well if different conditions inside nvme_reset_work fail and which might deadlock on device_release_driver. [ 480.327007] WARNING: CPU: 3 PID: 150 at drivers/nvme/host/pci.c:1900 nvme_reset_work+0x36c/0xec0 [ 480.327008] Modules linked in: rfcomm fuse nf_conntrack_netbios_ns nf_conntrack_broadcast... [ 480.327044] btusb videobuf2_core ghash_clmulni_intel snd_hwdep cfg80211 acer_wmi hci_uart.. [ 480.327065] CPU: 3 PID: 150 Comm: kworker/u16:2 Not tainted 4.12.0-rc1+ #13 [ 480.327065] Hardware name: Acer Predator G9-591/Mustang_SLS, BIOS V1.10 03/03/2016 [ 480.327066] Workqueue: nvme nvme_reset_work [ 480.327067] task: ffff880498ad8000 task.stack: ffffc90002218000 [ 480.327068] RIP: 0010:nvme_reset_work+0x36c/0xec0 [ 480.327069] RSP: 0018:ffffc9000221bdb8 EFLAGS: 00010246 [ 480.327070] RAX: 0000000000460000 RBX: ffff880498a98128 RCX: dead000000000200 [ 480.327070] RDX: 0000000000000001 RSI: ffff8804b1028020 RDI: ffff880498a98128 [ 480.327071] RBP: ffffc9000221be50 R08: 0000000000000000 R09: 0000000000000000 [ 480.327071] R10: ffffc90001963ce8 R11: 000000000000020d R12: ffff880498a98000 [ 480.327072] R13: ffff880498a53500 R14: ffff880498a98130 R15: ffff880498a98128 [ 480.327072] FS: 0000000000000000(0000) GS:ffff8804c1cc0000(0000) knlGS:0000000000000000 [ 480.327073] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 480.327074] CR2: 00007ffcf3c37f78 CR3: 0000000001e09000 CR4: 00000000003406e0 [ 480.327074] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 480.327075] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 480.327075] Call Trace: [ 480.327079] ? __switch_to+0x227/0x400 [ 480.327081] process_one_work+0x18c/0x3a0 [ 480.327082] worker_thread+0x4e/0x3b0 [ 480.327084] kthread+0x109/0x140 [ 480.327085] ? process_one_work+0x3a0/0x3a0 [ 480.327087] ? kthread_park+0x60/0x60 [ 480.327102] ret_from_fork+0x2c/0x40 [ 480.327103] Code: e8 5a dc ff ff 85 c0 41 89 c1 0f..... This patch addresses the problem by using state of controller to decide whether reset should be queued or not as state change is synchronizated using controller spinlock. Also cancel_work_sync is used to make sure remove cancels the reset_work and waits for it to finish. This patch also changes return value from -ENODEV to more appropriate -EBUSY if nvme_reset fails to change state. Fixes: c5f6ce97c1210 ("nvme: don't schedule multiple resets") Signed-off-by: Rakesh Pandit Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/pci.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index e48ecb9303ca..8cc856ecec95 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1263,7 +1263,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO); /* If there is a reset ongoing, we shouldn't reset again. */ - if (work_busy(&dev->reset_work)) + if (dev->ctrl.state == NVME_CTRL_RESETTING) return false; /* We shouldn't reset unless the controller is on fatal error state @@ -1755,7 +1755,7 @@ static void nvme_reset_work(struct work_struct *work) struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work); int result = -ENODEV; - if (WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING)) + if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) goto out; /* @@ -1765,9 +1765,6 @@ static void nvme_reset_work(struct work_struct *work) if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) nvme_dev_disable(dev, false); - if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) - goto out; - result = nvme_pci_enable(dev); if (result) goto out; @@ -1841,8 +1838,8 @@ static int nvme_reset(struct nvme_dev *dev) { if (!dev->ctrl.admin_q || blk_queue_dying(dev->ctrl.admin_q)) return -ENODEV; - if (work_busy(&dev->reset_work)) - return -ENODEV; + if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) + return -EBUSY; if (!queue_work(nvme_workq, &dev->reset_work)) return -EBUSY; return 0; @@ -1944,6 +1941,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (result) goto release_pools; + nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING); dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); queue_work(nvme_workq, &dev->reset_work); @@ -1987,6 +1985,7 @@ static void nvme_remove(struct pci_dev *pdev) nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); + cancel_work_sync(&dev->reset_work); pci_set_drvdata(pdev, NULL); if (!pci_device_is_present(pdev)) { -- cgit v1.2.3 From 4aae4388165a2611fa4206363ccb243c1622446c Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 2 Jun 2017 16:32:08 +0800 Subject: nvme: fix hang in remove path [ Upstream commit 82654b6b8ef8b93ee87a97fc562f87f081fc2f91 ] We need to start admin queues too in nvme_kill_queues() for avoiding hang in remove path[1]. This patch is very similar with 806f026f9b901eaf(nvme: use blk_mq_start_hw_queues() in nvme_kill_queues()). [1] hang stack trace [] blk_execute_rq+0x56/0x80 [] __nvme_submit_sync_cmd+0x89/0xf0 [] nvme_set_features+0x5e/0x90 [] nvme_configure_apst+0x166/0x200 [] nvme_set_latency_tolerance+0x35/0x50 [] apply_constraint+0xb1/0xc0 [] dev_pm_qos_constraints_destroy+0xf4/0x1f0 [] dpm_sysfs_remove+0x2a/0x60 [] device_del+0x101/0x320 [] device_unregister+0x1a/0x60 [] device_destroy+0x3c/0x50 [] nvme_uninit_ctrl+0x45/0xa0 [] nvme_remove+0x78/0x110 [] pci_device_remove+0x39/0xb0 [] device_release_driver_internal+0x155/0x210 [] device_release_driver+0x12/0x20 [] nvme_remove_dead_ctrl_work+0x6b/0x70 [] process_one_work+0x18c/0x3a0 [] worker_thread+0x4e/0x3b0 [] kthread+0x109/0x140 [] ret_from_fork+0x2c/0x40 [] 0xffffffffffffffff Fixes: c5552fde102fc("nvme: Enable autonomous power state transitions") Reported-by: Rakesh Pandit Tested-by: Rakesh Pandit Reviewed-by: Sagi Grimberg Signed-off-by: Ming Lei Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ad9d82eb2aed..c823e9346389 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2040,6 +2040,10 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl) struct nvme_ns *ns; mutex_lock(&ctrl->namespaces_mutex); + + /* Forcibly start all queues to avoid having stuck requests */ + blk_mq_start_hw_queues(ctrl->admin_q); + list_for_each_entry(ns, &ctrl->namespaces, list) { /* * Revalidating a dead namespace sets capacity to 0. This will -- cgit v1.2.3 From d54421849563260d8344a5f60190188822214cda Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 31 May 2017 18:50:43 +0300 Subject: e1000e: Undo e1000e_pm_freeze if __e1000_shutdown fails [ Upstream commit 833521ebc65b1c3092e5c0d8a97092f98eec595d ] An error during suspend (e100e_pm_suspend), [ 429.994338] ACPI : EC: event blocked [ 429.994633] e1000e: EEE TX LPI TIMER: 00000011 [ 430.955451] pci_pm_suspend(): e1000e_pm_suspend+0x0/0x30 [e1000e] returns -2 [ 430.955454] dpm_run_callback(): pci_pm_suspend+0x0/0x140 returns -2 [ 430.955458] PM: Device 0000:00:19.0 failed to suspend async: error -2 [ 430.955581] PM: Some devices failed to suspend, or early wake event detected [ 430.957709] ACPI : EC: event unblocked lead to complete failure: [ 432.585002] ------------[ cut here ]------------ [ 432.585013] WARNING: CPU: 3 PID: 8372 at kernel/irq/manage.c:1478 __free_irq+0x9f/0x280 [ 432.585015] Trying to free already-free IRQ 20 [ 432.585016] Modules linked in: cdc_ncm usbnet x86_pkg_temp_thermal intel_powerclamp coretemp mii crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep lpc_ich snd_hda_core snd_pcm mei_me mei sdhci_pci sdhci i915 mmc_core e1000e ptp pps_core prime_numbers [ 432.585042] CPU: 3 PID: 8372 Comm: kworker/u16:40 Tainted: G U 4.10.0-rc8-CI-Patchwork_3870+ #1 [ 432.585044] Hardware name: LENOVO 2356GCG/2356GCG, BIOS G7ET31WW (1.13 ) 07/02/2012 [ 432.585050] Workqueue: events_unbound async_run_entry_fn [ 432.585051] Call Trace: [ 432.585058] dump_stack+0x67/0x92 [ 432.585062] __warn+0xc6/0xe0 [ 432.585065] warn_slowpath_fmt+0x4a/0x50 [ 432.585070] ? _raw_spin_lock_irqsave+0x49/0x60 [ 432.585072] __free_irq+0x9f/0x280 [ 432.585075] free_irq+0x34/0x80 [ 432.585089] e1000_free_irq+0x65/0x70 [e1000e] [ 432.585098] e1000e_pm_freeze+0x7a/0xb0 [e1000e] [ 432.585106] e1000e_pm_suspend+0x21/0x30 [e1000e] [ 432.585113] pci_pm_suspend+0x71/0x140 [ 432.585118] dpm_run_callback+0x6f/0x330 [ 432.585122] ? pci_pm_freeze+0xe0/0xe0 [ 432.585125] __device_suspend+0xea/0x330 [ 432.585128] async_suspend+0x1a/0x90 [ 432.585132] async_run_entry_fn+0x34/0x160 [ 432.585137] process_one_work+0x1f4/0x6d0 [ 432.585140] ? process_one_work+0x16e/0x6d0 [ 432.585143] worker_thread+0x49/0x4a0 [ 432.585145] kthread+0x107/0x140 [ 432.585148] ? process_one_work+0x6d0/0x6d0 [ 432.585150] ? kthread_create_on_node+0x40/0x40 [ 432.585154] ret_from_fork+0x2e/0x40 [ 432.585156] ---[ end trace 6712df7f8c4b9124 ]--- The unwind failures stems from commit 2800209994f8 ("e1000e: Refactor PM flows"), but it may be a later patch that introduced the non-recoverable behaviour. Fixes: 2800209994f8 ("e1000e: Refactor PM flows") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99847 Signed-off-by: Chris Wilson Signed-off-by: Jani Nikula Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000e/netdev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 64a0c61435c7..825ec8f710e7 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6651,12 +6651,17 @@ static int e1000e_pm_thaw(struct device *dev) static int e1000e_pm_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + int rc; e1000e_flush_lpic(pdev); e1000e_pm_freeze(dev); - return __e1000_shutdown(pdev, false); + rc = __e1000_shutdown(pdev, false); + if (rc) + e1000e_pm_thaw(dev); + + return rc; } static int e1000e_pm_resume(struct device *dev) -- cgit v1.2.3 From 7f736f0e9ba38705eaf8e36a622a4b47218c14ae Mon Sep 17 00:00:00 2001 From: James Wang Date: Thu, 8 Jun 2017 14:52:51 +0800 Subject: Fix loop device flush before configure v3 [ Upstream commit 6460495709aeb651896bc8e5c134b2e4ca7d34a8 ] While installing SLES-12 (based on v4.4), I found that the installer will stall for 60+ seconds during LVM disk scan. The root cause was determined to be the removal of a bound device check in loop_flush() by commit b5dd2f6047ca ("block: loop: improve performance via blk-mq"). Restoring this check, examining ->lo_state as set by loop_set_fd() eliminates the bad behavior. Test method: modprobe loop max_loop=64 dd if=/dev/zero of=disk bs=512 count=200K for((i=0;i<4;i++))do losetup -f disk; done mkfs.ext4 -F /dev/loop0 for((i=0;i<4;i++))do mkdir t$i; mount /dev/loop$i t$i;done for f in `ls /dev/loop[0-9]*|sort`; do \ echo $f; dd if=$f of=/dev/null bs=512 count=1; \ done Test output: stock patched /dev/loop0 18.1217e-05 8.3842e-05 /dev/loop1 6.1114e-05 0.000147979 /dev/loop10 0.414701 0.000116564 /dev/loop11 0.7474 6.7942e-05 /dev/loop12 0.747986 8.9082e-05 /dev/loop13 0.746532 7.4799e-05 /dev/loop14 0.480041 9.3926e-05 /dev/loop15 1.26453 7.2522e-05 Note that from loop10 onward, the device is not mounted, yet the stock kernel consumes several orders of magnitude more wall time than it does for a mounted device. (Thanks for Mike Galbraith , give a changelog review.) Reviewed-by: Hannes Reinecke Reviewed-by: Ming Lei Signed-off-by: James Wang Fixes: b5dd2f6047ca ("block: loop: improve performance via blk-mq") Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 68bfcef24701..dc318b9100c2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -612,6 +612,9 @@ static int loop_switch(struct loop_device *lo, struct file *file) */ static int loop_flush(struct loop_device *lo) { + /* loop not yet configured, no running thread, nothing to flush */ + if (lo->lo_state != Lo_bound) + return 0; return loop_switch(lo, NULL); } -- cgit v1.2.3 From b3ec3723a42fcaf998e128fd3768ce815e1ff398 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 7 Jun 2017 15:51:15 +0200 Subject: net: emac: fix reset timeout with AR8035 phy [ Upstream commit 19d90ece81da802207a9b91ce95a29fbdc40626e ] This patch fixes a problem where the AR8035 PHY can't be detected on an Cisco Meraki MR24, if the ethernet cable is not connected on boot. Russell Senior provided steps to reproduce the issue: |Disconnect ethernet cable, apply power, wait until device has booted, |plug in ethernet, check for interfaces, no eth0 is listed. | |This appears to be a problem during probing of the AR8035 Phy chip. |When ethernet has no link, the phy detection fails, and eth0 is not |created. Plugging ethernet later has no effect, because there is no |interface as far as the kernel is concerned. The relevant part of |the boot log looks like this: |this is the failing case: | |[ 0.876611] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode |[ 0.882532] /plb/opb/ethernet@ef600c00: reset timeout |[ 0.888546] /plb/opb/ethernet@ef600c00: can't find PHY! |and the succeeding case: | |[ 0.876672] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode |[ 0.883952] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 00:01:.. |[ 0.890822] eth0: found Atheros 8035 Gigabit Ethernet PHY (0x01) Based on the comment and the commit message of commit 23fbb5a87c56 ("emac: Fix EMAC soft reset on 460EX/GT"). This is because the AR8035 PHY doesn't provide the TX Clock, if the ethernet cable is not attached. This causes the reset to timeout and the PHY detection code in emac_init_phy() is unable to detect the AR8035 PHY. As a result, the emac driver bails out early and the user left with no ethernet. In order to stay compatible with existing configurations, the driver tries the current reset approach at first. Only if the first attempt timed out, it does perform one more retry with the clock temporarily switched to the internal source for just the duration of the reset. LEDE-Bug: #687 Cc: Chris Blake Reported-by: Russell Senior Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT") Signed-off-by: Christian Lamparter Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ibm/emac/core.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 8f139197f1aa..5977b695d0fa 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -342,6 +342,7 @@ static int emac_reset(struct emac_instance *dev) { struct emac_regs __iomem *p = dev->emacp; int n = 20; + bool __maybe_unused try_internal_clock = false; DBG(dev, "reset" NL); @@ -354,6 +355,7 @@ static int emac_reset(struct emac_instance *dev) } #ifdef CONFIG_PPC_DCR_NATIVE +do_retry: /* * PPC460EX/GT Embedded Processor Advanced User's Manual * section 28.10.1 Mode Register 0 (EMACx_MR0) states: @@ -361,10 +363,19 @@ static int emac_reset(struct emac_instance *dev) * of the EMAC. If none is present, select the internal clock * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1). * After a soft reset, select the external clock. + * + * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the + * ethernet cable is not attached. This causes the reset to timeout + * and the PHY detection code in emac_init_phy() is unable to + * communicate and detect the AR8035-A PHY. As a result, the emac + * driver bails out early and the user has no ethernet. + * In order to stay compatible with existing configurations, the + * driver will temporarily switch to the internal clock, after + * the first reset fails. */ if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { - if (dev->phy_address == 0xffffffff && - dev->phy_map == 0xffffffff) { + if (try_internal_clock || (dev->phy_address == 0xffffffff && + dev->phy_map == 0xffffffff)) { /* No PHY: select internal loop clock before reset */ dcri_clrset(SDR0, SDR0_ETH_CFG, 0, SDR0_ETH_CFG_ECS << dev->cell_index); @@ -382,8 +393,15 @@ static int emac_reset(struct emac_instance *dev) #ifdef CONFIG_PPC_DCR_NATIVE if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { - if (dev->phy_address == 0xffffffff && - dev->phy_map == 0xffffffff) { + if (!n && !try_internal_clock) { + /* first attempt has timed out. */ + n = 20; + try_internal_clock = true; + goto do_retry; + } + + if (try_internal_clock || (dev->phy_address == 0xffffffff && + dev->phy_map == 0xffffffff)) { /* No PHY: restore external clock source after reset */ dcri_clrset(SDR0, SDR0_ETH_CFG, SDR0_ETH_CFG_ECS << dev->cell_index, 0); -- cgit v1.2.3 From 577438f5774154305c80a5f5a4a66cd7c4a2ca39 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 7 Jun 2017 07:44:20 +0200 Subject: pinctrl: meson-gxbb: remove non-existing pin GPIOX_22 [ Upstream commit 4c8127cb523982e0a474ad80b14b665dc2f37b3b ] After commit 34e61801a3b9 "pinctrl: meson-gxbb: Add missing GPIODV_18 pin entry" I started to get the following warning: "meson-pinctrl c8834000.periphs:pinctrl@4b0: names 119 do not match number of GPIOs 120" It turned out that not the mentioned commit has a problem, it just revealed another problem which had existed before. There is no PIN GPIOX_22 on Meson GXBB. Fixes: 468c234f9ed7 ("pinctrl: amlogic: Add support for Amlogic Meson GXBB SoC") Signed-off-by: Heiner Kallweit Reviewed-by: Neil Armstrong Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index 7511723c6b05..257c1c2e5888 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -138,7 +138,6 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = { MESON_PIN(GPIOX_19, EE_OFF), MESON_PIN(GPIOX_20, EE_OFF), MESON_PIN(GPIOX_21, EE_OFF), - MESON_PIN(GPIOX_22, EE_OFF), MESON_PIN(GPIOCLK_0, EE_OFF), MESON_PIN(GPIOCLK_1, EE_OFF), -- cgit v1.2.3 From 41830b8672a801adb74486d37fee4c35c9ca42b2 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 5 Jun 2017 14:15:03 -0600 Subject: coresight: Fix reference count for software sources [ Upstream commit 022aa1a81b778789ee7cf3124595854276a0330d ] For software sources (i.e STM), there could be multiple agents generating the trace data, unlike the ETMs. So we need to properly do the accounting for the active number of users to disable the device when the last user goes away. Right now, the reference counting is broken for sources as we skip the actions when we detect that the source is enabled. This patch fixes the problem by adding the refcounting for software sources, even when they are enabled. Cc: Mathieu Poirier Reported-by: Robert Walker Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 7bf00a0beb6f..4383324ec01c 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -498,6 +498,9 @@ int coresight_enable(struct coresight_device *csdev) { int cpu, ret = 0; struct list_head *path; + enum coresight_dev_subtype_source subtype; + + subtype = csdev->subtype.source_subtype; mutex_lock(&coresight_mutex); @@ -505,8 +508,16 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto out; - if (csdev->enable) + if (csdev->enable) { + /* + * There could be multiple applications driving the software + * source. So keep the refcount for each such user when the + * source is already enabled. + */ + if (subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) + atomic_inc(csdev->refcnt); goto out; + } path = coresight_build_path(csdev); if (IS_ERR(path)) { @@ -523,7 +534,7 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto err_source; - switch (csdev->subtype.source_subtype) { + switch (subtype) { case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: /* * When working from sysFS it is important to keep track -- cgit v1.2.3 From 9606743ca7f8f45b0e589e5ff8dd93a3e49dcdd1 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 5 Jun 2017 14:15:09 -0600 Subject: coresight: tmc: Configure DMA mask appropriately [ Upstream commit a3959c50b02f57df4c4e4f14f632220f1c0b1f79 ] Before making any DMA API calls, the ETR driver should really be setting its masks to ensure that DMA is possible. Especially since it can address more than the 32-bit default mask set by the AMBA bus code. Signed-off-by: Robin Murphy Tested-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index d8517d2a968c..864488793f09 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -362,6 +362,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etr_cs_ops; + /* + * ETR configuration uses a 40-bit AXI master in place of + * the embedded SRAM of ETB/ETF. + */ + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); + if (ret) + goto out; } else { desc.type = CORESIGHT_DEV_TYPE_LINKSINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; -- cgit v1.2.3 From 3f7b3c7a792c8d74bcdf6dfca0189c9d2065508f Mon Sep 17 00:00:00 2001 From: Mario Molitor Date: Thu, 8 Jun 2017 22:41:02 +0200 Subject: stmmac: fix ptp header for GMAC3 hw timestamp [ Upstream commit fd6720aefde06eacf17404eed2cad65c6ec103e1 ] According the CYCLON V documention only the bit 16 of snaptypesel should set. (more information see Table 17-20 (cv_5v4.pdf) : Timestamp Snapshot Dependency on Register Bits) Fixes: d2042052a0aa ("stmmac: update the PTP header file") Signed-off-by: Mario Molitor Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 15 ++++++++++++--- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 98bbb91336e4..c212d1dd8bfd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -478,7 +478,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) /* PTP v1, UDP, any kind of event packet */ config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -510,7 +513,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -544,7 +550,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h index c06938c47af5..174777cd888e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h @@ -63,7 +63,8 @@ /* Enable Snapshot for Messages Relevant to Master */ #define PTP_TCR_TSMSTRENA BIT(15) /* Select PTP packets for Taking Snapshots */ -#define PTP_TCR_SNAPTYPSEL_1 GENMASK(17, 16) +#define PTP_TCR_SNAPTYPSEL_1 BIT(16) +#define PTP_GMAC4_TCR_SNAPTYPSEL_1 GENMASK(17, 16) /* Enable MAC address for PTP Frame Filtering */ #define PTP_TCR_TSENMACADDR BIT(18) -- cgit v1.2.3 From fb96822d6c4d5c3e252dbf687ad2f7d6d8b0ef8b Mon Sep 17 00:00:00 2001 From: Girish Moodalbail Date: Thu, 8 Jun 2017 17:07:48 -0700 Subject: geneve: add missing rx stats accounting [ Upstream commit fe741e2362f33bbea813bcc3a921de356c6653db ] There are few places on the receive path where packet drops and packet errors were not accounted for. This patch fixes that issue. Signed-off-by: Girish Moodalbail Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/geneve.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 3c1f89ab0110..92ad43e53c72 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -209,6 +209,7 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, struct genevehdr *gnvh = geneve_hdr(skb); struct metadata_dst *tun_dst = NULL; struct pcpu_sw_netstats *stats; + unsigned int len; int err = 0; void *oiph; @@ -222,8 +223,10 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, tun_dst = udp_tun_rx_dst(skb, geneve_get_sk_family(gs), flags, vni_to_tunnel_id(gnvh->vni), gnvh->opt_len * 4); - if (!tun_dst) + if (!tun_dst) { + geneve->dev->stats.rx_dropped++; goto drop; + } /* Update tunnel dst according to Geneve options. */ ip_tunnel_info_opts_set(&tun_dst->u.tun_info, gnvh->options, gnvh->opt_len * 4); @@ -231,8 +234,11 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, /* Drop packets w/ critical options, * since we don't support any... */ - if (gnvh->critical) + if (gnvh->critical) { + geneve->dev->stats.rx_frame_errors++; + geneve->dev->stats.rx_errors++; goto drop; + } } skb_reset_mac_header(skb); @@ -243,8 +249,10 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, skb_dst_set(skb, &tun_dst->dst); /* Ignore packet loops (and multicast echo) */ - if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) + if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) { + geneve->dev->stats.rx_errors++; goto drop; + } oiph = skb_network_header(skb); skb_reset_network_header(skb); @@ -276,13 +284,15 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, } } - stats = this_cpu_ptr(geneve->dev->tstats); - u64_stats_update_begin(&stats->syncp); - stats->rx_packets++; - stats->rx_bytes += skb->len; - u64_stats_update_end(&stats->syncp); - - gro_cells_receive(&geneve->gro_cells, skb); + len = skb->len; + err = gro_cells_receive(&geneve->gro_cells, skb); + if (likely(err == NET_RX_SUCCESS)) { + stats = this_cpu_ptr(geneve->dev->tstats); + u64_stats_update_begin(&stats->syncp); + stats->rx_packets++; + stats->rx_bytes += len; + u64_stats_update_end(&stats->syncp); + } return; drop: /* Consume bad packet */ @@ -332,7 +342,7 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb) struct geneve_sock *gs; int opts_len; - /* Need Geneve and inner Ethernet header to be present */ + /* Need UDP and Geneve header to be present */ if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN))) goto drop; @@ -355,8 +365,10 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb) opts_len = geneveh->opt_len * 4; if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, htons(ETH_P_TEB), - !net_eq(geneve->net, dev_net(geneve->dev)))) + !net_eq(geneve->net, dev_net(geneve->dev)))) { + geneve->dev->stats.rx_dropped++; goto drop; + } geneve_rx(geneve, gs, skb); return 0; -- cgit v1.2.3 From c0fe1e29a59f436c10b9ed05df52ab650a9f3727 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 24 May 2017 10:35:32 +0300 Subject: crypto: omap-sham - buffer handling fixes for hashing later [ Upstream commit 5d78d57ede8f9e7f656c610ed25be7be337e0529 ] Currently, the hash later code only handles the cases when we have either new data coming in with the request or old data in the buffer, but not the combination when we have both. Fix this by changing the ordering of the code a bit and handling both cases properly simultaneously if needed. Also, fix an issue with omap_sham_update that surfaces with this fix, so that the code checks the bufcnt instead of total data amount against buffer length to avoid any buffer overflows. Signed-off-by: Tero Kristo Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/omap-sham.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index d0b16e5e4ee5..c65b49baf0c7 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -873,14 +873,21 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update) } if (hash_later) { - if (req->nbytes) { - scatterwalk_map_and_copy(rctx->buffer, req->src, - req->nbytes - hash_later, - hash_later, 0); - } else { + int offset = 0; + + if (hash_later > req->nbytes) { memcpy(rctx->buffer, rctx->buffer + xmit_len, - hash_later); + hash_later - req->nbytes); + offset = hash_later - req->nbytes; } + + if (req->nbytes) { + scatterwalk_map_and_copy(rctx->buffer + offset, + req->src, + offset + req->nbytes - + hash_later, hash_later, 0); + } + rctx->bufcnt = hash_later; } else { rctx->bufcnt = 0; @@ -1189,11 +1196,10 @@ static int omap_sham_update(struct ahash_request *req) if (!req->nbytes) return 0; - if (ctx->total + req->nbytes < ctx->buflen) { + if (ctx->bufcnt + req->nbytes <= ctx->buflen) { scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, req->src, 0, req->nbytes, 0); ctx->bufcnt += req->nbytes; - ctx->total += req->nbytes; return 0; } -- cgit v1.2.3 From 1fb08363c85da3c3c3c0acb53d7809ca2c72bede Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 24 May 2017 10:35:33 +0300 Subject: crypto: omap-sham - fix closing of hash with separate finalize call [ Upstream commit 898d86a565925f09de3d0b30cf3b47ec2e409680 ] Currently there is an interesting corner case failure with omap-sham driver, if the finalize call is done separately with no data, but all previous data has already been processed. In this case, it is not possible to close the hash with the hardware without providing any data, so we get incorrect results. Fix this by adjusting the size of data sent to the hardware crypto engine in case the non-final data size falls on the block size boundary, by reducing the amount of data sent by one full block. This makes it sure that we always have some data available for the finalize call and we can close the hash properly. Signed-off-by: Tero Kristo Reported-by: Aparna Balasubramanian Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/omap-sham.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index c65b49baf0c7..d8305ddf87d0 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -750,7 +750,10 @@ static int omap_sham_align_sgs(struct scatterlist *sg, if (final) new_len = DIV_ROUND_UP(new_len, bs) * bs; else - new_len = new_len / bs * bs; + new_len = (new_len - 1) / bs * bs; + + if (nbytes != new_len) + list_ok = false; while (nbytes > 0 && sg_tmp) { n++; @@ -846,6 +849,8 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update) xmit_len = DIV_ROUND_UP(xmit_len, bs) * bs; else xmit_len = xmit_len / bs * bs; + } else if (!final) { + xmit_len -= bs; } hash_later = rctx->total - xmit_len; @@ -1137,7 +1142,7 @@ retry: ctx = ahash_request_ctx(req); err = omap_sham_prepare_request(req, ctx->op == OP_UPDATE); - if (err) + if (err || !ctx->total) goto err1; dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n", -- cgit v1.2.3 From 5c27f6464438761af16038180e37d1b92986f29a Mon Sep 17 00:00:00 2001 From: "Mintz, Yuval" Date: Fri, 9 Jun 2017 17:17:01 +0300 Subject: bnx2x: Allow vfs to disable txvlan offload [ Upstream commit 92f85f05caa51d844af6ea14ffbc7a786446a644 ] VF clients are configured as enforced, meaning firmware is validating the correctness of their ethertype/vid during transmission. Once txvlan is disabled, VF would start getting SKBs for transmission here vlan is on the payload - but it'll pass the packet's ethertype instead of the vid, leading to firmware declaring it as malicious. Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index ca6c4718000f..31287cec6e3a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3887,15 +3887,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* when transmitting in a vf, start bd must hold the ethertype * for fw to enforce it */ + u16 vlan_tci = 0; #ifndef BNX2X_STOP_ON_ERROR - if (IS_VF(bp)) + if (IS_VF(bp)) { #endif - tx_start_bd->vlan_or_ethertype = - cpu_to_le16(ntohs(eth->h_proto)); + /* Still need to consider inband vlan for enforced */ + if (__vlan_get_tag(skb, &vlan_tci)) { + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(ntohs(eth->h_proto)); + } else { + tx_start_bd->bd_flags.as_bitfield |= + (X_ETH_INBAND_VLAN << + ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(vlan_tci); + } #ifndef BNX2X_STOP_ON_ERROR - else + } else { /* used by FW for packet accounting */ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); + } #endif } -- cgit v1.2.3 From aabd70361a7ff2546d00f32d83a96713b33ad4ad Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 9 Jun 2017 22:37:22 -0300 Subject: net: fec: Add a fec_enet_clear_ethtool_stats() stub for CONFIG_M5272 [ Upstream commit bf292f1b2c813f1d6ac49b04bd1a9863d8314266 ] Commit 2b30842b23b9 ("net: fec: Clear and enable MIB counters on imx51") introduced fec_enet_clear_ethtool_stats(), but missed to add a stub for the CONFIG_M5272=y case, causing build failure for the m5272c3_defconfig. Add the missing empty stub to fix the build failure. Reported-by: Paul Gortmaker Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/fec_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 05e5b38e4891..fe00f71bc6b4 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2371,6 +2371,10 @@ static int fec_enet_get_sset_count(struct net_device *dev, int sset) static inline void fec_enet_update_ethtool_stats(struct net_device *dev) { } + +static inline void fec_enet_clear_ethtool_stats(struct net_device *dev) +{ +} #endif /* !defined(CONFIG_M5272) */ static int fec_enet_nway_reset(struct net_device *dev) -- cgit v1.2.3 From c613f7c06b9ad259cf66fb14bdc8f7442dfeea85 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 6 Jun 2017 22:51:24 +0200 Subject: iio: magnetometer: st_magn_spi: fix spi_device_id table [ Upstream commit c83761ff0aac954aa368c623bb0f0d1a3214e834 ] Remove LSM303DLHC, LSM303DLM from st_magn_id_table since LSM303DL series does not support spi interface Fixes: 872e79add756 (iio: magn: Add STMicroelectronics magn driver) Signed-off-by: Lorenzo Bianconi Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/magnetometer/st_magn_spi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index 6325e7dc8e03..f3cb4dc05391 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -48,8 +48,6 @@ static int st_magn_spi_remove(struct spi_device *spi) } static const struct spi_device_id st_magn_id_table[] = { - { LSM303DLHC_MAGN_DEV_NAME }, - { LSM303DLM_MAGN_DEV_NAME }, { LIS3MDL_MAGN_DEV_NAME }, { LSM303AGR_MAGN_DEV_NAME }, {}, -- cgit v1.2.3 From 61e01f1db6dadcfd56b32fb879bcad01f691f064 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Sun, 11 Jun 2017 15:42:43 +0300 Subject: net: ena: fix rare uncompleted admin command false alarm [ Upstream commit a77c1aafcc906f657d1a0890c1d898be9ee1d5c9 ] The current flow to detect admin completion is: while (command_not_completed) { if (timeout) error check_for_completion() sleep() } So in case the sleep took more than the timeout (in case the thread/workqueue was not scheduled due to higher priority task or prolonged VMexit), the driver can detect a stall even if the completion is present. The fix changes the order of this function to first check for completion and only after that check if the timeout expired. Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amazon/ena/ena_com.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index e2512ab41168..564b556baba9 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status) static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx, struct ena_com_admin_queue *admin_queue) { - unsigned long flags; - u32 start_time; + unsigned long flags, timeout; int ret; - start_time = ((u32)jiffies_to_usecs(jiffies)); + timeout = jiffies + ADMIN_CMD_TIMEOUT_US; + + while (1) { + spin_lock_irqsave(&admin_queue->q_lock, flags); + ena_com_handle_admin_completion(admin_queue); + spin_unlock_irqrestore(&admin_queue->q_lock, flags); - while (comp_ctx->status == ENA_CMD_SUBMITTED) { - if ((((u32)jiffies_to_usecs(jiffies)) - start_time) > - ADMIN_CMD_TIMEOUT_US) { + if (comp_ctx->status != ENA_CMD_SUBMITTED) + break; + + if (time_is_before_jiffies(timeout)) { pr_err("Wait for completion (polling) timeout\n"); /* ENA didn't have any completion */ spin_lock_irqsave(&admin_queue->q_lock, flags); @@ -528,10 +533,6 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c goto err; } - spin_lock_irqsave(&admin_queue->q_lock, flags); - ena_com_handle_admin_completion(admin_queue); - spin_unlock_irqrestore(&admin_queue->q_lock, flags); - msleep(100); } -- cgit v1.2.3 From 0dc5e02cf060233b5a7c11f3b3e0592f8fb4505f Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Sun, 11 Jun 2017 15:42:46 +0300 Subject: net: ena: fix race condition between submit and completion admin command [ Upstream commit 661d2b0ccef6a63f48b61105cf7be17403d1db01 ] Bug: "Completion context is occupied" error printout will be noticed in dmesg. This error will cause the admin command to fail, which will lead to an ena_probe() failure or a watchdog reset (depends on which admin command failed). Root cause: __ena_com_submit_admin_cmd() is the function that submits new entries to the admin queue. The function have a check that makes sure the queue is not full and the function does not override any outstanding command. It uses head and tail indexes for this check. The head is increased by ena_com_handle_admin_completion() which runs from interrupt context, and the tail index is increased by the submit function (the function is running under ->q_lock, so there is no risk of multithread increment). Each command is associated with a completion context. This context allocated before call to __ena_com_submit_admin_cmd() and freed by ena_com_wait_and_process_admin_cq_interrupts(), right after the command was completed. This can lead to a state where the head was increased, the check passed, but the completion context is still in use. Solution: Use the atomic variable ->outstanding_cmds instead of using the head and the tail indexes. This variable is safe for use since it is bumped in get_comp_ctx() in __ena_com_submit_admin_cmd() and is freed by comp_ctxt_release() Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 564b556baba9..f4c107b66af4 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -232,11 +232,9 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu tail_masked = admin_queue->sq.tail & queue_size_mask; /* In case of queue FULL */ - cnt = admin_queue->sq.tail - admin_queue->sq.head; + cnt = atomic_read(&admin_queue->outstanding_cmds); if (cnt >= admin_queue->q_depth) { - pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n", - admin_queue->sq.tail, admin_queue->sq.head, - admin_queue->q_depth); + pr_debug("admin queue is full.\n"); admin_queue->stats.out_of_space++; return ERR_PTR(-ENOSPC); } -- cgit v1.2.3 From d06b43ba6706b26c9c3eadd9383161e220dfe808 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Sun, 11 Jun 2017 15:42:45 +0300 Subject: net: ena: add missing return when ena_com_get_io_handlers() fails [ Upstream commit 2d2c600a917127f16f179d5a88fc44ba3ed263ed ] Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index bfeaec5bd7b9..fe691017d5aa 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -1542,6 +1542,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid) "Failed to get TX queue handlers. TX queue num %d rc: %d\n", qid, rc); ena_com_destroy_io_queue(ena_dev, ena_qid); + return rc; } ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node); @@ -1606,6 +1607,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid) "Failed to get RX queue handlers. RX queue num %d rc: %d\n", qid, rc); ena_com_destroy_io_queue(ena_dev, ena_qid); + return rc; } ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node); -- cgit v1.2.3 From ff5b272d686912f1e49f01bb779ea57176095aa3 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Sun, 11 Jun 2017 15:42:47 +0300 Subject: net: ena: add missing unmap bars on device removal [ Upstream commit 0857d92f71b6cb75281fde913554b2d5436c394b ] This patch also change the mapping functions to devm_ functions Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index fe691017d5aa..0d9ce08ee3a9 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -2808,6 +2808,11 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev) { int release_bars; + if (ena_dev->mem_bar) + devm_iounmap(&pdev->dev, ena_dev->mem_bar); + + devm_iounmap(&pdev->dev, ena_dev->reg_bar); + release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK; pci_release_selected_regions(pdev, release_bars); } @@ -2895,8 +2900,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_free_ena_dev; } - ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR), - pci_resource_len(pdev, ENA_REG_BAR)); + ena_dev->reg_bar = devm_ioremap(&pdev->dev, + pci_resource_start(pdev, ENA_REG_BAR), + pci_resource_len(pdev, ENA_REG_BAR)); if (!ena_dev->reg_bar) { dev_err(&pdev->dev, "failed to remap regs bar\n"); rc = -EFAULT; @@ -2916,8 +2922,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ena_set_push_mode(pdev, ena_dev, &get_feat_ctx); if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { - ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, ENA_MEM_BAR), - pci_resource_len(pdev, ENA_MEM_BAR)); + ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, + pci_resource_start(pdev, ENA_MEM_BAR), + pci_resource_len(pdev, ENA_MEM_BAR)); if (!ena_dev->mem_bar) { rc = -EFAULT; goto err_device_destroy; -- cgit v1.2.3 From 70accaaca83b13210a8c866fa60421ff88b63d60 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Sun, 11 Jun 2017 15:42:49 +0300 Subject: net: ena: disable admin msix while working in polling mode [ Upstream commit a2cc5198dac102775b21787752a2e0afe44ad311 ] Fixes: 1738cd3ed342 ("Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amazon/ena/ena_com.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index f4c107b66af4..e13c9cd45dc0 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -61,6 +61,8 @@ #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF +#define ENA_REGS_ADMIN_INTR_MASK 1 + /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ @@ -1448,6 +1450,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev) void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling) { + u32 mask_value = 0; + + if (polling) + mask_value = ENA_REGS_ADMIN_INTR_MASK; + + writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF); ena_dev->admin_queue.polling = polling; } -- cgit v1.2.3 From a81437a759337a9fa6a89704d22e9adf1874a20d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 4 Jun 2017 20:33:39 +0200 Subject: clk: meson: meson8b: add compatibles for Meson8 and Meson8m2 [ Upstream commit 855f06a1009faabb0c6a3e9b49d115496d325856 ] The clock controller on Meson8, Meson8b and Meson8m2 is very similar based on the code from the Amlogic GPL kernel sources. Add separate compatibles for each SoC to make sure that we can easily implement all the small differences for each SoC later on. In general the Meson8 and Meson8m2 seem to be almost identical as they even share the same mach-meson8 directory in Amlogic's GPL kernel sources. The main clocks on Meson8, Meson8b and Meson8m2 are very similar, because they are all using the same PLL values, 90% of the clock gates are the same (the actual diffstat of the mach-meson8/clock.c and mach-meson8b/clock.c files is around 30 to 40 lines, when excluding all commented out code). The difference between the Meson8 and Meson8b clock gates seem to be: - Meson8 has AIU_PCLK, HDMI_RX, VCLK2_ENCT, VCLK2_ENCL, UART3, CSI_DIG_CLKIN gates which don't seem to be available on Meson8b - the gate on Meson8 for bit 7 seems to be named "_1200XXX" instead of "PERIPHS_TOP" (on Meson8b) - Meson8b has a SANA gate which doesn't seem to exist on Meson8 (or on Meson8 the same bit is used by the UART3 gate in Amlogic's GPL kernel sources) None of these gates is added for now, since it's unclear whether these definitions are actually correct (the VCLK2_ENCT gate for example is defined, but only used in some commented block). The main difference between all three SoCs seem to be the video (VPU) clocks. Apart from different supported clock rates (according to vpu.c in mach-meson8 and mach-meson8b from Amlogic's GPL kernel sources) the most notable difference is that Meson8m2 has a GP_PLL clock and a mux (probably the same as on the Meson GX SoCs) to support glitch-free (clock rate) switching. None of these VPU clocks are not supported by our mainline meson8b clock driver yet though. Signed-off-by: Martin Blumenstingl Acked-by: Rob Herring Acked-by: Kevin Hilman Signed-off-by: Jerome Brunet Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/clk/meson/Kconfig | 6 +++--- drivers/clk/meson/meson8b.c | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 2f29ee1a4d00..5588f75a8414 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -7,9 +7,9 @@ config COMMON_CLK_MESON8B bool depends on COMMON_CLK_AMLOGIC help - Support for the clock controller on AmLogic S805 devices, aka - meson8b. Say Y if you want peripherals and CPU frequency scaling to - work. + Support for the clock controller on AmLogic S802 (Meson8), + S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you + want peripherals and CPU frequency scaling to work. config COMMON_CLK_GXBB bool diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 3f1be46cbb33..70567958b86a 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -1,5 +1,6 @@ /* - * AmLogic S805 / Meson8b Clock Controller Driver + * AmLogic S802 (Meson8) / S805 (Meson8b) / S812 (Meson8m2) Clock Controller + * Driver * * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione @@ -661,7 +662,9 @@ iounmap: } static const struct of_device_id meson8b_clkc_match_table[] = { + { .compatible = "amlogic,meson8-clkc" }, { .compatible = "amlogic,meson8b-clkc" }, + { .compatible = "amlogic,meson8m2-clkc" }, { } }; -- cgit v1.2.3 From b22081fbfbaac0016fec3c087216ec11adba64d3 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Sun, 11 Jun 2017 14:28:54 +0200 Subject: cpuidle: dt: Add missing 'of_node_put()' [ Upstream commit b2cdd8e1b54849477a32d820acc2e87828a38f3d ] 'of_node_put()' should be called on pointer returned by 'of_parse_phandle()' when done. In this function this is done in all path except this 'continue', so add it. Fixes: 97735da074fd (drivers: cpuidle: Add status property to ARM idle states) Signed-off-by: Christophe Jaillet Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/cpuidle/dt_idle_states.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c index a5c111b67f37..ea11a33e7fff 100644 --- a/drivers/cpuidle/dt_idle_states.c +++ b/drivers/cpuidle/dt_idle_states.c @@ -174,8 +174,10 @@ int dt_init_idle_driver(struct cpuidle_driver *drv, if (!state_node) break; - if (!of_device_is_available(state_node)) + if (!of_device_is_available(state_node)) { + of_node_put(state_node); continue; + } if (!idle_state_valid(state_node, i, cpumask)) { pr_warn("%s idle state not valid, bailing out\n", -- cgit v1.2.3 From 9711cf143de362d05ae149bd5c54be23aa4d4882 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 5 Jun 2017 16:40:02 +0800 Subject: ACPICA: Events: Add runtime stub support for event APIs [ Upstream commit 861ba6351c520328e94a78c923b415faa9116287 ] ACPICA commit 99bc3beca92c6574ea1d69de42e54f872e6373ce It is reported that on Linux, RTC driver complains wrong errors on hardware reduced platform: [ 4.085420] ACPI Warning: Could not enable fixed event - real_time_clock (4) (20160422/evxface-654) This patch fixes this by correctly adding runtime reduced hardware check. Reported by Chandan Tagore, fixed by Lv Zheng. Link: https://github.com/acpica/acpica/commit/99bc3bec Tested-by: Chandan Tagore Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/evxfevnt.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 9179e9abe3db..35a2d9ea0654 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -180,6 +180,12 @@ acpi_status acpi_enable_event(u32 event, u32 flags) ACPI_FUNCTION_TRACE(acpi_enable_event); + /* If Hardware Reduced flag is set, there are no fixed events */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* Decode the Fixed Event */ if (event > ACPI_EVENT_MAX) { @@ -237,6 +243,12 @@ acpi_status acpi_disable_event(u32 event, u32 flags) ACPI_FUNCTION_TRACE(acpi_disable_event); + /* If Hardware Reduced flag is set, there are no fixed events */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* Decode the Fixed Event */ if (event > ACPI_EVENT_MAX) { @@ -290,6 +302,12 @@ acpi_status acpi_clear_event(u32 event) ACPI_FUNCTION_TRACE(acpi_clear_event); + /* If Hardware Reduced flag is set, there are no fixed events */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* Decode the Fixed Event */ if (event > ACPI_EVENT_MAX) { -- cgit v1.2.3 From 352b45c2ff86d59944e6bbc5381f6c1e62822a65 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 5 Jun 2017 16:40:34 +0800 Subject: ACPICA: Disassembler: Abort on an invalid/unknown AML opcode [ Upstream commit 6f0527b77d9e0129dd8e50945b0d610ed943d6b2 ] ACPICA commit ed0389cb11a61e63c568ac1f67948fc6a7bd1aeb An invalid opcode indicates something seriously wrong with the input AML file. The AML parser is immediately confused and lost, causing the resulting parse tree to be ill-formed. The actual disassembly can then cause numerous unrelated errors and faults. This change aborts the disassembly upon discovery of such an opcode during the AML parse phase. Link: https://github.com/acpica/acpica/commit/ed0389cb Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/psobject.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index db0e90342e82..ac2e8dfdf74e 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -121,6 +121,9 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) (u32)(aml_offset + sizeof(struct acpi_table_header))); + ACPI_ERROR((AE_INFO, + "Aborting disassembly, AML byte code is corrupt")); + /* Dump the context surrounding the invalid opcode */ acpi_ut_dump_buffer(((u8 *)walk_state->parser_state. @@ -129,6 +132,14 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) sizeof(struct acpi_table_header) - 16)); acpi_os_printf(" */\n"); + + /* + * Just abort the disassembly, cannot continue because the + * parser is essentially lost. The disassembler can then + * randomly fail because an ill-constructed parse tree + * can result. + */ + return_ACPI_STATUS(AE_AML_BAD_OPCODE); #endif } @@ -293,6 +304,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, if (status == AE_CTRL_PARSE_CONTINUE) { return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); } + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } /* Create Op structure and append to parent's argument list */ -- cgit v1.2.3 From d5a4ef2bce3598d5dd6ca749e2e48e56869d9965 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 18 May 2017 13:24:45 +0200 Subject: s390/dasd: fix hanging safe offline [ Upstream commit e8ac01555d9e464249e8bb122337d6d6e5589ccc ] The safe offline processing may hang forever because it waits for I/O which can not be started because of the offline flag that prevents new I/O from being started. Allow I/O to be started during safe offline processing because in this special case we take care that the queues are empty before throwing away the device. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/s390/block/dasd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 5ecd40884f01..0da246505f70 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1950,8 +1950,12 @@ static int __dasd_device_is_unusable(struct dasd_device *device, { int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); - if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { - /* dasd is being set offline. */ + if (test_bit(DASD_FLAG_OFFLINE, &device->flags) && + !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { + /* + * dasd is being set offline + * but it is no safe offline where we have to allow I/O + */ return 1; } if (device->stopped) { -- cgit v1.2.3 From deaee4d29d05bde5fa3c2dda5ad813b8bae944e2 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Sun, 11 Jun 2017 16:32:50 -0700 Subject: vxlan: dont migrate permanent fdb entries during learn [ Upstream commit e0090a9e979de5202c7d16c635dea2f005221073 ] This patch fixes vxlan_snoop to not move permanent fdb entries on learn events. This is consistent with the bridge fdb handling of permanent entries. Fixes: 26a41ae60438 ("vxlan: only migrate dynamic FDB entries") Signed-off-by: Roopa Prabhu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 0f5dfb8a545d..28afdf22b88f 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -930,7 +930,7 @@ static bool vxlan_snoop(struct net_device *dev, return false; /* Don't migrate static entries, drop packets */ - if (f->state & NUD_NOARP) + if (f->state & (NUD_PERMANENT | NUD_NOARP)) return true; if (net_ratelimit()) -- cgit v1.2.3 From 9622668cf21a54b7df0c0d2d5e923576187ab603 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 12 May 2017 14:38:03 +0200 Subject: drm/vc4: Fix resource leak in 'vc4_get_hang_state_ioctl()' in error handling path [ Upstream commit d0b1d259a4b58b21a21ea82d7174bf7ea825e9cc ] If one 'drm_gem_handle_create()' fails, we leak somes handles and some memory. In order to fix it: - move the 'free(bo_state)' at the end of the function so that it is also called in the eror handling path. This has the side effect to also try to free it if the first 'kcalloc' fails. This is harmless. - add a new label, err_delete_handle, in order to delete already allocated handles in error handling path - remove the now useless 'err' label The way the code is now written will also delete the handles if the 'copy_to_user()' call fails. Signed-off-by: Christophe JAILLET Reviewed-by: Eric Anholt Link: http://patchwork.freedesktop.org/patch/msgid/20170512123803.1886-1-christophe.jaillet@wanadoo.fr Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vc4/vc4_gem.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index ab3016982466..b608cd463d4e 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -110,8 +110,8 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, &handle); if (ret) { - state->bo_count = i - 1; - goto err; + state->bo_count = i; + goto err_delete_handle; } bo_state[i].handle = handle; bo_state[i].paddr = vc4_bo->base.paddr; @@ -123,13 +123,16 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, state->bo_count * sizeof(*bo_state))) ret = -EFAULT; - kfree(bo_state); +err_delete_handle: + if (ret) { + for (i = 0; i < state->bo_count; i++) + drm_gem_handle_delete(file_priv, bo_state[i].handle); + } err_free: - vc4_free_hang_state(dev, kernel_state); + kfree(bo_state); -err: return ret; } -- cgit v1.2.3 From d046bb9ec4947cd131ff22e1989179007c41b31f Mon Sep 17 00:00:00 2001 From: Tang Junhui Date: Mon, 8 Jan 2018 12:21:19 -0800 Subject: bcache: stop writeback thread after detaching [ Upstream commit 8d29c4426b9f8afaccf28de414fde8a722b35fdf ] Currently, when a cached device detaching from cache, writeback thread is not stopped, and writeback_rate_update work is not canceled. For example, after the following command: echo 1 >/sys/block/sdb/bcache/detach you can still see the writeback thread. Then you attach the device to the cache again, bcache will create another writeback thread, for example, after below command: echo ba0fb5cd-658a-4533-9806-6ce166d883b9 > /sys/block/sdb/bcache/attach then you will see 2 writeback threads. This patch stops writeback thread and cancels writeback_rate_update work when cached device detaching from cache. Compare with patch v1, this v2 patch moves code down into the register lock for safety in case of any future changes as Coly and Mike suggested. [edit by mlyle: commit log spelling/formatting] Signed-off-by: Tang Junhui Reviewed-by: Michael Lyle Signed-off-by: Michael Lyle Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/bcache/super.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index c61341c84d2d..4af7cd423c71 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -892,6 +892,12 @@ static void cached_dev_detach_finish(struct work_struct *w) mutex_lock(&bch_register_lock); + cancel_delayed_work_sync(&dc->writeback_rate_update); + if (!IS_ERR_OR_NULL(dc->writeback_thread)) { + kthread_stop(dc->writeback_thread); + dc->writeback_thread = NULL; + } + memset(&dc->sb.set_uuid, 0, 16); SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE); -- cgit v1.2.3 From 38f1e54e5dfa3d132b884cd4c394efb3d265b4e5 Mon Sep 17 00:00:00 2001 From: Tang Junhui Date: Mon, 8 Jan 2018 12:21:21 -0800 Subject: bcache: segregate flash only volume write streams [ Upstream commit 4eca1cb28d8b0574ca4f1f48e9331c5f852d43b9 ] In such scenario that there are some flash only volumes , and some cached devices, when many tasks request these devices in writeback mode, the write IOs may fall to the same bucket as bellow: | cached data | flash data | cached data | cached data| flash data| then after writeback of these cached devices, the bucket would be like bellow bucket: | free | flash data | free | free | flash data | So, there are many free space in this bucket, but since data of flash only volumes still exists, so this bucket cannot be reclaimable, which would cause waste of bucket space. In this patch, we segregate flash only volume write streams from cached devices, so data from flash only volumes and cached devices can store in different buckets. Compare to v1 patch, this patch do not add a additionally open bucket list, and it is try best to segregate flash only volume write streams from cached devices, sectors of flash only volumes may still be mixed with dirty sectors of cached device, but the number is very small. [mlyle: fixed commit log formatting, permissions, line endings] Signed-off-by: Tang Junhui Reviewed-by: Michael Lyle Signed-off-by: Michael Lyle Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/md/bcache/alloc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index 537903bf9add..d23337e8c4ee 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -512,15 +512,21 @@ struct open_bucket { /* * We keep multiple buckets open for writes, and try to segregate different - * write streams for better cache utilization: first we look for a bucket where - * the last write to it was sequential with the current write, and failing that - * we look for a bucket that was last used by the same task. + * write streams for better cache utilization: first we try to segregate flash + * only volume write streams from cached devices, secondly we look for a bucket + * where the last write to it was sequential with the current write, and + * failing that we look for a bucket that was last used by the same task. * * The ideas is if you've got multiple tasks pulling data into the cache at the * same time, you'll get better cache utilization if you try to segregate their * data and preserve locality. * - * For example, say you've starting Firefox at the same time you're copying a + * For example, dirty sectors of flash only volume is not reclaimable, if their + * dirty sectors mixed with dirty sectors of cached device, such buckets will + * be marked as dirty and won't be reclaimed, though the dirty data of cached + * device have been written back to backend device. + * + * And say you've starting Firefox at the same time you're copying a * bunch of files. Firefox will likely end up being fairly hot and stay in the * cache awhile, but the data you copied might not be; if you wrote all that * data to the same buckets it'd get invalidated at the same time. @@ -537,7 +543,10 @@ static struct open_bucket *pick_data_bucket(struct cache_set *c, struct open_bucket *ret, *ret_task = NULL; list_for_each_entry_reverse(ret, &c->data_buckets, list) - if (!bkey_cmp(&ret->key, search)) + if (UUID_FLASH_ONLY(&c->uuids[KEY_INODE(&ret->key)]) != + UUID_FLASH_ONLY(&c->uuids[KEY_INODE(search)])) + continue; + else if (!bkey_cmp(&ret->key, search)) goto found; else if (ret->last_write_point == write_point) ret_task = ret; -- cgit v1.2.3 From 0ef71347d2e8db15ab0f8c7b79cf2c38d34d1870 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Thu, 4 Jan 2018 21:04:31 +0800 Subject: scsi: libsas: fix memory leak in sas_smp_get_phy_events() [ Upstream commit 4a491b1ab11ca0556d2fda1ff1301e862a2d44c4 ] We've got a memory leak with the following producer: while true; do cat /sys/class/sas_phy/phy-1:0:12/invalid_dword_count >/dev/null; done The buffer req is allocated and not freed after we return. Fix it. Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Signed-off-by: Jason Yan CC: John Garry CC: chenqilin CC: chenxiang Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/libsas/sas_expander.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 022bb6e10d98..76730a5637ca 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -684,6 +684,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) phy->phy_reset_problem_count = scsi_to_u32(&resp[24]); out: + kfree(req); kfree(resp); return res; -- cgit v1.2.3 From 7333f17273a15a218e778135ef730f2d4a6f9213 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Thu, 4 Jan 2018 21:04:32 +0800 Subject: scsi: libsas: fix error when getting phy events [ Upstream commit 2b23d9509fd7174b362482cf5f3b5f9a2265bc33 ] The intend purpose here was to goto out if smp_execute_task() returned error. Obviously something got screwed up. We will never get these link error statistics below: ~:/sys/class/sas_phy/phy-1:0:12 # cat invalid_dword_count 0 ~:/sys/class/sas_phy/phy-1:0:12 # cat running_disparity_error_count 0 ~:/sys/class/sas_phy/phy-1:0:12 # cat loss_of_dword_sync_count 0 ~:/sys/class/sas_phy/phy-1:0:12 # cat phy_reset_problem_count 0 Obviously we should goto error handler if smp_execute_task() returns non-zero. Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Signed-off-by: Jason Yan CC: John Garry CC: chenqilin CC: chenxiang Reviewed-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/libsas/sas_expander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 76730a5637ca..ccdb9d5e2f28 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -675,7 +675,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) res = smp_execute_task(dev, req, RPEL_REQ_SIZE, resp, RPEL_RESP_SIZE); - if (!res) + if (res) goto out; phy->invalid_dword_count = scsi_to_u32(&resp[12]); -- cgit v1.2.3 From cafd951e8bf2b2f70246a329dd0e226bf3c45d3d Mon Sep 17 00:00:00 2001 From: chenxiang Date: Thu, 4 Jan 2018 21:04:33 +0800 Subject: scsi: libsas: initialize sas_phy status according to response of DISCOVER [ Upstream commit affc67788fe5dfffad5cda3d461db5cf2b2ff2b0 ] The status of SAS PHY is in sas_phy->enabled. There is an issue that the status of a remote SAS PHY may be initialized incorrectly: if disable remote SAS PHY through sysfs interface (such as echo 0 > /sys/class/sas_phy/phy-1:0:0/enable), then reboot the system, and we will find the status of remote SAS PHY which is disabled before is 1 (cat /sys/class/sas_phy/phy-1:0:0/enable). But actually the status of remote SAS PHY is disabled and the device attached is not found. In SAS protocol, NEGOTIATED LOGICAL LINK RATE field of DISCOVER response is 0x1 when remote SAS PHY is disabled. So initialize sas_phy->enabled according to the value of NEGOTIATED LOGICAL LINK RATE field. Signed-off-by: chenxiang Reviewed-by: John Garry Signed-off-by: Jason Yan Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/libsas/sas_expander.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index ccdb9d5e2f28..12886f96b286 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -282,6 +282,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->phy->minimum_linkrate = dr->pmin_linkrate; phy->phy->maximum_linkrate = dr->pmax_linkrate; phy->phy->negotiated_linkrate = phy->linkrate; + phy->phy->enabled = (phy->linkrate != SAS_PHY_DISABLED); skip: if (new_phy) -- cgit v1.2.3 From a74b51be6cf0dec61dccff34358daf7e900dd096 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 3 Jan 2018 10:18:03 -0800 Subject: tty: n_gsm: Allow ADM response in addition to UA for control dlci [ Upstream commit ea3d8465ab9b3e01be329ac5195970a84bef76c5 ] Some devices have the control dlci stay in ADM mode instead of the UA mode. This can seen at least on droid 4 when trying to open the ts 27.010 mux port. Enabling n_gsm debug mode shows the control dlci always respond with DM to SABM instead of UA: # modprobe n_gsm debug=0xff # ldattach -d GSM0710 /dev/ttyS0 & gsmld_output: 00000000: f9 03 3f 01 1c f9 --> 0) C: SABM(P) gsmld_receive: 00000000: f9 03 1f 01 36 f9 <-- 0) C: DM(P) ... $ minicom -D /dev/gsmtty1 minicom: cannot open /dev/gsmtty1: No error information $ strace minicom -D /dev/gsmtty1 ... open("/dev/gsmtty1", O_RDWR|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = -1 EL2HLT Note that this is different issue from other n_gsm -EL2HLT issues such as timeouts when the control dlci does not respond at all. The ADM mode seems to be a quite common according to "RF Wireless World" article "GSM Issue-UE sends SABM and gets a DM response instead of UA response": This issue is most commonly observed in GSM networks where in UE sends SABM and expects network to send UA response but it ends up receiving DM response from the network. SABM stands for Set asynchronous balanced mode, UA stands for Unnumbered Acknowledge and DA stands for Disconnected Mode. An RLP entity can be in one of two modes: - Asynchronous Balanced Mode (ABM) - Asynchronous Disconnected Mode (ADM) Currently Linux kernel closes the control dlci after several retries in gsm_dlci_t1() on DM. This causes n_gsm /dev/gsmtty ports to produce error code -EL2HLT when trying to open them as the closing of control dlci has already set gsm->dead. Let's fix the issue by allowing control dlci stay in ADM mode after the retries so the /dev/gsmtty ports can be opened and used. It seems that it might take several attempts to get any response from the control dlci, so it's best to allow ADM mode only after the SABM retries are done. Note that for droid 4 additional patches are needed to mux the ttyS0 pins and to toggle RTS gpio_149 to wake up the mdm6600 modem are also needed to use n_gsm. And the mdm6600 modem needs to be powered on. Cc: linux-serial@vger.kernel.org Cc: Alan Cox Cc: Jiri Prchal Cc: Jiri Slaby Cc: Marcel Partap Cc: Michael Scott Cc: Peter Hurley Cc: Russ Gorby Cc: Sascha Hauer Cc: Sebastian Reichel Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 54cab59e20ed..fe2291795d2f 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1467,6 +1467,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) * in which case an opening port goes back to closed and a closing port * is simply put into closed state (any further frames from the other * end will get a DM response) + * + * Some control dlci can stay in ADM mode with other dlci working just + * fine. In that case we can just keep the control dlci open after the + * DLCI_OPENING retries time out. */ static void gsm_dlci_t1(unsigned long data) @@ -1480,8 +1484,15 @@ static void gsm_dlci_t1(unsigned long data) if (dlci->retries) { gsm_command(dlci->gsm, dlci->addr, SABM|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); - } else + } else if (!dlci->addr && gsm->control == (DM | PF)) { + if (debug & 8) + pr_info("DLCI %d opening in ADM mode.\n", + dlci->addr); + gsm_dlci_open(dlci); + } else { gsm_dlci_close(dlci); + } + break; case DLCI_CLOSING: dlci->retries--; @@ -1499,8 +1510,8 @@ static void gsm_dlci_t1(unsigned long data) * @dlci: DLCI to open * * Commence opening a DLCI from the Linux side. We issue SABM messages - * to the modem which should then reply with a UA, at which point we - * will move into open state. Opening is done asynchronously with retry + * to the modem which should then reply with a UA or ADM, at which point + * we will move into open state. Opening is done asynchronously with retry * running off timers and the responses. */ -- cgit v1.2.3 From 8c2ba5fafdd9b0fc822f78fce42fc46ef5a2c3af Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 7 Jan 2018 21:54:00 +0100 Subject: EDAC, mv64x60: Fix an error handling path [ Upstream commit 68fa24f9121c04ef146b5158f538c8b32f285be5 ] We should not call edac_mc_del_mc() if a corresponding call to edac_mc_add_mc() has not been performed yet. So here, we should go to err instead of err2 to branch at the right place of the error handling path. Signed-off-by: Christophe JAILLET Cc: linux-edac Link: http://lkml.kernel.org/r/20180107205400.14068-1-christophe.jaillet@wanadoo.fr Signed-off-by: Borislav Petkov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/edac/mv64x60_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c index cb9b8577acbc..61c19b81ed81 100644 --- a/drivers/edac/mv64x60_edac.c +++ b/drivers/edac/mv64x60_edac.c @@ -759,7 +759,7 @@ static int mv64x60_mc_err_probe(struct platform_device *pdev) /* Non-ECC RAM? */ printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__); res = -ENODEV; - goto err2; + goto err; } edac_dbg(3, "init mci\n"); -- cgit v1.2.3 From d774913ba20e86338aedda6fee84351739dc100d Mon Sep 17 00:00:00 2001 From: Arjun Vynipadath Date: Wed, 10 Jan 2018 12:02:13 +0530 Subject: cxgb4vf: Fix SGE FL buffer initialization logic for 64K pages [ Upstream commit ea0a42109aee7b92e631c4eb3f2219fadf58acdd ] We'd come in with SGE_FL_BUFFER_SIZE[0] and [1] both equal to 64KB and the extant logic would flag that as an error. This was already fixed in cxgb4 driver with "92ddcc7 cxgb4: Fix some small bugs in t4_sge_init_soft() when our Page Size is 64KB". Original Work by: Casey Leedom Signed-off-by: Arjun Vynipadath Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index f3ed9ce99e5e..9d64e8e7c417 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -2616,8 +2616,8 @@ void t4vf_sge_stop(struct adapter *adapter) int t4vf_sge_init(struct adapter *adapter) { struct sge_params *sge_params = &adapter->params.sge; - u32 fl0 = sge_params->sge_fl_buffer_size[0]; - u32 fl1 = sge_params->sge_fl_buffer_size[1]; + u32 fl_small_pg = sge_params->sge_fl_buffer_size[0]; + u32 fl_large_pg = sge_params->sge_fl_buffer_size[1]; struct sge *s = &adapter->sge; /* @@ -2625,9 +2625,20 @@ int t4vf_sge_init(struct adapter *adapter) * the Physical Function Driver. Ideally we should be able to deal * with _any_ configuration. Practice is different ... */ - if (fl0 != PAGE_SIZE || (fl1 != 0 && fl1 <= fl0)) { + + /* We only bother using the Large Page logic if the Large Page Buffer + * is larger than our Page Size Buffer. + */ + if (fl_large_pg <= fl_small_pg) + fl_large_pg = 0; + + /* The Page Size Buffer must be exactly equal to our Page Size and the + * Large Page Size Buffer should be 0 (per above) or a power of 2. + */ + if (fl_small_pg != PAGE_SIZE || + (fl_large_pg & (fl_large_pg - 1)) != 0) { dev_err(adapter->pdev_dev, "bad SGE FL buffer sizes [%d, %d]\n", - fl0, fl1); + fl_small_pg, fl_large_pg); return -EINVAL; } if ((sge_params->sge_control & RXPKTCPLMODE_F) != @@ -2639,8 +2650,8 @@ int t4vf_sge_init(struct adapter *adapter) /* * Now translate the adapter parameters into our internal forms. */ - if (fl1) - s->fl_pg_order = ilog2(fl1) - PAGE_SHIFT; + if (fl_large_pg) + s->fl_pg_order = ilog2(fl_large_pg) - PAGE_SHIFT; s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_F) ? 128 : 64); s->pktshift = PKTSHIFT_G(sge_params->sge_control); -- cgit v1.2.3 From 905348d08acd1d35d270f49090c3ac1d2c4bc374 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 11 Jan 2018 15:51:58 +0200 Subject: sdhci: Advertise 2.0v supply on SDIO host controller [ Upstream commit 2a609abe71ca59e4bd7139e161eaca2144ae6f2e ] On Intel Edison the Broadcom Wi-Fi card, which is connected to SDIO, requires 2.0v, while the host, according to Intel Merrifield TRM, supports 1.8v supply only. The card announces itself as mmc2: new ultra high speed DDR50 SDIO card at address 0001 Introduce a custom OCR mask for SDIO host controller on Intel Merrifield and add a special case to sdhci_set_power_noreg() to override 2.0v supply by enforcing 1.8v power choice. Signed-off-by: Andy Shevchenko Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-pci-core.c | 2 ++ drivers/mmc/host/sdhci.c | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index b0b9ceb0ab01..cfb794766fea 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -492,6 +492,8 @@ static int intel_mrfld_mmc_probe_slot(struct sdhci_pci_slot *slot) slot->host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; break; case INTEL_MRFLD_SDIO: + /* Advertise 2.0v for compatibility with the SDIO card's OCR */ + slot->host->ocr_mask = MMC_VDD_20_21 | MMC_VDD_165_195; slot->host->mmc->caps |= MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD; break; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7d275e72903a..44ea9d88651f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1404,6 +1404,13 @@ void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, if (mode != MMC_POWER_OFF) { switch (1 << vdd) { case MMC_VDD_165_195: + /* + * Without a regulator, SDHCI does not support 2.0v + * so we only get here if the driver deliberately + * added the 2.0v range to ocr_avail. Map it to 1.8v + * for the purpose of turning on the power. + */ + case MMC_VDD_20_21: pwr = SDHCI_POWER_180; break; case MMC_VDD_29_30: -- cgit v1.2.3 From 2a584051aba85f3fbb246c01429df073db3e3f2f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 12 Jan 2018 00:36:48 -0800 Subject: Input: goodix - disable IRQs while suspended [ Upstream commit faec44b6838312484d63e82286087cf2d5ebb891 ] We should not try to do any i2c transfers before the controller is resumed (which happens before our resume method gets called). So we need to disable our IRQ while suspended to enforce this. The code paths for devices with GPIOs for the int and reset pins already disable the IRQ the through goodix_free_irq(). This commit also disables the IRQ while suspended for devices without GPIOs for the int and reset pins. This fixes the i2c bus sometimes getting stuck after a suspend/resume causing the touchscreen to sometimes not work after a suspend/resume. This has been tested on a GPD pocked device. BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://www.reddit.com/r/GPDPocket/comments/7niut2/fix_for_broken_touch_after_resume_all_linux/ Tested-by: Hans de Goede Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/goodix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 240b16f3ee97..5907fddcc966 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -778,8 +778,10 @@ static int __maybe_unused goodix_suspend(struct device *dev) int error; /* We need gpio pins to suspend/resume */ - if (!ts->gpiod_int || !ts->gpiod_rst) + if (!ts->gpiod_int || !ts->gpiod_rst) { + disable_irq(client->irq); return 0; + } wait_for_completion(&ts->firmware_loading_complete); @@ -819,8 +821,10 @@ static int __maybe_unused goodix_resume(struct device *dev) struct goodix_ts_data *ts = i2c_get_clientdata(client); int error; - if (!ts->gpiod_int || !ts->gpiod_rst) + if (!ts->gpiod_int || !ts->gpiod_rst) { + enable_irq(client->irq); return 0; + } /* * Exit sleep mode by outputting HIGH level to INT pin -- cgit v1.2.3 From f6df92f22be342118d2eedbbcc5ca1953aab1a13 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 11 Jan 2018 21:39:20 +0100 Subject: mtd: mtd_oobtest: Handle bitflips during reads [ Upstream commit 12663b442e5ac5aa3d6097cd3f287c71ba46d26e ] Reads from NAND devices usually trigger bitflips, this is an expected behavior. While bitflips are under a given threshold, the MTD core returns 0. However, when the number of corrected bitflips is above this same threshold, -EUCLEAN is returned to inform the upper layer that this block is slightly dying and soon the ECC engine will be overtaken so actions should be taken to move the data out of it. This particular condition should not be treated like an error and the test should continue. Signed-off-by: Miquel Raynal Signed-off-by: Boris Brezillon Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/tests/oobtest.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index 1cb3f7758fb6..766b2c385682 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -193,6 +193,9 @@ static int verify_eraseblock(int ebnum) ops.datbuf = NULL; ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err || ops.oobretlen != use_len) { pr_err("error: readoob failed at %#llx\n", (long long)addr); @@ -227,6 +230,9 @@ static int verify_eraseblock(int ebnum) ops.datbuf = NULL; ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err || ops.oobretlen != mtd->oobavail) { pr_err("error: readoob failed at %#llx\n", (long long)addr); @@ -286,6 +292,9 @@ static int verify_eraseblock_in_one_go(int ebnum) /* read entire block's OOB at one go */ err = mtd_read_oob(mtd, addr, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err || ops.oobretlen != len) { pr_err("error: readoob failed at %#llx\n", (long long)addr); @@ -527,6 +536,9 @@ static int __init mtd_oobtest_init(void) pr_info("attempting to start read past end of OOB\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, addr0, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err) { pr_info("error occurred as expected\n"); err = 0; @@ -571,6 +583,9 @@ static int __init mtd_oobtest_init(void) pr_info("attempting to read past end of device\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err) { pr_info("error occurred as expected\n"); err = 0; @@ -615,6 +630,9 @@ static int __init mtd_oobtest_init(void) pr_info("attempting to read past end of device\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err) { pr_info("error occurred as expected\n"); err = 0; @@ -684,6 +702,9 @@ static int __init mtd_oobtest_init(void) ops.datbuf = NULL; ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); + if (mtd_is_bitflip(err)) + err = 0; + if (err) goto out; if (memcmpshow(addr, readbuf, writebuf, -- cgit v1.2.3 From 0414cff3e8de1688d694439d366be04d1dacd835 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 4 Jun 2017 04:16:26 +0200 Subject: virtio_net: check return value of skb_to_sgvec always commit e2fcad58fd230f635a74e4e983c6f4ea893642d2 upstream. Signed-off-by: Jason A. Donenfeld Reviewed-by: Sergei Shtylyov Cc: "Michael S. Tsirkin" Cc: Jason Wang Signed-off-by: David S. Miller Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 1568aedddfc9..0a2f3ac36be2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -831,7 +831,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) struct virtio_net_hdr_mrg_rxbuf *hdr; const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; struct virtnet_info *vi = sq->vq->vdev->priv; - unsigned num_sg; + int num_sg; unsigned hdr_len = vi->hdr_len; bool can_push; @@ -858,11 +858,16 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) if (can_push) { __skb_push(skb, hdr_len); num_sg = skb_to_sgvec(skb, sq->sg, 0, skb->len); + if (unlikely(num_sg < 0)) + return num_sg; /* Pull header back to avoid skew in tx bytes calculations. */ __skb_pull(skb, hdr_len); } else { sg_set_buf(sq->sg, hdr, hdr_len); - num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1; + num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len); + if (unlikely(num_sg < 0)) + return num_sg; + num_sg++; } return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC); } -- cgit v1.2.3 From 32a1f12961b485a02ba84ecddf39c17deeb345d7 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 9 Apr 2018 18:21:50 -0700 Subject: virtio_net: check return value of skb_to_sgvec in one more location Kernels that do not have f6b10209b90d ("virtio-net: switch to use build_skb() for small buffer") will have an extra call to skb_to_sgvec that is not handled by e2fcad58fd23 ("virtio_net: check return value of skb_to_sgvec always"). Since the former does not appear to be stable material, just fix the call up directly. Cc: Jason A. Donenfeld Cc: Sergei Shtylyov Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: David S. Miller Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0a2f3ac36be2..472ed6df2221 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -529,7 +529,12 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq, hdr = skb_vnet_hdr(skb); sg_init_table(rq->sg, 2); sg_set_buf(rq->sg, hdr, vi->hdr_len); - skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); + + err = skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); + if (unlikely(err < 0)) { + dev_kfree_skb(skb); + return err; + } err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp); if (err < 0) -- cgit v1.2.3 From b4d93c6f89688a1e18fc1e4d8c089e163c1ce54f Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 7 Jun 2017 19:01:32 -0400 Subject: random: use lockless method of accessing and updating f->reg_idx commit 92e75428ffc90e2a0321062379f883f3671cfebe upstream. Linus pointed out that there is a much more efficient way of avoiding the problem that we were trying to address in commit 9dfa7bba35ac0: "fix race in drivers/char/random.c:get_reg()". Signed-off-by: Theodore Ts'o Cc: Michael Schmitz Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 23f3fb45ff07..0c23ced255cb 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1115,15 +1115,15 @@ static void add_interrupt_bench(cycles_t start) static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) { __u32 *ptr = (__u32 *) regs; - unsigned long flags; + unsigned int idx; if (regs == NULL) return 0; - local_irq_save(flags); - if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) - f->reg_idx = 0; - ptr += f->reg_idx++; - local_irq_restore(flags); + idx = READ_ONCE(f->reg_idx); + if (idx >= sizeof(struct pt_regs) / sizeof(__u32)) + idx = 0; + ptr += idx++; + WRITE_ONCE(f->reg_idx, idx); return *ptr; } -- cgit v1.2.3 From 2f9c90e7ad3314f5207d9fc6d069cc218303199a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 5 Jun 2017 00:02:57 +0200 Subject: clk: at91: fix clk-generated compilation commit 4a5f06a01cfd1f7a9141bdb760bf5b68cca7f224 upstream. Fix missing } Signed-off-by: Alexandre Belloni Signed-off-by: Stephen Boyd Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/clk/at91/clk-generated.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 70474bd97a10..07c8f701e51c 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -266,6 +266,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, if (ret) { kfree(gck); hw = ERR_PTR(ret); + } return hw; } -- cgit v1.2.3 From 765884bc645b142bbac3c18a08d06237cbd05a73 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 2 Apr 2018 18:48:37 -0700 Subject: pptp: remove a buggy dst release in pptp_connect() [ Upstream commit bfacfb457b36911a10140b8cb3ce76a74883ac5a ] Once dst has been cached in socket via sk_setup_caps(), it is illegal to call ip_rt_put() (or dst_release()), since sk_setup_caps() did not change dst refcount. We can still dereference it since we hold socket lock. Caugth by syzbot : BUG: KASAN: use-after-free in atomic_dec_return include/asm-generic/atomic-instrumented.h:198 [inline] BUG: KASAN: use-after-free in dst_release+0x27/0xa0 net/core/dst.c:185 Write of size 4 at addr ffff8801c54dc040 by task syz-executor4/20088 CPU: 1 PID: 20088 Comm: syz-executor4 Not tainted 4.16.0+ #376 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:17 [inline] dump_stack+0x1a7/0x27d lib/dump_stack.c:53 print_address_description+0x73/0x250 mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report+0x23c/0x360 mm/kasan/report.c:412 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x137/0x190 mm/kasan/kasan.c:267 kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278 atomic_dec_return include/asm-generic/atomic-instrumented.h:198 [inline] dst_release+0x27/0xa0 net/core/dst.c:185 sk_dst_set include/net/sock.h:1812 [inline] sk_dst_reset include/net/sock.h:1824 [inline] sock_setbindtodevice net/core/sock.c:610 [inline] sock_setsockopt+0x431/0x1b20 net/core/sock.c:707 SYSC_setsockopt net/socket.c:1845 [inline] SyS_setsockopt+0x2ff/0x360 net/socket.c:1828 do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x42/0xb7 RIP: 0033:0x4552d9 RSP: 002b:00007f4878126c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000036 RAX: ffffffffffffffda RBX: 00007f48781276d4 RCX: 00000000004552d9 RDX: 0000000000000019 RSI: 0000000000000001 RDI: 0000000000000013 RBP: 000000000072bea0 R08: 0000000000000010 R09: 0000000000000000 R10: 00000000200010c0 R11: 0000000000000246 R12: 00000000ffffffff R13: 0000000000000526 R14: 00000000006fac30 R15: 0000000000000000 Allocated by task 20088: save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:552 kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:489 kmem_cache_alloc+0x12e/0x760 mm/slab.c:3542 dst_alloc+0x11f/0x1a0 net/core/dst.c:104 rt_dst_alloc+0xe9/0x540 net/ipv4/route.c:1520 __mkroute_output net/ipv4/route.c:2265 [inline] ip_route_output_key_hash_rcu+0xa49/0x2c60 net/ipv4/route.c:2493 ip_route_output_key_hash+0x20b/0x370 net/ipv4/route.c:2322 __ip_route_output_key include/net/route.h:126 [inline] ip_route_output_flow+0x26/0xa0 net/ipv4/route.c:2577 ip_route_output_ports include/net/route.h:163 [inline] pptp_connect+0xa84/0x1170 drivers/net/ppp/pptp.c:453 SYSC_connect+0x213/0x4a0 net/socket.c:1639 SyS_connect+0x24/0x30 net/socket.c:1620 do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x42/0xb7 Freed by task 20082: save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:520 kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:527 __cache_free mm/slab.c:3486 [inline] kmem_cache_free+0x83/0x2a0 mm/slab.c:3744 dst_destroy+0x266/0x380 net/core/dst.c:140 dst_destroy_rcu+0x16/0x20 net/core/dst.c:153 __rcu_reclaim kernel/rcu/rcu.h:178 [inline] rcu_do_batch kernel/rcu/tree.c:2675 [inline] invoke_rcu_callbacks kernel/rcu/tree.c:2930 [inline] __rcu_process_callbacks kernel/rcu/tree.c:2897 [inline] rcu_process_callbacks+0xd6c/0x17b0 kernel/rcu/tree.c:2914 __do_softirq+0x2d7/0xb85 kernel/softirq.c:285 The buggy address belongs to the object at ffff8801c54dc000 which belongs to the cache ip_dst_cache of size 168 The buggy address is located 64 bytes inside of 168-byte region [ffff8801c54dc000, ffff8801c54dc0a8) The buggy address belongs to the page: page:ffffea0007153700 count:1 mapcount:0 mapping:ffff8801c54dc000 index:0x0 flags: 0x2fffc0000000100(slab) raw: 02fffc0000000100 ffff8801c54dc000 0000000000000000 0000000100000010 raw: ffffea0006b34b20 ffffea0006b6c1e0 ffff8801d674a1c0 0000000000000000 page dumped because: kasan: bad access detected Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ppp/pptp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 1951b1085cb8..3045c9662ed6 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -465,7 +465,6 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.mtu = dst_mtu(&rt->dst); if (!po->chan.mtu) po->chan.mtu = PPP_MRU; - ip_rt_put(rt); po->chan.mtu -= PPTP_HEADER_OVERHEAD; po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); -- cgit v1.2.3 From 360e1e58f3fa7fe4eb266ebc0ae1690e0d1e372b Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 26 Mar 2018 19:19:30 +0200 Subject: r8169: fix setting driver_data after register_netdev [ Upstream commit 19c9ea363a244f85f90a424f9936e6d56449e33c ] pci_set_drvdata() is called only after registering the net_device, therefore we could run into a NPE if one of the functions using driver_data is called before it's set. Fix this by calling pci_set_drvdata() before registering the net_device. This fix is a candidate for stable. As far as I can see the bug has been there in kernel version 3.2 already, therefore I can't provide a reference which commit is fixed by it. The fix may need small adjustments per kernel version because due to other changes the label which is jumped to if register_netdev() fails has changed over time. Reported-by: David Miller Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/realtek/r8169.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 18e68c91e651..dbb63640bc6e 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -8446,12 +8446,12 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_msi_5; } + pci_set_drvdata(pdev, dev); + rc = register_netdev(dev); if (rc < 0) goto err_out_cnt_6; - pci_set_drvdata(pdev, dev); - netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n", rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq); -- cgit v1.2.3 From 10200c71c411a451eec56d32dbcc29cdd940786e Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sat, 31 Mar 2018 23:42:03 +0800 Subject: sky2: Increase D3 delay to sky2 stops working after suspend [ Upstream commit afb133637071be6deeb8b3d0e55593ffbf63c527 ] The sky2 ethernet stops working after system resume from suspend: [ 582.852065] sky2 0000:04:00.0: Refused to change power state, currently in D3 The current 150ms delay is not enough, change it to 200ms can solve the issue. BugLink: https://bugs.launchpad.net/bugs/1758507 Cc: Stable Signed-off-by: Kai-Heng Feng Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/marvell/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 941c8e2c944e..93ab0b3ad393 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -5079,7 +5079,7 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_WORK(&hw->restart_work, sky2_restart); pci_set_drvdata(pdev, hw); - pdev->d3_delay = 150; + pdev->d3_delay = 200; return 0; -- cgit v1.2.3 From 827148d08d43bce95fda03b462e213fc0094c8b1 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 27 Mar 2018 20:50:52 +0800 Subject: vhost: correctly remove wait queue during poll failure [ Upstream commit dc6455a71c7fc5117977e197f67f71b49f27baba ] We tried to remove vq poll from wait queue, but do not check whether or not it was in a list before. This will lead double free. Fixing this by switching to use vhost_poll_stop() which zeros poll->wqh after removing poll from waitqueue to make sure it won't be freed twice. Cc: Darren Kenny Reported-by: syzbot+c0272972b01b872e604a@syzkaller.appspotmail.com Fixes: 2b8b328b61c79 ("vhost_net: handle polling errors when setting backend") Signed-off-by: Jason Wang Reviewed-by: Darren Kenny Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index cd38f5add254..126730384d7d 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -211,8 +211,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file) if (mask) vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); if (mask & POLLERR) { - if (poll->wqh) - remove_wait_queue(poll->wqh, &poll->wait); + vhost_poll_stop(poll); ret = -EINVAL; } -- cgit v1.2.3 From f611a5e1433f71989d3d9846964e91cfb0c1ba01 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 26 Mar 2018 01:16:45 +0800 Subject: bonding: fix the err path for dev hwaddr sync in bond_enslave [ Upstream commit 5c78f6bfae2b10ff70e21d343e64584ea6280c26 ] vlan_vids_add_by_dev is called right after dev hwaddr sync, so on the err path it should unsync dev hwaddr. Otherwise, the slave dev's hwaddr will never be unsync when this err happens. Fixes: 1ff412ad7714 ("bonding: change the bond's vlan syncing functions with the standard ones") Signed-off-by: Xin Long Reviewed-by: Nikolay Aleksandrov Acked-by: Andy Gospodarek Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index fb1141f7f6b5..64f2a3f3279f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1561,7 +1561,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (res) { netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n", slave_dev->name); - goto err_close; + goto err_hwaddr_unsync; } prev_slave = bond_last_slave(bond); @@ -1749,9 +1749,6 @@ err_unregister: netdev_rx_handler_unregister(slave_dev); err_detach: - if (!bond_uses_primary(bond)) - bond_hw_addr_flush(bond_dev, slave_dev); - vlan_vids_del_by_dev(slave_dev, bond_dev); if (rcu_access_pointer(bond->primary_slave) == new_slave) RCU_INIT_POINTER(bond->primary_slave, NULL); @@ -1765,6 +1762,10 @@ err_detach: synchronize_rcu(); slave_disable_netpoll(new_slave); +err_hwaddr_unsync: + if (!bond_uses_primary(bond)) + bond_hw_addr_flush(bond_dev, slave_dev); + err_close: slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); -- cgit v1.2.3 From d6d65b4c8fd700be97bd24980bc0bde9b0c55109 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 26 Mar 2018 01:16:46 +0800 Subject: bonding: move dev_mc_sync after master_upper_dev_link in bond_enslave [ Upstream commit ae42cc62a9f07f1f6979054ed92606b9c30f4a2e ] Beniamino found a crash when adding vlan as slave of bond which is also the parent link: ip link add bond1 type bond ip link set bond1 up ip link add link bond1 vlan1 type vlan id 80 ip link set vlan1 master bond1 The call trace is as below: [] queued_spin_lock_slowpath+0xb/0xf [] _raw_spin_lock+0x20/0x30 [] dev_mc_sync+0x37/0x80 [] vlan_dev_set_rx_mode+0x1c/0x30 [8021q] [] __dev_set_rx_mode+0x5a/0xa0 [] dev_mc_sync_multiple+0x78/0x80 [] bond_enslave+0x67c/0x1190 [bonding] [] do_setlink+0x9c9/0xe50 [] rtnl_newlink+0x522/0x880 [] rtnetlink_rcv_msg+0xa7/0x260 [] netlink_rcv_skb+0xab/0xc0 [] rtnetlink_rcv+0x28/0x30 [] netlink_unicast+0x170/0x210 [] netlink_sendmsg+0x308/0x420 [] sock_sendmsg+0xb6/0xf0 This is actually a dead lock caused by sync slave hwaddr from master when the master is the slave's 'slave'. This dead loop check is actually done by netdev_master_upper_dev_link. However, Commit 1f718f0f4f97 ("bonding: populate neighbour's private on enslave") moved it after dev_mc_sync. This patch is to fix it by moving dev_mc_sync after master_upper_dev_link, so that this loop check would be earlier than dev_mc_sync. It also moves if (mode == BOND_MODE_8023AD) into if (!bond_uses_primary) clause as an improvement. Note team driver also has this issue, I will fix it in another patch. Fixes: 1f718f0f4f97 ("bonding: populate neighbour's private on enslave") Reported-by: Beniamino Galvani Signed-off-by: Xin Long Acked-by: Andy Gospodarek Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 73 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 64f2a3f3279f..68b90391cfe2 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1524,44 +1524,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) goto err_close; } - /* If the mode uses primary, then the following is handled by - * bond_change_active_slave(). - */ - if (!bond_uses_primary(bond)) { - /* set promiscuity level to new slave */ - if (bond_dev->flags & IFF_PROMISC) { - res = dev_set_promiscuity(slave_dev, 1); - if (res) - goto err_close; - } - - /* set allmulti level to new slave */ - if (bond_dev->flags & IFF_ALLMULTI) { - res = dev_set_allmulti(slave_dev, 1); - if (res) - goto err_close; - } - - netif_addr_lock_bh(bond_dev); - - dev_mc_sync_multiple(slave_dev, bond_dev); - dev_uc_sync_multiple(slave_dev, bond_dev); - - netif_addr_unlock_bh(bond_dev); - } - - if (BOND_MODE(bond) == BOND_MODE_8023AD) { - /* add lacpdu mc addr to mc list */ - u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; - - dev_mc_add(slave_dev, lacpdu_multicast); - } - res = vlan_vids_add_by_dev(slave_dev, bond_dev); if (res) { netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n", slave_dev->name); - goto err_hwaddr_unsync; + goto err_close; } prev_slave = bond_last_slave(bond); @@ -1719,6 +1686,37 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) goto err_upper_unlink; } + /* If the mode uses primary, then the following is handled by + * bond_change_active_slave(). + */ + if (!bond_uses_primary(bond)) { + /* set promiscuity level to new slave */ + if (bond_dev->flags & IFF_PROMISC) { + res = dev_set_promiscuity(slave_dev, 1); + if (res) + goto err_sysfs_del; + } + + /* set allmulti level to new slave */ + if (bond_dev->flags & IFF_ALLMULTI) { + res = dev_set_allmulti(slave_dev, 1); + if (res) + goto err_sysfs_del; + } + + netif_addr_lock_bh(bond_dev); + dev_mc_sync_multiple(slave_dev, bond_dev); + dev_uc_sync_multiple(slave_dev, bond_dev); + netif_addr_unlock_bh(bond_dev); + + if (BOND_MODE(bond) == BOND_MODE_8023AD) { + /* add lacpdu mc addr to mc list */ + u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; + + dev_mc_add(slave_dev, lacpdu_multicast); + } + } + bond->slave_cnt++; bond_compute_features(bond); bond_set_carrier(bond); @@ -1742,6 +1740,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) return 0; /* Undo stages on error */ +err_sysfs_del: + bond_sysfs_slave_del(new_slave); + err_upper_unlink: bond_upper_dev_unlink(bond, new_slave); @@ -1762,10 +1763,6 @@ err_detach: synchronize_rcu(); slave_disable_netpoll(new_slave); -err_hwaddr_unsync: - if (!bond_uses_primary(bond)) - bond_hw_addr_flush(bond_dev, slave_dev); - err_close: slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); -- cgit v1.2.3 From 359d6e35786b3aafc4dea0d5cf59ff62c1eb126c Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 26 Mar 2018 01:16:47 +0800 Subject: bonding: process the err returned by dev_set_allmulti properly in bond_enslave [ Upstream commit 9f5a90c107741b864398f4ac0014711a8c1d8474 ] When dev_set_promiscuity(1) succeeds but dev_set_allmulti(1) fails, dev_set_promiscuity(-1) should be done before going to the err path. Otherwise, dev->promiscuity will leak. Fixes: 7e1a1ac1fbaa ("bonding: Check return of dev_set_promiscuity/allmulti") Signed-off-by: Xin Long Acked-by: Andy Gospodarek Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 68b90391cfe2..513457a2a7bf 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1700,8 +1700,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* set allmulti level to new slave */ if (bond_dev->flags & IFF_ALLMULTI) { res = dev_set_allmulti(slave_dev, 1); - if (res) + if (res) { + if (bond_dev->flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); goto err_sysfs_del; + } } netif_addr_lock_bh(bond_dev); -- cgit v1.2.3 From eb9b11a1abce0122d7851bb1f6ad1790a98f5eb9 Mon Sep 17 00:00:00 2001 From: Shahar Klein Date: Tue, 20 Mar 2018 14:44:40 +0200 Subject: net/mlx5e: Sync netdev vxlan ports at open [ Upstream commit a117f73dc2430443f23e18367fa545981129c1a6 ] When mlx5_core is loaded it is expected to sync ports with all vxlan devices so it can support vxlan encap/decap. This is done via udp_tunnel_get_rx_info(). Currently this call is set in mlx5e_nic_enable() and if the netdev is not in NETREG_REGISTERED state it will not be called. Normally on load the netdev state is not NETREG_REGISTERED so udp_tunnel_get_rx_info() will not be called. Moving udp_tunnel_get_rx_info() to mlx5e_open() so it will be called on netdev UP event and allow encap/decap. Fixes: 610e89e05c3f ("net/mlx5e: Don't sync netdev state when not registered") Signed-off-by: Shahar Klein Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 38981db43bc3..2d235e8433be 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -2741,6 +2741,9 @@ static int set_feature_lro(struct net_device *netdev, bool enable) mutex_unlock(&priv->state_lock); + if (mlx5e_vxlan_allowed(priv->mdev)) + udp_tunnel_get_rx_info(netdev); + return err; } @@ -3785,13 +3788,6 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) if (netdev->reg_state != NETREG_REGISTERED) return; - /* Device already registered: sync netdev system state */ - if (mlx5e_vxlan_allowed(mdev)) { - rtnl_lock(); - udp_tunnel_get_rx_info(netdev); - rtnl_unlock(); - } - queue_work(priv->wq, &priv->set_rx_mode_work); } -- cgit v1.2.3 From b3e1c92e59911cd61672f8f735bc78f36ca7fef0 Mon Sep 17 00:00:00 2001 From: Eran Ben Elisha Date: Tue, 27 Mar 2018 14:41:18 +0300 Subject: net/mlx4_en: Fix mixed PFC and Global pause user control requests [ Upstream commit 6e8814ceb7e8f468659ef9253bd212c07ae19584 ] Global pause and PFC configuration should be mutually exclusive (i.e. only one of them at most can be set). However, once PFC was turned off, driver automatically turned Global pause on. This is a bug. Fix the driver behaviour to turn off PFC/Global once the user turned the other on. This also fixed a weird behaviour that at a current time, the profile had both PFC and global pause configuration turned on, which is Hardware-wise impossible and caused returning false positive indication to query tools. In addition, fix error code when setting global pause or PFC to change metadata only upon successful change. Also, removed useless debug print. Fixes: af7d51852631 ("net/mlx4_en: Add DCB PFC support through CEE netlink commands") Fixes: c27a02cd94d6 ("mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC") Signed-off-by: Eran Ben Elisha Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 72 ++++++++++++++----------- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 33 +++++++----- drivers/net/ethernet/mellanox/mlx4/en_main.c | 4 +- 3 files changed, 62 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index d98827adec9b..af2e6ea36eac 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c @@ -156,57 +156,63 @@ static int mlx4_en_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev) { struct mlx4_en_priv *priv = netdev_priv(netdev); + struct mlx4_en_port_profile *prof = priv->prof; struct mlx4_en_dev *mdev = priv->mdev; + u8 tx_pause, tx_ppp, rx_pause, rx_ppp; if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return 1; if (priv->cee_config.pfc_state) { int tc; + rx_ppp = prof->rx_ppp; + tx_ppp = prof->tx_ppp; - priv->prof->rx_pause = 0; - priv->prof->tx_pause = 0; for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) { u8 tc_mask = 1 << tc; switch (priv->cee_config.dcb_pfc[tc]) { case pfc_disabled: - priv->prof->tx_ppp &= ~tc_mask; - priv->prof->rx_ppp &= ~tc_mask; + tx_ppp &= ~tc_mask; + rx_ppp &= ~tc_mask; break; case pfc_enabled_full: - priv->prof->tx_ppp |= tc_mask; - priv->prof->rx_ppp |= tc_mask; + tx_ppp |= tc_mask; + rx_ppp |= tc_mask; break; case pfc_enabled_tx: - priv->prof->tx_ppp |= tc_mask; - priv->prof->rx_ppp &= ~tc_mask; + tx_ppp |= tc_mask; + rx_ppp &= ~tc_mask; break; case pfc_enabled_rx: - priv->prof->tx_ppp &= ~tc_mask; - priv->prof->rx_ppp |= tc_mask; + tx_ppp &= ~tc_mask; + rx_ppp |= tc_mask; break; default: break; } } - en_dbg(DRV, priv, "Set pfc on\n"); + rx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->rx_pause; + tx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->tx_pause; } else { - priv->prof->rx_pause = 1; - priv->prof->tx_pause = 1; - en_dbg(DRV, priv, "Set pfc off\n"); + rx_ppp = 0; + tx_ppp = 0; + rx_pause = prof->rx_pause; + tx_pause = prof->tx_pause; } if (mlx4_SET_PORT_general(mdev->dev, priv->port, priv->rx_skb_size + ETH_FCS_LEN, - priv->prof->tx_pause, - priv->prof->tx_ppp, - priv->prof->rx_pause, - priv->prof->rx_ppp)) { + tx_pause, tx_ppp, rx_pause, rx_ppp)) { en_err(priv, "Failed setting pause params\n"); return 1; } + prof->tx_ppp = tx_ppp; + prof->rx_ppp = rx_ppp; + prof->tx_pause = tx_pause; + prof->rx_pause = rx_pause; + return 0; } @@ -408,6 +414,7 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev, struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_port_profile *prof = priv->prof; struct mlx4_en_dev *mdev = priv->mdev; + u32 tx_pause, tx_ppp, rx_pause, rx_ppp; int err; en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n", @@ -416,23 +423,26 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev, pfc->mbc, pfc->delay); - prof->rx_pause = !pfc->pfc_en; - prof->tx_pause = !pfc->pfc_en; - prof->rx_ppp = pfc->pfc_en; - prof->tx_ppp = pfc->pfc_en; + rx_pause = prof->rx_pause && !pfc->pfc_en; + tx_pause = prof->tx_pause && !pfc->pfc_en; + rx_ppp = pfc->pfc_en; + tx_ppp = pfc->pfc_en; err = mlx4_SET_PORT_general(mdev->dev, priv->port, priv->rx_skb_size + ETH_FCS_LEN, - prof->tx_pause, - prof->tx_ppp, - prof->rx_pause, - prof->rx_ppp); - if (err) + tx_pause, tx_ppp, rx_pause, rx_ppp); + if (err) { en_err(priv, "Failed setting pause params\n"); - else - mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap, - prof->rx_ppp, prof->rx_pause, - prof->tx_ppp, prof->tx_pause); + return err; + } + + mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap, + rx_ppp, rx_pause, tx_ppp, tx_pause); + + prof->tx_ppp = tx_ppp; + prof->rx_ppp = rx_ppp; + prof->rx_pause = rx_pause; + prof->tx_pause = tx_pause; return err; } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index bdda17d2ea0f..24977cc881d2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1003,27 +1003,32 @@ static int mlx4_en_set_pauseparam(struct net_device *dev, { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; + u8 tx_pause, tx_ppp, rx_pause, rx_ppp; int err; if (pause->autoneg) return -EINVAL; - priv->prof->tx_pause = pause->tx_pause != 0; - priv->prof->rx_pause = pause->rx_pause != 0; + tx_pause = !!(pause->tx_pause); + rx_pause = !!(pause->rx_pause); + rx_ppp = priv->prof->rx_ppp && !(tx_pause || rx_pause); + tx_ppp = priv->prof->tx_ppp && !(tx_pause || rx_pause); + err = mlx4_SET_PORT_general(mdev->dev, priv->port, priv->rx_skb_size + ETH_FCS_LEN, - priv->prof->tx_pause, - priv->prof->tx_ppp, - priv->prof->rx_pause, - priv->prof->rx_ppp); - if (err) - en_err(priv, "Failed setting pause params\n"); - else - mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap, - priv->prof->rx_ppp, - priv->prof->rx_pause, - priv->prof->tx_ppp, - priv->prof->tx_pause); + tx_pause, tx_ppp, rx_pause, rx_ppp); + if (err) { + en_err(priv, "Failed setting pause params, err = %d\n", err); + return err; + } + + mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap, + rx_ppp, rx_pause, tx_ppp, tx_pause); + + priv->prof->tx_pause = tx_pause; + priv->prof->rx_pause = rx_pause; + priv->prof->tx_ppp = tx_ppp; + priv->prof->rx_ppp = rx_ppp; return err; } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index bf7628db098a..22c3fdd5482a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -163,9 +163,9 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) params->udp_rss = 0; } for (i = 1; i <= MLX4_MAX_PORTS; i++) { - params->prof[i].rx_pause = 1; + params->prof[i].rx_pause = !(pfcrx || pfctx); params->prof[i].rx_ppp = pfcrx; - params->prof[i].tx_pause = 1; + params->prof[i].tx_pause = !(pfcrx || pfctx); params->prof[i].tx_ppp = pfctx; params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; -- cgit v1.2.3 From 992dbb1d5a653c49a7f2159f75d9cda0d8248f1f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 29 Mar 2018 16:00:04 +0800 Subject: vhost: validate log when IOTLB is enabled [ Upstream commit d65026c6c62e7d9616c8ceb5a53b68bcdc050525 ] Vq log_base is the userspace address of bitmap which has nothing to do with IOTLB. So it needs to be validated unconditionally otherwise we may try use 0 as log_base which may lead to pin pages that will lead unexpected result (e.g trigger BUG_ON() in set_bit_to_user()). Fixes: 6b1e6cc7855b0 ("vhost: new device IOTLB API") Reported-by: syzbot+6304bf97ef436580fede@syzkaller.appspotmail.com Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 126730384d7d..e2c37aeed45a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1175,14 +1175,12 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, /* Caller should have vq mutex and device mutex */ int vhost_vq_access_ok(struct vhost_virtqueue *vq) { - if (vq->iotlb) { - /* When device IOTLB was used, the access validation - * will be validated during prefetching. - */ - return 1; - } - return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used) && - vq_log_access_ok(vq, vq->log_base); + int ret = vq_log_access_ok(vq, vq->log_base); + + if (ret || vq->iotlb) + return ret; + + return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used); } EXPORT_SYMBOL_GPL(vhost_vq_access_ok); -- cgit v1.2.3 From e0cfa0d3e53b6e4f2fd4280b2f9474e6fb8e13f4 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 26 Mar 2018 01:25:06 +0800 Subject: team: move dev_mc_sync after master_upper_dev_link in team_port_add [ Upstream commit 982cf3b3999d39a2eaca0a65542df33c19b5d814 ] The same fix as in 'bonding: move dev_mc_sync after master_upper_dev_link in bond_enslave' is needed for team driver. The panic can be reproduced easily: ip link add team1 type team ip link set team1 up ip link add link team1 vlan1 type vlan id 80 ip link set vlan1 master team1 Fixes: cb41c997d444 ("team: team should sync the port's uc/mc addrs when add a port") Signed-off-by: Xin Long Acked-by: Jiri Pirko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index a0a9c9d39f01..8673ef3c9cdc 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1203,11 +1203,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_dev_open; } - netif_addr_lock_bh(dev); - dev_uc_sync_multiple(port_dev, dev); - dev_mc_sync_multiple(port_dev, dev); - netif_addr_unlock_bh(dev); - err = vlan_vids_add_by_dev(port_dev, dev); if (err) { netdev_err(dev, "Failed to add vlan ids to device %s\n", @@ -1247,6 +1242,11 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_option_port_add; } + netif_addr_lock_bh(dev); + dev_uc_sync_multiple(port_dev, dev); + dev_mc_sync_multiple(port_dev, dev); + netif_addr_unlock_bh(dev); + port->index = -1; list_add_tail_rcu(&port->list, &team->port_list); team_port_enable(team, port); @@ -1271,8 +1271,6 @@ err_enable_netpoll: vlan_vids_del_by_dev(port_dev, dev); err_vids_add: - dev_uc_unsync(port_dev, dev); - dev_mc_unsync(port_dev, dev); dev_close(port_dev); err_dev_open: -- cgit v1.2.3 From 1cb81756b7c3813f7d65d3c6bb1133cb53b69775 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 26 Mar 2018 16:10:23 +0800 Subject: vhost_net: add missing lock nesting notation [ Upstream commit aaa3149bbee9ba9b4e6f0bd6e3e7d191edeae942 ] We try to hold TX virtqueue mutex in vhost_net_rx_peek_head_len() after RX virtqueue mutex is held in handle_rx(). This requires an appropriate lock nesting notation to calm down deadlock detector. Fixes: 0308813724606 ("vhost_net: basic polling support") Reported-by: syzbot+7f073540b1384a614e09@syzkaller.appspotmail.com Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index e5b7652234fc..487586e2d8b9 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -524,7 +524,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk) if (!len && vq->busyloop_timeout) { /* Both tx vq and rx socket were polled here */ - mutex_lock(&vq->mutex); + mutex_lock_nested(&vq->mutex, 1); vhost_disable_notify(&net->dev, vq); preempt_disable(); @@ -657,7 +657,7 @@ static void handle_rx(struct vhost_net *net) struct iov_iter fixup; __virtio16 num_buffers; - mutex_lock(&vq->mutex); + mutex_lock_nested(&vq->mutex, 0); sock = vq->private_data; if (!sock) goto out; -- cgit v1.2.3 From 3d392d2e3ed5b59b995da08a8deb3abb3e48b99b Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Tue, 27 Mar 2018 14:41:19 +0300 Subject: net/mlx4_core: Fix memory leak while delete slave's resources [ Upstream commit 461d5f1b59490ce0096dfda45e10038c122a7892 ] mlx4_delete_all_resources_for_slave in resource tracker should free all memory allocated for a slave. While releasing memory of fs_rule, it misses releasing memory of fs_rule->mirr_mbox. Fixes: 78efed275117 ('net/mlx4_core: Support mirroring VF DMFS rules on both ports') Signed-off-by: Moshe Shemesh Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 8fd1b1ab7d81..d6b06bef1b69 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -5048,6 +5048,7 @@ static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave) &tracker->res_tree[RES_FS_RULE]); list_del(&fs_rule->com.list); spin_unlock_irq(mlx4_tlock(dev)); + kfree(fs_rule->mirr_mbox); kfree(fs_rule); state = 0; break; -- cgit v1.2.3 From 89cd658056d24f8fbde817a263674a5253d4f427 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 29 Mar 2018 12:49:52 -0700 Subject: vrf: Fix use after free and double free in vrf_finish_output commit 82dd0d2a9a76fc8fa2b18d80b987d455728bf83a upstream. Miguel reported an skb use after free / double free in vrf_finish_output when neigh_output returns an error. The vrf driver should return after the call to neigh_output as it takes over the skb on error path as well. Patch is a simplified version of Miguel's patch which was written for 4.9, and updated to top of tree. Fixes: 8f58336d3f78a ("net: Add ethernet header for pass through VRF device") Signed-off-by: Miguel Fadon Perlines Signed-off-by: David Ahern Signed-off-by: David S. Miller [ backport to 4.4 and 4.9 dropped the sock_confirm_neigh and changed neigh_output to dst_neigh_output ] Signed-off-by: Greg Kroah-Hartman --- drivers/net/vrf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 346e48698555..42c9480acdc7 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -585,13 +585,15 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s neigh = __ipv4_neigh_lookup_noref(dev, nexthop); if (unlikely(!neigh)) neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); - if (!IS_ERR(neigh)) + if (!IS_ERR(neigh)) { ret = dst_neigh_output(dst, neigh, skb); + rcu_read_unlock_bh(); + return ret; + } rcu_read_unlock_bh(); err: - if (unlikely(ret < 0)) - vrf_tx_error(skb->dev, skb); + vrf_tx_error(skb->dev, skb); return ret; } -- cgit v1.2.3 From 0efce82a41ce9b9cd1371622011a85827c099d0f Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Thu, 12 Apr 2018 17:29:51 -0700 Subject: Revert "xhci: plat: Register shutdown for xhci_plat" Pixel 2 field testers reported that when they tried to reboot their phones with some USB devices plugged in, the reboot would get wedged and eventually trigger watchdog reset. Once the Pixel kernel team found a reliable repro case, they narrowed it down to this commit's 4.4.y backport. Reverting the change made the issue go away. This reverts commit b07c12517f2aed0add8ce18146bb426b14099392. Signed-off-by: Greg Hackmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index dec100811946..ca8b0b1ae37d 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -335,7 +335,6 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); static struct platform_driver usb_xhci_driver = { .probe = xhci_plat_probe, .remove = xhci_plat_remove, - .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "xhci-hcd", .pm = DEV_PM_OPS, -- cgit v1.2.3 From 394a9a7b7387e5cc8661b45e9bd111c850437c8e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 28 Mar 2018 13:59:22 -0400 Subject: media: v4l2-compat-ioctl32: don't oops on overlay commit 85ea29f19eab56ec16ec6b92bc67305998706afa upstream. At put_v4l2_window32(), it tries to access kp->clips. However, kp points to an userspace pointer. So, it should be obtained via get_user(), otherwise it can OOPS: vivid-000: ================== END STATUS ================== BUG: unable to handle kernel paging request at 00000000fffb18e0 IP: [] __put_v4l2_format32+0x169/0x220 [videodev] PGD 3f5776067 PUD 3f576f067 PMD 3f5769067 PTE 800000042548f067 Oops: 0001 [#1] SMP Modules linked in: vivid videobuf2_vmalloc videobuf2_memops v4l2_dv_timings videobuf2_core v4l2_common videodev media xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill binfmt_misc snd_hda_codec_hdmi i915 snd_hda_intel snd_hda_controller snd_hda_codec intel_rapl x86_pkg_temp_thermal snd_hwdep intel_powerclamp snd_pcm coretemp snd_seq_midi kvm_intel kvm snd_seq_midi_event snd_rawmidi i2c_algo_bit drm_kms_helper snd_seq drm crct10dif_pclmul e1000e snd_seq_device crc32_pclmul snd_timer ghash_clmulni_intel snd mei_me mei ptp pps_core soundcore lpc_ich video crc32c_intel [last unloaded: media] CPU: 2 PID: 28332 Comm: v4l2-compliance Not tainted 3.18.102+ #107 Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017 task: ffff8804293f8000 ti: ffff8803f5640000 task.ti: ffff8803f5640000 RIP: 0010:[] [] __put_v4l2_format32+0x169/0x220 [videodev] RSP: 0018:ffff8803f5643e28 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000fffb1ab4 RDX: 00000000fffb1a68 RSI: 00000000fffb18d8 RDI: 00000000fffb1aa8 RBP: ffff8803f5643e48 R08: 0000000000000001 R09: ffff8803f54b0378 R10: 0000000000000000 R11: 0000000000000168 R12: 00000000fffb18c0 R13: 00000000fffb1a94 R14: 00000000fffb18c8 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff880456d00000(0063) knlGS:00000000f7100980 CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 CR2: 00000000fffb18e0 CR3: 00000003f552b000 CR4: 00000000003407e0 Stack: 00000000fffb1a94 00000000c0cc5640 0000000000000056 ffff8804274f3600 ffff8803f5643ed0 ffffffffc0547e16 0000000000000003 ffff8803f5643eb0 ffffffff81301460 ffff88009db44b01 ffff880441942520 ffff8800c0d05640 Call Trace: [] v4l2_compat_ioctl32+0x12d6/0x1b1d [videodev] [] ? file_has_perm+0x70/0xc0 [] compat_SyS_ioctl+0xec/0x1200 [] sysenter_dispatch+0x7/0x21 Code: 00 00 48 8b 80 48 c0 ff ff 48 83 e8 38 49 39 c6 0f 87 2b ff ff ff 49 8d 45 1c e8 a3 ce e3 c0 85 c0 0f 85 1a ff ff ff 41 8d 40 ff <4d> 8b 64 24 20 41 89 d5 48 8d 44 40 03 4d 8d 34 c4 eb 15 0f 1f RIP [] __put_v4l2_format32+0x169/0x220 [videodev] RSP CR2: 00000000fffb18e0 Tested with vivid driver on Kernel v3.18.102. Same bug happens upstream too: BUG: KASAN: user-memory-access in __put_v4l2_format32+0x98/0x4d0 [videodev] Read of size 8 at addr 00000000ffe48400 by task v4l2-compliance/8713 CPU: 0 PID: 8713 Comm: v4l2-compliance Not tainted 4.16.0-rc4+ #108 Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017 Call Trace: dump_stack+0x5c/0x7c kasan_report+0x164/0x380 ? __put_v4l2_format32+0x98/0x4d0 [videodev] __put_v4l2_format32+0x98/0x4d0 [videodev] v4l2_compat_ioctl32+0x1aec/0x27a0 [videodev] ? __fsnotify_inode_delete+0x20/0x20 ? __put_v4l2_format32+0x4d0/0x4d0 [videodev] compat_SyS_ioctl+0x646/0x14d0 ? do_ioctl+0x30/0x30 do_fast_syscall_32+0x191/0x3f4 entry_SYSENTER_compat+0x6b/0x7a ================================================================== Disabling lock debugging due to kernel taint BUG: unable to handle kernel paging request at 00000000ffe48400 IP: __put_v4l2_format32+0x98/0x4d0 [videodev] PGD 3a22fb067 P4D 3a22fb067 PUD 39b6f0067 PMD 39b6f1067 PTE 80000003256af067 Oops: 0001 [#1] SMP KASAN Modules linked in: vivid videobuf2_vmalloc videobuf2_dma_contig videobuf2_memops v4l2_tpg v4l2_dv_timings videobuf2_v4l2 videobuf2_common v4l2_common videodev xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack libcrc32c tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill ecdh_generic binfmt_misc snd_hda_codec_hdmi intel_rapl x86_pkg_temp_thermal intel_powerclamp i915 coretemp snd_hda_intel snd_hda_codec kvm_intel snd_hwdep snd_hda_core kvm snd_pcm irqbypass crct10dif_pclmul crc32_pclmul snd_seq_midi ghash_clmulni_intel snd_seq_midi_event i2c_algo_bit intel_cstate snd_rawmidi intel_uncore snd_seq drm_kms_helper e1000e snd_seq_device snd_timer intel_rapl_perf drm ptp snd mei_me mei lpc_ich pps_core soundcore video crc32c_intel CPU: 0 PID: 8713 Comm: v4l2-compliance Tainted: G B 4.16.0-rc4+ #108 Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017 RIP: 0010:__put_v4l2_format32+0x98/0x4d0 [videodev] RSP: 0018:ffff8803b9be7d30 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff8803ac983e80 RCX: ffffffff8cd929f2 RDX: 1ffffffff1d0a149 RSI: 0000000000000297 RDI: 0000000000000297 RBP: 00000000ffe485c0 R08: fffffbfff1cf5123 R09: ffffffff8e7a8948 R10: 0000000000000001 R11: fffffbfff1cf5122 R12: 00000000ffe483e0 R13: 00000000ffe485c4 R14: ffff8803ac985918 R15: 00000000ffe483e8 FS: 0000000000000000(0000) GS:ffff880407400000(0063) knlGS:00000000f7a46980 CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 CR2: 00000000ffe48400 CR3: 00000003a83f2003 CR4: 00000000003606f0 Call Trace: v4l2_compat_ioctl32+0x1aec/0x27a0 [videodev] ? __fsnotify_inode_delete+0x20/0x20 ? __put_v4l2_format32+0x4d0/0x4d0 [videodev] compat_SyS_ioctl+0x646/0x14d0 ? do_ioctl+0x30/0x30 do_fast_syscall_32+0x191/0x3f4 entry_SYSENTER_compat+0x6b/0x7a Code: 4c 89 f7 4d 8d 7c 24 08 e8 e6 a4 69 cb 48 8b 83 98 1a 00 00 48 83 e8 10 49 39 c7 0f 87 9d 01 00 00 49 8d 7c 24 20 e8 c8 a4 69 cb <4d> 8b 74 24 20 4c 89 ef 4c 89 fe ba 10 00 00 00 e8 23 d9 08 cc RIP: __put_v4l2_format32+0x98/0x4d0 [videodev] RSP: ffff8803b9be7d30 CR2: 00000000ffe48400 cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Sakari Ailus Reviewed-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 48a39222fdf9..a9fc64557c53 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -101,7 +101,7 @@ static int get_v4l2_window32(struct v4l2_window __user *kp, static int put_v4l2_window32(struct v4l2_window __user *kp, struct v4l2_window32 __user *up) { - struct v4l2_clip __user *kclips = kp->clips; + struct v4l2_clip __user *kclips; struct v4l2_clip32 __user *uclips; compat_caddr_t p; u32 clipcount; @@ -116,6 +116,8 @@ static int put_v4l2_window32(struct v4l2_window __user *kp, if (!clipcount) return 0; + if (get_user(kclips, &kp->clips)) + return -EFAULT; if (get_user(p, &up->clips)) return -EFAULT; uclips = compat_ptr(p); -- cgit v1.2.3 From 6408066f849ee17f0db76e8f091b759242ea2f52 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Tue, 27 Mar 2018 15:01:02 -0700 Subject: Drivers: hv: vmbus: do not mark HV_PCIE as perf_device commit 238064f13d057390a8c5e1a6a80f4f0a0ec46499 upstream. The pci-hyperv driver's channel callback hv_pci_onchannelcallback() is not really a hot path, so we don't need to mark it as a perf_device, meaning with this patch all HV_PCIE channels' target_cpu will be CPU0. Signed-off-by: Dexuan Cui Cc: stable@vger.kernel.org Cc: Stephen Hemminger Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index d8bc4b910192..9360cdce740e 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -70,7 +70,7 @@ static const struct vmbus_device vmbus_devs[] = { /* PCIE */ { .dev_type = HV_PCIE, HV_PCIE_GUID, - .perf_device = true, + .perf_device = false, }, /* Synthetic Frame Buffer */ -- cgit v1.2.3 From cacf021760ee51ef163b1094c9163a863be6b104 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Feb 2018 16:26:57 +0100 Subject: radeon: hide pointless #warning when compile testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c02216acf4177c4411d33735c81cad687790fa59 upstream. In randconfig testing, we sometimes get this warning: drivers/gpu/drm/radeon/radeon_object.c: In function 'radeon_bo_create': drivers/gpu/drm/radeon/radeon_object.c:242:2: error: #warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance thanks to write-combining [-Werror=cpp] #warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \ This is rather annoying since almost all other code produces no build-time output unless we have found a real bug. We already fixed this in the amdgpu driver in commit 31bb90f1cd08 ("drm/amdgpu: shut up #warning for compile testing") by adding a CONFIG_COMPILE_TEST check last year and agreed to do the same here, but both Michel and I then forgot about it until I came across the issue again now. For stable kernels, as this is one of very few remaining randconfig warnings in 4.14. Cc: stable@vger.kernel.org Link: https://patchwork.kernel.org/patch/9550009/ Signed-off-by: Arnd Bergmann Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 41b72ce6613f..83e1345db9e2 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -238,9 +238,10 @@ int radeon_bo_create(struct radeon_device *rdev, * may be slow * See https://bugs.freedesktop.org/show_bug.cgi?id=88758 */ - +#ifndef CONFIG_COMPILE_TEST #warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \ thanks to write-combining +#endif if (bo->flags & RADEON_GEM_GTT_WC) DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for " -- cgit v1.2.3 From 6289541c4804c7ed81d7f8a97de7be9a88297752 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 12 Apr 2018 12:11:10 +0100 Subject: drivers/firmware: Expose psci_get_version through psci_ops structure From: Will Deacon commit d68e3ba5303f7e1099f51fdcd155f5263da8569b upstream. Entry into recent versions of ARM Trusted Firmware will invalidate the CPU branch predictor state in order to protect against aliasing attacks. This patch exposes the PSCI "VERSION" function via psci_ops, so that it can be invoked outside of the PSCI driver where necessary. Acked-by: Lorenzo Pieralisi Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas Signed-off-by: Mark Rutland [v4.9 backport] Tested-by: Greg Hackmann Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/psci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 8263429e21b8..9a3ce76304b6 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -496,6 +496,8 @@ static void __init psci_init_migrate(void) static void __init psci_0_2_set_functions(void) { pr_info("Using standard PSCI v0.2 function IDs\n"); + psci_ops.get_version = psci_get_version; + psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_FN_NATIVE(0_2, CPU_SUSPEND); psci_ops.cpu_suspend = psci_cpu_suspend; -- cgit v1.2.3 From 56d37971abfc59d6c6eaafab9bd4d62445c1d66f Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 12 Apr 2018 12:11:33 +0100 Subject: firmware/psci: Expose PSCI conduit From: Marc Zyngier commit 09a8d6d48499f93e2abde691f5800081cd858726 upstream. In order to call into the firmware to apply workarounds, it is useful to find out whether we're using HVC or SMC. Let's expose this through the psci_ops. Acked-by: Lorenzo Pieralisi Reviewed-by: Robin Murphy Tested-by: Ard Biesheuvel Signed-off-by: Marc Zyngier Signed-off-by: Catalin Marinas Signed-off-by: Mark Rutland [v4.9 backport] Tested-by: Greg Hackmann Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/psci.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 9a3ce76304b6..a49196ae0840 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -59,7 +59,9 @@ bool psci_tos_resident_on(int cpu) return cpu == resident_cpu; } -struct psci_operations psci_ops; +struct psci_operations psci_ops = { + .conduit = PSCI_CONDUIT_NONE, +}; typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); @@ -210,6 +212,22 @@ static unsigned long psci_migrate_info_up_cpu(void) 0, 0, 0); } +static void set_conduit(enum psci_conduit conduit) +{ + switch (conduit) { + case PSCI_CONDUIT_HVC: + invoke_psci_fn = __invoke_psci_fn_hvc; + break; + case PSCI_CONDUIT_SMC: + invoke_psci_fn = __invoke_psci_fn_smc; + break; + default: + WARN(1, "Unexpected PSCI conduit %d\n", conduit); + } + + psci_ops.conduit = conduit; +} + static int get_set_conduit_method(struct device_node *np) { const char *method; @@ -222,9 +240,9 @@ static int get_set_conduit_method(struct device_node *np) } if (!strcmp("hvc", method)) { - invoke_psci_fn = __invoke_psci_fn_hvc; + set_conduit(PSCI_CONDUIT_HVC); } else if (!strcmp("smc", method)) { - invoke_psci_fn = __invoke_psci_fn_smc; + set_conduit(PSCI_CONDUIT_SMC); } else { pr_warn("invalid \"method\" property: %s\n", method); return -EINVAL; @@ -654,9 +672,9 @@ int __init psci_acpi_init(void) pr_info("probing for conduit method from ACPI.\n"); if (acpi_psci_use_hvc()) - invoke_psci_fn = __invoke_psci_fn_hvc; + set_conduit(PSCI_CONDUIT_HVC); else - invoke_psci_fn = __invoke_psci_fn_smc; + set_conduit(PSCI_CONDUIT_SMC); return psci_probe(); } -- cgit v1.2.3 From 883a91d37ff3809d3c5a144ec0a59f4f68509acc Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 12 Apr 2018 12:11:34 +0100 Subject: firmware/psci: Expose SMCCC version through psci_ops From: Marc Zyngier commit e78eef554a912ef6c1e0bbf97619dafbeae3339f upstream. Since PSCI 1.0 allows the SMCCC version to be (indirectly) probed, let's do that at boot time, and expose the version of the calling convention as part of the psci_ops structure. Acked-by: Lorenzo Pieralisi Reviewed-by: Robin Murphy Tested-by: Ard Biesheuvel Signed-off-by: Marc Zyngier Signed-off-by: Catalin Marinas Signed-off-by: Mark Rutland [v4.9 backport] Tested-by: Greg Hackmann Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/psci.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index a49196ae0840..79a48c37fb35 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -61,6 +61,7 @@ bool psci_tos_resident_on(int cpu) struct psci_operations psci_ops = { .conduit = PSCI_CONDUIT_NONE, + .smccc_version = SMCCC_VERSION_1_0, }; typedef unsigned long (psci_fn)(unsigned long, unsigned long, @@ -511,6 +512,31 @@ static void __init psci_init_migrate(void) pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid); } +static void __init psci_init_smccc(void) +{ + u32 ver = ARM_SMCCC_VERSION_1_0; + int feature; + + feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID); + + if (feature != PSCI_RET_NOT_SUPPORTED) { + u32 ret; + ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0); + if (ret == ARM_SMCCC_VERSION_1_1) { + psci_ops.smccc_version = SMCCC_VERSION_1_1; + ver = ret; + } + } + + /* + * Conveniently, the SMCCC and PSCI versions are encoded the + * same way. No, this isn't accidental. + */ + pr_info("SMC Calling Convention v%d.%d\n", + PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver)); + +} + static void __init psci_0_2_set_functions(void) { pr_info("Using standard PSCI v0.2 function IDs\n"); @@ -559,6 +585,7 @@ static int __init psci_probe(void) psci_init_migrate(); if (PSCI_VERSION_MAJOR(ver) >= 1) { + psci_init_smccc(); psci_init_cpu_suspend(); psci_init_system_suspend(); } -- cgit v1.2.3 From c3530143fe2442b2b84abe4d720efb2cf6ec4338 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Fri, 6 Apr 2018 10:03:17 +0900 Subject: block/loop: fix deadlock after loop_set_status commit 1e047eaab3bb5564f25b41e9cd3a053009f4e789 upstream. syzbot is reporting deadlocks at __blkdev_get() [1]. ---------------------------------------- [ 92.493919] systemd-udevd D12696 525 1 0x00000000 [ 92.495891] Call Trace: [ 92.501560] schedule+0x23/0x80 [ 92.502923] schedule_preempt_disabled+0x5/0x10 [ 92.504645] __mutex_lock+0x416/0x9e0 [ 92.510760] __blkdev_get+0x73/0x4f0 [ 92.512220] blkdev_get+0x12e/0x390 [ 92.518151] do_dentry_open+0x1c3/0x2f0 [ 92.519815] path_openat+0x5d9/0xdc0 [ 92.521437] do_filp_open+0x7d/0xf0 [ 92.527365] do_sys_open+0x1b8/0x250 [ 92.528831] do_syscall_64+0x6e/0x270 [ 92.530341] entry_SYSCALL_64_after_hwframe+0x42/0xb7 [ 92.931922] 1 lock held by systemd-udevd/525: [ 92.933642] #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x73/0x4f0 ---------------------------------------- The reason of deadlock turned out that wait_event_interruptible() in blk_queue_enter() got stuck with bdev->bd_mutex held at __blkdev_put() due to q->mq_freeze_depth == 1. ---------------------------------------- [ 92.787172] a.out S12584 634 633 0x80000002 [ 92.789120] Call Trace: [ 92.796693] schedule+0x23/0x80 [ 92.797994] blk_queue_enter+0x3cb/0x540 [ 92.803272] generic_make_request+0xf0/0x3d0 [ 92.807970] submit_bio+0x67/0x130 [ 92.810928] submit_bh_wbc+0x15e/0x190 [ 92.812461] __block_write_full_page+0x218/0x460 [ 92.815792] __writepage+0x11/0x50 [ 92.817209] write_cache_pages+0x1ae/0x3d0 [ 92.825585] generic_writepages+0x5a/0x90 [ 92.831865] do_writepages+0x43/0xd0 [ 92.836972] __filemap_fdatawrite_range+0xc1/0x100 [ 92.838788] filemap_write_and_wait+0x24/0x70 [ 92.840491] __blkdev_put+0x69/0x1e0 [ 92.841949] blkdev_close+0x16/0x20 [ 92.843418] __fput+0xda/0x1f0 [ 92.844740] task_work_run+0x87/0xb0 [ 92.846215] do_exit+0x2f5/0xba0 [ 92.850528] do_group_exit+0x34/0xb0 [ 92.852018] SyS_exit_group+0xb/0x10 [ 92.853449] do_syscall_64+0x6e/0x270 [ 92.854944] entry_SYSCALL_64_after_hwframe+0x42/0xb7 [ 92.943530] 1 lock held by a.out/634: [ 92.945105] #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_put+0x3c/0x1e0 ---------------------------------------- The reason of q->mq_freeze_depth == 1 turned out that loop_set_status() forgot to call blk_mq_unfreeze_queue() at error paths for info->lo_encrypt_type != NULL case. ---------------------------------------- [ 37.509497] CPU: 2 PID: 634 Comm: a.out Tainted: G W 4.16.0+ #457 [ 37.513608] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017 [ 37.518832] RIP: 0010:blk_freeze_queue_start+0x17/0x40 [ 37.521778] RSP: 0018:ffffb0c2013e7c60 EFLAGS: 00010246 [ 37.524078] RAX: 0000000000000000 RBX: ffff8b07b1519798 RCX: 0000000000000000 [ 37.527015] RDX: 0000000000000002 RSI: ffffb0c2013e7cc0 RDI: ffff8b07b1519798 [ 37.529934] RBP: ffffb0c2013e7cc0 R08: 0000000000000008 R09: 47a189966239b898 [ 37.532684] R10: dad78b99b278552f R11: 9332dca72259d5ef R12: ffff8b07acd73678 [ 37.535452] R13: 0000000000004c04 R14: 0000000000000000 R15: ffff8b07b841e940 [ 37.538186] FS: 00007fede33b9740(0000) GS:ffff8b07b8e80000(0000) knlGS:0000000000000000 [ 37.541168] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 37.543590] CR2: 00000000206fdf18 CR3: 0000000130b30006 CR4: 00000000000606e0 [ 37.546410] Call Trace: [ 37.547902] blk_freeze_queue+0x9/0x30 [ 37.549968] loop_set_status+0x67/0x3c0 [loop] [ 37.549975] loop_set_status64+0x3b/0x70 [loop] [ 37.549986] lo_ioctl+0x223/0x810 [loop] [ 37.549995] blkdev_ioctl+0x572/0x980 [ 37.550003] block_ioctl+0x34/0x40 [ 37.550006] do_vfs_ioctl+0xa7/0x6d0 [ 37.550017] ksys_ioctl+0x6b/0x80 [ 37.573076] SyS_ioctl+0x5/0x10 [ 37.574831] do_syscall_64+0x6e/0x270 [ 37.576769] entry_SYSCALL_64_after_hwframe+0x42/0xb7 ---------------------------------------- [1] https://syzkaller.appspot.com/bug?id=cd662bc3f6022c0979d01a262c318fab2ee9b56f Signed-off-by: Tetsuo Handa Reported-by: syzbot Fixes: ecdd09597a572513 ("block/loop: fix race between I/O and set_status") Cc: Ming Lei Cc: Dmitry Vyukov Cc: stable Cc: Jens Axboe Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index dc318b9100c2..ff1c4d7aa025 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1110,11 +1110,15 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (info->lo_encrypt_type) { unsigned int type = info->lo_encrypt_type; - if (type >= MAX_LO_CRYPT) - return -EINVAL; + if (type >= MAX_LO_CRYPT) { + err = -EINVAL; + goto exit; + } xfer = xfer_funcs[type]; - if (xfer == NULL) - return -EINVAL; + if (xfer == NULL) { + err = -EINVAL; + goto exit; + } } else xfer = NULL; -- cgit v1.2.3 From 768fce44221a2db5a68fdd1bd12dd2aed107cfe0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 Apr 2018 16:49:30 -0700 Subject: nfit: fix region registration vs block-data-window ranges commit 8d0d8ed3356aa9ed43b819aaedd39b08ca453007 upstream. Commit 1cf03c00e7c1 "nfit: scrub and register regions in a workqueue" mistakenly attempts to register a region per BLK aperture. There is nothing to register for individual apertures as they belong as a set to a BLK aperture group that are registered with a corresponding DIMM-control-region. Filter them for registration to prevent some needless devm_kzalloc() allocations. Cc: Fixes: 1cf03c00e7c1 ("nfit: scrub and register regions in a workqueue") Reviewed-by: Dave Jiang Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/nfit/core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index b1815b20a99c..37032545c58e 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -2547,15 +2547,21 @@ static void acpi_nfit_scrub(struct work_struct *work) static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc) { struct nfit_spa *nfit_spa; - int rc; - list_for_each_entry(nfit_spa, &acpi_desc->spas, list) - if (nfit_spa_type(nfit_spa->spa) == NFIT_SPA_DCR) { - /* BLK regions don't need to wait for ars results */ - rc = acpi_nfit_register_region(acpi_desc, nfit_spa); - if (rc) - return rc; - } + list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { + int rc, type = nfit_spa_type(nfit_spa->spa); + + /* PMEM and VMEM will be registered by the ARS workqueue */ + if (type == NFIT_SPA_PM || type == NFIT_SPA_VOLATILE) + continue; + /* BLK apertures belong to BLK region registration below */ + if (type == NFIT_SPA_BDW) + continue; + /* BLK regions don't need to wait for ARS results */ + rc = acpi_nfit_register_region(acpi_desc, nfit_spa); + if (rc) + return rc; + } queue_work(nfit_wq, &acpi_desc->work); return 0; -- cgit v1.2.3 From deda8e039680411eb881fcea17f5a358bc4c4589 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Mon, 5 Mar 2018 09:39:38 +0100 Subject: s390/qdio: don't retry EQBS after CCQ 96 commit dae55b6fef58530c13df074bcc182c096609339e upstream. Immediate retry of EQBS after CCQ 96 means that we potentially misreport the state of buffers inspected during the first EQBS call. This occurs when 1. the first EQBS finds all inspected buffers still in the initial state set by the driver (ie INPUT EMPTY or OUTPUT PRIMED), 2. the EQBS terminates early with CCQ 96, and 3. by the time that the second EQBS comes around, the state of those previously inspected buffers has changed. If the state reported by the second EQBS is 'driver-owned', all we know is that the previous buffers are driver-owned now as well. But we can't tell if they all have the same state. So for instance - the second EQBS reports OUTPUT EMPTY, but any number of the previous buffers could be OUTPUT ERROR by now, - the second EQBS reports OUTPUT ERROR, but any number of the previous buffers could be OUTPUT EMPTY by now. Effectively, this can result in both over- and underreporting of errors. If the state reported by the second EQBS is 'HW-owned', that doesn't guarantee that the previous buffers have not been switched to driver-owned in the mean time. So for instance - the second EQBS reports INPUT EMPTY, but any number of the previous buffers could be INPUT PRIMED (or INPUT ERROR) by now. This would result in failure to process pending work on the queue. If it's the final check before yielding initiative, this can cause a (temporary) queue stall due to IRQ avoidance. Fixes: 25f269f17316 ("[S390] qdio: EQBS retry after CCQ 96") Cc: #v3.2+ Signed-off-by: Julian Wiedmann Reviewed-by: Benjamin Block Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/qdio_main.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 71bf9bded485..601010f2d270 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -126,7 +126,7 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq) static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, int start, int count, int auto_ack) { - int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0; + int rc, tmp_count = count, tmp_start = start, nr = q->nr; unsigned int ccq = 0; qperf_inc(q, eqbs); @@ -149,14 +149,7 @@ again: qperf_inc(q, eqbs_partial); DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x", tmp_count); - /* - * Retry once, if that fails bail out and process the - * extracted buffers before trying again. - */ - if (!retried++) - goto again; - else - return count - tmp_count; + return count - tmp_count; } DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); -- cgit v1.2.3 From 5a768873810afbd22b1c22a9f2d962b3fde10312 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 7 Mar 2018 14:01:01 +0100 Subject: s390/qdio: don't merge ERROR output buffers commit 0cf1e05157b9e5530dcc3ca9fec9bf617fc93375 upstream. On an Output queue, both EMPTY and PENDING buffer states imply that the buffer is ready for completion-processing by the upper-layer drivers. So for a non-QEBSM Output queue, get_buf_states() merges mixed batches of PENDING and EMPTY buffers into one large batch of EMPTY buffers. The upper-layer driver (ie. qeth) later distuingishes PENDING from EMPTY by inspecting the slsb_state for QDIO_OUTBUF_STATE_FLAG_PENDING. But the merge logic in get_buf_states() contains a bug that causes us to erronously also merge ERROR buffers into such a batch of EMPTY buffers (ERROR is 0xaf, EMPTY is 0xa1; so ERROR & EMPTY == EMPTY). Effectively, most outbound ERROR buffers are currently discarded silently and processed as if they had succeeded. Note that this affects _all_ non-QEBSM device types, not just IQD with CQ. Fix it by explicitly spelling out the exact conditions for merging. For extracting the "get initial state" part out of the loop, this relies on the fact that get_buf_states() is never called with a count of 0. The QEBSM path already strictly requires this, and the two callers with variable 'count' make sure of it. Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") Cc: #v3.2+ Signed-off-by: Julian Wiedmann Reviewed-by: Ursula Braun Reviewed-by: Benjamin Block Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/qdio_main.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 601010f2d270..66e9bb053629 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -205,7 +205,10 @@ again: return 0; } -/* returns number of examined buffers and their common state in *state */ +/* + * Returns number of examined buffers and their common state in *state. + * Requested number of buffers-to-examine must be > 0. + */ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, unsigned char *state, unsigned int count, int auto_ack, int merge_pending) @@ -216,17 +219,23 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, if (is_qebsm(q)) return qdio_do_eqbs(q, state, bufnr, count, auto_ack); - for (i = 0; i < count; i++) { - if (!__state) { - __state = q->slsb.val[bufnr]; - if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) - __state = SLSB_P_OUTPUT_EMPTY; - } else if (merge_pending) { - if ((q->slsb.val[bufnr] & __state) != __state) - break; - } else if (q->slsb.val[bufnr] != __state) - break; + /* get initial state: */ + __state = q->slsb.val[bufnr]; + if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) + __state = SLSB_P_OUTPUT_EMPTY; + + for (i = 1; i < count; i++) { bufnr = next_buf(bufnr); + + /* merge PENDING into EMPTY: */ + if (merge_pending && + q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING && + __state == SLSB_P_OUTPUT_EMPTY) + continue; + + /* stop if next state differs from initial state: */ + if (q->slsb.val[bufnr] != __state) + break; } *state = __state; return i; -- cgit v1.2.3 From bcd7de03d68a6953d00453bc1380ee34d2f4e000 Mon Sep 17 00:00:00 2001 From: Sudhir Sreedharan Date: Thu, 15 Feb 2018 12:52:45 +0530 Subject: rtl8187: Fix NULL pointer dereference in priv->conf_mutex commit 7972326a26b5bf8dc2adac575c4e03ee7e9d193a upstream. This can be reproduced by bind/unbind the driver multiple times in AM3517 board. Analysis revealed that rtl8187_start() was invoked before probe finishes(ie. before the mutex is initialized). INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250 Hardware name: Generic AM3517 (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (register_lock_class+0x4f4/0x55c) [] (register_lock_class) from [] (__lock_acquire+0x74/0x1938) [] (__lock_acquire) from [] (lock_acquire+0xfc/0x23c) [] (lock_acquire) from [] (mutex_lock_nested+0x50/0x3b0) [] (mutex_lock_nested) from [] (rtl8187_start+0x2c/0xd54) [] (rtl8187_start) from [] (drv_start+0xa8/0x320) [] (drv_start) from [] (ieee80211_do_open+0x2bc/0x8e4) [] (ieee80211_do_open) from [] (__dev_open+0xb8/0x120) [] (__dev_open) from [] (__dev_change_flags+0x88/0x14c) [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [] (dev_change_flags) from [] (devinet_ioctl+0x738/0x840) [] (devinet_ioctl) from [] (sock_ioctl+0x164/0x2f4) [] (sock_ioctl) from [] (do_vfs_ioctl+0x8c/0x9d0) [] (do_vfs_ioctl) from [] (SyS_ioctl+0x6c/0x7c) [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x1c) Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = cd1ec000 [00000000] *pgd=8d1de831, *pte=00000000, *ppte=00000000 Internal error: Oops: 817 [#1] PREEMPT ARM Modules linked in: CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250 Hardware name: Generic AM3517 (Flattened Device Tree) task: ce73eec0 task.stack: cd1ea000 PC is at mutex_lock_nested+0xe8/0x3b0 LR is at mutex_lock_nested+0xd0/0x3b0 Cc: stable@vger.kernel.org Signed-off-by: Sudhir Sreedharan Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c index 231f84db9ab0..6113624ccec3 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -1454,6 +1454,7 @@ static int rtl8187_probe(struct usb_interface *intf, goto err_free_dev; } mutex_init(&priv->io_mutex); + mutex_init(&priv->conf_mutex); SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); @@ -1627,7 +1628,6 @@ static int rtl8187_probe(struct usb_interface *intf, printk(KERN_ERR "rtl8187: Cannot register device\n"); goto err_free_dmabuf; } - mutex_init(&priv->conf_mutex); skb_queue_head_init(&priv->b_tx_status.queue); wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", -- cgit v1.2.3 From ebdb0d5abc412a5461db8a1a562551d6b643d578 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 15 Jan 2018 14:58:21 +0100 Subject: hwmon: (ina2xx) Fix access to uninitialized mutex commit 0c4c5860e9983eb3da7a3d73ca987643c3ed034b upstream. Initialize data->config_lock mutex before it is used by the driver code. This fixes following warning on Odroid XU3 boards: INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 5 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc7-next-20180115-00001-gb75575dee3f2 #107 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x90/0xc8) [] (dump_stack) from [] (register_lock_class+0x1c0/0x59c) [] (register_lock_class) from [] (__lock_acquire+0x78/0x1850) [] (__lock_acquire) from [] (lock_acquire+0xc8/0x2b8) [] (lock_acquire) from [] (__mutex_lock+0x60/0xa0c) [] (__mutex_lock) from [] (mutex_lock_nested+0x1c/0x24) [] (mutex_lock_nested) from [] (ina2xx_set_shunt+0x70/0xb0) [] (ina2xx_set_shunt) from [] (ina2xx_probe+0x88/0x1b0) [] (ina2xx_probe) from [] (i2c_device_probe+0x1e0/0x2d0) [] (i2c_device_probe) from [] (driver_probe_device+0x2b8/0x4a0) [] (driver_probe_device) from [] (__driver_attach+0xfc/0x120) [] (__driver_attach) from [] (bus_for_each_dev+0x58/0x7c) [] (bus_for_each_dev) from [] (bus_add_driver+0x174/0x250) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (i2c_register_driver+0x38/0xa8) [] (i2c_register_driver) from [] (do_one_initcall+0x48/0x18c) [] (do_one_initcall) from [] (kernel_init_freeable+0x110/0x1d4) [] (kernel_init_freeable) from [] (kernel_init+0x8/0x114) [] (kernel_init) from [] (ret_from_fork+0x14/0x20) Fixes: 5d389b125186 ("hwmon: (ina2xx) Make calibration register value fixed") Signed-off-by: Marek Szyprowski Signed-off-by: Guenter Roeck [backport to v4.4.y/v4.9.y: context changes] Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/ina2xx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index a629f7c130f0..ac63e562071f 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -447,6 +447,7 @@ static int ina2xx_probe(struct i2c_client *client, /* set the device type */ data->config = &ina2xx_config[id->driver_data]; + mutex_init(&data->config_lock); if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { struct ina2xx_platform_data *pdata = dev_get_platdata(dev); @@ -473,8 +474,6 @@ static int ina2xx_probe(struct i2c_client *client, return -ENODEV; } - mutex_init(&data->config_lock); - data->groups[group++] = &ina2xx_group; if (id->driver_data == ina226) data->groups[group++] = &ina226_group; -- cgit v1.2.3 From 6b61154b0680ebd3d82fd9415e9cd2c977bebcf2 Mon Sep 17 00:00:00 2001 From: Bassem Boubaker Date: Wed, 11 Apr 2018 13:15:53 +0200 Subject: cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN [ Upstream commit 53765341ee821c0a0f1dec41adc89c9096ad694c ] The Cinterion AHS8 is a 3G device with one embedded WWAN interface using cdc_ether as a driver. The modem is controlled via AT commands through the exposed TTYs. AT+CGDCONT write command can be used to activate or deactivate a WWAN connection for a PDP context defined with the same command. UE supports one WWAN adapter. Signed-off-by: Bassem Boubaker Acked-by: Oliver Neukum Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ether.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 1fca0024f294..4fb468666b19 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -773,6 +773,12 @@ static const struct usb_device_id products[] = { USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&wwan_info, +}, { + /* Cinterion AHS3 modem by GEMALTO */ + USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, }, { /* Telit modules */ USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, -- cgit v1.2.3 From 0eecffb5e95390e72c5ac0c6d184881c14ad1b3a Mon Sep 17 00:00:00 2001 From: Tejaswi Tanikella Date: Wed, 11 Apr 2018 16:34:47 +0530 Subject: slip: Check if rstate is initialized before uncompressing [ Upstream commit 3f01ddb962dc506916c243f9524e8bef97119b77 ] On receiving a packet the state index points to the rstate which must be used to fill up IP and TCP headers. But if the state index points to a rstate which is unitialized, i.e. filled with zeros, it gets stuck in an infinite loop inside ip_fast_csum trying to compute the ip checsum of a header with zero length. 89.666953: <2> [] slhc_uncompress+0x464/0x468 89.666965: <2> [] ppp_receive_nonmp_frame+0x3b4/0x65c 89.666978: <2> [] ppp_receive_frame+0x64/0x7e0 89.666991: <2> [] ppp_input+0x104/0x198 89.667005: <2> [] pppopns_recv_core+0x238/0x370 89.667027: <2> [] __sk_receive_skb+0xdc/0x250 89.667040: <2> [] pppopns_recv+0x44/0x60 89.667053: <2> [] __sock_queue_rcv_skb+0x16c/0x24c 89.667065: <2> [] sock_queue_rcv_skb+0x2c/0x38 89.667085: <2> [] raw_rcv+0x124/0x154 89.667098: <2> [] raw_local_deliver+0x1e0/0x22c 89.667117: <2> [] ip_local_deliver_finish+0x70/0x24c 89.667131: <2> [] ip_local_deliver+0x100/0x10c ./scripts/faddr2line vmlinux slhc_uncompress+0x464/0x468 output: ip_fast_csum at arch/arm64/include/asm/checksum.h:40 (inlined by) slhc_uncompress at drivers/net/slip/slhc.c:615 Adding a variable to indicate if the current rstate is initialized. If such a packet arrives, move to toss state. Signed-off-by: Tejaswi Tanikella Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/slip/slhc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 27ed25252aac..cfd81eb1b532 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c @@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) if(x < 0 || x > comp->rslot_limit) goto bad; + /* Check if the cstate is initialized */ + if (!comp->rstate[x].initialized) + goto bad; + comp->flags &=~ SLF_TOSS; comp->recv_current = x; } else { @@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) if (cs->cs_tcp.doff > 5) memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; + cs->initialized = true; /* Put headers back on packet * Neither header checksum is recalculated */ -- cgit v1.2.3 From 72de9891b5f46f1f98e7e6243c47076a4b4daa3c Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 11 Apr 2018 10:35:40 +0800 Subject: vhost: fix vhost_vq_access_ok() log check [ Upstream commit d14d2b78090c7de0557362b26a4ca591aa6a9faa ] Commit d65026c6c62e7d9616c8ceb5a53b68bcdc050525 ("vhost: validate log when IOTLB is enabled") introduced a regression. The logic was originally: if (vq->iotlb) return 1; return A && B; After the patch the short-circuit logic for A was inverted: if (A || vq->iotlb) return A; return B; This patch fixes the regression by rewriting the checks in the obvious way, no longer returning A when vq->iotlb is non-NULL (which is hard to understand). Reported-by: syzbot+65a84dde0214b0387ccd@syzkaller.appspotmail.com Cc: Jason Wang Signed-off-by: Stefan Hajnoczi Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e2c37aeed45a..fce49ebc575d 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1175,10 +1175,12 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, /* Caller should have vq mutex and device mutex */ int vhost_vq_access_ok(struct vhost_virtqueue *vq) { - int ret = vq_log_access_ok(vq, vq->log_base); + if (!vq_log_access_ok(vq, vq->log_base)) + return 0; - if (ret || vq->iotlb) - return ret; + /* Access validation occurs at prefetch time with IOTLB */ + if (vq->iotlb) + return 1; return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used); } -- cgit v1.2.3 From 82236561095d64471a3a38d3a8f1fd7d815df3dd Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 Apr 2018 10:59:17 +0100 Subject: lan78xx: Correctly indicate invalid OTP [ Upstream commit 4bfc33807a9a02764bdd1e42e794b3b401240f27 ] lan78xx_read_otp tries to return -EINVAL in the event of invalid OTP content, but the value gets overwritten before it is returned and the read goes ahead anyway. Make the read conditional as it should be and preserve the error code. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Phil Elwell Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/lan78xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index c53385a0052f..f5a96678494b 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -873,7 +873,8 @@ static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset, offset += 0x100; else ret = -EINVAL; - ret = lan78xx_read_raw_otp(dev, offset, length, data); + if (!ret) + ret = lan78xx_read_raw_otp(dev, offset, length, data); } return ret; -- cgit v1.2.3 From c3ba64bb3a6c8a4bc9fd3fd4e3a882e66f1942fa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 19 Apr 2018 16:00:32 +0200 Subject: Revert "net: phy: micrel: Restore led_mode and clk_sel on resume" This reverts commit d7ba3c00047dfd88fe0360a2d27169b54c88c4f1 which was commit 79e498a9c7da0737829ff864aae44df434105676 upstream. Turns out it breaks things, so drop it. Reported-by: Naresh Kamboju Cc: Leonard Crestez Cc: Florian Fainelli Cc: David S. Miller Cc: Sasha Levin Cc: Dan Rue Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/micrel.c | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 4da73e2c37cf..2032a6de026b 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -268,12 +268,23 @@ out: return ret; } -/* Some config bits need to be set again on resume, handle them here. */ -static int kszphy_config_reset(struct phy_device *phydev) +static int kszphy_config_init(struct phy_device *phydev) { struct kszphy_priv *priv = phydev->priv; + const struct kszphy_type *type; int ret; + if (!priv) + return 0; + + type = priv->type; + + if (type->has_broadcast_disable) + kszphy_broadcast_disable(phydev); + + if (type->has_nand_tree_disable) + kszphy_nand_tree_disable(phydev); + if (priv->rmii_ref_clk_sel) { ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val); if (ret) { @@ -284,7 +295,7 @@ static int kszphy_config_reset(struct phy_device *phydev) } if (priv->led_mode >= 0) - kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode); + kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode); if (phy_interrupt_is_valid(phydev)) { int ctl = phy_read(phydev, MII_BMCR); @@ -300,25 +311,6 @@ static int kszphy_config_reset(struct phy_device *phydev) return 0; } -static int kszphy_config_init(struct phy_device *phydev) -{ - struct kszphy_priv *priv = phydev->priv; - const struct kszphy_type *type; - - if (!priv) - return 0; - - type = priv->type; - - if (type->has_broadcast_disable) - kszphy_broadcast_disable(phydev); - - if (type->has_nand_tree_disable) - kszphy_nand_tree_disable(phydev); - - return kszphy_config_reset(phydev); -} - static int ksz8041_config_init(struct phy_device *phydev) { struct device_node *of_node = phydev->mdio.dev.of_node; @@ -723,14 +715,8 @@ static int kszphy_suspend(struct phy_device *phydev) static int kszphy_resume(struct phy_device *phydev) { - int ret; - genphy_resume(phydev); - ret = kszphy_config_reset(phydev); - if (ret) - return ret; - /* Enable PHY Interrupts */ if (phy_interrupt_is_valid(phydev)) { phydev->interrupts = PHY_INTERRUPT_ENABLED; -- cgit v1.2.3 From a7e19062d115e3acf71649a1fba6d5c7d65be3d1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Feb 2018 07:38:08 -0800 Subject: tty: make n_tty_read() always abort if hangup is in progress commit 28b0f8a6962a24ed21737578f3b1b07424635c9e upstream. A tty is hung up by __tty_hangup() setting file->f_op to hung_up_tty_fops, which is skipped on ttys whose write operation isn't tty_write(). This means that, for example, /dev/console whose write op is redirected_tty_write() is never actually marked hung up. Because n_tty_read() uses the hung up status to decide whether to abort the waiting readers, the lack of hung-up marking can lead to the following scenario. 1. A session contains two processes. The leader and its child. The child ignores SIGHUP. 2. The leader exits and starts disassociating from the controlling terminal (/dev/console). 3. __tty_hangup() skips setting f_op to hung_up_tty_fops. 4. SIGHUP is delivered and ignored. 5. tty_ldisc_hangup() is invoked. It wakes up the waits which should clear the read lockers of tty->ldisc_sem. 6. The reader wakes up but because tty_hung_up_p() is false, it doesn't abort and goes back to sleep while read-holding tty->ldisc_sem. 7. The leader progresses to tty_ldisc_lock() in tty_ldisc_hangup() and is now stuck in D sleep indefinitely waiting for tty->ldisc_sem. The following is Alan's explanation on why some ttys aren't hung up. http://lkml.kernel.org/r/20171101170908.6ad08580@alans-desktop 1. It broke the serial consoles because they would hang up and close down the hardware. With tty_port that *should* be fixable properly for any cases remaining. 2. The console layer was (and still is) completely broken and doens't refcount properly. So if you turn on console hangups it breaks (as indeed does freeing consoles and half a dozen other things). As neither can be fixed quickly, this patch works around the problem by introducing a new flag, TTY_HUPPING, which is used solely to tell n_tty_read() that hang-up is in progress for the console and the readers should be aborted regardless of the hung-up status of the device. The following is a sample hung task warning caused by this issue. INFO: task agetty:2662 blocked for more than 120 seconds. Not tainted 4.11.3-dbg-tty-lockup-02478-gfd6c7ee-dirty #28 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. 0 2662 1 0x00000086 Call Trace: __schedule+0x267/0x890 schedule+0x36/0x80 schedule_timeout+0x23c/0x2e0 ldsem_down_write+0xce/0x1f6 tty_ldisc_lock+0x16/0x30 tty_ldisc_hangup+0xb3/0x1b0 __tty_hangup+0x300/0x410 disassociate_ctty+0x6c/0x290 do_exit+0x7ef/0xb00 do_group_exit+0x3f/0xa0 get_signal+0x1b3/0x5d0 do_signal+0x28/0x660 exit_to_usermode_loop+0x46/0x86 do_syscall_64+0x9c/0xb0 entry_SYSCALL64_slow_path+0x25/0x25 The following is the repro. Run "$PROG /dev/console". The parent process hangs in D state. #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { struct sigaction sact = { .sa_handler = SIG_IGN }; struct timespec ts1s = { .tv_sec = 1 }; pid_t pid; int fd; if (argc < 2) { fprintf(stderr, "test-hung-tty /dev/$TTY\n"); return 1; } /* fork a child to ensure that it isn't already the session leader */ pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid > 0) { /* top parent, wait for everyone */ while (waitpid(-1, NULL, 0) >= 0) ; if (errno != ECHILD) perror("waitpid"); return 0; } /* new session, start a new session and set the controlling tty */ if (setsid() < 0) { perror("setsid"); return 1; } fd = open(argv[1], O_RDWR); if (fd < 0) { perror("open"); return 1; } if (ioctl(fd, TIOCSCTTY, 1) < 0) { perror("ioctl"); return 1; } /* fork a child, sleep a bit and exit */ pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid > 0) { nanosleep(&ts1s, NULL); printf("Session leader exiting\n"); exit(0); } /* * The child ignores SIGHUP and keeps reading from the controlling * tty. Because SIGHUP is ignored, the child doesn't get killed on * parent exit and the bug in n_tty makes the read(2) block the * parent's control terminal hangup attempt. The parent ends up in * D sleep until the child is explicitly killed. */ sigaction(SIGHUP, &sact, NULL); printf("Child reading tty\n"); while (1) { char buf[1024]; if (read(fd, buf, sizeof(buf)) < 0) { perror("read"); return 1; } } return 0; } Signed-off-by: Tejun Heo Cc: Alan Cox Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 6 ++++++ drivers/tty/tty_io.c | 9 +++++++++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index faf50df81622..1c70541a1467 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2182,6 +2182,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, } if (tty_hung_up_p(file)) break; + /* + * Abort readers for ttys which never actually + * get hung up. See __tty_hangup(). + */ + if (test_bit(TTY_HUPPING, &tty->flags)) + break; if (!timeout) break; if (file->f_flags & O_NONBLOCK) { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fb9bada5f1d5..4ee0a9de7556 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -709,6 +709,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) return; } + /* + * Some console devices aren't actually hung up for technical and + * historical reasons, which can lead to indefinite interruptible + * sleep in n_tty_read(). The following explicitly tells + * n_tty_read() to abort readers. + */ + set_bit(TTY_HUPPING, &tty->flags); + /* inuse_filps is protected by the single tty lock, this really needs to change if we want to flush the workqueue with the lock held */ @@ -763,6 +771,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) * from the ldisc side, which is now guaranteed. */ set_bit(TTY_HUPPED, &tty->flags); + clear_bit(TTY_HUPPING, &tty->flags); tty_unlock(tty); if (f) -- cgit v1.2.3 From 00f308c0eea4d2f7bc5bb3b9d0947f2219f53760 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 17 Jan 2018 23:15:57 +0100 Subject: ubi: fastmap: Don't flush fastmap work on detach commit 29b7a6fa1ec07e8480b0d9caf635a4498a438bf4 upstream. At this point UBI volumes have already been free()'ed and fastmap can no longer access these data structures. Reported-by: Martin Townsend Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL sub-system") Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/fastmap-wl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 4f0bd6b4422a..69dd21679a30 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi) { int i; - flush_work(&ubi->fm_work); return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); -- cgit v1.2.3 From 434a1dd2c0e4f6af3fa4ca9cc3e88bbf07b8f41c Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Mon, 29 Jan 2018 11:18:20 +0100 Subject: ubi: Fix error for write access commit 78a8dfbabbece22bee58ac4cb26cab10e7a19c5d upstream. When opening a device with write access, ubiblock_open returns an error code. Currently, this error code is -EPERM, but this is not the right value. The open function for other block devices returns -EROFS when opening read-only devices with FMODE_WRITE set. When used with dm-verity, the veritysetup userspace tool is expecting EROFS, and refuses to use the ubiblock device. Use -EROFS for ubiblock as well. As a result, veritysetup accepts the ubiblock device as valid. Cc: stable@vger.kernel.org Fixes: 9d54c8a33eec (UBI: R/O block driver on top of UBI volumes) Signed-off-by: Romain Izard Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 46913ef25bc0..479a5f02d10b 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -244,7 +244,7 @@ static int ubiblock_open(struct block_device *bdev, fmode_t mode) * in any case. */ if (mode & FMODE_WRITE) { - ret = -EPERM; + ret = -EROFS; goto out_unlock; } -- cgit v1.2.3 From c64c4c81aed52fc84be225ce47863a41eb4f7bb6 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 3 Mar 2018 11:45:54 +0100 Subject: ubi: Reject MLC NAND commit b5094b7f135be34630e3ea8a98fa215715d0f29d upstream. While UBI and UBIFS seem to work at first sight with MLC NAND, you will most likely lose all your data upon a power-cut or due to read/write disturb. In order to protect users from bad surprises, refuse to attach to MLC NAND. Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger Acked-by: Boris Brezillon Acked-by: Artem Bityutskiy Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/build.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 85d54f37e28f..6cb5ca52cb5a 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -894,6 +894,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, return -EINVAL; } + /* + * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. + * MLC NAND is different and needs special care, otherwise UBI or UBIFS + * will die soon and you will lose all your data. + */ + if (mtd->type == MTD_MLCNANDFLASH) { + pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", + mtd->index); + return -EINVAL; + } + if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) -- cgit v1.2.3 From a576d7fea68be666b2a0d2104ddf936d587e65de Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 29 Mar 2018 10:48:28 -0500 Subject: usb: musb: gadget: misplaced out of bounds check commit af6f8529098aeb0e56a68671b450cf74e7a64fcd upstream. musb->endpoints[] has array size MUSB_C_NUM_EPS. We must check array bounds before accessing the array and not afterwards. Signed-off-by: Heinrich Schuchardt Signed-off-by: Bin Liu Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget_ep0.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 844a309fe895..e85b9c2a4910 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -114,15 +114,19 @@ static int service_tx_status_request( } is_in = epnum & USB_DIR_IN; - if (is_in) { - epnum &= 0x0f; + epnum &= 0x0f; + if (epnum >= MUSB_C_NUM_EPS) { + handled = -EINVAL; + break; + } + + if (is_in) ep = &musb->endpoints[epnum].ep_in; - } else { + else ep = &musb->endpoints[epnum].ep_out; - } regs = musb->endpoints[epnum].regs; - if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { + if (!ep->desc) { handled = -EINVAL; break; } -- cgit v1.2.3 From ba260ce74cb8acef791563a7d3f1445fe06d6805 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 26 Mar 2018 13:14:46 +0300 Subject: usb: gadget: udc: core: update usb_ep_queue() documentation commit eaa358c7790338d83bb6a31258bdc077de120414 upstream. Mention that ->complete() should never be called from within usb_ep_queue(). Signed-off-by: Felipe Balbi Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 7d658565b20f..188961780b8a 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -248,6 +248,9 @@ EXPORT_SYMBOL_GPL(usb_ep_free_request); * arranges to poll once per interval, and the gadget driver usually will * have queued some data to transfer at that time. * + * Note that @req's ->complete() callback must never be called from + * within usb_ep_queue() as that can create deadlock situations. + * * Returns zero, or a negative error code. Endpoints that are not enabled * report errors; errors will also be * reported when the usb peripheral is disconnected. -- cgit v1.2.3 From 34023ca384a75c064544b92bad7bd347afdb3067 Mon Sep 17 00:00:00 2001 From: Maxime Chevallier Date: Fri, 2 Mar 2018 15:55:09 +0100 Subject: spi: Fix scatterlist elements size in spi_map_buf commit ce99319a182fe766be67f96338386f3ec73e321c upstream. When SPI transfers can be offloaded using DMA, the SPI core need to build a scatterlist to make sure that the buffer to be transferred is dma-able. This patch fixes the scatterlist entry size computation in the case where the maximum acceptable scatterlist entry supported by the DMA controller is less than PAGE_SIZE, when the buffer is vmalloced. For each entry, the actual size is given by the minimum between the desc_len (which is the max buffer size supported by the DMA controller) and the remaining buffer length until we cross a page boundary. Fixes: 65598c13fd66 ("spi: Fix per-page mapping of unaligned vmalloc-ed buffer") Signed-off-by: Maxime Chevallier Signed-off-by: Mark Brown Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6db80635ace8..c2e85e23d538 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -743,8 +743,14 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, for (i = 0; i < sgs; i++) { if (vmalloced_buf || kmap_buf) { - min = min_t(size_t, - len, desc_len - offset_in_page(buf)); + /* + * Next scatterlist entry size is the minimum between + * the desc_len and the remaining buffer length that + * fits in a page. + */ + min = min_t(size_t, desc_len, + min_t(size_t, len, + PAGE_SIZE - offset_in_page(buf))); if (vmalloced_buf) vm_page = vmalloc_to_page(buf); else -- cgit v1.2.3 From 9c78aeef4272a6ded4bbf500ae611050904daaa9 Mon Sep 17 00:00:00 2001 From: Jason Andryuk Date: Wed, 28 Feb 2018 07:23:23 -0500 Subject: xen-netfront: Fix hang on device removal commit c2d2e6738a209f0f9dffa2dc8e7292fc45360d61 upstream. A toolstack may delete the vif frontend and backend xenstore entries while xen-netfront is in the removal code path. In that case, the checks for xenbus_read_driver_state would return XenbusStateUnknown, and xennet_remove would hang indefinitely. This hang prevents system shutdown. xennet_remove must be able to handle XenbusStateUnknown, and netback_changed must also wake up the wake_queue for that state as well. Fixes: 5b5971df3bc2 ("xen-netfront: remove warning when unloading module") Signed-off-by: Jason Andryuk Cc: Eduardo Otubo Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netfront.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b09c81e882b4..1b287861e34f 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -2038,7 +2038,10 @@ static void netback_changed(struct xenbus_device *dev, case XenbusStateInitialised: case XenbusStateReconfiguring: case XenbusStateReconfigured: + break; + case XenbusStateUnknown: + wake_up_all(&module_unload_q); break; case XenbusStateInitWait: @@ -2169,7 +2172,9 @@ static int xennet_remove(struct xenbus_device *dev) xenbus_switch_state(dev, XenbusStateClosing); wait_event(module_unload_q, xenbus_read_driver_state(dev->otherend) == - XenbusStateClosing); + XenbusStateClosing || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown); xenbus_switch_state(dev, XenbusStateClosed); wait_event(module_unload_q, -- cgit v1.2.3 From cddf0e1ce6c7d68e2f6e004079396a238de5f86a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 8 Feb 2018 10:23:44 +0300 Subject: regmap: Fix reversed bounds check in regmap_raw_write() commit f00e71091ab92eba52122332586c6ecaa9cd1a56 upstream. We're supposed to be checking that "val_len" is not too large but instead we check if it is smaller than the max. The only function affected would be regmap_i2c_smbus_i2c_write() in drivers/base/regmap/regmap-i2c.c. Strangely that function has its own limit check which returns an error if (count >= I2C_SMBUS_BLOCK_MAX) so it doesn't look like it has ever been able to do anything except return an error. Fixes: c335931ed9d2 ("regmap: Add raw_write/read checks for max_raw_write/read sizes") Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index ae63bb0875ea..a7b0fc7cb468 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1736,7 +1736,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, return -EINVAL; if (val_len % map->format.val_bytes) return -EINVAL; - if (map->max_raw_write && map->max_raw_write > val_len) + if (map->max_raw_write && map->max_raw_write < val_len) return -E2BIG; map->lock(map->lock_arg); -- cgit v1.2.3 From e324a44b0443ec91c86b417f3a34792d1bf58f14 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Mar 2018 18:01:45 +0100 Subject: ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E commit bbf038618a24d72e2efc19146ef421bb1e1eda1a upstream. Just like many other Samsung models, the 670Z5E needs to use the acpi-video backlight interface rather then the native one for backlight control to work, add a quirk for this. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1557060 Cc: All applicable Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/video_detect.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 02ded25c82e4..cdc47375178e 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -213,6 +213,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { "3570R/370R/470R/450R/510R/4450RV"), }, }, + { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ + .callback = video_detect_force_video, + .ident = "SAMSUNG 670Z5E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), + }, + }, { /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ .callback = video_detect_force_video, -- cgit v1.2.3 From a59ba739a13f010eaecdd7a97e94dd94edefbfd8 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 12 Feb 2018 13:55:23 +0300 Subject: ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status() commit 13d3047c81505cc0fb9bdae7810676e70523c8bf upstream. Mike Lothian reported that plugging in a USB-C device does not work properly in his Dell Alienware system. This system has an Intel Alpine Ridge Thunderbolt controller providing USB-C functionality. In these systems the USB controller (xHCI) is hotplugged whenever a device is connected to the port using ACPI-based hotplug. The ACPI description of the root port in question is as follows: Device (RP01) { Name (_ADR, 0x001C0000) Device (PXSX) { Name (_ADR, 0x02) Method (_RMV, 0, NotSerialized) { // ... } } Here _ADR 0x02 means device 0, function 2 on the bus under root port (RP01) but that seems to be incorrect because device 0 is the upstream port of the Alpine Ridge PCIe switch and it has no functions other than 0 (the bridge itself). When we get ACPI Notify() to the root port resulting from connecting a USB-C device, Linux tries to read PCI_VENDOR_ID from device 0, function 2 which of course always returns 0xffffffff because there is no such function and we never find the device. In Windows this works fine. Now, since we get ACPI Notify() to the root port and not to the PXSX device we should actually start our scan from there as well and not from the non-existent PXSX device. Fix this by checking presence of the slot itself (function 0) if we fail to do that otherwise. While there use pci_bus_read_dev_vendor_id() in get_slot_status(), which is the recommended way to read Device and Vendor IDs of devices on PCI buses. Link: https://bugzilla.kernel.org/show_bug.cgi?id=198557 Reported-by: Mike Lothian Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Rafael J. Wysocki Cc: Greg Kroah-Hartman Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a46b585fae31..d44b55879c67 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -587,6 +587,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) { unsigned long long sta = 0; struct acpiphp_func *func; + u32 dvid; list_for_each_entry(func, &slot->funcs, sibling) { if (func->flags & FUNC_HAS_STA) { @@ -597,19 +598,27 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) if (ACPI_SUCCESS(status) && sta) break; } else { - u32 dvid; - - pci_bus_read_config_dword(slot->bus, - PCI_DEVFN(slot->device, - func->function), - PCI_VENDOR_ID, &dvid); - if (dvid != 0xffffffff) { + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, func->function), + &dvid, 0)) { sta = ACPI_STA_ALL; break; } } } + if (!sta) { + /* + * Check for the slot itself since it may be that the + * ACPI slot is a device below PCIe upstream port so in + * that case it may not even be reachable yet. + */ + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, 0), &dvid, 0)) { + sta = ACPI_STA_ALL; + } + } + return (unsigned int)sta; } -- cgit v1.2.3 From b3b0809ac25c3ffedc58e7f83bc01a03193e7834 Mon Sep 17 00:00:00 2001 From: "Yavuz, Tuba" Date: Fri, 23 Mar 2018 17:00:38 +0000 Subject: USB: gadget: f_midi: fixing a possible double-free in f_midi commit 7fafcfdf6377b18b2a726ea554d6e593ba44349f upstream. It looks like there is a possibility of a double-free vulnerability on an error path of the f_midi_set_alt function in the f_midi driver. If the path is feasible then free_ep_req gets called twice: req->complete = f_midi_complete; err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); => ... usb_gadget_giveback_request => f_midi_complete (CALLBACK) (inside f_midi_complete, for various cases of status) free_ep_req(ep, req); // first kfree if (err) { ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); free_ep_req(midi->out_ep, req); // second kfree return err; } The double-free possibility was introduced with commit ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests"). Found by MOXCAFE tool. Signed-off-by: Tuba Yavuz Fixes: ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests") Acked-by: Felipe Balbi Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_midi.c | 3 ++- drivers/usb/gadget/u_f.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a5719f271bf0..70ac1963b598 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -389,7 +389,8 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) { ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); - free_ep_req(midi->out_ep, req); + if (req->buf != NULL) + free_ep_req(midi->out_ep, req); return err; } } diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 7d53a4773d1a..2f03334c6874 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -64,7 +64,9 @@ struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len); /* Frees a usb_request previously allocated by alloc_ep_req() */ static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) { + WARN_ON(req->buf == NULL); kfree(req->buf); + req->buf = NULL; usb_ep_free_request(ep, req); } -- cgit v1.2.3 From 73300bd1fdedcb4f0e78aab61737bda5bf7b0c24 Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Wed, 21 Mar 2018 13:29:42 +0800 Subject: USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 64627388b50158fd24d6ad88132525b95a5ef573 upstream. USB3 hubs don't support global suspend. USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective suspend and resume, they do not support global suspend/resume where the hub downstream facing ports states are not affected. When system enters hibernation it first enters freeze process where only the root hub enters suspend, usb_port_suspend() is not called for other devices, and suspend status flags are not set for them. Other devices are expected to suspend globally. Some external USB3 hubs will suspend the downstream facing port at global suspend. These devices won't be resumed at thaw as the suspend status flag is not set. A USB3 removable hard disk connected through a USB3 hub that won't resume at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71” error, and needs a 60 seconds timeout which causing system hang for 60s before the USB host reset the port for the USB3 removable hard disk to recover. Fix this by always calling usb_port_suspend() during freeze for USB3 devices. Signed-off-by: Zhengjun Xing Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/generic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 358ca8dd784f..a5240b4d7ab9 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -208,8 +208,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) if (!udev->parent) rc = hcd_bus_suspend(udev, msg); - /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ - else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) + /* + * Non-root USB2 devices don't need to do anything for FREEZE + * or PRETHAW. USB3 devices don't support global suspend and + * needs to be selectively suspended. + */ + else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) + && (udev->speed < USB_SPEED_SUPER)) rc = 0; else rc = usb_port_suspend(udev, msg); -- cgit v1.2.3 From cd93ff92e1d71a2f13447ecc36e17e74bf897ef4 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Mon, 19 Mar 2018 13:07:35 -0700 Subject: usb: dwc3: pci: Properly cleanup resource commit cabdf83dadfb3d83eec31e0f0638a92dbd716435 upstream. Platform device is allocated before adding resources. Make sure to properly cleanup on error case. Cc: Fixes: f1c7e7108109 ("usb: dwc3: convert to pcim_enable_device()") Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 427291a19e6d..d6493abcf6bc 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -173,7 +173,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); - return ret; + goto err; } dwc3->dev.parent = dev; -- cgit v1.2.3 From b599902c30803a6b7f9818e6dc4710d4a64f55af Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Mon, 8 Jan 2018 10:41:40 +0800 Subject: HID: i2c-hid: fix size check and type usage commit ac75a041048b8c1f7418e27621ca5efda8571043 upstream. When convert char array with signed int, if the inbuf[x] is negative then upper bits will be set to 1. Fix this by using u8 instead of char. ret_size has to be at least 3, hid_input_report use it after minus 2 bytes. Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 7d6da9b43dab..2548c5dbdc75 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -142,10 +142,10 @@ struct i2c_hid { * register of the HID * descriptor. */ unsigned int bufsize; /* i2c buffer size */ - char *inbuf; /* Input buffer */ - char *rawbuf; /* Raw Input buffer */ - char *cmdbuf; /* Command buffer */ - char *argsbuf; /* Command arguments buffer */ + u8 *inbuf; /* Input buffer */ + u8 *rawbuf; /* Raw Input buffer */ + u8 *cmdbuf; /* Command buffer */ + u8 *argsbuf; /* Command arguments buffer */ unsigned long flags; /* device flags */ unsigned long quirks; /* Various quirks */ @@ -451,7 +451,8 @@ out_unlock: static void i2c_hid_get_input(struct i2c_hid *ihid) { - int ret, ret_size; + int ret; + u32 ret_size; int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); if (size > ihid->bufsize) @@ -476,7 +477,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) return; } - if (ret_size > size) { + if ((ret_size > size) || (ret_size <= 2)) { dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", __func__, size, ret_size); return; -- cgit v1.2.3 From 10ab7c947d4921b962c7c2a6bffa2486d0cd127d Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Sat, 3 Feb 2018 23:57:15 +0800 Subject: HID: Fix hid_report_len usage commit 3064a03b94e60388f0955fcc29f3e8a978d28f75 upstream. Follow the change of return type u32 of hid_report_len, fix all the types of variables those get the return value of hid_report_len to u32, and all other code already uses u32. Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-input.c | 3 ++- drivers/hid/hid-multitouch.c | 5 +++-- drivers/hid/hid-rmi.c | 4 ++-- drivers/hid/wacom_sys.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 40233315d5f5..5ff6dd8147b6 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1279,7 +1279,8 @@ static void hidinput_led_worker(struct work_struct *work) led_work); struct hid_field *field; struct hid_report *report; - int len, ret; + int ret; + u32 len; __u8 *buf; field = hidinput_get_led_field(hid); diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 89e9032ab1e7..fba655d639af 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -315,7 +315,8 @@ static struct attribute_group mt_attribute_group = { static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) { struct mt_device *td = hid_get_drvdata(hdev); - int ret, size = hid_report_len(report); + int ret; + u32 size = hid_report_len(report); u8 *buf; /* @@ -919,7 +920,7 @@ static void mt_set_input_mode(struct hid_device *hdev) struct hid_report_enum *re; struct mt_class *cls = &td->mtclass; char *buf; - int report_len; + u32 report_len; if (td->inputmode < 0) return; diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index be89bcbf6a71..276d12d4b576 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c @@ -110,8 +110,8 @@ struct rmi_data { u8 *writeReport; u8 *readReport; - int input_report_size; - int output_report_size; + u32 input_report_size; + u32 output_report_size; unsigned long flags; diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 7a4d39ce51d9..e8b90b534f08 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -351,7 +351,7 @@ static int wacom_set_device_mode(struct hid_device *hdev, u8 *rep_data; struct hid_report *r; struct hid_report_enum *re; - int length; + u32 length; int error = -ENOMEM, limit = 0; if (wacom_wac->mode_report < 0) -- cgit v1.2.3 From 4b43f4139e4054bc06a1f92be3018ebb6326f73f Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Mon, 8 Jan 2018 10:41:41 +0800 Subject: HID: core: Fix size as type u32 commit 6de0b13cc0b4ba10e98a9263d7a83b940720b77a upstream. When size is negative, calling memset will make segment fault. Declare the size as type u32 to keep memset safe. size in struct hid_report is unsigned, fix return type of hid_report_len to u32. Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 49406e106cee..7944a1f589eb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1370,7 +1370,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) * of implement() working on 8 byte chunks */ - int len = hid_report_len(report) + 7; + u32 len = hid_report_len(report) + 7; return kmalloc(len, flags); } @@ -1435,7 +1435,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report, { char *buf; int ret; - int len; + u32 len; buf = hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) @@ -1461,14 +1461,14 @@ out: } EXPORT_SYMBOL_GPL(__hid_request); -int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) { struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; unsigned int a; - int rsize, csize = size; + u32 rsize, csize = size; u8 *cdata = data; int ret = 0; @@ -1526,7 +1526,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); * * This is data entry for lower layers. */ -int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) +int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) { struct hid_report_enum *report_enum; struct hid_driver *hdrv; -- cgit v1.2.3 From c9bb6fb2df18eda60e8dc125232338a76ffb7163 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 19 Dec 2017 12:44:56 +0300 Subject: thunderbolt: Resume control channel after hibernation image is created commit f2a659f7d8d5da803836583aa16df06bdf324252 upstream. The driver misses implementation of PM hook that undoes what ->freeze_noirq() does after the hibernation image is created. This means the control channel is not resumed properly and the Thunderbolt bus becomes useless in later stages of hibernation (when the image is stored or if the operation fails). Fix this by pointing ->thaw_noirq to driver nhi_resume_noirq(). This makes sure the control channel is resumed properly. Fixes: 23dd5bb49d98 ("thunderbolt: Add suspend/hibernate support") Signed-off-by: Mika Westerberg Reviewed-by: Andy Shevchenko Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/nhi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index a8c20413dbda..cba6bc6ab9ed 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -628,6 +628,7 @@ static const struct dev_pm_ops nhi_pm_ops = { * we just disable hotplug, the * pci-tunnels stay alive. */ + .thaw_noirq = nhi_resume_noirq, .restore_noirq = nhi_resume_noirq, }; -- cgit v1.2.3 From 910d84009977441fcb5661683528f88ed1dcca93 Mon Sep 17 00:00:00 2001 From: Aniruddha Banerjee Date: Wed, 28 Mar 2018 19:12:00 +0530 Subject: irqchip/gic: Take lock when updating irq type commit aa08192a254d362a4d5317647a81de6996961aef upstream. Most MMIO GIC register accesses use a 1-hot bit scheme that avoids requiring any form of locking. This isn't true for the GICD_ICFGRn registers, which require a RMW sequence. Unfortunately, we seem to be missing a lock for these particular accesses, which could result in a race condition if changing the trigger type on any two interrupts within the same set of 16 interrupts (and thus controlled by the same CFGR register). Introduce a private lock in the GIC common comde for this particular case, making it cover both GIC implementations in one go. Cc: stable@vger.kernel.org Signed-off-by: Aniruddha Banerjee [maz: updated changelog] Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-gic-common.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..1c2ca8d51a70 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -52,11 +54,13 @@ int gic_configure_irq(unsigned int irq, unsigned int type, u32 confoff = (irq / 16) * 4; u32 val, oldval; int ret = 0; + unsigned long flags; /* * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock_irqsave(&irq_controller_lock, flags); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +68,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +89,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); if (sync_access) sync_access(); -- cgit v1.2.3 From bb6f26a637b4da6cb752c55635baa425d803f02d Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 25 Feb 2017 18:21:33 -0400 Subject: random: use a tighter cap in credit_entropy_bits_safe() commit 9f886f4d1d292442b2f22a0a33321eae821bde40 upstream. This fixes a harmless UBSAN where root could potentially end up causing an overflow while bumping the entropy_total field (which is ignored once the entropy pool has been initialized, and this generally is completed during the boot sequence). This is marginal for the stable kernel series, but it's a really trivial patch, and it fixes UBSAN warning that might cause security folks to get overly excited for no reason. Signed-off-by: Theodore Ts'o Reported-by: Chen Feng Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 0c23ced255cb..cf1b91e33a28 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -741,7 +741,7 @@ retry: static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) { - const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); + const int nbits_max = r->poolinfo->poolwords * 32; if (nbits < 0) return -EINVAL; -- cgit v1.2.3 From 8e455917885613ce6fdbbfb981364c983b29060d Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 3 Apr 2018 15:33:01 -0700 Subject: RDMA/ucma: Don't allow setting RDMA_OPTION_IB_PATH without an RDMA device commit 8435168d50e66fa5eae01852769d20a36f9e5e83 upstream. Check to make sure that ctx->cm_id->device is set before we use it. Otherwise userspace can trigger a NULL dereference by doing RDMA_USER_CM_CMD_SET_OPTION on an ID that is not bound to a device. Cc: Reported-by: Signed-off-by: Roland Dreier Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 4d732810f6fc..cb79d171d1e4 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1231,6 +1231,9 @@ static int ucma_set_ib_path(struct ucma_context *ctx, if (!optlen) return -EINVAL; + if (!ctx->cm_id->device) + return -EINVAL; + memset(&sa_path, 0, sizeof(sa_path)); ib_sa_unpack_path(path_data->path_rec, &sa_path); -- cgit v1.2.3 From 4b37ec8703b3131c3f8b39735046c64d33ccb921 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 1 Mar 2018 14:00:29 -0800 Subject: RDMA/rxe: Fix an out-of-bounds read commit a6544a624c3ff92a64e4aca3931fa064607bd3da upstream. This patch avoids that KASAN reports the following when the SRP initiator calls srp_post_send(): ================================================================== BUG: KASAN: stack-out-of-bounds in rxe_post_send+0x5c4/0x980 [rdma_rxe] Read of size 8 at addr ffff880066606e30 by task 02-mq/1074 CPU: 2 PID: 1074 Comm: 02-mq Not tainted 4.16.0-rc3-dbg+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 Call Trace: dump_stack+0x85/0xc7 print_address_description+0x65/0x270 kasan_report+0x231/0x350 rxe_post_send+0x5c4/0x980 [rdma_rxe] srp_post_send.isra.16+0x149/0x190 [ib_srp] srp_queuecommand+0x94d/0x1670 [ib_srp] scsi_dispatch_cmd+0x1c2/0x550 [scsi_mod] scsi_queue_rq+0x843/0xa70 [scsi_mod] blk_mq_dispatch_rq_list+0x143/0xac0 blk_mq_do_dispatch_ctx+0x1c5/0x260 blk_mq_sched_dispatch_requests+0x2bf/0x2f0 __blk_mq_run_hw_queue+0xdb/0x160 __blk_mq_delay_run_hw_queue+0xba/0x100 blk_mq_run_hw_queue+0xf2/0x190 blk_mq_sched_insert_request+0x163/0x2f0 blk_execute_rq+0xb0/0x130 scsi_execute+0x14e/0x260 [scsi_mod] scsi_probe_and_add_lun+0x366/0x13d0 [scsi_mod] __scsi_scan_target+0x18a/0x810 [scsi_mod] scsi_scan_target+0x11e/0x130 [scsi_mod] srp_create_target+0x1522/0x19e0 [ib_srp] kernfs_fop_write+0x180/0x210 __vfs_write+0xb1/0x2e0 vfs_write+0xf6/0x250 SyS_write+0x99/0x110 do_syscall_64+0xee/0x2b0 entry_SYSCALL_64_after_hwframe+0x42/0xb7 The buggy address belongs to the page: page:ffffea0001998180 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x4000000000000000() raw: 4000000000000000 0000000000000000 0000000000000000 00000000ffffffff raw: dead000000000100 dead000000000200 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff880066606d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 ffff880066606d80: f1 00 f2 f2 f2 f2 f2 f2 f2 00 00 f2 f2 f2 f2 f2 >ffff880066606e00: f2 00 00 00 00 00 f2 f2 f2 f3 f3 f3 f3 00 00 00 ^ ffff880066606e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff880066606f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Bart Van Assche Cc: Moni Shoua Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/sw/rxe/rxe_verbs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index 59f37f412a7f..ced416f5dffb 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -747,9 +747,8 @@ static int init_send_wqe(struct rxe_qp *qp, struct ib_send_wr *ibwr, memcpy(wqe->dma.sge, ibwr->sg_list, num_sge * sizeof(struct ib_sge)); - wqe->iova = (mask & WR_ATOMIC_MASK) ? - atomic_wr(ibwr)->remote_addr : - rdma_wr(ibwr)->remote_addr; + wqe->iova = mask & WR_ATOMIC_MASK ? atomic_wr(ibwr)->remote_addr : + mask & WR_READ_OR_WRITE_MASK ? rdma_wr(ibwr)->remote_addr : 0; wqe->mask = mask; wqe->dma.length = length; wqe->dma.resid = length; -- cgit v1.2.3 From f4374991ddd73e1b23a62decb9548a2d599716a4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 23 Feb 2018 14:09:24 -0800 Subject: IB/srp: Fix srp_abort() commit e68088e78d82920632eba112b968e49d588d02a2 upstream. Before commit e494f6a72839 ("[SCSI] improved eh timeout handler") it did not really matter whether or not abort handlers like srp_abort() called .scsi_done() when returning another value than SUCCESS. Since that commit however this matters. Hence only call .scsi_done() when returning SUCCESS. Signed-off-by: Bart Van Assche Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/srp/ib_srp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 84f91858b5e6..245a59bab27c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2626,9 +2626,11 @@ static int srp_abort(struct scsi_cmnd *scmnd) ret = FAST_IO_FAIL; else ret = FAILED; - srp_free_req(ch, req, scmnd, 0); - scmnd->result = DID_ABORT << 16; - scmnd->scsi_done(scmnd); + if (ret == SUCCESS) { + srp_free_req(ch, req, scmnd, 0); + scmnd->result = DID_ABORT << 16; + scmnd->scsi_done(scmnd); + } return ret; } -- cgit v1.2.3 From 16757e775dd6db0fda7cf7da1eaa31d8e5a11ff1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 12 Feb 2018 09:50:25 -0800 Subject: IB/srp: Fix completion vector assignment algorithm commit 3a148896b24adf8688dc0c59af54531931677a40 upstream. Ensure that cv_end is equal to ibdev->num_comp_vectors for the NUMA node with the highest index. This patch improves spreading of RDMA channels over completion vectors and thereby improves performance, especially on systems with only a single NUMA node. This patch drops support for the comp_vector login parameter by ignoring the value of that parameter since I have not found a good way to combine support for that parameter and automatic spreading of RDMA channels over completion vectors. Fixes: d92c0da71a35 ("IB/srp: Add multichannel support") Reported-by: Alexander Schmid Signed-off-by: Bart Van Assche Cc: Alexander Schmid Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/srp/ib_srp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 245a59bab27c..463ea592a42a 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -3397,12 +3397,10 @@ static ssize_t srp_create_target(struct device *dev, num_online_nodes()); const int ch_end = ((node_idx + 1) * target->ch_count / num_online_nodes()); - const int cv_start = (node_idx * ibdev->num_comp_vectors / - num_online_nodes() + target->comp_vector) - % ibdev->num_comp_vectors; - const int cv_end = ((node_idx + 1) * ibdev->num_comp_vectors / - num_online_nodes() + target->comp_vector) - % ibdev->num_comp_vectors; + const int cv_start = node_idx * ibdev->num_comp_vectors / + num_online_nodes(); + const int cv_end = (node_idx + 1) * ibdev->num_comp_vectors / + num_online_nodes(); int cpu_idx = 0; for_each_online_cpu(cpu) { -- cgit v1.2.3 From 5d151871b1cb6338daac36e5c7c375c1f4b83ded Mon Sep 17 00:00:00 2001 From: Maxime Jayat Date: Thu, 22 Feb 2018 12:39:55 +0100 Subject: dmaengine: at_xdmac: fix rare residue corruption commit c5637476bbf9bb86c7f0413b8f4822a73d8d2d07 upstream. Despite the efforts made to correctly read the NDA and CUBC registers, the order in which the registers are read could sometimes lead to an inconsistent state. Re-using the timeline from the comments, this following timing of registers reads could lead to reading NDA with value "@desc2" and CUBC with value "MAX desc1": INITD -------- ------------ |____________________| _______________________ _______________ NDA @desc2 \/ @desc3 _______________________/\_______________ __________ ___________ _______________ CUBC 0 \/ MAX desc1 \/ MAX desc2 __________/\___________/\_______________ | | | | Events:(1)(2) (3)(4) (1) check_nda = @desc2 (2) initd = 1 (3) cur_ubc = MAX desc1 (4) cur_nda = @desc2 This is allowed by the condition ((check_nda == cur_nda) && initd), despite cur_ubc and cur_nda being in the precise state we don't want. This error leads to incorrect residue computation. Fix it by inversing the order in which CUBC and INITD are read. This makes sure that NDA and CUBC are always read together either _before_ INITD goes to 0 or _after_ it is back at 1. The case where NDA is read before INITD is at 0 and CUBC is read after INITD is back at 1 will be rejected by check_nda and cur_nda being different. Fixes: 53398f488821 ("dmaengine: at_xdmac: fix residue corruption") Cc: stable@vger.kernel.org Signed-off-by: Maxime Jayat Acked-by: Ludovic Desroches Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/at_xdmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index b7d7f2d443a1..ee7b48d5243c 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1473,10 +1473,10 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) { check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; rmb(); - initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); - rmb(); cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC); rmb(); + initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); + rmb(); cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; rmb(); -- cgit v1.2.3 From a1ada79437d7120050c38db6501ac1de62474da9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2018 16:37:21 -0700 Subject: libnvdimm, namespace: use a safe lookup for dimm device name commit 4f8672201b7e7ed4f5f6c3cf6dcd080648580582 upstream. The following NULL dereference results from incorrectly assuming that ndd is valid in this print: struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]); /* * Give up if we don't find an instance of a uuid at each * position (from 0 to nd_region->ndr_mappings - 1), or if we * find a dimm with two instances of the same uuid. */ dev_err(&nd_region->dev, "%s missing label for %pUb\n", dev_name(ndd->dev), nd_label->uuid); BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 IP: nd_region_register_namespaces+0xd67/0x13c0 [libnvdimm] PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 43 PID: 673 Comm: kworker/u609:10 Not tainted 4.16.0-rc4+ #1 [..] RIP: 0010:nd_region_register_namespaces+0xd67/0x13c0 [libnvdimm] [..] Call Trace: ? devres_add+0x2f/0x40 ? devm_kmalloc+0x52/0x60 ? nd_region_activate+0x9c/0x320 [libnvdimm] nd_region_probe+0x94/0x260 [libnvdimm] ? kernfs_add_one+0xe4/0x130 nvdimm_bus_probe+0x63/0x100 [libnvdimm] Switch to using the nvdimm device directly. Fixes: 0e3b0d123c8f ("libnvdimm, namespace: allow multiple pmem...") Cc: Reported-by: Dave Jiang Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/namespace_devs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index b8fb1ef1fc15..74257ac92490 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1747,7 +1747,7 @@ struct device *create_namespace_pmem(struct nd_region *nd_region, } if (i < nd_region->ndr_mappings) { - struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]); + struct nvdimm *nvdimm = nd_region->mapping[i].nvdimm; /* * Give up if we don't find an instance of a uuid at each @@ -1755,7 +1755,7 @@ struct device *create_namespace_pmem(struct nd_region *nd_region, * find a dimm with two instances of the same uuid. */ dev_err(&nd_region->dev, "%s missing label for %pUb\n", - dev_name(ndd->dev), nd_label->uuid); + nvdimm_name(nvdimm), nd_label->uuid); rc = -EINVAL; goto err; } -- cgit v1.2.3 From 1c72e231eb06499e376842defa03e1e295d63ba0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 Apr 2018 16:40:04 -0700 Subject: nfit, address-range-scrub: fix scrub in-progress reporting commit 78727137fdf49edf9f731bde79d7189067b4047a upstream. There is a small window whereby ARS scan requests can schedule work that userspace will miss when polling scrub_show. Hold the init_mutex lock over calls to report the status to close this potential escape. Also, make sure that requests to cancel the ARS workqueue are treated as an idle event. Cc: Cc: Vishal Verma Fixes: 37b137ff8c83 ("nfit, libnvdimm: allow an ARS scrub...") Reviewed-by: Dave Jiang Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/nfit/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 37032545c58e..3874eec972cd 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -967,8 +967,11 @@ static ssize_t scrub_show(struct device *dev, if (nd_desc) { struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); + mutex_lock(&acpi_desc->init_mutex); rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, - (work_busy(&acpi_desc->work)) ? "+\n" : "\n"); + work_busy(&acpi_desc->work) + && !acpi_desc->cancel ? "+\n" : "\n"); + mutex_unlock(&acpi_desc->init_mutex); } device_unlock(dev); return rc; -- cgit v1.2.3 From 94911a0cded960b5e85f9ef33e9861007e84cd16 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 24 Feb 2018 13:42:27 +0800 Subject: iommu/vt-d: Fix a potential memory leak commit bbe4b3af9d9e3172fb9aa1f8dcdfaedcb381fc64 upstream. A memory block was allocated in intel_svm_bind_mm() but never freed in a failure path. This patch fixes this by free it to avoid memory leakage. Cc: Ashok Raj Cc: Jacob Pan Cc: # v4.4+ Signed-off-by: Lu Baolu Fixes: 2f26e0a9c9860 ('iommu/vt-d: Add basic SVM PASID support') Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/intel-svm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 3a1c40684213..f846f0140a9d 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -389,6 +389,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ pasid_max - 1, GFP_KERNEL); if (ret < 0) { kfree(svm); + kfree(sdev); goto out; } svm->pasid = ret; -- cgit v1.2.3 From 4685f789b234f7e5e19f45b430becf1a723ce1d6 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Wed, 28 Mar 2018 18:00:43 -0300 Subject: mmc: jz4740: Fix race condition in IRQ mask update commit a04f0017c22453613d5f423326b190c61e3b4f98 upstream. A spinlock is held while updating the internal copy of the IRQ mask, but not while writing it to the actual IMASK register. After the lock is released, an IRQ can occur before the IMASK register is written. If handling this IRQ causes the mask to be changed, when the handler returns back to the middle of the first mask update, a stale value will be written to the mask register. If this causes an IRQ to become unmasked that cannot have its status cleared by writing a 1 to it in the IREG register, e.g. the SDIO IRQ, then we can end up stuck with the same IRQ repeatedly being fired but not handled. Normally the MMC IRQ handler attempts to clear any unexpected IRQs by writing IREG, but for those that cannot be cleared in this way then the IRQ will just repeatedly fire. This was resulting in lockups after a while of using Wi-Fi on the CI20 (GitHub issue #19). Resolve by holding the spinlock until after the IMASK register has been updated. Cc: stable@vger.kernel.org Link: https://github.com/MIPS/CI20_linux/issues/19 Fixes: 61bfbdb85687 ("MMC: Add support for the controller on JZ4740 SoCs.") Tested-by: Mathieu Malaterre Signed-off-by: Alex Smith Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/jz4740_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 684087db170b..1752007397f9 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -368,9 +368,9 @@ static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host, host->irq_mask &= ~irq; else host->irq_mask |= irq; - spin_unlock_irqrestore(&host->lock, flags); writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); + spin_unlock_irqrestore(&host->lock, flags); } static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host, -- cgit v1.2.3 From 1b22bdc3a303d26329abf3abbb441f97cfaecc3b Mon Sep 17 00:00:00 2001 From: Ralph Sennhauser Date: Wed, 24 May 2017 16:58:52 +0200 Subject: clk: mvebu: armada-38x: add support for 1866MHz variants commit 9593f4f56cf5d1c443f66660a0c7f01de38f979d upstream. The Linksys WRT3200ACM CPU is clocked at 1866MHz. Add 1866MHz to the list of supported CPU frequencies. Also update multiplier and divisor for the l2clk and ddrclk. Noticed by the following warning: [ 0.000000] Selected CPU frequency (16) unsupported Signed-off-by: Ralph Sennhauser Reviewed-by: Gregory CLEMENT Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/mvebu/armada-38x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c index 8bccf4ecdab6..394aa6f03f01 100644 --- a/drivers/clk/mvebu/armada-38x.c +++ b/drivers/clk/mvebu/armada-38x.c @@ -49,7 +49,8 @@ static const u32 armada_38x_cpu_frequencies[] __initconst = { 0, 0, 0, 0, 1066 * 1000 * 1000, 0, 0, 0, 1332 * 1000 * 1000, 0, 0, 0, - 1600 * 1000 * 1000, + 1600 * 1000 * 1000, 0, 0, 0, + 1866 * 1000 * 1000, }; static u32 __init armada_38x_get_cpu_freq(void __iomem *sar) @@ -79,7 +80,7 @@ static const int armada_38x_cpu_l2_ratios[32][2] __initconst = { {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, @@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = { {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, -- cgit v1.2.3 From b2c89d89eefa43ab6dbfd09b3dc18f14125877f6 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 13 Mar 2018 16:27:02 +0100 Subject: clk: mvebu: armada-38x: add support for missing clocks commit 6a4a4595804548e173f0763a0e7274a3521c59a9 upstream. Clearfog boards can come with a CPU clocked at 1600MHz (commercial) or 1333MHz (industrial). They have also some dip-switches to select a different clock (666, 800, 1066, 1200). The funny thing is that the recovery button is on the MPP34 fq selector. So, when booting an industrial board with this button down, the frequency 666MHz is selected (and the kernel didn't boot). This patch add all the missing clocks. The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ). Fixes: 0e85aeced4d6 ("clk: mvebu: add clock support for Armada 380/385") Cc: # 3.16.x: 9593f4f56cf5: clk: mvebu: armada-38x: add support for 1866MHz variants Cc: # 3.16.x Signed-off-by: Richard Genoud Acked-by: Gregory CLEMENT Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/mvebu/armada-38x.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c index 394aa6f03f01..9ff4ea63932d 100644 --- a/drivers/clk/mvebu/armada-38x.c +++ b/drivers/clk/mvebu/armada-38x.c @@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem *sar) } static const u32 armada_38x_cpu_frequencies[] __initconst = { - 0, 0, 0, 0, - 1066 * 1000 * 1000, 0, 0, 0, + 666 * 1000 * 1000, 0, 800 * 1000 * 1000, 0, + 1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0, 1332 * 1000 * 1000, 0, 0, 0, 1600 * 1000 * 1000, 0, 0, 0, - 1866 * 1000 * 1000, + 1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000, }; static u32 __init armada_38x_get_cpu_freq(void __iomem *sar) @@ -76,11 +76,11 @@ static const struct coreclk_ratio armada_38x_coreclk_ratios[] __initconst = { }; static const int armada_38x_cpu_l2_ratios[32][2] __initconst = { - {0, 1}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {1, 2}, {0, 1}, + {1, 2}, {0, 1}, {1, 2}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, @@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = { {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {7, 15}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, -- cgit v1.2.3 From 5971ee251010e1ce4969cded71800ce993a36a33 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Feb 2018 16:27:47 +0100 Subject: clk: fix false-positive Wmaybe-uninitialized warning commit ce33f284935e08229046b30635e6aadcbab02b53 upstream. When we build this driver with on x86-32, gcc produces a false-positive warning: drivers/clk/renesas/clk-sh73a0.c: In function 'sh73a0_cpg_clocks_init': drivers/clk/renesas/clk-sh73a0.c:155:10: error: 'parent_name' may be used uninitialized in this function [-Werror=maybe-uninitialized] return clk_register_fixed_factor(NULL, name, parent_name, 0, We can work around that warning by adding a fake initialization, I tried and failed to come up with any better workaround. This is currently one of few remaining warnings for a 4.14.y randconfig build, so it would be good to also have it backported at least to that version. Older versions have more randconfig warnings, so we might not care. I had not noticed this earlier, because one patch in my randconfig test tree removes the '-ffreestanding' option on x86-32, and that avoids the warning. The -ffreestanding flag was originally global but moved into arch/i386 by Andi Kleen in commit 6edfba1b33c7 ("[PATCH] x86_64: Don't define string functions to builtin") as a 'temporary workaround'. Like many temporary hacks, this turned out to be rather long-lived, from all I can tell we still need a simple fix to asm/string_32.h before it can be removed, but I'm not sure about how to best do that. Cc: stable@vger.kernel.org Cc: Andi Kleen Signed-off-by: Arnd Bergmann Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/renesas/clk-sh73a0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index eea38f6ea77e..3892346c4fcc 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -46,7 +46,7 @@ struct div4_clk { unsigned int shift; }; -static struct div4_clk div4_clks[] = { +static const struct div4_clk div4_clks[] = { { "zg", "pll0", CPG_FRQCRA, 16 }, { "m3", "pll1", CPG_FRQCRA, 12 }, { "b", "pll1", CPG_FRQCRA, 8 }, @@ -79,7 +79,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, { const struct clk_div_table *table = NULL; unsigned int shift, reg, width; - const char *parent_name; + const char *parent_name = NULL; unsigned int mult = 1; unsigned int div = 1; @@ -135,7 +135,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, shift = 24; width = 5; } else { - struct div4_clk *c; + const struct div4_clk *c; for (c = div4_clks; c->name; c++) { if (!strcmp(name, c->name)) { -- cgit v1.2.3 From 6af2423153c430055c39947550ca341d75d0120f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 22 Mar 2018 10:11:30 +0100 Subject: clk: bcm2835: De-assert/assert PLL reset signal when appropriate commit 753872373b599384ac7df809aa61ea12d1c4d5d1 upstream. In order to enable a PLL, not only the PLL has to be powered up and locked, but you also have to de-assert the reset signal. The last part was missing. Add it so PLLs that were not enabled by the FW/bootloader can be enabled from Linux. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Cc: Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/bcm/clk-bcm2835.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index abdc149941e2..73aab6e984cd 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -545,9 +545,7 @@ static void bcm2835_pll_off(struct clk_hw *hw) const struct bcm2835_pll_data *data = pll->data; spin_lock(&cprman->regs_lock); - cprman_write(cprman, data->cm_ctrl_reg, - cprman_read(cprman, data->cm_ctrl_reg) | - CM_PLL_ANARST); + cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); cprman_write(cprman, data->a2w_ctrl_reg, cprman_read(cprman, data->a2w_ctrl_reg) | A2W_PLL_CTRL_PWRDN); @@ -583,6 +581,10 @@ static int bcm2835_pll_on(struct clk_hw *hw) cpu_relax(); } + cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PRST_DISABLE); + return 0; } -- cgit v1.2.3 From f6ed0ff4c7de070c630eac654627ce5a402712db Mon Sep 17 00:00:00 2001 From: Ryo Kodama Date: Fri, 9 Mar 2018 20:24:21 +0900 Subject: pwm: rcar: Fix a condition to prevent mismatch value setting to duty commit 6225f9c64b40bc8a22503e9cda70f55d7a9dd3c6 upstream. This patch fixes an issue that is possible to set mismatch value to duty for R-Car PWM if we input the following commands: # cd /sys/class/pwm// # echo 0 > export # cd pwm0 # echo 30 > period # echo 30 > duty_cycle # echo 0 > duty_cycle # cat duty_cycle 0 # echo 1 > enable --> Then, the actual duty_cycle is 30, not 0. So, this patch adds a condition into rcar_pwm_config() to fix this issue. Signed-off-by: Ryo Kodama [shimoda: revise the commit log and add Fixes and Cc tags] Fixes: ed6c1476bf7f ("pwm: Add support for R-Car PWM Timer") Cc: Cc: # v4.4+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-rcar.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c index 1c85ecc9e7ac..0fcf94ffad32 100644 --- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -156,8 +156,12 @@ static int rcar_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (div < 0) return div; - /* Let the core driver set pwm->period if disabled and duty_ns == 0 */ - if (!pwm_is_enabled(pwm) && !duty_ns) + /* + * Let the core driver set pwm->period if disabled and duty_ns == 0. + * But, this driver should prevent to set the new duty_ns if current + * duty_cycle is not set + */ + if (!pwm_is_enabled(pwm) && !duty_ns && !pwm->state.duty_cycle) return 0; rcar_pwm_update(rp, RCAR_PWMCR_SYNC, RCAR_PWMCR_SYNC, RCAR_PWMCR); -- cgit v1.2.3 From a84a584c08783919a0e138e1e15ee2c45cdc0751 Mon Sep 17 00:00:00 2001 From: Mikhail Lappo Date: Fri, 2 Feb 2018 16:17:46 -0200 Subject: thermal: imx: Fix race condition in imx_thermal_probe() commit cf1ba1d73a33944d8c1a75370a35434bf146b8a7 upstream. When device boots with T > T_trip_1 and requests interrupt, the race condition takes place. The interrupt comes before THERMAL_DEVICE_ENABLED is set. This leads to an attempt to reading sensor value from irq and disabling the sensor, based on the data->mode field, which expected to be THERMAL_DEVICE_ENABLED, but still stays as THERMAL_DEVICE_DISABLED. Afher this issue sensor is never re-enabled, as the driver state is wrong. Fix this problem by setting the 'data' members prior to requesting the interrupts. Fixes: 37713a1e8e4c ("thermal: imx: implement thermal alarm interrupt handling") Cc: Signed-off-by: Mikhail Lappo Signed-off-by: Fabio Estevam Reviewed-by: Philipp Zabel Acked-by: Dong Aisheng Signed-off-by: Zhang Rui Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/imx_thermal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 06912f0602b7..b7cb49afa056 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -587,6 +587,9 @@ static int imx_thermal_probe(struct platform_device *pdev) regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); + data->irq_enabled = true; + data->mode = THERMAL_DEVICE_ENABLED; + ret = devm_request_threaded_irq(&pdev->dev, data->irq, imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 0, "imx_thermal", data); @@ -598,9 +601,6 @@ static int imx_thermal_probe(struct platform_device *pdev) return ret; } - data->irq_enabled = true; - data->mode = THERMAL_DEVICE_ENABLED; - return 0; } -- cgit v1.2.3 From 4076d92cc204fde02b07ca3a399c89d217c9ff0f Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 6 Mar 2018 23:47:25 -0800 Subject: watchdog: f71808e_wdt: Fix WD_EN register read commit 977f6f68331f94bb72ad84ee96b7b87ce737d89d upstream. F71808FG_FLAG_WD_EN defines bit position, not a bitmask Signed-off-by: Igor Pylypiv Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/f71808e_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 8658dba21768..e682bf046e50 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -496,7 +496,7 @@ static bool watchdog_is_running(void) is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) - & F71808FG_FLAG_WD_EN); + & BIT(F71808FG_FLAG_WD_EN)); superio_exit(watchdog.sioaddr); -- cgit v1.2.3 From 502b50e87038e63011dbe83f210292b1c505b6c9 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 2 Oct 2017 12:39:10 -0600 Subject: vfio/pci: Virtualize Maximum Read Request Size commit cf0d53ba4947aad6e471491d5b20a567cbe92e56 upstream. MRRS defines the maximum read request size a device is allowed to make. Drivers will often increase this to allow more data transfer with a single request. Completions to this request are bound by the MPS setting for the bus. Aside from device quirks (none known), it doesn't seem to make sense to set an MRRS value less than MPS, yet this is a likely scenario given that user drivers do not have a system-wide view of the PCI topology. Virtualize MRRS such that the user can set MRRS >= MPS, but use MPS as the floor value that we'll write to hardware. Signed-off-by: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/pci/vfio_pci_config.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 9f1ec4392209..7b8a957b008d 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -810,6 +810,7 @@ static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos, { __le16 *ctrl = (__le16 *)(vdev->vconfig + pos - offset + PCI_EXP_DEVCTL); + int readrq = le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ; count = vfio_default_config_write(vdev, pos, count, perm, offset, val); if (count < 0) @@ -835,6 +836,27 @@ static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos, pci_try_reset_function(vdev->pdev); } + /* + * MPS is virtualized to the user, writes do not change the physical + * register since determining a proper MPS value requires a system wide + * device view. The MRRS is largely independent of MPS, but since the + * user does not have that system-wide view, they might set a safe, but + * inefficiently low value. Here we allow writes through to hardware, + * but we set the floor to the physical device MPS setting, so that + * we can at least use full TLPs, as defined by the MPS value. + * + * NB, if any devices actually depend on an artificially low MRRS + * setting, this will need to be revisited, perhaps with a quirk + * though pcie_set_readrq(). + */ + if (readrq != (le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ)) { + readrq = 128 << + ((le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ) >> 12); + readrq = max(readrq, pcie_get_mps(vdev->pdev)); + + pcie_set_readrq(vdev->pdev, readrq); + } + return count; } @@ -853,11 +875,12 @@ static int __init init_pci_cap_exp_perm(struct perm_bits *perm) * Allow writes to device control fields, except devctl_phantom, * which could confuse IOMMU, MPS, which can break communication * with other physical devices, and the ARI bit in devctl2, which - * is set at probe time. FLR gets virtualized via our writefn. + * is set at probe time. FLR and MRRS get virtualized via our + * writefn. */ p_setw(perm, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD, - ~PCI_EXP_DEVCTL_PHANTOM); + PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD | + PCI_EXP_DEVCTL_READRQ, ~PCI_EXP_DEVCTL_PHANTOM); p_setw(perm, PCI_EXP_DEVCTL2, NO_VIRT, ~PCI_EXP_DEVCTL2_ARI); return 0; } -- cgit v1.2.3 From 54279928a84d5fc6f9e15d43ad31170c7eae1c1d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 21 Mar 2018 21:05:46 -0500 Subject: drm/amdgpu: Add an ATPX quirk for hybrid laptop commit 13b40935cf64f59b93cf1c716a2033488e5a228c upstream. _PR3 doesn't seem to work properly, use ATPX instead. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=104064 Reviewed-by: Huang Rui Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 0e8f8972a160..0217f5d6ecb9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -569,6 +569,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x67DF, 0x1028, 0x0774, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0, 0, 0, 0, 0 }, }; -- cgit v1.2.3 From 267e6921ca7c7e776804a8be6aa53fca37d68fd6 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Wed, 31 Jan 2018 13:58:55 +0100 Subject: drm/amdgpu: Fix always_valid bos multiple LRU insertions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a20ee0b1f8b42e2568f3a4408003d22b2dfcc706 upstream. If these bos are evicted and are in the validated list things blow up, so do not put them in there. Notably, that tries to add the bo to the LRU twice, which results in a BUG_ON in ttm_bo.c. While for the bo_list an alternative would be to not allow always valid bos in there, that does not work for the user fence. v2: Fixed whitespace issue pointed out by checkpatch.pl Signed-off-by: Bas Nieuwenhuizen Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 6 ++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index c02db01f6583..fe011c7ec70a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -201,8 +201,10 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, for (i = 0; i < list->num_entries; i++) { unsigned priority = list->array[i].priority; - list_add_tail(&list->array[i].tv.head, - &bucket[priority]); + if (!list->array[i].robj->parent) + list_add_tail(&list->array[i].tv.head, + &bucket[priority]); + list->array[i].user_pages = NULL; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index cb505f66d3aa..c801624f33bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -519,7 +519,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, INIT_LIST_HEAD(&duplicates); amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); - if (p->uf_entry.robj) + if (p->uf_entry.robj && !p->uf_entry.robj->parent) list_add(&p->uf_entry.tv.head, &p->validated); if (need_mmap_lock) -- cgit v1.2.3 From aab59482e65969b176e97bb6cff7e443d3115ec8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Apr 2018 12:29:26 -0500 Subject: drm/amdgpu: Fix PCIe lane width calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 41212e2fe72b26ded7ed78224d9eab720c2891e2 upstream. The calculation of the lane widths via ATOM_PPLIB_PCIE_LINK_WIDTH_MASK and ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT macros did not increment the resulting value, per the comment in pptable.h ("lanes - 1"), and per usage elsewhere. Port of the radeon fix to amdgpu. Acked-by: Christian König Acked-by: Chunming Zhou Bug: https://bugs.freedesktop.org/show_bug.cgi?id=102553 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 002862be2df6..3fa8320e49c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -6449,9 +6449,9 @@ static void si_set_pcie_lane_width_in_smc(struct amdgpu_device *adev, { u32 lane_width; u32 new_lane_width = - (amdgpu_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; + ((amdgpu_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; u32 current_lane_width = - (amdgpu_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; + ((amdgpu_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; if (new_lane_width != current_lane_width) { amdgpu_set_pcie_lanes(adev, new_lane_width); -- cgit v1.2.3 From 7c320edaa4c8b5c864b11c5e5c51b9dfd36a19c4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 20 Feb 2018 13:01:18 +0000 Subject: drm/rockchip: Clear all interrupts before requesting the IRQ commit 5f9e93fed4d45e9a8f84728aff1a8f2ab8922902 upstream. Calling request_irq() followed by disable_irq() is usually a bad idea, specially if the interrupt can be pending, and you're not yet in a position to handle it. This is exactly what happens on my kevin system when rebooting in a second kernel using kexec: Some interrupt is left pending from the previous kernel, and we take it too early, before disable_irq() could do anything. Let's clear the pending interrupts as we initialize the HW, and move the interrupt request after that point. This ensures that we're in a sane state when the interrupt is requested. Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier [adapted to recent rockchip-drm changes] Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20180220130120.5254-2-marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 6e3c4acb16ac..32d87c6035c9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1386,6 +1386,9 @@ static int vop_initial(struct vop *vop) usleep_range(10, 20); reset_control_deassert(ahb_rst); + VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1); + VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0); + memcpy(vop->regsbak, vop->regs, vop->len); for (i = 0; i < vop_data->table_size; i++) @@ -1541,17 +1544,9 @@ static int vop_bind(struct device *dev, struct device *master, void *data) mutex_init(&vop->vsync_mutex); - ret = devm_request_irq(dev, vop->irq, vop_isr, - IRQF_SHARED, dev_name(dev), vop); - if (ret) - return ret; - - /* IRQ is initially disabled; it gets enabled in power_on */ - disable_irq(vop->irq); - ret = vop_create_crtc(vop); if (ret) - goto err_enable_irq; + return ret; pm_runtime_enable(&pdev->dev); @@ -1561,13 +1556,19 @@ static int vop_bind(struct device *dev, struct device *master, void *data) goto err_disable_pm_runtime; } + ret = devm_request_irq(dev, vop->irq, vop_isr, + IRQF_SHARED, dev_name(dev), vop); + if (ret) + goto err_disable_pm_runtime; + + /* IRQ is initially disabled; it gets enabled in power_on */ + disable_irq(vop->irq); + return 0; err_disable_pm_runtime: pm_runtime_disable(&pdev->dev); vop_destroy_crtc(vop); -err_enable_irq: - enable_irq(vop->irq); /* To balance out the disable_irq above */ return ret; } -- cgit v1.2.3 From 9607290a18352cba4a7d015d826c1ce40bdb25bb Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Sat, 2 Apr 2016 12:32:30 +0100 Subject: drm/radeon: Fix PCIe lane width calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 85e290d92b4b794d0c758c53007eb4248d385386 upstream. Two years ago I tried an AMD Radeon E8860 embedded GPU with the drm driver. The dmesg output included driver warnings about an invalid PCIe lane width. Tracking the problem back led to si_set_pcie_lane_width_in_smc(). The calculation of the lane widths via ATOM_PPLIB_PCIE_LINK_WIDTH_MASK and ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT macros did not increment the resulting value, per the comment in pptable.h ("lanes - 1"), and per usage elsewhere. Applying the increment silenced the warnings. The code has not changed since, so either my analysis was incorrect or the bug has gone unnoticed. Hence submitting this as an RFC. Acked-by: Christian König Acked-by: Chunming Zhou Signed-off-by: Paul Parsons Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/si_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 574ab0016a57..b82ef5ed727c 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -5969,9 +5969,9 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev, { u32 lane_width; u32 new_lane_width = - (radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; + ((radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; u32 current_lane_width = - (radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; + ((radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; if (new_lane_width != current_lane_width) { radeon_set_pcie_lanes(rdev, new_lane_width); -- cgit v1.2.3 From 4dfb3442bb7e1fb80515df4a199ca5a7a8edf900 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 11 Apr 2018 13:27:52 -0400 Subject: random: fix crng_ready() test commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream. The crng_init variable has three states: 0: The CRNG is not initialized at all 1: The CRNG has a small amount of entropy, hopefully good enough for early-boot, non-cryptographical use cases 2: The CRNG is fully initialized and we are sure it is safe for cryptographic use cases. The crng_ready() function should only return true once we are in the last state. This addresses CVE-2018-1108. Reported-by: Jann Horn Fixes: e192be9d9a30 ("random: replace non-blocking pool...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o Reviewed-by: Jann Horn Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index cf1b91e33a28..4f82fe0789e4 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -434,7 +434,7 @@ struct crng_state primary_crng = { * its value (from 0->1->2). */ static int crng_init = 0; -#define crng_ready() (likely(crng_init > 0)) +#define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) static void _extract_crng(struct crng_state *crng, @@ -800,7 +800,7 @@ static int crng_fast_load(const char *cp, size_t len) if (!spin_trylock_irqsave(&primary_crng.lock, flags)) return 0; - if (crng_ready()) { + if (crng_init != 0) { spin_unlock_irqrestore(&primary_crng.lock, flags); return 0; } @@ -872,7 +872,7 @@ static void _extract_crng(struct crng_state *crng, { unsigned long v, flags; - if (crng_init > 1 && + if (crng_ready() && time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); spin_lock_irqsave(&crng->lock, flags); @@ -1153,7 +1153,7 @@ void add_interrupt_randomness(int irq, int irq_flags) fast_mix(fast_pool); add_interrupt_bench(cycles); - if (!crng_ready()) { + if (unlikely(crng_init == 0)) { if ((fast_pool->count >= 64) && crng_fast_load((char *) fast_pool->pool, sizeof(fast_pool->pool))) { @@ -2148,7 +2148,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count, { struct entropy_store *poolp = &input_pool; - if (!crng_ready()) { + if (unlikely(crng_init == 0)) { crng_fast_load(buffer, count); return; } -- cgit v1.2.3 From befd00cfc189672adfdf6850cf460a7f53c56cf0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 12 Apr 2018 00:50:45 -0400 Subject: random: crng_reseed() should lock the crng instance that it is modifying commit 0bb29a849a6433b72e249eea7695477b02056e94 upstream. Reported-by: Jann Horn Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o Reviewed-by: Jann Horn Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 4f82fe0789e4..9d24f3cdc9bb 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -836,7 +836,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) _crng_backtrack_protect(&primary_crng, buf.block, CHACHA20_KEY_SIZE); } - spin_lock_irqsave(&primary_crng.lock, flags); + spin_lock_irqsave(&crng->lock, flags); for (i = 0; i < 8; i++) { unsigned long rv; if (!arch_get_random_seed_long(&rv) && @@ -852,7 +852,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) wake_up_interruptible(&crng_init_wait); pr_notice("random: crng init done\n"); } - spin_unlock_irqrestore(&primary_crng.lock, flags); + spin_unlock_irqrestore(&crng->lock, flags); } static inline void maybe_reseed_primary_crng(void) -- cgit v1.2.3 From 1d49e2ab766df649c540959a96f1ab839471fbe8 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 11 Apr 2018 16:32:17 -0400 Subject: random: add new ioctl RNDRESEEDCRNG commit d848e5f8e1ebdb227d045db55fe4f825e82965fa upstream. Add a new ioctl which forces the the crng to be reseeded. Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 9d24f3cdc9bb..8d08a8062904 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -436,6 +436,7 @@ struct crng_state primary_crng = { static int crng_init = 0; #define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; +static unsigned long crng_global_init_time = 0; #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA20_BLOCK_SIZE]); @@ -873,7 +874,8 @@ static void _extract_crng(struct crng_state *crng, unsigned long v, flags; if (crng_ready() && - time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) + (time_after(crng_global_init_time, crng->init_time) || + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); spin_lock_irqsave(&crng->lock, flags); if (arch_get_random_long(&v)) @@ -1668,6 +1670,7 @@ static int rand_initialize(void) init_std_data(&input_pool); init_std_data(&blocking_pool); crng_initialize(&primary_crng); + crng_global_init_time = jiffies; #ifdef CONFIG_NUMA pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); @@ -1854,6 +1857,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) input_pool.entropy_count = 0; blocking_pool.entropy_count = 0; return 0; + case RNDRESEEDCRNG: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (crng_init < 2) + return -ENODATA; + crng_reseed(&primary_crng, NULL); + crng_global_init_time = jiffies - 1; + return 0; default: return -EINVAL; } -- cgit v1.2.3 From d385cc6917c4fb27f883694b5f53253a289b60c8 Mon Sep 17 00:00:00 2001 From: Rodrigo Rivas Costa Date: Fri, 6 Apr 2018 01:09:36 +0200 Subject: HID: hidraw: Fix crash on HIDIOCGFEATURE with a destroyed device commit a955358d54695e4ad9f7d6489a7ac4d69a8fc711 upstream. Doing `ioctl(HIDIOCGFEATURE)` in a tight loop on a hidraw device and then disconnecting the device, or unloading the driver, can cause a NULL pointer dereference. When a hidraw device is destroyed it sets 0 to `dev->exist`. Most functions check 'dev->exist' before doing its work, but `hidraw_get_report()` was missing that check. Cc: stable@vger.kernel.org Signed-off-by: Rodrigo Rivas Costa Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hidraw.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index f0e2757cb909..216f0338a1f7 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t int ret = 0, len; unsigned char report_number; + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + ret = -ENODEV; + goto out; + } + dev = hidraw_table[minor]->hid; if (!dev->ll_driver->raw_request) { -- cgit v1.2.3 From 5ddab9f7be78b36ded2a7a93d45642dff46fd409 Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Mon, 2 Apr 2018 15:10:35 +0800 Subject: drm/vc4: Fix memory leak during BO teardown commit c0db1b677e1d584fab5d7ac76a32e1c0157542e0 upstream. During BO teardown, an indirect list 'uniform_addr_offsets' wasn't being freed leading to leaking many 128B allocations. Fix the memory leak by releasing it at teardown time. Cc: stable@vger.kernel.org Fixes: 6d45c81d229d ("drm/vc4: Add support for branching in shader validation.") Signed-off-by: Daniel J Blueman Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20180402071035.25356-1-daniel@quora.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vc4/vc4_bo.c | 2 ++ drivers/gpu/drm/vc4/vc4_validate_shaders.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index ec9023bd935b..d53e805d392f 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -80,6 +80,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo) struct vc4_dev *vc4 = to_vc4_dev(obj->dev); if (bo->validated_shader) { + kfree(bo->validated_shader->uniform_addr_offsets); kfree(bo->validated_shader->texture_samples); kfree(bo->validated_shader); bo->validated_shader = NULL; @@ -328,6 +329,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo) } if (bo->validated_shader) { + kfree(bo->validated_shader->uniform_addr_offsets); kfree(bo->validated_shader->texture_samples); kfree(bo->validated_shader); bo->validated_shader = NULL; diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 917321ce832f..19a5bde8e490 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -874,6 +874,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) fail: kfree(validation_state.branch_targets); if (validated_shader) { + kfree(validated_shader->uniform_addr_offsets); kfree(validated_shader->texture_samples); kfree(validated_shader); } -- cgit v1.2.3 From 9c87602abe12b555e5176403dc7e8b4ddb8ace33 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 16 Apr 2018 18:53:09 +0300 Subject: drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7eb2c4dd54ff841f2fe509a84973eb25fa20bda2 upstream. LSPCON adapters in low-power state may ignore the first I2C write during TMDS output buffer enabling, resulting in a blank screen even with an otherwise enabled pipe. Fix this by reading back and validating the written value a few times. The problem was noticed on GLK machines with an onboard LSPCON adapter after entering/exiting DC5 power state. Doing an I2C read of the adapter ID as the first transaction - instead of the I2C write to enable the TMDS buffers - returns the correct value. Based on this we assume that the transaction itself is sent properly, it's only the adapter that is not ready for some reason to accept this first write after waking from low-power state. In my case the second I2C write attempt always succeeded. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105854 Cc: Clinton Taylor Cc: Ville Syrjälä Cc: stable@vger.kernel.org Signed-off-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180416155309.11100-1-imre.deak@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_dp_dual_mode_helper.c | 39 +++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c index a7b2a751f6fe..cdb53586c8fe 100644 --- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c +++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c @@ -322,19 +322,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type, { uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE; ssize_t ret; + int retry; if (type < DRM_DP_DUAL_MODE_TYPE2_DVI) return 0; - ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN, - &tmds_oen, sizeof(tmds_oen)); - if (ret) { - DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n", - enable ? "enable" : "disable"); - return ret; + /* + * LSPCON adapters in low-power state may ignore the first write, so + * read back and verify the written value a few times. + */ + for (retry = 0; retry < 3; retry++) { + uint8_t tmp; + + ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN, + &tmds_oen, sizeof(tmds_oen)); + if (ret) { + DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n", + enable ? "enable" : "disable", + retry + 1); + return ret; + } + + ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN, + &tmp, sizeof(tmp)); + if (ret) { + DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n", + enable ? "enabling" : "disabling", + retry + 1); + return ret; + } + + if (tmp == tmds_oen) + return 0; } - return 0; + DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n", + enable ? "enabling" : "disabling"); + + return -EIO; } EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output); -- cgit v1.2.3 From fbd45e2957fbf7ed392deab29cd3050a1ab2562f Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 13 Oct 2016 14:10:35 +0200 Subject: i2c: i801: store and restore the SLVCMD register at load and unload commit 22e94bd6779e1140350c0792e85c79552ec43673 upstream. Also do not override any other configuration in this register. Signed-off-by: Benjamin Tissoires Signed-off-by: Wolfram Sang Cc: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e6fe21a6135b..e7c91494d1cd 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -243,6 +243,7 @@ struct i801_priv { struct i2c_adapter adapter; unsigned long smba; unsigned char original_hstcfg; + unsigned char original_slvcmd; struct pci_dev *pci_dev; unsigned int features; @@ -962,13 +963,26 @@ static int i801_enable_host_notify(struct i2c_adapter *adapter) if (!priv->host_notify) return -ENOMEM; - outb_p(SMBSLVCMD_HST_NTFY_INTREN, SMBSLVCMD(priv)); + priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); + + if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) + outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, + SMBSLVCMD(priv)); + /* clear Host Notify bit to allow a new notification */ outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); return 0; } +static void i801_disable_host_notify(struct i801_priv *priv) +{ + if (!(priv->features & FEATURE_HOST_NOTIFY)) + return; + + outb_p(priv->original_slvcmd, SMBSLVCMD(priv)); +} + static const struct i2c_algorithm smbus_algorithm = { .smbus_xfer = i801_access, .functionality = i801_func, @@ -1666,6 +1680,7 @@ static void i801_remove(struct pci_dev *dev) pm_runtime_forbid(&dev->dev); pm_runtime_get_noresume(&dev->dev); + i801_disable_host_notify(priv); i801_del_mux(priv); i2c_del_adapter(&priv->adapter); i801_acpi_remove(priv); -- cgit v1.2.3 From 53defab7a561973cc3b815b87ce0ddbb9bc3ee18 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Apr 2018 18:03:31 +0200 Subject: i2c: i801: Save register SMBSLVCMD value only once commit a086bb8317303dd74725dca933b9b29575159382 upstream. Saving the original value of register SMBSLVCMD in i801_enable_host_notify() doesn't work, because this function is called not only at probe time but also at resume time. Do it in i801_probe() instead, so that the saved value is not overwritten at resume time. Signed-off-by: Jean Delvare Fixes: 22e94bd6779e ("i2c: i801: store and restore the SLVCMD register at load and unload") Reviewed-by: Benjamin Tissoires Tested-by: Jason Andryuk Signed-off-by: Wolfram Sang Cc: stable@vger.kernel.org # v4.10+ Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e7c91494d1cd..fcffd60410eb 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -963,8 +963,6 @@ static int i801_enable_host_notify(struct i2c_adapter *adapter) if (!priv->host_notify) return -ENOMEM; - priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); - if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, SMBSLVCMD(priv)); @@ -1603,6 +1601,10 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) outb_p(inb_p(SMBAUXCTL(priv)) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); + /* Remember original Host Notify setting */ + if (priv->features & FEATURE_HOST_NOTIFY) + priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); + /* Default timeout in interrupt mode: 200 ms */ priv->adapter.timeout = HZ / 5; -- cgit v1.2.3 From bd8505f3f3d408da000957452d119b97f6eb2bba Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Apr 2018 18:05:34 +0200 Subject: i2c: i801: Restore configuration at shutdown commit f7f6d915a10f7f2bce17e3b1b7d3376562395a28 upstream. On some systems, the BIOS expects certain SMBus register values to match the hardware defaults. Restore these configuration registers at shutdown time to avoid confusing the BIOS. This avoids hard-locking such systems upon reboot. Signed-off-by: Jean Delvare Tested-by: Jason Andryuk Signed-off-by: Wolfram Sang Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index fcffd60410eb..b32bf7eac3c8 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1696,6 +1696,15 @@ static void i801_remove(struct pci_dev *dev) */ } +static void i801_shutdown(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + /* Restore config registers to avoid hard hang on some systems */ + i801_disable_host_notify(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); +} + #ifdef CONFIG_PM static int i801_suspend(struct device *dev) { @@ -1728,6 +1737,7 @@ static struct pci_driver i801_driver = { .id_table = i801_ids, .probe = i801_probe, .remove = i801_remove, + .shutdown = i801_shutdown, .driver = { .pm = &i801_pm_ops, }, -- cgit v1.2.3 From c274101cd18bcf4d93941edc911b89fdb8065816 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Tue, 20 Feb 2018 07:30:10 -0600 Subject: usb: musb: fix enumeration after resume commit 17539f2f4f0b7fa906b508765c8ada07a1e45f52 upstream. On dm3730 there are enumeration problems after resume. Investigation led to the cause that the MUSB_POWER_SOFTCONN bit is not set. If it was set before suspend (because it was enabled via musb_pullup()), it is set in musb_restore_context() so the pullup is enabled. But then musb_start() is called which overwrites MUSB_POWER and therefore disables MUSB_POWER_SOFTCONN, so no pullup is enabled and the device is not enumerated. So let's do a subset of what musb_start() does in the same way as musb_suspend() does it. Platform-specific stuff it still called as there might be some phy-related stuff which needs to be enabled. Also interrupts are enabled, as it was the original idea of calling musb_start() in musb_resume() according to Commit 6fc6f4b87cb3 ("usb: musb: Disable interrupts on suspend, enable them on resume") Signed-off-by: Andreas Kemnade Tested-by: Tony Lindgren Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 2d9a8067eaca..0736cc27b5e7 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2710,7 +2710,8 @@ static int musb_resume(struct device *dev) if ((devctl & mask) != (musb->context.devctl & mask)) musb->port1_status = 0; - musb_start(musb); + musb_enable_interrupts(musb); + musb_platform_enable(musb); spin_lock_irqsave(&musb->lock, flags); error = musb_run_resume_work(musb); -- cgit v1.2.3 From 9e565114f4bc9459606dfc59d84df11fa6dc75a4 Mon Sep 17 00:00:00 2001 From: Merlijn Wajer Date: Mon, 5 Mar 2018 11:35:10 -0600 Subject: usb: musb: call pm_runtime_{get,put}_sync before reading vbus registers commit df6b074dbe248d8c43a82131e8fd429e401841a5 upstream. Without pm_runtime_{get,put}_sync calls in place, reading vbus status via /sys causes the following error: Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa0ab060 pgd = b333e822 [fa0ab060] *pgd=48011452(bad) [] (musb_default_readb) from [] (musb_vbus_show+0x58/0xe4) [] (musb_vbus_show) from [] (dev_attr_show+0x20/0x44) [] (dev_attr_show) from [] (sysfs_kf_seq_show+0x80/0xdc) [] (sysfs_kf_seq_show) from [] (seq_read+0x250/0x448) [] (seq_read) from [] (__vfs_read+0x1c/0x118) [] (__vfs_read) from [] (vfs_read+0x90/0x144) [] (vfs_read) from [] (SyS_read+0x3c/0x74) [] (SyS_read) from [] (ret_fast_syscall+0x0/0x54) Solution was suggested by Tony Lindgren . Signed-off-by: Merlijn Wajer Acked-by: Tony Lindgren Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0736cc27b5e7..d4c9e9544ba0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1774,6 +1774,7 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) int vbus; u8 devctl; + pm_runtime_get_sync(dev); spin_lock_irqsave(&musb->lock, flags); val = musb->a_wait_bcon; vbus = musb_platform_get_vbus_status(musb); @@ -1787,6 +1788,7 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) vbus = 0; } spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_put_sync(dev); return sprintf(buf, "Vbus %s, timeout %lu msec\n", vbus ? "on" : "off", val); -- cgit v1.2.3 From 4dcd6ce1dff4903a6f3a928962dd03b0a7ecef15 Mon Sep 17 00:00:00 2001 From: Merlijn Wajer Date: Tue, 13 Mar 2018 09:48:40 -0500 Subject: usb: musb: Fix external abort in musb_remove on omap2430 commit 94e46a4f2d5eb14059e42f313c098d4854847376 upstream. This fixes an oops on unbind / module unload (on the musb omap2430 platform). musb_remove function now calls musb_platform_exit before disabling runtime pm. Signed-off-by: Merlijn Wajer Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d4c9e9544ba0..579aa9accafc 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2485,10 +2485,11 @@ static int musb_remove(struct platform_device *pdev) musb_generic_disable(musb); spin_unlock_irqrestore(&musb->lock, flags); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_platform_exit(musb); + pm_runtime_dont_use_autosuspend(musb->controller); pm_runtime_put_sync(musb->controller); pm_runtime_disable(musb->controller); - musb_platform_exit(musb); musb_phy_callback = NULL; if (musb->dma_controller) musb_dma_controller_destroy(musb->dma_controller); -- cgit v1.2.3 From 98b62bd6823dc7da57a940b84c5e16fd459dc50e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 10 Dec 2016 22:56:21 -0800 Subject: Input: drv260x - fix initializing overdrive voltage commit 74c82dae6c474933f2be401976e1530b5f623221 upstream. We were accidentally initializing haptics->rated_voltage twice, and did not initialize overdrive voltage. Acked-by: Dan Murphy Signed-off-by: Dmitry Torokhov Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/drv260x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 930424e55439..251d64ca41ce 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -521,7 +521,7 @@ static int drv260x_probe(struct i2c_client *client, if (!haptics) return -ENOMEM; - haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT; + haptics->overdrive_voltage = DRV260X_DEF_OD_CLAMP_VOLT; haptics->rated_voltage = DRV260X_DEF_RATED_VOLT; if (pdata) { -- cgit v1.2.3 From f9437fa5d27bd475017107a59a246c7eb4045b57 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 20 Jan 2017 13:25:06 +0000 Subject: power: supply: bq2415x: check for NULL acpi_id to avoid null pointer dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a1b94355ea3fde5e13db7ff37c0272fcde4e29b2 upstream. acpi_match_device can potentially return NULL, so it is prudent to check if acpi_id is null before it is dereferenced. Add a check and an error message to indicate the failure. Signed-off-by: Colin Ian King Reviewed-by: Pali Rohár Signed-off-by: Sebastian Reichel Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq2415x_charger.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/power/supply/bq2415x_charger.c b/drivers/power/supply/bq2415x_charger.c index 73e2f0b79dd4..c4770a94cc8e 100644 --- a/drivers/power/supply/bq2415x_charger.c +++ b/drivers/power/supply/bq2415x_charger.c @@ -1569,6 +1569,11 @@ static int bq2415x_probe(struct i2c_client *client, acpi_id = acpi_match_device(client->dev.driver->acpi_match_table, &client->dev); + if (!acpi_id) { + dev_err(&client->dev, "failed to match device name\n"); + ret = -ENODEV; + goto error_1; + } name = kasprintf(GFP_KERNEL, "%s-%d", acpi_id->id, num); } if (!name) { -- cgit v1.2.3 From d539f0aa5d1c07f312136363a020b7bde0d31094 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 16 Nov 2016 09:11:54 -0200 Subject: stk-webcam: fix an endian bug in stk_camera_read_reg() commit d08876f524a605d64c7ca32cb8e9f5be3839e82e upstream. We pass an int pointer to stk_camera_read_reg() but only write to the highest byte. It's a bug on big endian systems and generally a nasty thing to do and doesn't match the write function either. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/stkwebcam/stk-sensor.c | 6 +++--- drivers/media/usb/stkwebcam/stk-webcam.c | 11 ++++++----- drivers/media/usb/stkwebcam/stk-webcam.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c index e546b014d7ad..2dcc8d0be9e7 100644 --- a/drivers/media/usb/stkwebcam/stk-sensor.c +++ b/drivers/media/usb/stkwebcam/stk-sensor.c @@ -228,7 +228,7 @@ static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) { int i = 0; - int tmpval = 0; + u8 tmpval = 0; if (stk_camera_write_reg(dev, STK_IIC_TX_INDEX, reg)) return 1; @@ -253,7 +253,7 @@ static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) { int i = 0; - int tmpval = 0; + u8 tmpval = 0; if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg)) return 1; @@ -274,7 +274,7 @@ static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval)) return 1; - *val = (u8) tmpval; + *val = tmpval; return 0; } diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 22a9aae16291..1c48f2f1e14a 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -144,7 +144,7 @@ int stk_camera_write_reg(struct stk_camera *dev, u16 index, u8 value) return 0; } -int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) +int stk_camera_read_reg(struct stk_camera *dev, u16 index, u8 *value) { struct usb_device *udev = dev->udev; unsigned char *buf; @@ -163,7 +163,7 @@ int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) sizeof(u8), 500); if (ret >= 0) - memcpy(value, buf, sizeof(u8)); + *value = *buf; kfree(buf); return ret; @@ -171,9 +171,10 @@ int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) static int stk_start_stream(struct stk_camera *dev) { - int value; + u8 value; int i, ret; - int value_116, value_117; + u8 value_116, value_117; + if (!is_present(dev)) return -ENODEV; @@ -213,7 +214,7 @@ static int stk_start_stream(struct stk_camera *dev) static int stk_stop_stream(struct stk_camera *dev) { - int value; + u8 value; int i; if (is_present(dev)) { stk_camera_read_reg(dev, 0x0100, &value); diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 9bbfa3d9bfdd..92bb48e3c74e 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -129,7 +129,7 @@ struct stk_camera { #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) int stk_camera_write_reg(struct stk_camera *, u16, u8); -int stk_camera_read_reg(struct stk_camera *, u16, int *); +int stk_camera_read_reg(struct stk_camera *, u16, u8 *); int stk_sensor_init(struct stk_camera *); int stk_sensor_configure(struct stk_camera *); -- cgit v1.2.3 From faf6fd7539a104a6ad2d263090738ab46c1828c5 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 23 Sep 2016 16:38:27 +0100 Subject: OF: Prevent unaligned access in of_alias_scan() commit de96ec2a77c6d06a423c2c495bb4a2f4299f3d9e upstream. When allocating a struct alias_prop, of_alias_scan() only requested that it be aligned on a 4 byte boundary. The struct contains pointers which leads to us attempting 64 bit writes on 64 bit systems, and if the CPU doesn't support unaligned memory accesses then this causes problems - for example on some MIPS64r2 CPUs including the "mips64r2-generic" QEMU emulated CPU it will trigger an address error exception. Fix this by requesting alignment for the struct alias_prop allocation matching that which the compiler expects, using the __alignof__ keyword. Signed-off-by: Paul Burton Acked-by: Rob Herring Reviewed-by: Grant Likely Cc: Frank Rowand Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14306/ Signed-off-by: Ralf Baechle Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/of/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index a0bccb54a9bd..466b285cef3e 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2109,7 +2109,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) continue; /* Allocate an alias_prop with enough space for the stem */ - ap = dt_alloc(sizeof(*ap) + len + 1, 4); + ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap)); if (!ap) continue; memset(ap, 0, sizeof(*ap) + len + 1); -- cgit v1.2.3 From ff738afb8a847414f73b729cb25df624bd743089 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Feb 2017 10:14:51 +0100 Subject: ath9k_hw: check if the chip failed to wake up commit a34d0a0da1abae46a5f6ebd06fb0ec484ca099d9 upstream. In an RFC patch, Sven Eckelmann and Simon Wunderlich reported: "QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a state in which a read of AR_CFG always returns 0xdeadbeef. This should not happen when when the power_mode of the device is ATH9K_PM_AWAKE." Include the check for the default register state in the existing MAC hang check. Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo Cc: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a35f78be8dec..acef4ec928c1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1603,6 +1603,10 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) int count = 50; u32 reg, last_val; + /* Check if chip failed to wake up */ + if (REG_READ(ah, AR_CFG) == 0xdeadbeef) + return false; + if (AR_SREV_9300(ah)) return !ath9k_hw_detect_mac_hang(ah); -- cgit v1.2.3 From 9ffa6fb2583b2c9afdb83c14948a9e3e2192bf1f Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Sun, 11 Mar 2018 13:51:32 +0200 Subject: RDMA/mlx5: Fix NULL dereference while accessing XRC_TGT QPs commit 75a4598209cbe45540baa316c3b51d9db222e96e upstream. mlx5 modify_qp() relies on FW that the error will be thrown if wrong state is supplied. The missing check in FW causes the following crash while using XRC_TGT QPs. [ 14.769632] BUG: unable to handle kernel NULL pointer dereference at (null) [ 14.771085] IP: mlx5_ib_modify_qp+0xf60/0x13f0 [ 14.771894] PGD 800000001472e067 P4D 800000001472e067 PUD 14529067 PMD 0 [ 14.773126] Oops: 0002 [#1] SMP PTI [ 14.773763] CPU: 0 PID: 365 Comm: ubsan Not tainted 4.16.0-rc1-00038-g8151138c0793 #119 [ 14.775192] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 [ 14.777522] RIP: 0010:mlx5_ib_modify_qp+0xf60/0x13f0 [ 14.778417] RSP: 0018:ffffbf48001c7bd8 EFLAGS: 00010246 [ 14.779346] RAX: 0000000000000000 RBX: ffff9a8f9447d400 RCX: 0000000000000000 [ 14.780643] RDX: 0000000000000000 RSI: 000000000000000a RDI: 0000000000000000 [ 14.781930] RBP: 0000000000000000 R08: 00000000000217b0 R09: ffffffffbc9c1504 [ 14.783214] R10: fffff4a180519480 R11: ffff9a8f94523600 R12: ffff9a8f9493e240 [ 14.784507] R13: ffff9a8f9447d738 R14: 000000000000050a R15: 0000000000000000 [ 14.785800] FS: 00007f545b466700(0000) GS:ffff9a8f9fc00000(0000) knlGS:0000000000000000 [ 14.787073] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 14.787792] CR2: 0000000000000000 CR3: 00000000144be000 CR4: 00000000000006b0 [ 14.788689] Call Trace: [ 14.789007] _ib_modify_qp+0x71/0x120 [ 14.789475] modify_qp.isra.20+0x207/0x2f0 [ 14.790010] ib_uverbs_modify_qp+0x90/0xe0 [ 14.790532] ib_uverbs_write+0x1d2/0x3c0 [ 14.791049] ? __handle_mm_fault+0x93c/0xe40 [ 14.791644] __vfs_write+0x36/0x180 [ 14.792096] ? handle_mm_fault+0xc1/0x210 [ 14.792601] vfs_write+0xad/0x1e0 [ 14.793018] SyS_write+0x52/0xc0 [ 14.793422] do_syscall_64+0x75/0x180 [ 14.793888] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 14.794527] RIP: 0033:0x7f545ad76099 [ 14.794975] RSP: 002b:00007ffd78787468 EFLAGS: 00000287 ORIG_RAX: 0000000000000001 [ 14.795958] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f545ad76099 [ 14.797075] RDX: 0000000000000078 RSI: 0000000020009000 RDI: 0000000000000003 [ 14.798140] RBP: 00007ffd78787470 R08: 00007ffd78787480 R09: 00007ffd78787480 [ 14.799207] R10: 00007ffd78787480 R11: 0000000000000287 R12: 00005599ada98760 [ 14.800277] R13: 00007ffd78787560 R14: 0000000000000000 R15: 0000000000000000 [ 14.801341] Code: 4c 8b 1c 24 48 8b 83 70 02 00 00 48 c7 83 cc 02 00 00 00 00 00 00 48 c7 83 24 03 00 00 00 00 00 00 c7 83 2c 03 00 00 00 00 00 00 00 00 00 00 00 48 8b 83 70 02 00 00 c7 40 04 00 00 00 00 4c [ 14.804012] RIP: mlx5_ib_modify_qp+0xf60/0x13f0 RSP: ffffbf48001c7bd8 [ 14.804838] CR2: 0000000000000000 [ 14.805288] ---[ end trace 3f1da0df5c8b7c37 ]--- Cc: syzkaller Reported-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/qp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 403df3591d29..5b8909d1b55e 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -2848,7 +2848,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, * If we moved a kernel QP to RESET, clean up all old CQ * entries and reinitialize the QP. */ - if (new_state == IB_QPS_RESET && !ibqp->uobject) { + if (new_state == IB_QPS_RESET && + !ibqp->uobject && ibqp->qp_type != IB_QPT_XRC_TGT) { mlx5_ib_cq_clean(recv_cq, base->mqp.qpn, ibqp->srq ? to_msrq(ibqp->srq) : NULL); if (send_cq != recv_cq) -- cgit v1.2.3 From 2d1264b5e665909a3217a16c362802c14ee807c0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 30 Jan 2018 16:29:38 +0200 Subject: drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 5e1df40f40ee45a97bb1066c3d71f0ae920a9672 upstream. Currently we see sporadic timeouts during CDCLK changing both on BXT and GLK as reported by the Bugzilla: ticket. It's easy to reproduce this by changing the frequency in a tight loop after blanking the display. The upper bound for the completion time is 800us based on my tests, so increase it from the current 500us to 2ms; with that I couldn't trigger the problem either on BXT or GLK. Note that timeouts happened during both the change notification and the voltage level setting PCODE request. (For the latter one BSpec doesn't require us to wait for completion before further HW programming.) This issue is similar to commit 2c7d0602c815 ("drm/i915/gen9: Fix PCODE polling during CDCLK change notification") but there the PCODE request does complete (as shown by the mbox busy flag), only the reply we get from PCODE indicates a failure. So there we keep resending the request until a success reply, here we just have to increase the timeout for the one PCODE request we send. v2: - s/snb_pcode_request/sandybridge_pcode_write_timeout/ (Ville) Cc: Chris Wilson Cc: Ville Syrjälä Cc: # v4.9 Acked-by: Chris Wilson (v1) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103326 Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20180130142939.17983-1-imre.deak@intel.com (cherry picked from commit e76019a81921e87a4d9e7b3d86102bc708a6c227) Signed-off-by: Rodrigo Vivi (Rebased for v4.9 stable tree due to upstream intel_cdclk.c, cdclk_state and pcu_lock change) Signed-off-by: Imre Deak Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_drv.h | 6 +++++- drivers/gpu/drm/i915/intel_display.c | 9 +++++---- drivers/gpu/drm/i915/intel_pm.c | 6 +++--- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 36a665f0e5c9..e23748cca0c0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3681,7 +3681,11 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e, struct intel_display_error_state *error); int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val); -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val); +int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox, + u32 val, int timeout_us); +#define sandybridge_pcode_write(dev_priv, mbox, val) \ + sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500) + int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, u32 reply_mask, u32 reply, int timeout_base_ms); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ce32303b3013..c185625d67f2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6012,8 +6012,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) /* Inform power controller of upcoming frequency change */ mutex_lock(&dev_priv->rps.hw_lock); - ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x80000000); + ret = sandybridge_pcode_write_timeout(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, + 0x80000000, 2000); mutex_unlock(&dev_priv->rps.hw_lock); if (ret) { @@ -6044,8 +6044,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) I915_WRITE(CDCLK_CTL, val); mutex_lock(&dev_priv->rps.hw_lock); - ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, - DIV_ROUND_UP(cdclk, 25000)); + ret = sandybridge_pcode_write_timeout(dev_priv, + HSW_PCODE_DE_WRITE_FREQ_REQ, + DIV_ROUND_UP(cdclk, 25000), 2000); mutex_unlock(&dev_priv->rps.hw_lock); if (ret) { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 49de4760cc16..05427d292457 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7913,8 +7913,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val return 0; } -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, - u32 mbox, u32 val) +int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, + u32 mbox, u32 val, int timeout_us) { int status; @@ -7935,7 +7935,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, if (intel_wait_for_register_fw(dev_priv, GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0, - 500)) { + timeout_us)) { DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", mbox); return -ETIMEDOUT; } -- cgit v1.2.3 From 21670a464c6b05d92d24e64332e4c57b984d8701 Mon Sep 17 00:00:00 2001 From: Benjamin Beichler Date: Wed, 7 Mar 2018 18:11:07 +0100 Subject: mac80211_hwsim: fix use-after-free bug in hwsim_exit_net commit 8cfd36a0b53aeb4ec21d81eb79706697b84dfc3d upstream. When destroying a net namespace, all hwsim interfaces, which are not created in default namespace are deleted. But the async deletion of the interfaces could last longer than the actual destruction of the namespace, which results to an use after free bug. Therefore use synchronous deletion in this case. Fixes: 100cb9ff40e0 ("mac80211_hwsim: Allow managing radios from non-initial namespaces") Reported-by: syzbot+70ce058e01259de7bb1d@syzkaller.appspotmail.com Signed-off-by: Benjamin Beichler Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mac80211_hwsim.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4182c3775a72..2681b5339810 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3346,8 +3346,11 @@ static void __net_exit hwsim_exit_net(struct net *net) continue; list_del(&data->list); - INIT_WORK(&data->destroy_work, destroy_radio); - schedule_work(&data->destroy_work); + spin_unlock_bh(&hwsim_radio_lock); + mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), + NULL); + spin_lock_bh(&hwsim_radio_lock); + } spin_unlock_bh(&hwsim_radio_lock); } -- cgit v1.2.3 From 403e7bd6ed4aa2515b05b6f5942a8bbad322d3e8 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Thu, 28 Sep 2017 11:35:00 -0700 Subject: r8152: add Linksys USB3GIGV1 id commit 90841047a01b452cc8c3f9b990698b264143334a upstream. This linksys dongle by default comes up in cdc_ether mode. This patch allows r8152 to claim the device: Bus 002 Device 002: ID 13b1:0041 Linksys Signed-off-by: Grant Grundler Reviewed-by: Douglas Anderson Signed-off-by: David S. Miller [krzk: Rebase on v4.4] Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ether.c | 10 ++++++++++ drivers/net/usb/r8152.c | 2 ++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4fb468666b19..99424c87b464 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -530,6 +530,7 @@ static const struct driver_info wwan_info = { #define REALTEK_VENDOR_ID 0x0bda #define SAMSUNG_VENDOR_ID 0x04e8 #define LENOVO_VENDOR_ID 0x17ef +#define LINKSYS_VENDOR_ID 0x13b1 #define NVIDIA_VENDOR_ID 0x0955 #define HP_VENDOR_ID 0x03f0 @@ -719,6 +720,15 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, +#if IS_ENABLED(CONFIG_USB_RTL8152) +/* Linksys USB3GIGV1 Ethernet Adapter */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, +#endif + /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index b2d7c7e32250..3cdfa2465e3f 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -519,6 +519,7 @@ enum rtl8152_flags { #define VENDOR_ID_REALTEK 0x0bda #define VENDOR_ID_SAMSUNG 0x04e8 #define VENDOR_ID_LENOVO 0x17ef +#define VENDOR_ID_LINKSYS 0x13b1 #define VENDOR_ID_NVIDIA 0x0955 #define MCU_TYPE_PLA 0x0100 @@ -4506,6 +4507,7 @@ static struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, {} }; -- cgit v1.2.3 From b5145685a8bbe0756e5ab8440b5012d74c0daf5b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 26 Apr 2018 17:28:00 +0200 Subject: Revert "pinctrl: intel: Initialize GPIO properly when used through irqchip" This reverts commit f5a26acf0162477af6ee4c11b4fb9cffe5d3e257 Mike writes: It seems that commit f5a26acf0162 ("pinctrl: intel: Initialize GPIO properly when used through irqchip") can cause problems on some Skylake systems with Sunrisepoint PCH-H. Namely on certain systems it may turn the backlight PWM pin from native mode to GPIO which makes the screen blank during boot. There is more information here: https://bugzilla.redhat.com/show_bug.cgi?id=1543769 The actual reason is that GPIO numbering used in BIOS is using "Windows" numbers meaning that they don't match the hardware 1:1 and because of this a wrong pin (backlight PWM) is picked and switched to GPIO mode. There is a proper fix for this but since it has quite many dependencies on commits that cannot be considered stable material, I suggest we revert commit f5a26acf0162 from stable trees 4.9, 4.14 and 4.15 to prevent the backlight issue. Reported-by: Mika Westerberg Fixes: f5a26acf0162 ("pinctrl: intel: Initialize GPIO properly when used through irqchip") Cc: Daniel Drake Cc: Chris Chiu Cc: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/intel/pinctrl-intel.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index df63b7d997e8..b40a074822cf 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -368,18 +368,6 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) writel(value, padcfg0); } -static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) -{ - u32 value; - - /* Put the pad into GPIO mode */ - value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; - /* Disable SCI/SMI/NMI generation */ - value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); - value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); - writel(value, padcfg0); -} - static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin) @@ -387,6 +375,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); void __iomem *padcfg0; unsigned long flags; + u32 value; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -396,7 +385,13 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, } padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - intel_gpio_set_gpio_mode(padcfg0); + /* Put the pad into GPIO mode */ + value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; + /* Disable SCI/SMI/NMI generation */ + value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); + value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); + writel(value, padcfg0); + /* Disable TX buffer and enable RX (this will be input) */ __intel_gpio_set_direction(padcfg0, true); @@ -775,8 +770,6 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) raw_spin_lock_irqsave(&pctrl->lock, flags); - intel_gpio_set_gpio_mode(reg); - value = readl(reg); value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); -- cgit v1.2.3 From 237b5a362399bdd81422ef9f9ac9b9f034161efd Mon Sep 17 00:00:00 2001 From: Karthikeyan Periyasamy Date: Tue, 27 Mar 2018 11:25:29 +0300 Subject: Revert "ath10k: send (re)assoc peer command when NSS changed" commit 55cc11da69895a680940c1733caabc37be685f5e upstream. This reverts commit 55884c045d31a29cf69db8332d1064a1b61dd159. When Ath10k is in AP mode and an unassociated STA sends a VHT action frame (Operating Mode Notification for the NSS change) periodically to AP this causes ath10k to call ath10k_station_assoc() which sends WMI_PEER_ASSOC_CMDID during NSS update. Over the time (with a certain client it can happen within 15 mins when there are over 500 of these VHT action frames) continuous calls of WMI_PEER_ASSOC_CMDID cause firmware to assert due to resource exhaust. To my knowledge setting WMI_PEER_NSS peer param itself enough to handle NSS updates and no need to call ath10k_station_assoc(). So revert the original commit from 2014 as it's unclear why the change was really needed. Now the firmware assert doesn't happen anymore. Issue observed in QCA9984 platform with firmware version:10.4-3.5.3-00053. This Change tested in QCA9984 with firmware version: 10.4-3.5.3-00053 and QCA988x platform with firmware version: 10.2.4-1.0-00036. Firmware Assert log: ath10k_pci 0002:01:00.0: firmware crashed! (guid e61f1274-9acd-4c5b-bcca-e032ea6e723c) ath10k_pci 0002:01:00.0: qca9984/qca9994 hw1.0 target 0x01000000 chip_id 0x00000000 sub 168c:cafe ath10k_pci 0002:01:00.0: kconfig debug 1 debugfs 1 tracing 0 dfs 1 testmode 1 ath10k_pci 0002:01:00.0: firmware ver 10.4-3.5.3-00053 api 5 features no-p2p,mfp,peer-flow-ctrl,btcoex-param,allows-mesh-bcast crc32 4c56a386 ath10k_pci 0002:01:00.0: board_file api 2 bmi_id 0:4 crc32 c2271344 ath10k_pci 0002:01:00.0: htt-ver 2.2 wmi-op 6 htt-op 4 cal otp max-sta 512 raw 0 hwcrypto 1 ath10k_pci 0002:01:00.0: firmware register dump: ath10k_pci 0002:01:00.0: [00]: 0x0000000A 0x000015B3 0x00981E5F 0x00975B31 ath10k_pci 0002:01:00.0: [04]: 0x00981E5F 0x00060530 0x00000011 0x00446C60 ath10k_pci 0002:01:00.0: [08]: 0x0042F1FC 0x00458080 0x00000017 0x00000000 ath10k_pci 0002:01:00.0: [12]: 0x00000009 0x00000000 0x00973ABC 0x00973AD2 ath10k_pci 0002:01:00.0: [16]: 0x00973AB0 0x00960E62 0x009606CA 0x00000000 ath10k_pci 0002:01:00.0: [20]: 0x40981E5F 0x004066DC 0x00400000 0x00981E34 ath10k_pci 0002:01:00.0: [24]: 0x80983B48 0x0040673C 0x000000C0 0xC0981E5F ath10k_pci 0002:01:00.0: [28]: 0x80993DEB 0x0040676C 0x00431AB8 0x0045D0C4 ath10k_pci 0002:01:00.0: [32]: 0x80993E5C 0x004067AC 0x004303C0 0x0045D0C4 ath10k_pci 0002:01:00.0: [36]: 0x80994AAB 0x004067DC 0x00000000 0x0045D0C4 ath10k_pci 0002:01:00.0: [40]: 0x809971A0 0x0040681C 0x004303C0 0x00441B00 ath10k_pci 0002:01:00.0: [44]: 0x80991904 0x0040688C 0x004303C0 0x0045D0C4 ath10k_pci 0002:01:00.0: [48]: 0x80963AD3 0x00406A7C 0x004303C0 0x009918FC ath10k_pci 0002:01:00.0: [52]: 0x80960E80 0x00406A9C 0x0000001F 0x00400000 ath10k_pci 0002:01:00.0: [56]: 0x80960E51 0x00406ACC 0x00400000 0x00000000 ath10k_pci 0002:01:00.0: Copy Engine register dump: ath10k_pci 0002:01:00.0: index: addr: sr_wr_idx: sr_r_idx: dst_wr_idx: dst_r_idx: ath10k_pci 0002:01:00.0: [00]: 0x0004a000 15 15 3 3 ath10k_pci 0002:01:00.0: [01]: 0x0004a400 17 17 212 213 ath10k_pci 0002:01:00.0: [02]: 0x0004a800 21 21 20 21 ath10k_pci 0002:01:00.0: [03]: 0x0004ac00 25 25 27 25 ath10k_pci 0002:01:00.0: [04]: 0x0004b000 515 515 144 104 ath10k_pci 0002:01:00.0: [05]: 0x0004b400 28 28 155 156 ath10k_pci 0002:01:00.0: [06]: 0x0004b800 12 12 12 12 ath10k_pci 0002:01:00.0: [07]: 0x0004bc00 1 1 1 1 ath10k_pci 0002:01:00.0: [08]: 0x0004c000 0 0 127 0 ath10k_pci 0002:01:00.0: [09]: 0x0004c400 1 1 1 1 ath10k_pci 0002:01:00.0: [10]: 0x0004c800 0 0 0 0 ath10k_pci 0002:01:00.0: [11]: 0x0004cc00 0 0 0 0 ath10k_pci 0002:01:00.0: CE[1] write_index 212 sw_index 213 hw_index 0 nentries_mask 0x000001ff ath10k_pci 0002:01:00.0: CE[2] write_index 20 sw_index 21 hw_index 0 nentries_mask 0x0000007f ath10k_pci 0002:01:00.0: CE[5] write_index 155 sw_index 156 hw_index 0 nentries_mask 0x000001ff ath10k_pci 0002:01:00.0: DMA addr: nbytes: meta data: byte swap: gather: ath10k_pci 0002:01:00.0: [455]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [456]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [457]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [458]: 0x594a0038 0 0 0 1 ath10k_pci 0002:01:00.0: [459]: 0x580c0a42 0 0 0 0 ath10k_pci 0002:01:00.0: [460]: 0x594a0060 0 0 0 1 ath10k_pci 0002:01:00.0: [461]: 0x580c0c42 0 0 0 0 ath10k_pci 0002:01:00.0: [462]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [463]: 0x580c0c42 0 0 0 0 ath10k_pci 0002:01:00.0: [464]: 0x594a0038 0 0 0 1 ath10k_pci 0002:01:00.0: [465]: 0x580c0a42 0 0 0 0 ath10k_pci 0002:01:00.0: [466]: 0x594a0060 0 0 0 1 ath10k_pci 0002:01:00.0: [467]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [468]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [469]: 0x580c1c42 0 0 0 0 ath10k_pci 0002:01:00.0: [470]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [471]: 0x580c1c42 0 0 0 0 ath10k_pci 0002:01:00.0: [472]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [473]: 0x580c1c42 0 0 0 0 ath10k_pci 0002:01:00.0: [474]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [475]: 0x580c0642 0 0 0 0 ath10k_pci 0002:01:00.0: [476]: 0x594a0038 0 0 0 1 ath10k_pci 0002:01:00.0: [477]: 0x580c0842 0 0 0 0 ath10k_pci 0002:01:00.0: [478]: 0x594a0060 0 0 0 1 ath10k_pci 0002:01:00.0: [479]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [480]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [481]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [482]: 0x594a0038 0 0 0 1 ath10k_pci 0002:01:00.0: [483]: 0x580c0842 0 0 0 0 ath10k_pci 0002:01:00.0: [484]: 0x594a0060 0 0 0 1 ath10k_pci 0002:01:00.0: [485]: 0x580c0642 0 0 0 0 ath10k_pci 0002:01:00.0: [486]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [487]: 0x580c0642 0 0 0 0 ath10k_pci 0002:01:00.0: [488]: 0x594a0038 0 0 0 1 ath10k_pci 0002:01:00.0: [489]: 0x580c0842 0 0 0 0 ath10k_pci 0002:01:00.0: [490]: 0x594a0060 0 0 0 1 ath10k_pci 0002:01:00.0: [491]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [492]: 0x58174040 0 1 0 0 ath10k_pci 0002:01:00.0: [493]: 0x5a946040 0 1 0 0 ath10k_pci 0002:01:00.0: [494]: 0x59909040 0 1 0 0 ath10k_pci 0002:01:00.0: [495]: 0x5ae5a040 0 1 0 0 ath10k_pci 0002:01:00.0: [496]: 0x58096040 0 1 0 0 ath10k_pci 0002:01:00.0: [497]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [498]: 0x580c0642 0 0 0 0 ath10k_pci 0002:01:00.0: [499]: 0x5c1e0040 0 1 0 0 ath10k_pci 0002:01:00.0: [500]: 0x58153040 0 1 0 0 ath10k_pci 0002:01:00.0: [501]: 0x58129040 0 1 0 0 ath10k_pci 0002:01:00.0: [502]: 0x5952f040 0 1 0 0 ath10k_pci 0002:01:00.0: [503]: 0x59535040 0 1 0 0 ath10k_pci 0002:01:00.0: [504]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [505]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [506]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [507]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [508]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [509]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [510]: 0x594a0010 0 0 0 1 ath10k_pci 0002:01:00.0: [511]: 0x580c0042 0 0 0 0 ath10k_pci 0002:01:00.0: [512]: 0x5adcc040 0 1 0 0 ath10k_pci 0002:01:00.0: [513]: 0x5cf3d040 0 1 0 0 ath10k_pci 0002:01:00.0: [514]: 0x5c1e9040 64 1 0 0 ath10k_pci 0002:01:00.0: [515]: 0x00000000 0 0 0 0 Signed-off-by: Karthikeyan Periyasamy Signed-off-by: Kalle Valo Cc: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath10k/mac.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a497bf31953d..5aa5df24f4dc 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -5819,9 +5819,8 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) sta->addr, smps, err); } - if (changed & IEEE80211_RC_SUPP_RATES_CHANGED || - changed & IEEE80211_RC_NSS_CHANGED) { - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n", + if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", sta->addr); err = ath10k_station_assoc(ar, arvif->vif, sta, true); -- cgit v1.2.3 From c8b1584e5e37fdbf654113a746076d37e9a93206 Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Tue, 29 Aug 2017 14:45:45 -0500 Subject: PCI: Wait up to 60 seconds for device to become ready after FLR commit 821cdad5c46cae94ce65b9a98614c70a6ff021f8 upstream. Sporadic reset issues have been observed with an Intel 750 NVMe drive while assigning the physical function to the guest machine. The sequence of events observed is as follows: - perform a Function Level Reset (FLR) - sleep up to 1000ms total - read ~0 from PCI_COMMAND (CRS completion for config read) - warn that the device didn't return from FLR - touch the device before it's ready - device drops config writes when we restore register settings (there's no mechanism for software to learn about CRS completions for writes) - incomplete register restore leaves device in inconsistent state - device probe fails because device is in inconsistent state After reset, an endpoint may respond to config requests with Configuration Request Retry Status (CRS) to indicate that it is not ready to accept new requests. See PCIe r3.1, sec 2.3.1 and 6.6.2. Increase the timeout value from 1 second to 60 seconds to cover the period where device responds with CRS and also report polling progress. Signed-off-by: Sinan Kaya [bhelgaas: include the mandatory 100ms in the delays we print] Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a87c8e1aef68..9c13aeeeb973 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3756,27 +3756,49 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) } EXPORT_SYMBOL(pci_wait_for_pending_transaction); -/* - * We should only need to wait 100ms after FLR, but some devices take longer. - * Wait for up to 1000ms for config space to return something other than -1. - * Intel IGD requires this when an LCD panel is attached. We read the 2nd - * dword because VFs don't implement the 1st dword. - */ static void pci_flr_wait(struct pci_dev *dev) { - int i = 0; + int delay = 1, timeout = 60000; u32 id; - do { - msleep(100); + /* + * Per PCIe r3.1, sec 6.6.2, a device must complete an FLR within + * 100ms, but may silently discard requests while the FLR is in + * progress. Wait 100ms before trying to access the device. + */ + msleep(100); + + /* + * After 100ms, the device should not silently discard config + * requests, but it may still indicate that it needs more time by + * responding to them with CRS completions. The Root Port will + * generally synthesize ~0 data to complete the read (except when + * CRS SV is enabled and the read was for the Vendor ID; in that + * case it synthesizes 0x0001 data). + * + * Wait for the device to return a non-CRS completion. Read the + * Command register instead of Vendor ID so we don't have to + * contend with the CRS SV value. + */ + pci_read_config_dword(dev, PCI_COMMAND, &id); + while (id == ~0) { + if (delay > timeout) { + dev_warn(&dev->dev, "not ready %dms after FLR; giving up\n", + 100 + delay - 1); + return; + } + + if (delay > 1000) + dev_info(&dev->dev, "not ready %dms after FLR; waiting\n", + 100 + delay - 1); + + msleep(delay); + delay *= 2; pci_read_config_dword(dev, PCI_COMMAND, &id); - } while (i++ < 10 && id == ~0); + } - if (id == ~0) - dev_warn(&dev->dev, "Failed to return from FLR\n"); - else if (i > 1) - dev_info(&dev->dev, "Required additional %dms to return from FLR\n", - (i - 1) * 100); + if (delay > 1000) + dev_info(&dev->dev, "ready %dms after FLR\n", 100 + delay - 1); } static int pcie_flr(struct pci_dev *dev, int probe) -- cgit v1.2.3 From 24fbc4eee899f1a8d291ffe47333a673a3ed6c01 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2018 07:36:47 +0200 Subject: s390: introduce execute-trampolines for branches [ Upstream commit f19fbd5ed642dc31c809596412dab1ed56f2f156 ] Add CONFIG_EXPOLINE to enable the use of the new -mindirect-branch= and -mfunction_return= compiler options to create a kernel fortified against the specte v2 attack. With CONFIG_EXPOLINE=y all indirect branches will be issued with an execute type instruction. For z10 or newer the EXRL instruction will be used, for older machines the EX instruction. The typical indirect call basr %r14,%r1 is replaced with a PC relative call to a new thunk brasl %r14,__s390x_indirect_jump_r1 The thunk contains the EXRL/EX instruction to the indirect branch __s390x_indirect_jump_r1: exrl 0,0f j . 0: br %r1 The detour via the execute type instruction has a performance impact. To get rid of the detour the new kernel parameter "nospectre_v2" and "spectre_v2=[on,off,auto]" can be used. If the parameter is specified the kernel and module code will be patched at runtime. Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 41e28b23b26a..8ac27efe34fc 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -2,6 +2,8 @@ # S/390 character devices # +CFLAGS_REMOVE_sclp_early_core.o += $(CC_FLAGS_EXPOLINE) + obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \ sclp_early.o -- cgit v1.2.3 From a43e7cba5444f062defc2145fe0b83b28ac35d5f Mon Sep 17 00:00:00 2001 From: Xin Long Date: Sun, 22 Apr 2018 19:11:50 +0800 Subject: bonding: do not set slave_dev npinfo before slave_enable_netpoll in bond_enslave [ Upstream commit ddea788c63094f7c483783265563dd5b50052e28 ] After Commit 8a8efa22f51b ("bonding: sync netpoll code with bridge"), it would set slave_dev npinfo in slave_enable_netpoll when enslaving a dev if bond->dev->npinfo was set. However now slave_dev npinfo is set with bond->dev->npinfo before calling slave_enable_netpoll. With slave_dev npinfo set, __netpoll_setup called in slave_enable_netpoll will not call slave dev's .ndo_netpoll_setup(). It causes that the lower dev of this slave dev can't set its npinfo. One way to reproduce it: # modprobe bonding # brctl addbr br0 # brctl addif br0 eth1 # ifconfig bond0 192.168.122.1/24 up # ifenslave bond0 eth2 # systemctl restart netconsole # ifenslave bond0 br0 # ifconfig eth2 down # systemctl restart netconsole The netpoll won't really work. This patch is to remove that slave_dev npinfo setting in bond_enslave(). Fixes: 8a8efa22f51b ("bonding: sync netpoll code with bridge") Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 513457a2a7bf..13a015b8052b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1654,8 +1654,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } /* switch(bond_mode) */ #ifdef CONFIG_NET_POLL_CONTROLLER - slave_dev->npinfo = bond->dev->npinfo; - if (slave_dev->npinfo) { + if (bond->dev->npinfo) { if (slave_enable_netpoll(new_slave)) { netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n"); res = -EBUSY; -- cgit v1.2.3 From 3626fb04d050139b1fe1249f67c7c3efbe73b0ad Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Fri, 13 Apr 2018 13:59:25 +0200 Subject: team: avoid adding twice the same option to the event list [ Upstream commit 4fb0534fb7bbc2346ba7d3a072b538007f4135a5 ] When parsing the options provided by the user space, team_nl_cmd_options_set() insert them in a temporary list to send multiple events with a single message. While each option's attribute is correctly validated, the code does not check for duplicate entries before inserting into the event list. Exploiting the above, the syzbot was able to trigger the following splat: kernel BUG at lib/list_debug.c:31! invalid opcode: 0000 [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 0 PID: 4466 Comm: syzkaller556835 Not tainted 4.16.0+ #17 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:__list_add_valid+0xaa/0xb0 lib/list_debug.c:29 RSP: 0018:ffff8801b04bf248 EFLAGS: 00010286 RAX: 0000000000000058 RBX: ffff8801c8fc7a90 RCX: 0000000000000000 RDX: 0000000000000058 RSI: ffffffff815fbf41 RDI: ffffed0036097e3f RBP: ffff8801b04bf260 R08: ffff8801b0b2a700 R09: ffffed003b604f90 R10: ffffed003b604f90 R11: ffff8801db027c87 R12: ffff8801c8fc7a90 R13: ffff8801c8fc7a90 R14: dffffc0000000000 R15: 0000000000000000 FS: 0000000000b98880(0000) GS:ffff8801db000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000043fc30 CR3: 00000001afe8e000 CR4: 00000000001406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __list_add include/linux/list.h:60 [inline] list_add include/linux/list.h:79 [inline] team_nl_cmd_options_set+0x9ff/0x12b0 drivers/net/team/team.c:2571 genl_family_rcv_msg+0x889/0x1120 net/netlink/genetlink.c:599 genl_rcv_msg+0xc6/0x170 net/netlink/genetlink.c:624 netlink_rcv_skb+0x172/0x440 net/netlink/af_netlink.c:2448 genl_rcv+0x28/0x40 net/netlink/genetlink.c:635 netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] netlink_unicast+0x58b/0x740 net/netlink/af_netlink.c:1336 netlink_sendmsg+0x9f0/0xfa0 net/netlink/af_netlink.c:1901 sock_sendmsg_nosec net/socket.c:629 [inline] sock_sendmsg+0xd5/0x120 net/socket.c:639 ___sys_sendmsg+0x805/0x940 net/socket.c:2117 __sys_sendmsg+0x115/0x270 net/socket.c:2155 SYSC_sendmsg net/socket.c:2164 [inline] SyS_sendmsg+0x29/0x30 net/socket.c:2162 do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x42/0xb7 RIP: 0033:0x4458b9 RSP: 002b:00007ffd1d4a7278 EFLAGS: 00000213 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 000000000000001b RCX: 00000000004458b9 RDX: 0000000000000010 RSI: 0000000020000d00 RDI: 0000000000000004 RBP: 00000000004a74ed R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000213 R12: 00007ffd1d4a7348 R13: 0000000000402a60 R14: 0000000000000000 R15: 0000000000000000 Code: 75 e8 eb a9 48 89 f7 48 89 75 e8 e8 d1 85 7b fe 48 8b 75 e8 eb bb 48 89 f2 48 89 d9 4c 89 e6 48 c7 c7 a0 84 d8 87 e8 ea 67 28 fe <0f> 0b 0f 1f 40 00 48 b8 00 00 00 00 00 fc ff df 55 48 89 e5 41 RIP: __list_add_valid+0xaa/0xb0 lib/list_debug.c:29 RSP: ffff8801b04bf248 This changeset addresses the avoiding list_add() if the current option is already present in the event list. Reported-and-tested-by: syzbot+4d4af685432dc0e56c91@syzkaller.appspotmail.com Signed-off-by: Paolo Abeni Fixes: 2fcdb2c9e659 ("team: allow to send multiple set events in one message") Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 8673ef3c9cdc..e5941e86f64a 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team, } } +static bool __team_option_inst_tmp_find(const struct list_head *opts, + const struct team_option_inst *needle) +{ + struct team_option_inst *opt_inst; + + list_for_each_entry(opt_inst, opts, tmp_list) + if (opt_inst == needle) + return true; + return false; +} + static int __team_options_register(struct team *team, const struct team_option *option, size_t option_count) @@ -2569,6 +2580,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) if (err) goto team_put; opt_inst->changed = true; + + /* dumb/evil user-space can send us duplicate opt, + * keep only the last one + */ + if (__team_option_inst_tmp_find(&opt_inst_list, + opt_inst)) + continue; + list_add(&opt_inst->tmp_list, &opt_inst_list); } if (!opt_found) { -- cgit v1.2.3 From 8599a1fe10b8c3f6e17568a1c43bfaccfeaff75c Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 24 Apr 2018 14:33:37 +0800 Subject: team: fix netconsole setup over team MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9cf2f437ca5b39828984064fad213e68fc17ef11 ] The same fix in Commit dbe173079ab5 ("bridge: fix netconsole setup over bridge") is also needed for team driver. While at it, remove the unnecessary parameter *team from team_port_enable_netpoll(). v1->v2: - fix it in a better way, as does bridge. Fixes: 0fb52a27a04a ("team: cleanup netpoll clode") Reported-by: João Avelino Bellomo Filho Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index e5941e86f64a..36963685d42a 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1078,14 +1078,11 @@ static void team_port_leave(struct team *team, struct team_port *port) } #ifdef CONFIG_NET_POLL_CONTROLLER -static int team_port_enable_netpoll(struct team *team, struct team_port *port) +static int __team_port_enable_netpoll(struct team_port *port) { struct netpoll *np; int err; - if (!team->dev->npinfo) - return 0; - np = kzalloc(sizeof(*np), GFP_KERNEL); if (!np) return -ENOMEM; @@ -1099,6 +1096,14 @@ static int team_port_enable_netpoll(struct team *team, struct team_port *port) return err; } +static int team_port_enable_netpoll(struct team_port *port) +{ + if (!port->team->dev->npinfo) + return 0; + + return __team_port_enable_netpoll(port); +} + static void team_port_disable_netpoll(struct team_port *port) { struct netpoll *np = port->np; @@ -1113,7 +1118,7 @@ static void team_port_disable_netpoll(struct team_port *port) kfree(np); } #else -static int team_port_enable_netpoll(struct team *team, struct team_port *port) +static int team_port_enable_netpoll(struct team_port *port) { return 0; } @@ -1221,7 +1226,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_vids_add; } - err = team_port_enable_netpoll(team, port); + err = team_port_enable_netpoll(port); if (err) { netdev_err(dev, "Failed to enable netpoll on device %s\n", portname); @@ -1919,7 +1924,7 @@ static int team_netpoll_setup(struct net_device *dev, mutex_lock(&team->lock); list_for_each_entry(port, &team->port_list, list) { - err = team_port_enable_netpoll(team, port); + err = __team_port_enable_netpoll(port); if (err) { __team_netpoll_cleanup(team); break; -- cgit v1.2.3 From ecaae08d72bd353c548545e521b68b00749f479a Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Mon, 23 Apr 2018 16:38:27 +0200 Subject: pppoe: check sockaddr length in pppoe_connect() [ Upstream commit a49e2f5d5fb141884452ddb428f551b123d436b5 ] We must validate sockaddr_len, otherwise userspace can pass fewer data than we expect and we end up accessing invalid data. Fixes: 224cf5ad14c0 ("ppp: Move the PPP drivers") Reported-by: syzbot+4f03bdf92fdf9ef5ddab@syzkaller.appspotmail.com Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ppp/pppoe.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index dc36c2ec1d10..fa2c7bd638be 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -620,6 +620,10 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, lock_sock(sk); error = -EINVAL; + + if (sockaddr_len != sizeof(struct sockaddr_pppox)) + goto end; + if (sp->sa_protocol != PX_PROTO_OE) goto end; -- cgit v1.2.3 From b031b84f3c39cfd0b69e7d40eebc20c3a6bd9193 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Thu, 19 Apr 2018 22:49:09 +0300 Subject: net: ethernet: ti: cpsw: fix tx vlan priority mapping [ Upstream commit 5e391dc5a8d801a2410d0032ad4a428d1d61800c ] The CPDMA_TX_PRIORITY_MAP in real is vlan pcp field priority mapping register and basically replaces vlan pcp field for tagged packets. So, set it to be 1:1 mapping. Otherwise, it will cause unexpected change of egress vlan tagged packets, like prio 2 -> prio 5. Fixes: e05107e6b747 ("net: ethernet: ti: cpsw: add multi queue support") Reviewed-by: Grygorii Strashko Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ti/cpsw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 552de9c490c6..de336897a28a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -124,7 +124,7 @@ do { \ #define RX_PRIORITY_MAPPING 0x76543210 #define TX_PRIORITY_MAPPING 0x33221100 -#define CPDMA_TX_PRIORITY_MAP 0x01234567 +#define CPDMA_TX_PRIORITY_MAP 0x76543210 #define CPSW_VLAN_AWARE BIT(1) #define CPSW_ALE_VLAN_AWARE 1 -- cgit v1.2.3 From 70f2351eca535c590dad1657a3761650c8515acb Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 18 Apr 2018 22:54:59 -0400 Subject: scsi: mptsas: Disable WRITE SAME commit 94e5395d2403c8bc2504a7cbe4c4caaacb7b8b84 upstream. First generation MPT Fusion controllers can not translate WRITE SAME when the attached device is a SATA drive. Disable WRITE SAME support. Reported-by: Nikola Ciprich Cc: Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/message/fusion/mptsas.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 7ee1667acde4..00dff9b5a6c4 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1994,6 +1994,7 @@ static struct scsi_host_template mptsas_driver_template = { .cmd_per_lun = 7, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = mptscsih_host_attrs, + .no_write_same = 1, }; static int mptsas_get_linkerrors(struct sas_phy *phy) -- cgit v1.2.3 From 4bd744b86114a406efb563c8717e5bea7672d427 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 18 Apr 2018 12:51:31 +0300 Subject: cdrom: information leak in cdrom_ioctl_media_changed() commit 9de4ee40547fd315d4a0ed1dd15a2fa3559ad707 upstream. This cast is wrong. "cdi->capacity" is an int and "arg" is an unsigned long. The way the check is written now, if one of the high 32 bits is set then we could read outside the info->slots[] array. This bug is pretty old and it predates git. Reviewed-by: Christoph Hellwig Cc: stable@vger.kernel.org Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/cdrom/cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 5d475b3a0b2e..128ebd439221 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2368,7 +2368,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT) return media_changed(cdi, 1); - if ((unsigned int)arg >= cdi->capacity) + if (arg >= cdi->capacity) return -EINVAL; info = kmalloc(sizeof(*info), GFP_KERNEL); -- cgit v1.2.3 From 04f87299884a26f64b643d810e68d56685d6ffc1 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 11 Apr 2018 11:21:17 +0200 Subject: s390/cio: update chpid descriptor after resource accessibility event commit af2e460ade0b0180d0f3812ca4f4f59cc9597f3e upstream. Channel path descriptors have been seen as something stable (as long as the chpid is configured). Recent tests have shown that the descriptor can also be altered when the link state of a channel path changes. Thus it is necessary to update the descriptor during handling of resource accessibility events. Cc: Signed-off-by: Sebastian Ott Reviewed-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/chsc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 11674698b36d..67903c93328b 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -451,6 +451,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area) static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) { + struct channel_path *chp; struct chp_link link; struct chp_id chpid; int status; @@ -463,10 +464,17 @@ static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) chpid.id = sei_area->rsid; /* allocate a new channel path structure, if needed */ status = chp_get_status(chpid); - if (status < 0) - chp_new(chpid); - else if (!status) + if (!status) return; + + if (status < 0) { + chp_new(chpid); + } else { + chp = chpid_to_chp(chpid); + mutex_lock(&chp->lock); + chp_update_desc(chp); + mutex_unlock(&chp->lock); + } memset(&link, 0, sizeof(struct chp_link)); link.chpid = chpid; if ((sei_area->vf & 0xc0) != 0) { -- cgit v1.2.3 From a714a5f3afdd8de38985a88fc6d29f81873369d1 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 12 Apr 2018 13:38:22 +0200 Subject: s390/dasd: fix IO error for newly defined devices commit 5d27a2bf6e14f5c7d1033ad1e993fcd0eba43e83 upstream. When a new CKD storage volume is defined at the storage server, Linux may be relying on outdated information about that volume, which leads to the following errors: 1. Command Reject Errors for minidisk on z/VM: dasd-eckd.b3193d: 0.0.XXXX: An error occurred in the DASD device driver, reason=09 dasd(eckd): I/O status report for device 0.0.XXXX: dasd(eckd): in req: 00000000XXXXXXXX CC:00 FC:04 AC:00 SC:17 DS:02 CS:00 RC:0 dasd(eckd): device 0.0.2046: Failing CCW: 00000000XXXXXXXX dasd(eckd): Sense(hex) 0- 7: 80 00 00 00 00 00 00 00 dasd(eckd): Sense(hex) 8-15: 00 00 00 00 00 00 00 00 dasd(eckd): Sense(hex) 16-23: 00 00 00 00 e1 00 0f 00 dasd(eckd): Sense(hex) 24-31: 00 00 40 e2 00 00 00 00 dasd(eckd): 24 Byte: 0 MSG 0, no MSGb to SYSOP 2. Equipment Check errors on LPAR or for dedicated devices on z/VM: dasd(eckd): I/O status report for device 0.0.XXXX: dasd(eckd): in req: 00000000XXXXXXXX CC:00 FC:04 AC:00 SC:17 DS:0E CS:40 fcxs:01 schxs:00 RC:0 dasd(eckd): device 0.0.9713: Failing TCW: 00000000XXXXXXXX dasd(eckd): Sense(hex) 0- 7: 10 00 00 00 13 58 4d 0f dasd(eckd): Sense(hex) 8-15: 67 00 00 00 00 00 00 04 dasd(eckd): Sense(hex) 16-23: e5 18 05 33 97 01 0f 0f dasd(eckd): Sense(hex) 24-31: 00 00 40 e2 00 04 58 0d dasd(eckd): 24 Byte: 0 MSG f, no MSGb to SYSOP Fix this problem by using the up-to-date information provided during online processing via the device specific SNEQ to detect the case of outdated LCU data. If there is a difference, perform a re-read of that data. Cc: stable@vger.kernel.org Reviewed-by: Jan Hoeppner Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/block/dasd_alias.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index 1e560188dd13..e453d2a7d7f9 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -591,13 +591,22 @@ static int _schedule_lcu_update(struct alias_lcu *lcu, int dasd_alias_add_device(struct dasd_device *device) { struct dasd_eckd_private *private = device->private; - struct alias_lcu *lcu; + __u8 uaddr = private->uid.real_unit_addr; + struct alias_lcu *lcu = private->lcu; unsigned long flags; int rc; - lcu = private->lcu; rc = 0; spin_lock_irqsave(&lcu->lock, flags); + /* + * Check if device and lcu type differ. If so, the uac data may be + * outdated and needs to be updated. + */ + if (private->uid.type != lcu->uac->unit[uaddr].ua_type) { + lcu->flags |= UPDATE_PENDING; + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "uid type mismatch - trigger rescan"); + } if (!(lcu->flags & UPDATE_PENDING)) { rc = _add_device_to_lcu(lcu, device, device); if (rc) -- cgit v1.2.3 From 4959a913ef6b274cedbc7fc06d5606aafd32ef80 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 17 Apr 2018 18:23:50 +0200 Subject: ACPI / video: Only default only_lcd to true on Win8-ready _desktops_ commit 53fa1f6e8a5958da698a31edf366ffe90596b490 upstream. Commit 5928c281524f (ACPI / video: Default lcd_only to true on Win8-ready and newer machines) made only_lcd default to true on all machines where acpi_osi_is_win8() returns true, including laptops. The purpose of this is to avoid the bogus / non-working acpi backlight interface which many newer BIOS-es define on desktop machines. But this is causing a regression on some laptops, specifically on the Dell XPS 13 2013 model, which does not have the LCD flag set for its fully functional ACPI backlight interface. Rather then DMI quirking our way out of this, this commits changes the logic for setting only_lcd to true, to only do this on machines with a desktop (or server) dmi chassis-type. Note that we cannot simply only check the chassis-type and not register the backlight interface based on that as there are some laptops and tablets which have their chassis-type set to "3" aka desktop. Hopefully the combination of checking the LCD flag, but only on devices with a desktop(ish) chassis-type will avoid the needs for DMI quirks for this, or at least limit the amount of DMI quirks which we need to a minimum. Fixes: 5928c281524f (ACPI / video: Default lcd_only to true on Win8-ready and newer machines) Reported-and-tested-by: James Hogan Signed-off-by: Hans de Goede Cc: 4.15+ # 4.15+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpi_video.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 94e04c9de12b..667dc5c86fef 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2069,6 +2069,25 @@ static int __init intel_opregion_present(void) return opregion; } +static bool dmi_is_desktop(void) +{ + const char *chassis_type; + + chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); + if (!chassis_type) + return false; + + if (!strcmp(chassis_type, "3") || /* 3: Desktop */ + !strcmp(chassis_type, "4") || /* 4: Low Profile Desktop */ + !strcmp(chassis_type, "5") || /* 5: Pizza Box */ + !strcmp(chassis_type, "6") || /* 6: Mini Tower */ + !strcmp(chassis_type, "7") || /* 7: Tower */ + !strcmp(chassis_type, "11")) /* 11: Main Server Chassis */ + return true; + + return false; +} + int acpi_video_register(void) { int ret = 0; @@ -2089,8 +2108,12 @@ int acpi_video_register(void) * win8 ready (where we also prefer the native backlight driver, so * normally the acpi_video code should not register there anyways). */ - if (only_lcd == -1) - only_lcd = acpi_osi_is_win8(); + if (only_lcd == -1) { + if (dmi_is_desktop() && acpi_osi_is_win8()) + only_lcd = true; + else + only_lcd = false; + } dmi_check_system(video_dmi_table); -- cgit v1.2.3 From 2971585b27f6a810c50b6f3a9ac391aa4d13fdf5 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 11 Apr 2018 15:23:56 -0400 Subject: random: set up the NUMA crng instances after the CRNG is fully initialized commit 8ef35c866f8862df074a49a93b0309725812dea8 upstream. Until the primary_crng is fully initialized, don't initialize the NUMA crng nodes. Otherwise users of /dev/urandom on NUMA systems before the CRNG is fully initialized can get very bad quality randomness. Of course everyone should move to getrandom(2) where this won't be an issue, but there's a lot of legacy code out there. This related to CVE-2018-1108. Reported-by: Jann Horn Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 8d08a8062904..b979173cb0e1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -819,6 +819,32 @@ static int crng_fast_load(const char *cp, size_t len) return 1; } +#ifdef CONFIG_NUMA +static void numa_crng_init(void) +{ + int i; + struct crng_state *crng; + struct crng_state **pool; + + pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); + for_each_online_node(i) { + crng = kmalloc_node(sizeof(struct crng_state), + GFP_KERNEL | __GFP_NOFAIL, i); + spin_lock_init(&crng->lock); + crng_initialize(crng); + pool[i] = crng; + } + mb(); + if (cmpxchg(&crng_node_pool, NULL, pool)) { + for_each_node(i) + kfree(pool[i]); + kfree(pool); + } +} +#else +static void numa_crng_init(void) {} +#endif + static void crng_reseed(struct crng_state *crng, struct entropy_store *r) { unsigned long flags; @@ -848,6 +874,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) memzero_explicit(&buf, sizeof(buf)); crng->init_time = jiffies; if (crng == &primary_crng && crng_init < 2) { + numa_crng_init(); crng_init = 2; process_random_ready_list(); wake_up_interruptible(&crng_init_wait); @@ -1661,29 +1688,10 @@ static void init_std_data(struct entropy_store *r) */ static int rand_initialize(void) { -#ifdef CONFIG_NUMA - int i; - struct crng_state *crng; - struct crng_state **pool; -#endif - init_std_data(&input_pool); init_std_data(&blocking_pool); crng_initialize(&primary_crng); crng_global_init_time = jiffies; - -#ifdef CONFIG_NUMA - pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); - for_each_online_node(i) { - crng = kmalloc_node(sizeof(struct crng_state), - GFP_KERNEL | __GFP_NOFAIL, i); - spin_lock_init(&crng->lock); - crng_initialize(crng); - pool[i] = crng; - } - mb(); - crng_node_pool = pool; -#endif return 0; } early_initcall(rand_initialize); -- cgit v1.2.3 From c3ff2da5cef05676d490fa9057b2dceb5e48cdb9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 23 Apr 2018 18:51:28 -0400 Subject: random: fix possible sleeping allocation from irq context commit 6c1e851c4edc13a43adb3ea4044e3fc8f43ccf7d upstream. We can do a sleeping allocation from an irq context when CONFIG_NUMA is enabled. Fix this by initializing the NUMA crng instances in a workqueue. Reported-by: Tetsuo Handa Reported-by: syzbot+9de458f6a5e713ee8c1a@syzkaller.appspotmail.com Fixes: 8ef35c866f8862df ("random: set up the NUMA crng instances...") Cc: stable@vger.kernel.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index b979173cb0e1..dbfb3e69600b 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -820,7 +820,7 @@ static int crng_fast_load(const char *cp, size_t len) } #ifdef CONFIG_NUMA -static void numa_crng_init(void) +static void do_numa_crng_init(struct work_struct *work) { int i; struct crng_state *crng; @@ -841,6 +841,13 @@ static void numa_crng_init(void) kfree(pool); } } + +static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init); + +static void numa_crng_init(void) +{ + schedule_work(&numa_crng_init_work); +} #else static void numa_crng_init(void) {} #endif -- cgit v1.2.3 From 17e20c8b5a2c0165516f9595e6ef65471326d532 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 25 Apr 2018 01:12:32 -0400 Subject: random: rate limit unseeded randomness warnings commit 4e00b339e264802851aff8e73cde7d24b57b18ce upstream. On systems without sufficient boot randomness, no point spamming dmesg. Signed-off-by: Theodore Ts'o Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index dbfb3e69600b..ddeac4eefd0a 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -259,6 +259,7 @@ #include #include #include +#include #include #include #include @@ -444,6 +445,16 @@ static void _crng_backtrack_protect(struct crng_state *crng, __u8 tmp[CHACHA20_BLOCK_SIZE], int used); static void process_random_ready_list(void); +static struct ratelimit_state unseeded_warning = + RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3); +static struct ratelimit_state urandom_warning = + RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3); + +static int ratelimit_disable __read_mostly; + +module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); +MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression"); + /********************************************************************** * * OS independent entropy store. Here are the functions which handle @@ -886,6 +897,18 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) process_random_ready_list(); wake_up_interruptible(&crng_init_wait); pr_notice("random: crng init done\n"); + if (unseeded_warning.missed) { + pr_notice("random: %d get_random_xx warning(s) missed " + "due to ratelimiting\n", + unseeded_warning.missed); + unseeded_warning.missed = 0; + } + if (urandom_warning.missed) { + pr_notice("random: %d urandom warning(s) missed " + "due to ratelimiting\n", + urandom_warning.missed); + urandom_warning.missed = 0; + } } spin_unlock_irqrestore(&crng->lock, flags); } @@ -1699,6 +1722,10 @@ static int rand_initialize(void) init_std_data(&blocking_pool); crng_initialize(&primary_crng); crng_global_init_time = jiffies; + if (ratelimit_disable) { + urandom_warning.interval = 0; + unseeded_warning.interval = 0; + } return 0; } early_initcall(rand_initialize); @@ -1766,9 +1793,10 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) if (!crng_ready() && maxwarn > 0) { maxwarn--; - printk(KERN_NOTICE "random: %s: uninitialized urandom read " - "(%zd bytes read)\n", - current->comm, nbytes); + if (__ratelimit(&urandom_warning)) + printk(KERN_NOTICE "random: %s: uninitialized " + "urandom read (%zd bytes read)\n", + current->comm, nbytes); spin_lock_irqsave(&primary_crng.lock, flags); crng_init_cnt = 0; spin_unlock_irqrestore(&primary_crng.lock, flags); -- cgit v1.2.3 From 3bebadf9931e00901f62f45f5b73ee49989bec7f Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 5 Apr 2018 16:29:50 -0600 Subject: usbip: usbip_event: fix to not print kernel pointer address commit 4c982482341c64f55daf69b6caa5a2bcd9b43824 upstream. Fix it to not print kernel pointer address. Remove the conditional and debug message as it isn't very useful. Signed-off-by: Shuah Khan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/usbip_event.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c index f1635662c299..f8f7f3803a99 100644 --- a/drivers/usb/usbip/usbip_event.c +++ b/drivers/usb/usbip/usbip_event.c @@ -105,10 +105,6 @@ static void event_handler(struct work_struct *work) unset_event(ud, USBIP_EH_UNUSABLE); } - /* Stop the error handler. */ - if (ud->event & USBIP_EH_BYE) - usbip_dbg_eh("removed %p\n", ud); - wake_up(&ud->eh_waitq); } } -- cgit v1.2.3 From 039cb1bb0b8904d3105150bb6908d05de7202111 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 5 Apr 2018 16:29:04 -0600 Subject: usbip: usbip_host: fix to hold parent lock for device_attach() calls commit 4bfb141bc01312a817d36627cc47c93f801c216d upstream. usbip_host calls device_attach() without holding dev->parent lock. Fix it. Signed-off-by: Shuah Khan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 325b4c05acdd..f761e02e75c9 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -201,7 +201,12 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, if (!bid) return -ENODEV; + /* 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"); return ret; -- cgit v1.2.3 From c0182ba5accbb1d8c7cc84a25cadb6fcf0132c98 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Mon, 2 Apr 2018 14:52:32 -0600 Subject: usbip: vhci_hcd: Fix usb device and sockfd leaks commit 9020a7efe537856eb3e826ebebdf38a5d07a7857 upstream. vhci_hcd fails to do reset to put usb device and sockfd in the module remove/stop paths. Fix the leak. Signed-off-by: Shuah Khan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/usbip_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index f0b955f8504e..109e65ba01a0 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -258,7 +258,7 @@ enum usbip_side { #define VUDC_EVENT_ERROR_USB (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) #define VUDC_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) -#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE) +#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE) #define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) -- cgit v1.2.3 From af50b899fe3871cf4d1b2d5cffe1e6f218dfffde Mon Sep 17 00:00:00 2001 From: Collin May Date: Sat, 7 Apr 2018 14:32:48 -0700 Subject: USB: serial: simple: add libtransistor console commit fe710508b6ba9d28730f3021fed70e7043433b2e upstream. Add simple driver for libtransistor USB console. This device is implemented in software: https://github.com/reswitched/libtransistor/blob/development/lib/usb_serial.c Signed-off-by: Collin May Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 1 + drivers/usb/serial/usb-serial-simple.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 584ae8cbaf1c..77c3ebe860c5 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE - Fundamental Software dongle. - Google USB serial devices - HP4x calculators + - Libtransistor USB console - a number of Motorola phones - Motorola Tetra devices - Novatel Wireless GPS receivers diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index 6aa7ff2c1cf7..2674da40d9cd 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -66,6 +66,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) } DEVICE(google, GOOGLE_IDS); +/* Libtransistor USB console */ +#define LIBTRANSISTOR_IDS() \ + { USB_DEVICE(0x1209, 0x8b00) } +DEVICE(libtransistor, LIBTRANSISTOR_IDS); + /* ViVOpay USB Serial Driver */ #define VIVOPAY_IDS() \ { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ @@ -113,6 +118,7 @@ static struct usb_serial_driver * const serial_drivers[] = { &funsoft_device, &flashloader_device, &google_device, + &libtransistor_device, &vivopay_device, &moto_modem_device, &motorola_tetra_device, @@ -129,6 +135,7 @@ static const struct usb_device_id id_table[] = { FUNSOFT_IDS(), FLASHLOADER_IDS(), GOOGLE_IDS(), + LIBTRANSISTOR_IDS(), VIVOPAY_IDS(), MOTO_IDS(), MOTOROLA_TETRA_IDS(), -- cgit v1.2.3 From 1c971e495035973c962b1bdc56086966fc4382e2 Mon Sep 17 00:00:00 2001 From: Vasyl Vavrychuk Date: Wed, 11 Apr 2018 17:05:13 +0300 Subject: USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster commit 470b5d6f0cf4674be2d1ec94e54283a1770b6a1a upstream. Arrow USB Blaster integrated on MAX1000 board uses the same vendor ID (0x0403) and product ID (0x6010) as the "original" FTDI device. This patch avoids picking up by ftdi_sio of the first interface of this USB device. After that this device can be used by Arrow user-space JTAG driver. Signed-off-by: Vasyl Vavrychuk Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 71cbc6890ac4..2e2f736384ab 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1911,7 +1911,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial) return ftdi_jtag_probe(serial); if (udev->product && - (!strcmp(udev->product, "BeagleBone/XDS100V2") || + (!strcmp(udev->product, "Arrow USB Blaster") || + !strcmp(udev->product, "BeagleBone/XDS100V2") || !strcmp(udev->product, "SNAP Connect E10"))) return ftdi_jtag_probe(serial); -- cgit v1.2.3 From 52721f22b88e549786611772629fdfbc9b8bab2e Mon Sep 17 00:00:00 2001 From: Kyle Roeschley Date: Mon, 9 Apr 2018 10:23:55 -0500 Subject: USB: serial: cp210x: add ID for NI USB serial console commit 1e23aace21515a8f7615a1de016c0ea8d4e0cc6e upstream. Added the USB VID and PID for the USB serial console on some National Instruments devices. Signed-off-by: Kyle Roeschley Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index cab80acace4e..d98531823998 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -211,6 +211,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; -- cgit v1.2.3 From e4f3654446490508caf7d64b8f10d429be49f0c8 Mon Sep 17 00:00:00 2001 From: Kamil Lulko Date: Thu, 19 Apr 2018 16:54:02 -0700 Subject: usb: core: Add quirk for HP v222w 16GB Mini commit 3180dabe08e3653bf0a838553905d88f3773f29c upstream. Add DELAY_INIT quirk to fix the following problem with HP v222w 16GB Mini: usb 1-3: unable to read config index 0 descriptor/start: -110 usb 1-3: can't read configurations, error -110 usb 1-3: can't set config #1, error -110 Signed-off-by: Kamil Lulko Signed-off-by: Kuppuswamy Sathyanarayanan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 4f1c6f8d4352..40ce175655e6 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -45,6 +45,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* HP v222w 16GB Mini USB Drive */ + { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, -- cgit v1.2.3 From 00bc34802fb84aafa5cc11f5fcd568b9a53b05f0 Mon Sep 17 00:00:00 2001 From: Ravi Chandra Sadineni Date: Fri, 20 Apr 2018 11:08:21 -0700 Subject: USB: Increment wakeup count on remote wakeup. commit 83a62c51ba7b3c0bf45150c4eac7aefc6c785e94 upstream. On chromebooks we depend on wakeup count to identify the wakeup source. But currently USB devices do not increment the wakeup count when they trigger the remote wake. This patch addresses the same. Resume condition is reported differently on USB 2.0 and USB 3.0 devices. On USB 2.0 devices, a wake capable device, if wake enabled, drives resume signal to indicate a remote wake (USB 2.0 spec section 7.1.7.7). The upstream facing port then sets C_PORT_SUSPEND bit and reports a port change event (USB 2.0 spec section 11.24.2.7.2.3). Thus if a port has resumed before driving the resume signal from the host and C_PORT_SUSPEND is set, then the device attached to the given port might be the reason for the last system wakeup. Increment the wakeup count for the same. On USB 3.0 devices, a function may signal that it wants to exit from device suspend by sending a Function Wake Device Notification to the host (USB3.0 spec section 8.5.6.4) Thus on receiving the Function Wake, increment the wakeup count. Signed-off-by: Ravi Chandra Sadineni Acked-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 1 + drivers/usb/core/hub.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index fcc7aa248ce7..bdb0d7a08ff9 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2365,6 +2365,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) spin_lock_irqsave (&hcd_root_hub_lock, flags); if (hcd->rh_registered) { + pm_wakeup_event(&hcd->self.root_hub->dev, 0); set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); queue_work(pm_wq, &hcd->wakeup_work); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d0d3f9ef9f10..d8d992b73e88 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -648,12 +648,17 @@ void usb_wakeup_notification(struct usb_device *hdev, unsigned int portnum) { struct usb_hub *hub; + struct usb_port *port_dev; if (!hdev) return; hub = usb_hub_to_struct_hub(hdev); if (hub) { + port_dev = hub->ports[portnum - 1]; + if (port_dev && port_dev->child) + pm_wakeup_event(&port_dev->child->dev, 0); + set_bit(portnum, hub->wakeup_bits); kick_hub_wq(hub); } @@ -3417,8 +3422,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) /* Skip the initial Clear-Suspend step for a remote wakeup */ status = hub_port_status(hub, port1, &portstatus, &portchange); - if (status == 0 && !port_is_suspended(hub, portstatus)) + if (status == 0 && !port_is_suspended(hub, portstatus)) { + if (portchange & USB_PORT_STAT_C_SUSPEND) + pm_wakeup_event(&udev->dev, 0); goto SuspendCleared; + } /* see 7.1.7.7; affects power usage, but not budgeting */ if (hub_is_superspeed(hub->hdev)) -- cgit v1.2.3 From 47cb14192bcbba3f15b1c3561e05e084e56fdef6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 20 Apr 2018 20:24:23 +0300 Subject: virtio_console: free buffers after reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a7a69ec0d8e4a58be7db88d33cbfa2912807bb2b upstream. Console driver is out of spec. The spec says: A driver MUST NOT decrement the available idx on a live virtqueue (ie. there is no way to “unexpose” buffers). and it does exactly that by trying to detach unused buffers without doing a device reset first. Defer detaching the buffers until device unplug. Of course this means we might get an interrupt for a vq without an attached port now. Handle that by discarding the consumed buffer. Reported-by: Tiwei Bie Fixes: b3258ff1d6 ("virtio: Decrement avail idx on buffer detach") Cc: stable@vger.kernel.org Signed-off-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 49 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 8f890c1aca57..8c0017d48571 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1405,7 +1405,6 @@ static int add_port(struct ports_device *portdev, u32 id) { char debugfs_name[16]; struct port *port; - struct port_buffer *buf; dev_t devt; unsigned int nr_added_bufs; int err; @@ -1516,8 +1515,6 @@ static int add_port(struct ports_device *portdev, u32 id) return 0; free_inbufs: - while ((buf = virtqueue_detach_unused_buf(port->in_vq))) - free_buf(buf, true); free_device: device_destroy(pdrvdata.class, port->dev->devt); free_cdev: @@ -1542,34 +1539,14 @@ static void remove_port(struct kref *kref) static void remove_port_data(struct port *port) { - struct port_buffer *buf; - spin_lock_irq(&port->inbuf_lock); /* Remove unused data this port might have received. */ discard_port_data(port); spin_unlock_irq(&port->inbuf_lock); - /* Remove buffers we queued up for the Host to send us data in. */ - do { - spin_lock_irq(&port->inbuf_lock); - buf = virtqueue_detach_unused_buf(port->in_vq); - spin_unlock_irq(&port->inbuf_lock); - if (buf) - free_buf(buf, true); - } while (buf); - spin_lock_irq(&port->outvq_lock); reclaim_consumed_buffers(port); spin_unlock_irq(&port->outvq_lock); - - /* Free pending buffers from the out-queue. */ - do { - spin_lock_irq(&port->outvq_lock); - buf = virtqueue_detach_unused_buf(port->out_vq); - spin_unlock_irq(&port->outvq_lock); - if (buf) - free_buf(buf, true); - } while (buf); } /* @@ -1794,13 +1771,24 @@ static void control_work_handler(struct work_struct *work) spin_unlock(&portdev->c_ivq_lock); } +static void flush_bufs(struct virtqueue *vq, bool can_sleep) +{ + struct port_buffer *buf; + unsigned int len; + + while ((buf = virtqueue_get_buf(vq, &len))) + free_buf(buf, can_sleep); +} + static void out_intr(struct virtqueue *vq) { struct port *port; port = find_port_by_vq(vq->vdev->priv, vq); - if (!port) + if (!port) { + flush_bufs(vq, false); return; + } wake_up_interruptible(&port->waitqueue); } @@ -1811,8 +1799,10 @@ static void in_intr(struct virtqueue *vq) unsigned long flags; port = find_port_by_vq(vq->vdev->priv, vq); - if (!port) + if (!port) { + flush_bufs(vq, false); return; + } spin_lock_irqsave(&port->inbuf_lock, flags); port->inbuf = get_inbuf(port); @@ -1987,6 +1977,15 @@ static const struct file_operations portdev_fops = { static void remove_vqs(struct ports_device *portdev) { + struct virtqueue *vq; + + virtio_device_for_each_vq(portdev->vdev, vq) { + struct port_buffer *buf; + + flush_bufs(vq, true); + while ((buf = virtqueue_detach_unused_buf(vq))) + free_buf(buf, true); + } portdev->vdev->config->del_vqs(portdev->vdev); kfree(portdev->in_vqs); kfree(portdev->out_vqs); -- cgit v1.2.3 From 97f54c13b6aaa49eeb9688e851d1ff955f45f5c3 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 3 Apr 2018 11:59:04 +0200 Subject: drm/virtio: fix vq wait_event condition commit d02d270014f70dcab0117776b81a37b6fca745ae upstream. Wait until we have enough space in the virt queue to actually queue up our request. Avoids the guest spinning in case we have a non-zero amount of free entries but not enough for the request. Cc: stable@vger.kernel.org Reported-by: Alain Magloire Signed-off-by: Gerd Hoffmann Reviewed-by: Dave Airlie Link: http://patchwork.freedesktop.org/patch/msgid/20180403095904.11152-1-kraxel@redhat.com Signed-off-by: Sean Paul Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/virtio/virtgpu_vq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 5a0f8a745b9d..52436b3c01bb 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -324,7 +324,7 @@ retry: ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); if (ret == -ENOSPC) { spin_unlock(&vgdev->ctrlq.qlock); - wait_event(vgdev->ctrlq.ack_queue, vq->num_free); + wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt); spin_lock(&vgdev->ctrlq.qlock); goto retry; } else { @@ -399,7 +399,7 @@ retry: ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); if (ret == -ENOSPC) { spin_unlock(&vgdev->cursorq.qlock); - wait_event(vgdev->cursorq.ack_queue, vq->num_free); + wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt); spin_lock(&vgdev->cursorq.qlock); goto retry; } else { -- cgit v1.2.3 From 6a506d48c187e621ca846b6c5b951411d5b7f531 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 5 Apr 2018 19:40:16 +0900 Subject: tty: Don't call panic() at tty_ldisc_init() commit 903f9db10f18f735e62ba447147b6c434b6af003 upstream. syzbot is reporting kernel panic [1] triggered by memory allocation failure at tty_ldisc_get() from tty_ldisc_init(). But since both tty_ldisc_get() and caller of tty_ldisc_init() can cleanly handle errors, tty_ldisc_init() does not need to call panic() when tty_ldisc_get() failed. [1] https://syzkaller.appspot.com/bug?id=883431818e036ae6a9981156a64b821110f39187 Signed-off-by: Tetsuo Handa Reported-by: syzbot Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 5 ++++- drivers/tty/tty_ldisc.c | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4ee0a9de7556..789c81482542 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3170,7 +3170,10 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) kref_init(&tty->kref); tty->magic = TTY_MAGIC; - tty_ldisc_init(tty); + if (tty_ldisc_init(tty)) { + kfree(tty); + return NULL; + } tty->session = NULL; tty->pgrp = NULL; mutex_init(&tty->legacy_mutex); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 3a9e2a2fd4c6..96f0d1090888 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -753,12 +753,13 @@ void tty_ldisc_release(struct tty_struct *tty) * the tty structure is not completely set up when this call is made. */ -void tty_ldisc_init(struct tty_struct *tty) +int tty_ldisc_init(struct tty_struct *tty) { struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY); if (IS_ERR(ld)) - panic("n_tty: init_tty"); + return PTR_ERR(ld); tty->ldisc = ld; + return 0; } /** -- cgit v1.2.3 From 11723a916fb7d7e1b303e0a331e4a8214830a9e4 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sat, 7 Apr 2018 10:19:50 -0700 Subject: tty: n_gsm: Fix long delays with control frame timeouts in ADM mode commit e9ec22547986dd32c5c70da78107ce35dbff1344 upstream. Commit ea3d8465ab9b ("tty: n_gsm: Allow ADM response in addition to UA for control dlci") added support for DLCI to stay in Asynchronous Disconnected Mode (ADM). But we still get long delays waiting for commands to other DLCI to complete: --> 5) C: SABM(P) Q> 0) C: UIH(F) Q> 0) C: UIH(F) Q> 0) C: UIH(F) ... This happens because gsm_control_send() sets cretries timer to T2 that is by default set to 34. This will cause resend for T2 times for the control frame. In ADM mode, we will never get a response so the control frame, so retries are just delaying all the commands. Let's fix the issue by setting DLCI_MODE_ADM flag after detecting the ADM mode for the control DLCI. Then we can use that in gsm_control_send() to set retries to 1. This means the control frame will be sent once allowing the other end at an opportunity to switch from ADM to ABM mode. Note that retries will be decremented in gsm_control_retransmit() so we don't want to set it to 0 here. Fixes: ea3d8465ab9b ("tty: n_gsm: Allow ADM response in addition to UA for control dlci") Cc: linux-serial@vger.kernel.org Cc: Alan Cox Cc: Dan Williams Cc: Jiri Prchal Cc: Jiri Slaby Cc: Marcel Partap Cc: Merlijn Wajer Cc: Michael Nazzareno Trimarchi Cc: Michael Scott Cc: Pavel Machek Cc: Peter Hurley Cc: Russ Gorby Cc: Sascha Hauer Cc: Sebastian Reichel Signed-off-by: Tony Lindgren Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index fe2291795d2f..f2ba65ba1ef6 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -137,6 +137,9 @@ struct gsm_dlci { struct mutex mutex; /* Link layer */ + int mode; +#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */ +#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */ spinlock_t lock; /* Protects the internal state */ struct timer_list t1; /* Retransmit timer for SABM and UA */ int retries; @@ -1380,7 +1383,13 @@ retry: ctrl->data = data; ctrl->len = clen; gsm->pending_cmd = ctrl; - gsm->cretries = gsm->n2; + + /* If DLCI0 is in ADM mode skip retries, it won't respond */ + if (gsm->dlci[0]->mode == DLCI_MODE_ADM) + gsm->cretries = 1; + else + gsm->cretries = gsm->n2; + mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); gsm_control_transmit(gsm, ctrl); spin_unlock_irqrestore(&gsm->control_lock, flags); @@ -1488,6 +1497,7 @@ static void gsm_dlci_t1(unsigned long data) if (debug & 8) pr_info("DLCI %d opening in ADM mode.\n", dlci->addr); + dlci->mode = DLCI_MODE_ADM; gsm_dlci_open(dlci); } else { gsm_dlci_close(dlci); -- cgit v1.2.3 From 5080d3339eaf9eff6765ec99c29bede5df80a360 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sat, 7 Apr 2018 10:19:51 -0700 Subject: tty: n_gsm: Fix DLCI handling for ADM mode if debug & 2 is not set commit b2d89ad9c9682e795ed6eeb9ed455789ad6cedf1 upstream. At least on droid 4 with control channel in ADM mode, there is no response to Modem Status Command (MSC). Currently gsmtty_modem_update() expects to have data in dlci->modem_rx unless debug & 2 is set. This means that on droid 4, things only work if debug & 2 is set. Let's fix the issue by ignoring empty dlci->modem_rx for ADM mode. In the AMD mode, CMD_MSC will never respond and gsm_process_modem() won't get called to set dlci->modem_rx. And according to ts_127010v140000p.pdf, MSC is only relevant if basic option is chosen, so let's test for that too. Fixes: ea3d8465ab9b ("tty: n_gsm: Allow ADM response in addition to UA for control dlci") Cc: linux-serial@vger.kernel.org Cc: Alan Cox Cc: Dan Williams Cc: Jiri Prchal Cc: Jiri Slaby Cc: Marcel Partap Cc: Merlijn Wajer Cc: Michael Nazzareno Trimarchi Cc: Michael Scott Cc: Pavel Machek Cc: Peter Hurley Cc: Russ Gorby Cc: Sascha Hauer Cc: Sebastian Reichel Signed-off-by: Tony Lindgren Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index f2ba65ba1ef6..9e9016e67843 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2875,11 +2875,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk) static int gsm_carrier_raised(struct tty_port *port) { struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); + struct gsm_mux *gsm = dlci->gsm; + /* Not yet open so no carrier info */ if (dlci->state != DLCI_OPEN) return 0; if (debug & 2) return 1; + + /* + * Basic mode with control channel in ADM mode may not respond + * to CMD_MSC at all and modem_rx is empty. + */ + if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM && + !dlci->modem_rx) + return 1; + return dlci->modem_rx & TIOCM_CD; } -- cgit v1.2.3 From ad30f0539ae71c09bba067ad72770b3a0d800686 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Wed, 25 Apr 2018 20:12:31 +0900 Subject: tty: Use __GFP_NOFAIL for tty_ldisc_get() commit bcdd0ca8cb8730573afebcaae4138f8f4c8eaa20 upstream. syzbot is reporting crashes triggered by memory allocation fault injection at tty_ldisc_get() [1]. As an attempt to handle OOM in a graceful way, we have tried commit 5362544bebe85071 ("tty: don't panic on OOM in tty_set_ldisc()"). But we reverted that attempt by commit a8983d01f9b7d600 ("Revert "tty: don't panic on OOM in tty_set_ldisc()"") due to reproducible crash. We should spend resource for finding and fixing race condition bugs rather than complicate error paths for 2 * sizeof(void *) bytes allocation failure. [1] https://syzkaller.appspot.com/bug?id=489d33fa386453859ead58ff5171d43772b13aa3 Signed-off-by: Tetsuo Handa Reported-by: syzbot Cc: Michal Hocko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: Jiri Slaby Cc: Peter Hurley Cc: One Thousand Gnomes Cc: Linus Torvalds Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 96f0d1090888..4ab518d43758 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -175,12 +175,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) return ERR_CAST(ldops); } - ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL); - if (ld == NULL) { - put_ldops(ldops); - return ERR_PTR(-ENOMEM); - } - + /* + * There is no way to handle allocation failure of only 16 bytes. + * Let's simplify error handling and save more memory. + */ + ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL); ld->ops = ldops; ld->tty = tty; -- cgit v1.2.3 From 54a21fe4d8bbb0e82ac75e55bb8d46c4c3326ee4 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 1 Mar 2018 14:39:39 +0100 Subject: mtd: cfi: cmdset_0001: Do not allow read/write to suspend erase block. commit 6510bbc88e3258631831ade49033537081950605 upstream. Currently it is possible to read and/or write to suspend EB's. Writing /dev/mtdX or /dev/mtdblockX from several processes may break the flash state machine. Signed-off-by: Joakim Tjernlund Cc: Reviewed-by: Richard Weinberger Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 5e1b68cbcd0a..a239ed4cb076 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -831,21 +831,25 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) goto sleep; + /* Do not allow suspend iff read/write to EB address */ + if ((adr & chip->in_progress_block_mask) == + chip->in_progress_block_addr) + goto sleep; /* Erase suspend */ - map_write(map, CMD(0xB0), adr); + map_write(map, CMD(0xB0), chip->in_progress_block_addr); /* If the flash has finished erasing, then 'erase suspend' * appears to make some (28F320) flash devices switch to * 'read' mode. Make sure that we switch to 'read status' * mode so we get the right data. --rmk */ - map_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), chip->in_progress_block_addr); chip->oldstate = FL_ERASING; chip->state = FL_ERASE_SUSPENDING; chip->erase_suspended = 1; for (;;) { - status = map_read(map, adr); + status = map_read(map, chip->in_progress_block_addr); if (map_word_andequal(map, status, status_OK, status_OK)) break; @@ -1041,8 +1045,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad sending the 0x70 (Read Status) command to an erasing chip and expecting it to be ignored, that's what we do. */ - map_write(map, CMD(0xd0), adr); - map_write(map, CMD(0x70), adr); + map_write(map, CMD(0xd0), chip->in_progress_block_addr); + map_write(map, CMD(0x70), chip->in_progress_block_addr); chip->oldstate = FL_READY; chip->state = FL_ERASING; break; @@ -1933,6 +1937,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, map_write(map, CMD(0xD0), adr); chip->state = FL_ERASING; chip->erase_suspended = 0; + chip->in_progress_block_addr = adr; + chip->in_progress_block_mask = ~(len - 1); ret = INVAL_CACHE_AND_WAIT(map, chip, adr, adr, len, -- cgit v1.2.3 From 0d8f3797ed5d7204c0238825fe434a949822c60e Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 1 Mar 2018 14:39:40 +0100 Subject: mtd: cfi: cmdset_0001: Workaround Micron Erase suspend bug. commit 46a16a2283f9e678a4e26829175e0c37a5191860 upstream. Some Micron chips does not work well wrt Erase suspend for boot blocks. This avoids the issue by not allowing Erase suspend for the boot blocks for the 28F00AP30(1GBit) chip. Signed-off-by: Joakim Tjernlund Cc: Reviewed-by: Richard Weinberger Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/chips/cfi_cmdset_0001.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a239ed4cb076..e1b603ca0170 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -45,6 +45,7 @@ #define I82802AB 0x00ad #define I82802AC 0x00ac #define PF38F4476 0x881c +#define M28F00AP30 0x8963 /* STMicroelectronics chips */ #define M50LPW080 0x002F #define M50FLW080A 0x0080 @@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi, extp->MinorVersion = '1'; } +static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) +{ + /* + * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t + * Erase Supend for their small Erase Blocks(0x8000) + */ + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) + return 1; + return 0; +} + static inline struct cfi_pri_intelext * read_pri_intelext(struct map_info *map, __u16 adr) { @@ -836,6 +848,11 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long chip->in_progress_block_addr) goto sleep; + /* do not suspend small EBs, buggy Micron Chips */ + if (cfi_is_micron_28F00AP30(cfi, chip) && + (chip->in_progress_block_mask == ~(0x8000-1))) + goto sleep; + /* Erase suspend */ map_write(map, CMD(0xB0), chip->in_progress_block_addr); -- cgit v1.2.3 From f48bbbae0421bdf002f3fb565f1308695b2560a6 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 1 Mar 2018 14:39:41 +0100 Subject: mtd: cfi: cmdset_0002: Do not allow read/write to suspend erase block. commit 7b70eb14392a7cf505f9b358d06c33b5af73d1e7 upstream. Currently it is possible to read and/or write to suspend EB's. Writing /dev/mtdX or /dev/mtdblockX from several processes may break the flash state machine. Taken from cfi_cmdset_0001 driver. Signed-off-by: Joakim Tjernlund Cc: Reviewed-by: Richard Weinberger Signed-off-by: Boris Brezillon Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/chips/cfi_cmdset_0002.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 9dca881bb378..107c05b3ddbb 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -812,9 +812,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) goto sleep; - /* We could check to see if we're trying to access the sector - * that is currently being erased. However, no user will try - * anything like that so we just wait for the timeout. */ + /* Do not allow suspend iff read/write to EB address */ + if ((adr & chip->in_progress_block_mask) == + chip->in_progress_block_addr) + goto sleep; /* Erase suspend */ /* It's harmless to issue the Erase-Suspend and Erase-Resume @@ -2263,6 +2264,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) chip->state = FL_ERASING; chip->erase_suspended = 0; chip->in_progress_block_addr = adr; + chip->in_progress_block_mask = ~(map->size - 1); INVALIDATE_CACHE_UDELAY(map, chip, adr, map->size, @@ -2352,6 +2354,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, chip->state = FL_ERASING; chip->erase_suspended = 0; chip->in_progress_block_addr = adr; + chip->in_progress_block_mask = ~(len - 1); INVALIDATE_CACHE_UDELAY(map, chip, adr, len, -- cgit v1.2.3 From dbf1c17b6c2d4249d31a7b2516cdc2881c0a4860 Mon Sep 17 00:00:00 2001 From: Mahesh Rajashekhara Date: Tue, 17 Apr 2018 17:03:12 +0530 Subject: scsi: sd: Defer spinning up drive while SANITIZE is in progress commit 505aa4b6a8834a2300971c5220c380c3271ebde3 upstream. A drive being sanitized will return NOT READY / ASC 0x4 / ASCQ 0x1b ("LOGICAL UNIT NOT READY. SANITIZE IN PROGRESS"). Prevent spinning up the drive until this condition clears. [mkp: tweaked commit message] Signed-off-by: Mahesh Rajashekhara Cc: Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ace56c5e61e1..14ba1a2c0b7c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1935,6 +1935,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) break; /* standby */ if (sshdr.asc == 4 && sshdr.ascq == 0xc) break; /* unavailable */ + if (sshdr.asc == 4 && sshdr.ascq == 0x1b) + break; /* sanitize in progress */ /* * Issue command to spin up drive when not ready */ -- cgit v1.2.3 From d6bc6d12b532265027aee080dc171c557d827206 Mon Sep 17 00:00:00 2001 From: Victor Gu Date: Fri, 6 Apr 2018 16:55:31 +0200 Subject: PCI: aardvark: Fix logic in advk_pcie_{rd,wr}_conf() commit 660661afcd40ed7f515ef3369721ed58e80c0fc5 upstream. The PCI configuration space read/write functions were special casing the situation where PCI_SLOT(devfn) != 0, and returned PCIBIOS_DEVICE_NOT_FOUND in this case. However, while this is what is intended for the root bus, it is not intended for the child busses, as it prevents discovering devices with PCI_SLOT(x) != 0. Therefore, we return PCIBIOS_DEVICE_NOT_FOUND only if we're on the root bus. Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") Cc: Signed-off-by: Victor Gu Reviewed-by: Wilson Ding Reviewed-by: Nadav Haklai [Thomas: tweak commit log.] Signed-off-by: Thomas Petazzoni Signed-off-by: Lorenzo Pieralisi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-aardvark.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 4fce494271cc..9437840bee6d 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -439,7 +439,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, u32 reg; int ret; - if (PCI_SLOT(devfn) != 0) { + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } @@ -493,7 +493,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int offset; int ret; - if (PCI_SLOT(devfn) != 0) + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; if (where % size) -- cgit v1.2.3 From e57bde8bbd4ed072120d3fc088fc147ccc29bed4 Mon Sep 17 00:00:00 2001 From: Victor Gu Date: Fri, 6 Apr 2018 16:55:32 +0200 Subject: PCI: aardvark: Set PIO_ADDR_LS correctly in advk_pcie_rd_conf() commit 4fa3999ee672c54a5498ce98e20fe3fdf9c1cbb4 upstream. When setting the PIO_ADDR_LS register during a configuration read, we were properly passing the device number, function number and register number, but not the bus number, causing issues when reading the configuration of PCIe devices. Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") Cc: Signed-off-by: Victor Gu Reviewed-by: Wilson Ding Reviewed-by: Nadav Haklai [Thomas: tweak commit log.] Signed-off-by: Thomas Petazzoni Signed-off-by: Lorenzo Pieralisi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-aardvark.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 9437840bee6d..d3d24257c65a 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -175,8 +175,6 @@ #define PCIE_CONFIG_WR_TYPE0 0xa #define PCIE_CONFIG_WR_TYPE1 0xb -/* PCI_BDF shifts 8bit, so we need extra 4bit shift */ -#define PCIE_BDF(dev) (dev << 4) #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20) #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15) #define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12) @@ -458,7 +456,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, advk_writel(pcie, reg, PIO_CTRL); /* Program the address registers */ - reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); + reg = PCIE_CONF_ADDR(bus->number, devfn, where); advk_writel(pcie, reg, PIO_ADDR_LS); advk_writel(pcie, 0, PIO_ADDR_MS); -- cgit v1.2.3 From 5b066d6423b23fd95334184f721b94f8b61f7d21 Mon Sep 17 00:00:00 2001 From: Evan Wang Date: Fri, 6 Apr 2018 16:55:34 +0200 Subject: PCI: aardvark: Fix PCIe Max Read Request Size setting commit fc31c4e347c9dad50544d01d5ee98b22c7df88bb upstream. There is an obvious typo issue in the definition of the PCIe maximum read request size: a bit shift is directly used as a value, while it should be used to shift the correct value. Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") Cc: Signed-off-by: Evan Wang Reviewed-by: Victor Gu Reviewed-by: Nadav Haklai [Thomas: tweak commit log.] Signed-off-by: Thomas Petazzoni Signed-off-by: Lorenzo Pieralisi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-aardvark.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index d3d24257c65a..11bad826683e 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -32,6 +32,7 @@ #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 +#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) #define PCIE_CORE_LINK_TRAINING BIT(5) @@ -296,7 +297,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | - PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; + (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << + PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); /* Program PCIe Control 2 to disable strict ordering */ -- cgit v1.2.3 From a4e38e8dd596a3e03eeffb55df4aab27acd5eb2d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Apr 2018 15:21:43 +0200 Subject: ARM: amba: Make driver_override output consistent with other buses commit 5f53624662eaac89598641cee6cd54fc192572d9 upstream. For AMBA devices with unconfigured driver override, the "driver_override" sysfs virtual file is empty, while it contains "(null)" for platform and PCI devices. Make AMBA consistent with other buses by dropping the test for a NULL pointer. Note that contrary to popular belief, sprintf() handles NULL pointers fine; they are printed as "(null)". Signed-off-by: Geert Uytterhoeven Cc: stable Reviewed-by: Todd Kjos Signed-off-by: Greg Kroah-Hartman --- drivers/amba/bus.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index a56fa2a1e9aa..b8642519fc92 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -70,9 +70,6 @@ static ssize_t driver_override_show(struct device *_dev, { struct amba_device *dev = to_amba_device(_dev); - if (!dev->driver_override) - return 0; - return sprintf(buf, "%s\n", dev->driver_override); } -- cgit v1.2.3 From 272c99cf85a371401b78f3c56a18745bf07817a3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Apr 2018 15:21:44 +0200 Subject: ARM: amba: Fix race condition with driver_override commit 6a7228d90d42bcacfe38786756ba62762b91c20a upstream. The driver_override implementation is susceptible to a race condition when different threads are reading vs storing a different driver override. Add locking to avoid this race condition. Cfr. commits 6265539776a0810b ("driver core: platform: fix race condition with driver_override") and 9561475db680f714 ("PCI: Fix race condition with driver_override"). Fixes: 3cf385713460eb2b ("ARM: 8256/1: driver coamba: add device binding path 'driver_override'") Signed-off-by: Geert Uytterhoeven Reviewed-by: Todd Kjos Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/amba/bus.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index b8642519fc92..1c25b6ee9651 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -69,8 +69,12 @@ static ssize_t driver_override_show(struct device *_dev, struct device_attribute *attr, char *buf) { struct amba_device *dev = to_amba_device(_dev); + ssize_t len; - return sprintf(buf, "%s\n", dev->driver_override); + device_lock(_dev); + len = sprintf(buf, "%s\n", dev->driver_override); + device_unlock(_dev); + return len; } static ssize_t driver_override_store(struct device *_dev, @@ -78,7 +82,7 @@ static ssize_t driver_override_store(struct device *_dev, const char *buf, size_t count) { struct amba_device *dev = to_amba_device(_dev); - char *driver_override, *old = dev->driver_override, *cp; + char *driver_override, *old, *cp; if (count > PATH_MAX) return -EINVAL; @@ -91,12 +95,15 @@ static ssize_t driver_override_store(struct device *_dev, if (cp) *cp = '\0'; + device_lock(_dev); + old = dev->driver_override; if (strlen(driver_override)) { dev->driver_override = driver_override; } else { kfree(driver_override); dev->driver_override = NULL; } + device_unlock(_dev); kfree(old); -- cgit v1.2.3 From 8970c12ac9b917b27e42c0537ab7fce0357f0cf3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Apr 2018 15:21:45 +0200 Subject: ARM: amba: Don't read past the end of sysfs "driver_override" buffer commit d2ffed5185df9d8d9ccd150e4340e3b6f96a8381 upstream. When printing the driver_override parameter when it is 4095 and 4094 bytes long, the printing code would access invalid memory because we need count + 1 bytes for printing. Cfr. commits 4efe874aace57dba ("PCI: Don't read past the end of sysfs "driver_override" buffer") and bf563b01c2895a4b ("driver core: platform: Don't read past the end of "driver_override" buffer"). Fixes: 3cf385713460eb2b ("ARM: 8256/1: driver coamba: add device binding path 'driver_override'") Signed-off-by: Geert Uytterhoeven Reviewed-by: Todd Kjos Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/amba/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 1c25b6ee9651..93888ccb4e26 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -84,7 +84,8 @@ static ssize_t driver_override_store(struct device *_dev, struct amba_device *dev = to_amba_device(_dev); char *driver_override, *old, *cp; - if (count > PATH_MAX) + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) return -EINVAL; driver_override = kstrndup(buf, count, GFP_KERNEL); -- cgit v1.2.3 From a72ac679ca58e873670a4f8e935f302fd605fea5 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Fri, 6 Apr 2018 17:21:53 -0600 Subject: earlycon: Use a pointer table to fix __earlycon_table stride commit dd709e72cb934eefd44de8d9969097173fbf45dc upstream. Commit 99492c39f39f ("earlycon: Fix __earlycon_table stride") tried to fix __earlycon_table stride by forcing the earlycon_id struct alignment to 32 and asking the linker to 32-byte align the __earlycon_table symbol. This fix was based on commit 07fca0e57fca92 ("tracing: Properly align linker defined symbols") which tried a similar fix for the tracing subsystem. However, this fix doesn't quite work because there is no guarantee that gcc will place structures packed into an array format. In fact, gcc 4.9 chooses to 64-byte align these structs by inserting additional padding between the entries because it has no clue that they are supposed to be in an array. If we are unlucky, the linker will assign symbol "__earlycon_table" to a 32-byte aligned address which does not correspond to the 64-byte aligned contents of section "__earlycon_table". To address this same problem, the fix to the tracing system was subsequently re-implemented using a more robust table of pointers approach by commits: 3d56e331b653 ("tracing: Replace syscall_meta_data struct array with pointer array") 654986462939 ("tracepoints: Fix section alignment using pointer array") e4a9ea5ee7c8 ("tracing: Replace trace_event struct array with pointer array") Let's use this same "array of pointers to structs" approach for EARLYCON_TABLE. Fixes: 99492c39f39f ("earlycon: Fix __earlycon_table stride") Signed-off-by: Daniel Kurtz Suggested-by: Aaron Durbin Reviewed-by: Rob Herring Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/of/fdt.c | 7 +++++-- drivers/tty/serial/earlycon.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 502f5547a1f2..e9360d5cbcba 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -935,7 +935,7 @@ int __init early_init_dt_scan_chosen_stdout(void) int offset; const char *p, *q, *options = NULL; int l; - const struct earlycon_id *match; + const struct earlycon_id **p_match; const void *fdt = initial_boot_params; offset = fdt_path_offset(fdt, "/chosen"); @@ -962,7 +962,10 @@ int __init early_init_dt_scan_chosen_stdout(void) return 0; } - for (match = __earlycon_table; match < __earlycon_table_end; match++) { + for (p_match = __earlycon_table; p_match < __earlycon_table_end; + p_match++) { + const struct earlycon_id *match = *p_match; + if (!match->compatible[0]) continue; diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 3b31fd8863eb..b9a4625b8690 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -172,7 +172,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) */ int __init setup_earlycon(char *buf) { - const struct earlycon_id *match; + const struct earlycon_id **p_match; if (!buf || !buf[0]) return -EINVAL; @@ -180,7 +180,9 @@ int __init setup_earlycon(char *buf) if (early_con.flags & CON_ENABLED) return -EALREADY; - for (match = __earlycon_table; match < __earlycon_table_end; match++) { + for (p_match = __earlycon_table; p_match < __earlycon_table_end; + p_match++) { + const struct earlycon_id *match = *p_match; size_t len = strlen(match->name); if (strncmp(buf, match->name, len)) -- cgit v1.2.3 From 4edf8ffe0c826dab2a8c418fb44bef74a6be41ed Mon Sep 17 00:00:00 2001 From: Shilpasri G Bhat Date: Wed, 25 Apr 2018 16:29:31 +0530 Subject: cpufreq: powernv: Fix hardlockup due to synchronous smp_call in timer interrupt commit c0f7f5b6c69107ca92909512533e70258ee19188 upstream. gpstate_timer_handler() uses synchronous smp_call to set the pstate on the requested core. This causes the below hard lockup: smp_call_function_single+0x110/0x180 (unreliable) smp_call_function_any+0x180/0x250 gpstate_timer_handler+0x1e8/0x580 call_timer_fn+0x50/0x1c0 expire_timers+0x138/0x1f0 run_timer_softirq+0x1e8/0x270 __do_softirq+0x158/0x3e4 irq_exit+0xe8/0x120 timer_interrupt+0x9c/0xe0 decrementer_common+0x114/0x120 -- interrupt: 901 at doorbell_global_ipi+0x34/0x50 LR = arch_send_call_function_ipi_mask+0x120/0x130 arch_send_call_function_ipi_mask+0x4c/0x130 smp_call_function_many+0x340/0x450 pmdp_invalidate+0x98/0xe0 change_huge_pmd+0xe0/0x270 change_protection_range+0xb88/0xe40 mprotect_fixup+0x140/0x340 SyS_mprotect+0x1b4/0x350 system_call+0x58/0x6c One way to avoid this is removing the smp-call. We can ensure that the timer always runs on one of the policy-cpus. If the timer gets migrated to a cpu outside the policy then re-queue it back on the policy->cpus. This way we can get rid of the smp-call which was being used to set the pstate on the policy->cpus. Fixes: 7bc54b652f13 ("timers, cpufreq/powernv: Initialize the gpstate timer as pinned") Cc: stable@vger.kernel.org # v4.8+ Reported-by: Nicholas Piggin Reported-by: Pridhiviraj Paidipeddi Signed-off-by: Shilpasri G Bhat Acked-by: Nicholas Piggin Acked-by: Viresh Kumar Acked-by: Vaidyanathan Srinivasan Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/powernv-cpufreq.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 6fb3cd24c1b6..a1d7fa48229d 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -599,6 +599,16 @@ void gpstate_timer_handler(unsigned long data) if (!spin_trylock(&gpstates->gpstate_lock)) return; + /* + * If the timer has migrated to the different cpu then bring + * it back to one of the policy->cpus + */ + if (!cpumask_test_cpu(raw_smp_processor_id(), policy->cpus)) { + gpstates->timer.expires = jiffies + msecs_to_jiffies(1); + add_timer_on(&gpstates->timer, cpumask_first(policy->cpus)); + spin_unlock(&gpstates->gpstate_lock); + return; + } gpstates->last_sampled_time += time_diff; gpstates->elapsed_time += time_diff; @@ -626,10 +636,8 @@ void gpstate_timer_handler(unsigned long data) gpstates->last_gpstate_idx = pstate_to_idx(freq_data.gpstate_id); gpstates->last_lpstate_idx = pstate_to_idx(freq_data.pstate_id); + set_pstate(&freq_data); spin_unlock(&gpstates->gpstate_lock); - - /* Timer may get migrated to a different cpu on cpu hot unplug */ - smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); } /* -- cgit v1.2.3 From a2a8b263ebff901c789517908a779f54fad3f2d0 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Tue, 10 Apr 2018 21:49:32 +1000 Subject: rtc: opal: Fix OPAL RTC driver OPAL_BUSY loops commit 682e6b4da5cbe8e9a53f979a58c2a9d7dc997175 upstream. The OPAL RTC driver does not sleep in case it gets OPAL_BUSY or OPAL_BUSY_EVENT from firmware, which causes large scheduling latencies, up to 50 seconds have been observed here when RTC stops responding (BMC reboot can do it). Fix this by converting it to the standard form OPAL_BUSY loop that sleeps. Fixes: 628daa8d5abf ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks") Cc: stable@vger.kernel.org # v3.2+ Signed-off-by: Nicholas Piggin Acked-by: Alexandre Belloni Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-opal.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index aa53fceaa5e0..180ec1f8c917 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -57,7 +57,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) { - long rc = OPAL_BUSY; + s64 rc = OPAL_BUSY; int retries = 10; u32 y_m_d; u64 h_m_s_ms; @@ -66,13 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); - else if (retries-- && (rc == OPAL_HARDWARE - || rc == OPAL_INTERNAL_ERROR)) - msleep(10); - else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) - break; + } else if (rc == OPAL_BUSY) { + msleep(OPAL_BUSY_DELAY_MS); + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { + if (retries--) { + msleep(10); /* Wait 10ms before retry */ + rc = OPAL_BUSY; /* go around again */ + } + } } if (rc != OPAL_SUCCESS) @@ -87,21 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm) { - long rc = OPAL_BUSY; + s64 rc = OPAL_BUSY; int retries = 10; u32 y_m_d = 0; u64 h_m_s_ms = 0; tm_to_opal(tm, &y_m_d, &h_m_s_ms); + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_write(y_m_d, h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); - else if (retries-- && (rc == OPAL_HARDWARE - || rc == OPAL_INTERNAL_ERROR)) - msleep(10); - else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) - break; + } else if (rc == OPAL_BUSY) { + msleep(OPAL_BUSY_DELAY_MS); + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { + if (retries--) { + msleep(10); /* Wait 10ms before retry */ + rc = OPAL_BUSY; /* go around again */ + } + } } return rc == OPAL_SUCCESS ? 0 : -EIO; -- cgit v1.2.3 From 537ef3ab077d68d7c46b9cbf41018a93882b35ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Thu, 12 Apr 2018 16:34:19 +0200 Subject: drm/amdgpu: set COMPUTE_PGM_RSRC1 for SGPR/VGPR clearing shaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 75569c182e4f65cd8826a5853dc9cbca703cbd0e upstream. Otherwise, the SQ may skip some of the register writes, or shader waves may be allocated where we don't expect them, so that as a result we don't actually reset all of the register SRAMs. This can lead to spurious ECC errors later on if a shader uses an uninitialized register. Signed-off-by: Nicolai Hähnle Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index a88d365be4c5..564362e8b486 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1484,10 +1484,11 @@ static const u32 sgpr_init_compute_shader[] = static const u32 vgpr_init_regs[] = { mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff, - mmCOMPUTE_RESOURCE_LIMITS, 0, + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */ mmCOMPUTE_NUM_THREAD_X, 256*4, mmCOMPUTE_NUM_THREAD_Y, 1, mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC1, 0x100004f, /* VGPRS=15 (64 logical VGPRs), SGPRS=1 (16 SGPRs), BULKY=1 */ mmCOMPUTE_PGM_RSRC2, 20, mmCOMPUTE_USER_DATA_0, 0xedcedc00, mmCOMPUTE_USER_DATA_1, 0xedcedc01, @@ -1504,10 +1505,11 @@ static const u32 vgpr_init_regs[] = static const u32 sgpr1_init_regs[] = { mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f, - mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */ mmCOMPUTE_NUM_THREAD_X, 256*5, mmCOMPUTE_NUM_THREAD_Y, 1, mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */ mmCOMPUTE_PGM_RSRC2, 20, mmCOMPUTE_USER_DATA_0, 0xedcedc00, mmCOMPUTE_USER_DATA_1, 0xedcedc01, @@ -1528,6 +1530,7 @@ static const u32 sgpr2_init_regs[] = mmCOMPUTE_NUM_THREAD_X, 256*5, mmCOMPUTE_NUM_THREAD_Y, 1, mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */ mmCOMPUTE_PGM_RSRC2, 20, mmCOMPUTE_USER_DATA_0, 0xedcedc00, mmCOMPUTE_USER_DATA_1, 0xedcedc01, -- cgit v1.2.3 From 23fb8f797e6bee5c39b43e6f4c6f15203ee8ea14 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Thu, 22 Mar 2018 10:57:01 +0100 Subject: crypto: talitos - fix IPsec cipher in length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2b1227301a8e4729409694e323b72c064c47cb6b upstream. For SEC 2.x+, cipher in length must contain only the ciphertext length. In case of using hardware ICV checking, the ICV length is provided via the "extent" field of the descriptor pointer. Cc: # 4.8+ Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU") Reported-by: Horia Geantă Signed-off-by: Christophe Leroy Tested-by: Horia Geantă Signed-off-by: Herbert Xu [backported to 4.9.y, 4.14.y] Signed-off-by: Horia Geantă Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/talitos.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 42c060c7ae15..7c71722be395 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1116,10 +1116,10 @@ next: return count; } -int talitos_sg_map(struct device *dev, struct scatterlist *src, - unsigned int len, struct talitos_edesc *edesc, - struct talitos_ptr *ptr, - int sg_count, unsigned int offset, int tbl_off) +static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src, + unsigned int len, struct talitos_edesc *edesc, + struct talitos_ptr *ptr, int sg_count, + unsigned int offset, int tbl_off, int elen) { struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); @@ -1130,7 +1130,7 @@ int talitos_sg_map(struct device *dev, struct scatterlist *src, } to_talitos_ptr_len(ptr, len, is_sec1); - to_talitos_ptr_ext_set(ptr, 0, is_sec1); + to_talitos_ptr_ext_set(ptr, elen, is_sec1); if (sg_count == 1) { to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1); @@ -1140,7 +1140,7 @@ int talitos_sg_map(struct device *dev, struct scatterlist *src, to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1); return sg_count; } - sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, + sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen, &edesc->link_tbl[tbl_off]); if (sg_count == 1) { /* Only one segment now, so no link tbl needed*/ @@ -1154,6 +1154,15 @@ int talitos_sg_map(struct device *dev, struct scatterlist *src, return sg_count; } +static int talitos_sg_map(struct device *dev, struct scatterlist *src, + unsigned int len, struct talitos_edesc *edesc, + struct talitos_ptr *ptr, int sg_count, + unsigned int offset, int tbl_off) +{ + return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset, + tbl_off, 0); +} + /* * fill in and submit ipsec_esp descriptor */ @@ -1171,7 +1180,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, unsigned int ivsize = crypto_aead_ivsize(aead); int tbl_off = 0; int sg_count, ret; - int sg_link_tbl_len; + int elen = 0; bool sync_needed = false; struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); @@ -1225,20 +1234,12 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, * extent is bytes of HMAC postpended to ciphertext, * typically 12 for ipsec */ - to_talitos_ptr_len(&desc->ptr[4], cryptlen, is_sec1); - to_talitos_ptr_ext_set(&desc->ptr[4], 0, is_sec1); - - sg_link_tbl_len = cryptlen; - - if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) { - to_talitos_ptr_ext_set(&desc->ptr[4], authsize, is_sec1); - - if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) - sg_link_tbl_len += authsize; - } + if ((desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) && + (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)) + elen = authsize; - ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc, - &desc->ptr[4], sg_count, areq->assoclen, tbl_off); + ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4], + sg_count, areq->assoclen, tbl_off, elen); if (ret > 1) { tbl_off += ret; -- cgit v1.2.3 From aa6b517e74512ef8373ff66a40f4925f9b6edab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 24 May 2017 21:38:46 +0200 Subject: serial: imx: ensure UCR3 and UFCR are setup correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6df765dca378bddf994cfd2044acafa501bd800f upstream. Commit e61c38d85b73 ("serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off") has a flaw: While UCR3 and UFCR were modified using read-modify-write before it switched to write register values independent of the previous state. That's a good idea in principle (and that's why I did it) but needs more care. This patch reinstates read-modify-write for UFCR and for UCR3 ensures that RXDMUXSEL and ADNIMP are set for post imx1. Fixes: e61c38d85b73 ("serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off") Signed-off-by: Uwe Kleine-König Acked-by: Mika Penttilä Tested-by: Mika Penttilä Acked-by: Steve Twiss Tested-by: Steve Twiss Cc: Chris Ruehl Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index f575a33974fa..ecadc27eea48 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -2145,7 +2145,9 @@ static int serial_imx_probe(struct platform_device *pdev) * and DCD (when they are outputs) or enables the respective * irqs. So set this bit early, i.e. before requesting irqs. */ - writel(UFCR_DCEDTE, sport->port.membase + UFCR); + reg = readl(sport->port.membase + UFCR); + if (!(reg & UFCR_DCEDTE)) + writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR); /* * Disable UCR3_RI and UCR3_DCD irqs. They are also not @@ -2156,7 +2158,15 @@ static int serial_imx_probe(struct platform_device *pdev) sport->port.membase + UCR3); } else { - writel(0, sport->port.membase + UFCR); + unsigned long ucr3 = UCR3_DSR; + + reg = readl(sport->port.membase + UFCR); + if (reg & UFCR_DCEDTE) + writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR); + + if (!is_imx1_uart(sport)) + ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP; + writel(ucr3, sport->port.membase + UCR3); } clk_disable_unprepare(sport->clk_ipg); -- cgit v1.2.3 From 466e8d108d6f9cfacfc347ccc744e8d37a380560 Mon Sep 17 00:00:00 2001 From: Kristian Evensen Date: Thu, 1 Feb 2018 10:32:32 +0100 Subject: USB: serial: option: Add support for Quectel EP06 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 71a0483d56e784b1e11f38f10d7e22d265dbe244 upstream. The Quectel EP06 is a Cat. 6 LTE modem, and the interface mapping is as follows: 0: Diag 1: NMEA 2: AT 3: Modem Interface 4 is QMI and interface 5 is ADB, so they are blacklisted. This patch should also be considered for -stable. The QMI-patch for this modem is already in the -stable-queue. v1->v2: * Updated commit prefix (thanks Johan Hovold) * Updated commit message slightly. Signed-off-by: Kristian Evensen Acked-by: Johan Hovold Cc: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1799aa058a5b..a1cb1ea41282 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -244,6 +244,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EC21 0x0121 #define QUECTEL_PRODUCT_EC25 0x0125 #define QUECTEL_PRODUCT_BG96 0x0296 +#define QUECTEL_PRODUCT_EP06 0x0306 #define CMOTECH_VENDOR_ID 0x16d8 #define CMOTECH_PRODUCT_6001 0x6001 @@ -692,6 +693,10 @@ static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { .reserved = BIT(1) | BIT(4), }; +static const struct option_blacklist_info quectel_ep06_blacklist = { + .reserved = BIT(4) | BIT(5), +}; + static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -1206,6 +1211,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), + .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), -- cgit v1.2.3 From 4178de2e9e188b2c9839ddf518f0b38de3c9291a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 6 Apr 2018 10:23:05 -0700 Subject: Input: leds - fix out of bound access commit 6bd6ae639683c0b41f46990d5c64ff9fbfa019dc upstream. UI_SET_LEDBIT ioctl() causes the following KASAN splat when used with led > LED_CHARGING: [ 1274.663418] BUG: KASAN: slab-out-of-bounds in input_leds_connect+0x611/0x730 [input_leds] [ 1274.663426] Write of size 8 at addr ffff88003377b2c0 by task ckb-next-daemon/5128 This happens because we were writing to the led structure before making sure that it exists. Reported-by: Tasos Sahanidis Tested-by: Tasos Sahanidis Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/input-leds.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 766bf2660116..5f04b2d94635 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler, const struct input_device_id *id) { struct input_leds *leds; + struct input_led *led; unsigned int num_leds; unsigned int led_code; int led_no; @@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler, led_no = 0; for_each_set_bit(led_code, dev->ledbit, LED_CNT) { - struct input_led *led = &leds->leds[led_no]; + if (!input_led_info[led_code].name) + continue; + led = &leds->leds[led_no]; led->handle = &leds->handle; led->code = led_code; - if (!input_led_info[led_code].name) - continue; - led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", dev_name(&dev->dev), input_led_info[led_code].name); -- cgit v1.2.3 From c0ff32016565d4332e4012b82105918e4c28d4ea Mon Sep 17 00:00:00 2001 From: "Vittorio Gambaletta (VittGam)" Date: Wed, 25 Apr 2018 15:22:13 -0700 Subject: Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro commit f372b81101e6895252298e563d634d5e44ae81e7 upstream. This patch adds the correct platform data information for the Caroline Chromebook, so that the mouse button does not get stuck in pressed state after the first click. The Samus button keymap and platform data definition are the correct ones for Caroline, so they have been reused here. Signed-off-by: Vittorio Gambaletta Signed-off-by: Salvatore Bellizzi Tested-by: Guenter Roeck Cc: stable@vger.kernel.org [dtor: adjusted vendor spelling to match shipping firmware] Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/atmel_mxt_ts.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index e5d185fe69b9..26132402fdf9 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3027,6 +3027,15 @@ static const struct dmi_system_id mxt_dmi_table[] = { }, .driver_data = samus_platform_data, }, + { + /* Samsung Chromebook Pro */ + .ident = "Samsung Chromebook Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), + }, + .driver_data = samus_platform_data, + }, { /* Other Google Chromebooks */ .ident = "Chromebook", -- cgit v1.2.3 From 1378078b7a8b1635f1bcd4f5d2843ef9770c61ae Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Mon, 23 Apr 2018 21:42:37 +0530 Subject: RDMA/cxgb4: release hw resources on device removal commit 26bff1bd74a4f7417509a83295614e9dab995b2a upstream. The c4iw_rdev_close() logic was not releasing all the hw resources (PBL and RQT memory) during the device removal event (driver unload / system reboot). This can cause panic in gen_pool_destroy(). The module remove function will wait for all the hw resources to be released during the device removal event. Fixes c12a67fe(iw_cxgb4: free EQ queue memory on last deref) Signed-off-by: Raju Rangoju Reviewed-by: Steve Wise Cc: stable@vger.kernel.org Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/cxgb4/device.c | 9 ++++++++- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 4 ++++ drivers/infiniband/hw/cxgb4/resource.c | 26 ++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index b85a1a983e07..9e0f2ccf1d10 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -856,6 +856,11 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) rdev->status_page->db_off = 0; + init_completion(&rdev->rqt_compl); + init_completion(&rdev->pbl_compl); + kref_init(&rdev->rqt_kref); + kref_init(&rdev->pbl_kref); + return 0; err_free_status_page: free_page((unsigned long)rdev->status_page); @@ -872,12 +877,14 @@ destroy_resource: static void c4iw_rdev_close(struct c4iw_rdev *rdev) { - destroy_workqueue(rdev->free_workq); kfree(rdev->wr_log); free_page((unsigned long)rdev->status_page); c4iw_pblpool_destroy(rdev); c4iw_rqtpool_destroy(rdev); + wait_for_completion(&rdev->pbl_compl); + wait_for_completion(&rdev->rqt_compl); c4iw_destroy_resource(&rdev->resource); + destroy_workqueue(rdev->free_workq); } static void c4iw_dealloc(struct uld_ctx *ctx) diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 7d540667dad2..896dff7a6cee 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -186,6 +186,10 @@ struct c4iw_rdev { struct wr_log_entry *wr_log; int wr_log_size; struct workqueue_struct *free_workq; + struct completion rqt_compl; + struct completion pbl_compl; + struct kref rqt_kref; + struct kref pbl_kref; }; static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index 67df71a7012e..803c677e21cd 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c @@ -260,12 +260,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size) rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); if (rdev->stats.pbl.cur > rdev->stats.pbl.max) rdev->stats.pbl.max = rdev->stats.pbl.cur; + kref_get(&rdev->pbl_kref); } else rdev->stats.pbl.fail++; mutex_unlock(&rdev->stats.lock); return (u32)addr; } +static void destroy_pblpool(struct kref *kref) +{ + struct c4iw_rdev *rdev; + + rdev = container_of(kref, struct c4iw_rdev, pbl_kref); + gen_pool_destroy(rdev->pbl_pool); + complete(&rdev->pbl_compl); +} + void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) { PDBG("%s addr 0x%x size %d\n", __func__, addr, size); @@ -273,6 +283,7 @@ void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); mutex_unlock(&rdev->stats.lock); gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); + kref_put(&rdev->pbl_kref, destroy_pblpool); } int c4iw_pblpool_create(struct c4iw_rdev *rdev) @@ -312,7 +323,7 @@ int c4iw_pblpool_create(struct c4iw_rdev *rdev) void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) { - gen_pool_destroy(rdev->pbl_pool); + kref_put(&rdev->pbl_kref, destroy_pblpool); } /* @@ -333,12 +344,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); if (rdev->stats.rqt.cur > rdev->stats.rqt.max) rdev->stats.rqt.max = rdev->stats.rqt.cur; + kref_get(&rdev->rqt_kref); } else rdev->stats.rqt.fail++; mutex_unlock(&rdev->stats.lock); return (u32)addr; } +static void destroy_rqtpool(struct kref *kref) +{ + struct c4iw_rdev *rdev; + + rdev = container_of(kref, struct c4iw_rdev, rqt_kref); + gen_pool_destroy(rdev->rqt_pool); + complete(&rdev->rqt_compl); +} + void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) { PDBG("%s addr 0x%x size %d\n", __func__, addr, size << 6); @@ -346,6 +367,7 @@ void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); mutex_unlock(&rdev->stats.lock); gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); + kref_put(&rdev->rqt_kref, destroy_rqtpool); } int c4iw_rqtpool_create(struct c4iw_rdev *rdev) @@ -383,7 +405,7 @@ int c4iw_rqtpool_create(struct c4iw_rdev *rdev) void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) { - gen_pool_destroy(rdev->rqt_pool); + kref_put(&rdev->rqt_kref, destroy_rqtpool); } /* -- cgit v1.2.3 From aa2fb1f929c5dcfdcafd1456a029874c7a2f75c5 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 19 Apr 2018 08:28:11 -0700 Subject: RDMA/ucma: Allow resolving address w/o specifying source address commit 09abfe7b5b2f442a85f4c4d59ecf582ad76088d7 upstream. The RDMA CM will select a source device and address by consulting the routing table if no source address is passed into rdma_resolve_address(). Userspace will ask for this by passing an all-zero source address in the RESOLVE_IP command. Unfortunately the new check for non-zero address size rejects this with EINVAL, which breaks valid userspace applications. Fix this by explicitly allowing a zero address family for the source. Fixes: 2975d5de6428 ("RDMA/ucma: Check AF family prior resolving address") Cc: Signed-off-by: Roland Dreier Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/ucma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index cb79d171d1e4..f2f1c9fec0b1 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -676,7 +676,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - if (!rdma_addr_size_in6(&cmd.src_addr) || + if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) || !rdma_addr_size_in6(&cmd.dst_addr)) return -EINVAL; -- cgit v1.2.3 From a3fe8107c06f153d0eb87b435c7a5be477e986aa Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Mon, 23 Apr 2018 17:01:53 +0300 Subject: RDMA/mlx5: Protect from shift operand overflow commit 002bf2282b2d7318e444dca9ffcb994afc5d5f15 upstream. Ensure that user didn't supply values too large that can cause overflow. UBSAN: Undefined behaviour in drivers/infiniband/hw/mlx5/qp.c:263:23 shift exponent -2147483648 is negative CPU: 0 PID: 292 Comm: syzkaller612609 Not tainted 4.16.0-rc1+ #131 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 Call Trace: dump_stack+0xde/0x164 ubsan_epilogue+0xe/0x81 set_rq_size+0x7c2/0xa90 create_qp_common+0xc18/0x43c0 mlx5_ib_create_qp+0x379/0x1ca0 create_qp.isra.5+0xc94/0x2260 ib_uverbs_create_qp+0x21b/0x2a0 ib_uverbs_write+0xc2c/0x1010 vfs_write+0x1b0/0x550 SyS_write+0xc7/0x1a0 do_syscall_64+0x1aa/0x740 entry_SYSCALL_64_after_hwframe+0x26/0x9b RIP: 0033:0x433569 RSP: 002b:00007ffc6e62f448 EFLAGS: 00000217 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00000000004002f8 RCX: 0000000000433569 RDX: 0000000000000070 RSI: 00000000200042c0 RDI: 0000000000000003 RBP: 00000000006d5018 R08: 00000000004002f8 R09: 00000000004002f8 R10: 00000000004002f8 R11: 0000000000000217 R12: 0000000000000000 R13: 000000000040c9f0 R14: 000000000040ca80 R15: 0000000000000006 Cc: # 3.10 Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Cc: syzkaller Reported-by: Noa Osherovich Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/qp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 5b8909d1b55e..1d68c538d17e 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -253,7 +253,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap, } else { if (ucmd) { qp->rq.wqe_cnt = ucmd->rq_wqe_count; + if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift)) + return -EINVAL; qp->rq.wqe_shift = ucmd->rq_wqe_shift; + if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig) + return -EINVAL; qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; qp->rq.max_post = qp->rq.wqe_cnt; } else { -- cgit v1.2.3 From f0b2a493973ff8da3a648d6b08bca259e78d6481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?= Date: Thu, 26 Apr 2018 14:30:13 +0800 Subject: NET: usb: qmi_wwan: add support for ublox R410M PID 0x90b2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9306b38e42cb266f98bff6f6f4c1c652aa79ba45 upstream. This patch adds support for PID 0x90b2 of ublox R410M. qmicli -d /dev/cdc-wdm0 --dms-get-manufacturer [/dev/cdc-wdm0] Device manufacturer retrieved: Manufacturer: 'u-blox' qmicli -d /dev/cdc-wdm0 --dms-get-model [/dev/cdc-wdm0] Device model retrieved: Model: 'SARA-R410M-02B' Signed-off-by: SZ Lin (林上智) Cc: stable Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 973e90fb4a24..1029bd234c22 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -803,6 +803,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, + {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ -- cgit v1.2.3 From 7508e14f327f002093918800873e723337f0ceb7 Mon Sep 17 00:00:00 2001 From: Danit Goldberg Date: Mon, 23 Apr 2018 17:01:54 +0300 Subject: IB/mlx5: Use unlimited rate when static rate is not supported commit 4f32ac2e452c2180cd2df581cbadac183e27ecd0 upstream. Before the change, if the user passed a static rate value different than zero and the FW doesn't support static rate, it would end up configuring rate of 2.5 GBps. Fix this by using rate 0; unlimited, in cases where FW doesn't support static rate configuration. Cc: # 3.10 Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Reviewed-by: Majd Dibbiny Signed-off-by: Danit Goldberg Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/qp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 1d68c538d17e..3cdcbfbd6a79 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -2168,18 +2168,18 @@ enum { static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) { - if (rate == IB_RATE_PORT_CURRENT) { + if (rate == IB_RATE_PORT_CURRENT) return 0; - } else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) { + + if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) return -EINVAL; - } else { - while (rate != IB_RATE_2_5_GBPS && - !(1 << (rate + MLX5_STAT_RATE_OFFSET) & - MLX5_CAP_GEN(dev->mdev, stat_rate_support))) - --rate; - } - return rate + MLX5_STAT_RATE_OFFSET; + while (rate != IB_RATE_PORT_CURRENT && + !(1 << (rate + MLX5_STAT_RATE_OFFSET) & + MLX5_CAP_GEN(dev->mdev, stat_rate_support))) + --rate; + + return rate ? rate + MLX5_STAT_RATE_OFFSET : rate; } static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev, -- cgit v1.2.3 From 900ed3ec5634236a48e623ad3272ba59b0b1e842 Mon Sep 17 00:00:00 2001 From: Sebastian Sanchez Date: Tue, 1 May 2018 05:35:58 -0700 Subject: IB/hfi1: Fix NULL pointer dereference when invalid num_vls is used commit 45d924571a5e1329580811f2419da61b07ac3613 upstream. When an invalid num_vls is used as a module parameter, the code execution follows an exception path where the macro dd_dev_err() expects dd->pcidev->dev not to be NULL in hfi1_init_dd(). This causes a NULL pointer dereference. Fix hfi1_init_dd() by initializing dd->pcidev and dd->pcidev->dev earlier in the code. If a dd exists, then dd->pcidev and dd->pcidev->dev always exists. BUG: unable to handle kernel NULL pointer dereference at 00000000000000f0 IP: __dev_printk+0x15/0x90 Workqueue: events work_for_cpu_fn RIP: 0010:__dev_printk+0x15/0x90 Call Trace: dev_err+0x6c/0x90 ? hfi1_init_pportdata+0x38d/0x3f0 [hfi1] hfi1_init_dd+0xdd/0x2530 [hfi1] ? pci_conf1_read+0xb2/0xf0 ? pci_read_config_word.part.9+0x64/0x80 ? pci_conf1_write+0xb0/0xf0 ? pcie_capability_clear_and_set_word+0x57/0x80 init_one+0x141/0x490 [hfi1] local_pci_probe+0x3f/0xa0 work_for_cpu_fn+0x10/0x20 process_one_work+0x152/0x350 worker_thread+0x1cf/0x3e0 kthread+0xf5/0x130 ? max_active_store+0x80/0x80 ? kthread_bind+0x10/0x10 ? do_syscall_64+0x6e/0x1a0 ? SyS_exit_group+0x10/0x10 ret_from_fork+0x35/0x40 Cc: # 4.9.x Reviewed-by: Mike Marciniszyn Reviewed-by: Michael J. Ruhl Signed-off-by: Sebastian Sanchez Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/hfi1/init.c | 2 ++ drivers/infiniband/hw/hfi1/pcie.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 84a97f3f9299..ae1f90ddd4e8 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -1049,6 +1049,8 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) return ERR_PTR(-ENOMEM); dd->num_pports = nports; dd->pport = (struct hfi1_pportdata *)(dd + 1); + dd->pcidev = pdev; + pci_set_drvdata(pdev, dd); INIT_LIST_HEAD(&dd->list); idr_preload(GFP_KERNEL); diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 335613a1a46a..717626046ee5 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c @@ -162,9 +162,6 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev) unsigned long len; resource_size_t addr; - dd->pcidev = pdev; - pci_set_drvdata(pdev, dd); - addr = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); -- cgit v1.2.3 From 32c6a543d8a58cb4df06e103dae241d848263938 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 26 Apr 2018 09:59:30 +0200 Subject: drm/vmwgfx: Fix a buffer object leak commit 13f149d47392782baafd96d54d4e65f3b5ca342f upstream. A buffer object leak was introduced when fixing a premature buffer object release. Fix this. Cc: Fixes: 73a88250b709 ("Fix a destoy-while-held mutex problem.") Signed-off-by: Thomas Hellstrom Reviewed-by: Deepak Rawat Reviewed-by: Sinclair Yeh Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 87086af42114..33ca24ab983e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2014,6 +2014,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, out_fence, NULL); + vmw_dmabuf_unreference(&ctx->buf); vmw_resource_unreserve(res, false, NULL, 0); mutex_unlock(&res->dev_priv->cmdbuf_mutex); } -- cgit v1.2.3 From ccd174692f70da88ef5dac8292ccd3271b08643a Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 20 Apr 2018 14:59:59 -0400 Subject: drm/bridge: vga-dac: Fix edid memory leak commit 49ceda9de2da4d1827941d06701f3017c27c1855 upstream. edid should be freed once it's finished being used. Fixes: 56fe8b6f4991 ("drm/bridge: Add RGB to VGA bridge support") Cc: Rob Herring Cc: Sean Paul Cc: Maxime Ripard Cc: Archit Taneja Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: # v4.9+ Reviewed-by: Maxime Ripard Reviewed-by: Laurent Pinchart Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20180420190007.1572-1-seanpaul@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/dumb-vga-dac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c index afec232185a7..cfd80bc510b6 100644 --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c @@ -53,7 +53,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector) } drm_mode_connector_update_edid_property(connector, edid); - return drm_add_edid_modes(connector, edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + return ret; fallback: /* -- cgit v1.2.3 From ddb6f5228e6132c706719561cebf4347b930dbb5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 29 Apr 2018 17:41:55 +0200 Subject: USB: serial: visor: handle potential invalid device configuration commit 4842ed5bfcb9daf6660537d70503c18d38dbdbb8 upstream. If we get an invalid device configuration from a palm 3 type device, we might incorrectly parse things, and we have the potential to crash in "interesting" ways. Fix this up by verifying the size of the configuration passed to us by the device, and only if it is correct, will we handle it. Note that this also fixes an information leak of slab data. Reported-by: Andrey Konovalov Reviewed-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman [ johan: add comment about the info leak ] Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 69 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 337a0be89fcf..dbc3801b43eb 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_serial *serial, goto exit; } - if (retval == sizeof(*connection_info)) { - connection_info = (struct visor_connection_info *) - transfer_buffer; - - num_ports = le16_to_cpu(connection_info->num_ports); - for (i = 0; i < num_ports; ++i) { - switch ( - connection_info->connections[i].port_function_id) { - case VISOR_FUNCTION_GENERIC: - string = "Generic"; - break; - case VISOR_FUNCTION_DEBUGGER: - string = "Debugger"; - break; - case VISOR_FUNCTION_HOTSYNC: - string = "HotSync"; - break; - case VISOR_FUNCTION_CONSOLE: - string = "Console"; - break; - case VISOR_FUNCTION_REMOTE_FILE_SYS: - string = "Remote File System"; - break; - default: - string = "unknown"; - break; - } - dev_info(dev, "%s: port %d, is for %s use\n", - serial->type->description, - connection_info->connections[i].port, string); - } + if (retval != sizeof(*connection_info)) { + dev_err(dev, "Invalid connection information received from device\n"); + retval = -ENODEV; + goto exit; } - /* - * Handle devices that report invalid stuff here. - */ + + connection_info = (struct visor_connection_info *)transfer_buffer; + + num_ports = le16_to_cpu(connection_info->num_ports); + + /* Handle devices that report invalid stuff here. */ if (num_ports == 0 || num_ports > 2) { dev_warn(dev, "%s: No valid connect info available\n", serial->type->description); num_ports = 2; } + for (i = 0; i < num_ports; ++i) { + switch (connection_info->connections[i].port_function_id) { + case VISOR_FUNCTION_GENERIC: + string = "Generic"; + break; + case VISOR_FUNCTION_DEBUGGER: + string = "Debugger"; + break; + case VISOR_FUNCTION_HOTSYNC: + string = "HotSync"; + break; + case VISOR_FUNCTION_CONSOLE: + string = "Console"; + break; + case VISOR_FUNCTION_REMOTE_FILE_SYS: + string = "Remote File System"; + break; + default: + string = "unknown"; + break; + } + dev_info(dev, "%s: port %d, is for %s use\n", + serial->type->description, + connection_info->connections[i].port, string); + } dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, num_ports); -- cgit v1.2.3 From 1fac4fc6708edbad9c1a98d69958f828eb96144c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 May 2018 11:04:48 -0400 Subject: USB: Accept bulk endpoints with 1024-byte maxpacket commit fb5ee84ea72c5f1b6cabdd1c9d6e8648995ca7c6 upstream. Some non-compliant high-speed USB devices have bulk endpoints with a 1024-byte maxpacket size. Although such endpoints don't work with xHCI host controllers, they do work with EHCI controllers. We used to accept these invalid sizes (with a warning), but we no longer do because of an unintentional change introduced by commit aed9d65ac327 ("USB: validate wMaxPacketValue entries in endpoint descriptors"). This patch restores the old behavior, so that people with these peculiar devices can use them without patching their kernels by hand. Signed-off-by: Alan Stern Suggested-by: Elvinas Fixes: aed9d65ac327 ("USB: validate wMaxPacketValue entries in endpoint descriptors") CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 7c54a19b20e0..5e6136d2ed71 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -186,7 +186,9 @@ static const unsigned short full_speed_maxpacket_maxes[4] = { static const unsigned short high_speed_maxpacket_maxes[4] = { [USB_ENDPOINT_XFER_CONTROL] = 64, [USB_ENDPOINT_XFER_ISOC] = 1024, - [USB_ENDPOINT_XFER_BULK] = 512, + + /* Bulk should be 512, but some devices use 1024: we will warn below */ + [USB_ENDPOINT_XFER_BULK] = 1024, [USB_ENDPOINT_XFER_INT] = 1024, }; static const unsigned short super_speed_maxpacket_maxes[4] = { -- cgit v1.2.3 From 12b49756296bec11b319fd0e973036a4c5481dc5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 7 Mar 2018 17:40:48 +0100 Subject: USB: serial: option: reimplement interface masking commit c3a65808f04a8426481b63a4fbd9392f009f6330 upstream. Reimplement interface masking using device flags stored directly in the device-id table. This will make it easier to add and maintain device-id entries by using a more compact and readable notation compared to the current implementation (which manages pairs of masks in separate blacklist structs). Two convenience macros are used to flag an interface as either reserved or as not supporting modem-control requests: { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), .driver_info = NCTRL(0) | RSVD(3) }, For now, we limit the highest maskable interface number to seven, which allows for (up to 16) additional device flags to be added later should need arise. Note that this will likely need to be backported to stable in order to make future device-id backports more manageable. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 446 +++++++++++++++----------------------------- 1 file changed, 152 insertions(+), 294 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a1cb1ea41282..5ea92c9990c5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -551,151 +551,15 @@ static void option_instat_callback(struct urb *urb); #define WETELECOM_PRODUCT_6802 0x6802 #define WETELECOM_PRODUCT_WMD300 0x6803 -struct option_blacklist_info { - /* bitmask of interface numbers blacklisted for send_setup */ - const unsigned long sendsetup; - /* bitmask of interface numbers that are reserved */ - const unsigned long reserved; -}; -static const struct option_blacklist_info four_g_w14_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; +/* Device flags */ -static const struct option_blacklist_info four_g_w100_blacklist = { - .sendsetup = BIT(1) | BIT(2), - .reserved = BIT(3), -}; +/* Interface does not support modem-control requests */ +#define NCTRL(ifnum) ((BIT(ifnum) & 0xff) << 8) -static const struct option_blacklist_info alcatel_x200_blacklist = { - .sendsetup = BIT(0) | BIT(1), - .reserved = BIT(4), -}; +/* Interface is reserved */ +#define RSVD(ifnum) ((BIT(ifnum) & 0xff) << 0) -static const struct option_blacklist_info zte_0037_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_k3765_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info zte_mc2718_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - -static const struct option_blacklist_info zte_me3620_mbim_blacklist = { - .reserved = BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_me3620_xl_blacklist = { - .reserved = BIT(3) | BIT(4) | BIT(5), -}; - -static const struct option_blacklist_info zte_zm8620_x_blacklist = { - .reserved = BIT(3) | BIT(4) | BIT(5), -}; - -static const struct option_blacklist_info huawei_cdc12_blacklist = { - .reserved = BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info net_intf0_blacklist = { - .reserved = BIT(0), -}; - -static const struct option_blacklist_info net_intf1_blacklist = { - .reserved = BIT(1), -}; - -static const struct option_blacklist_info net_intf2_blacklist = { - .reserved = BIT(2), -}; - -static const struct option_blacklist_info net_intf3_blacklist = { - .reserved = BIT(3), -}; - -static const struct option_blacklist_info net_intf4_blacklist = { - .reserved = BIT(4), -}; - -static const struct option_blacklist_info net_intf5_blacklist = { - .reserved = BIT(5), -}; - -static const struct option_blacklist_info net_intf6_blacklist = { - .reserved = BIT(6), -}; - -static const struct option_blacklist_info zte_mf626_blacklist = { - .sendsetup = BIT(0) | BIT(1), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_1255_blacklist = { - .reserved = BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info simcom_sim7100e_blacklist = { - .reserved = BIT(5) | BIT(6), -}; - -static const struct option_blacklist_info telit_me910_blacklist = { - .sendsetup = BIT(0), - .reserved = BIT(1) | BIT(3), -}; - -static const struct option_blacklist_info telit_me910_dual_modem_blacklist = { - .sendsetup = BIT(0), - .reserved = BIT(3), -}; - -static const struct option_blacklist_info telit_le910_blacklist = { - .sendsetup = BIT(0), - .reserved = BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info telit_le920_blacklist = { - .sendsetup = BIT(0), - .reserved = BIT(1) | BIT(5), -}; - -static const struct option_blacklist_info telit_le920a4_blacklist_1 = { - .sendsetup = BIT(0), - .reserved = BIT(1), -}; - -static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { - .sendsetup = BIT(2), - .reserved = BIT(0) | BIT(1) | BIT(3), -}; - -static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = { - .sendsetup = BIT(0), - .reserved = BIT(1) | BIT(2) | BIT(3), -}; - -static const struct option_blacklist_info cinterion_rmnet2_blacklist = { - .reserved = BIT(4) | BIT(5), -}; - -static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { - .reserved = BIT(1) | BIT(4), -}; - -static const struct option_blacklist_info quectel_ep06_blacklist = { - .reserved = BIT(4) | BIT(5), -}; static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, @@ -729,26 +593,26 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + .driver_info = RSVD(1) | RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + .driver_info = RSVD(1) | RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ - .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + .driver_info = RSVD(1) | RSVD(2) }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, @@ -1193,67 +1057,67 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */ - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ /* Quectel products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, /* Yuga products use Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), - .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist }, + .driver_info = RSVD(1) | RSVD(4) }, /* Quectel products using Quectel vendor ID */ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), - .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist }, + .driver_info = RSVD(4) | RSVD(5) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213), - .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + .driver_info = RSVD(0) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, @@ -1261,38 +1125,38 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, + .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), - .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, + .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), - .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), - .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist }, + .driver_info = NCTRL(0) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), - .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), - .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(5) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208), - .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, + .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212), - .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, + .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), - .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, @@ -1308,58 +1172,58 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff), + .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_0037_blacklist }, + .driver_info = NCTRL(0) | NCTRL(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, @@ -1384,26 +1248,26 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) }, @@ -1419,50 +1283,50 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff), /* ONDA MT8205 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1579,23 +1443,23 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, + .driver_info = RSVD(3) | RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, @@ -1610,7 +1474,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, @@ -1646,17 +1510,17 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, @@ -1674,8 +1538,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), + .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ @@ -1686,20 +1550,20 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) }, @@ -1851,19 +1715,19 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, + .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) | NCTRL(4) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, + .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, + .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), - .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, + .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), - .driver_info = (kernel_ulong_t)&zte_me3620_mbim_blacklist }, + .driver_info = RSVD(2) | RSVD(3) | RSVD(4) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), - .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, + .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), - .driver_info = (kernel_ulong_t)&zte_zm8620_x_blacklist }, + .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, @@ -1883,37 +1747,34 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) }, { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E), - .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist }, + .driver_info = RSVD(5) | RSVD(6) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), - .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist - }, + .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + .driver_info = RSVD(5) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + .driver_info = RSVD(2) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), - .driver_info = (kernel_ulong_t)&four_g_w14_blacklist - }, + .driver_info = NCTRL(0) | NCTRL(1) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100), - .driver_info = (kernel_ulong_t)&four_g_w100_blacklist - }, + .driver_info = NCTRL(1) | NCTRL(2) | RSVD(3) }, {USB_DEVICE(LONGCHEER_VENDOR_ID, FUJISOFT_PRODUCT_FS040U), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist}, + .driver_info = RSVD(3)}, { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + .driver_info = RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, @@ -1939,14 +1800,14 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff), - .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist }, + .driver_info = RSVD(4) | RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, @@ -1956,20 +1817,20 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + .driver_info = RSVD(6) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, @@ -2046,9 +1907,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ @@ -2059,9 +1920,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + .driver_info = RSVD(4) }, { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ @@ -2121,7 +1982,7 @@ static int option_probe(struct usb_serial *serial, struct usb_interface_descriptor *iface_desc = &serial->interface->cur_altsetting->desc; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; - const struct option_blacklist_info *blacklist; + unsigned long device_flags = id->driver_info; /* Never bind to the CD-Rom emulation interface */ if (iface_desc->bInterfaceClass == 0x08) @@ -2132,9 +1993,7 @@ static int option_probe(struct usb_serial *serial, * the same class/subclass/protocol as the serial interfaces. Look at * the Windows driver .INF files for reserved interface numbers. */ - blacklist = (void *)id->driver_info; - if (blacklist && test_bit(iface_desc->bInterfaceNumber, - &blacklist->reserved)) + if (device_flags & RSVD(iface_desc->bInterfaceNumber)) return -ENODEV; /* * Don't bind network interface on Samsung GT-B3730, it is handled by @@ -2145,8 +2004,8 @@ static int option_probe(struct usb_serial *serial, iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; - /* Store the blacklist info so we can use it during attach. */ - usb_set_serial_data(serial, (void *)blacklist); + /* Store the device flags so we can use them during attach. */ + usb_set_serial_data(serial, (void *)device_flags); return 0; } @@ -2154,22 +2013,21 @@ static int option_probe(struct usb_serial *serial, static int option_attach(struct usb_serial *serial) { struct usb_interface_descriptor *iface_desc; - const struct option_blacklist_info *blacklist; struct usb_wwan_intf_private *data; + unsigned long device_flags; data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; - /* Retrieve blacklist info stored at probe. */ - blacklist = usb_get_serial_data(serial); + /* Retrieve device flags stored at probe. */ + device_flags = (unsigned long)usb_get_serial_data(serial); iface_desc = &serial->interface->cur_altsetting->desc; - if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, - &blacklist->sendsetup)) { + if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) data->use_send_setup = 1; - } + spin_lock_init(&data->susp_lock); usb_set_serial_data(serial, data); -- cgit v1.2.3 From 78456009fddfe7c762497aa1370c7fbf32d03e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?= Date: Thu, 26 Apr 2018 14:28:31 +0800 Subject: USB: serial: option: adding support for ublox R410M MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4205cb01f6e9ef2ae6daa7be4e8ac1edeb4c9d64 upstream. This patch adds support for ublox R410M PID 0x90b2 USB modem to option driver, this module supports LTE Cat M1 / NB1. Interface layout: 0: QCDM/DIAG 1: ADB 2: AT 3: RMNET Signed-off-by: SZ Lin (林上智) Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5ea92c9990c5..d982c455e18e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -236,6 +236,8 @@ static void option_instat_callback(struct urb *urb); /* These Quectel products use Qualcomm's vendor ID */ #define QUECTEL_PRODUCT_UC20 0x9003 #define QUECTEL_PRODUCT_UC15 0x9090 +/* These u-blox products use Qualcomm's vendor ID */ +#define UBLOX_PRODUCT_R410M 0x90b2 /* These Yuga products use Qualcomm's vendor ID */ #define YUGA_PRODUCT_CLM920_NC5 0x9625 @@ -1068,6 +1070,9 @@ static const struct usb_device_id option_ids[] = { /* Yuga products use Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), .driver_info = RSVD(1) | RSVD(4) }, + /* u-blox products using Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), + .driver_info = RSVD(1) | RSVD(3) }, /* Quectel products using Quectel vendor ID */ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), .driver_info = RSVD(4) }, -- cgit v1.2.3 From 9f3ac2e8dfc7f2b3eb6103da6711f2b0e6d1d58b Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Mon, 30 Apr 2018 11:20:53 -0500 Subject: usb: musb: host: fix potential NULL pointer dereference commit 2b63f1329df2cd814c1f8353fae4853ace6521d1 upstream. musb_start_urb() doesn't check the pass-in parameter if it is NULL. But in musb_bulk_nak_timeout() the parameter passed to musb_start_urb() is returned from first_qh(), which could be NULL. So wrap the musb_start_urb() call here with a if condition check to avoid the potential NULL pointer dereference. Fixes: f283862f3b5c ("usb: musb: NAK timeout scheme on bulk TX endpoint") Cc: stable@vger.kernel.org # v3.7+ Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 43033895e8f6..e2bc91585b4f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1023,7 +1023,9 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, /* set tx_reinit and schedule the next qh */ ep->tx_reinit = 1; } - musb_start_urb(musb, is_in, next_qh); + + if (next_qh) + musb_start_urb(musb, is_in, next_qh); } } -- cgit v1.2.3 From 097100202847a16cefc55675486b14250fbb894b Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Mon, 30 Apr 2018 11:20:54 -0500 Subject: usb: musb: trace: fix NULL pointer dereference in musb_g_tx() commit 9aea9b6cc78d2b99b23d84fb2e0bc6e464c6569e upstream. The usb_request pointer could be NULL in musb_g_tx(), where the tracepoint call would trigger the NULL pointer dereference failure when parsing the members of the usb_request pointer. Move the tracepoint call to where the usb_request pointer is already checked to solve the issue. Fixes: fc78003e5345 ("usb: musb: gadget: add usb-request tracepoints") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index a55173c9e564..f1219f6d58a9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -442,7 +442,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) req = next_request(musb_ep); request = &req->request; - trace_musb_req_tx(req); csr = musb_readw(epio, MUSB_TXCSR); musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr); @@ -481,6 +480,8 @@ void musb_g_tx(struct musb *musb, u8 epnum) u8 is_dma = 0; bool short_packet = false; + trace_musb_req_tx(req); + if (dma && (csr & MUSB_TXCSR_DMAENAB)) { is_dma = 1; csr |= MUSB_TXCSR_P_WZC_BITS; -- cgit v1.2.3 From a801ff4d8e4e84f8922694ece01193b17fe053bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Thu, 19 Apr 2018 07:04:34 -0700 Subject: platform/x86: asus-wireless: Fix NULL pointer dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9f0a93de9139c2b0a59299cd36b61564522458f8 upstream. When the module is removed the led workqueue is destroyed in the remove callback, before the led device is unregistered from the led subsystem. This leads to a NULL pointer derefence when the led device is unregistered automatically later as part of the module removal cleanup. Bellow is the backtrace showing the problem. BUG: unable to handle kernel NULL pointer dereference at (null) IP: __queue_work+0x8c/0x410 PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI Modules linked in: ccm edac_mce_amd kvm_amd kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 joydev crypto_simd asus_nb_wmi glue_helper uvcvideo snd_hda_codec_conexant snd_hda_codec_generic snd_hda_codec_hdmi snd_hda_intel asus_wmi snd_hda_codec cryptd snd_hda_core sparse_keymap videobuf2_vmalloc arc4 videobuf2_memops snd_hwdep input_leds videobuf2_v4l2 ath9k psmouse videobuf2_core videodev ath9k_common snd_pcm ath9k_hw media fam15h_power ath k10temp snd_timer mac80211 i2c_piix4 r8169 mii mac_hid cfg80211 asus_wireless(-) snd soundcore wmi shpchp 8250_dw ip_tables x_tables amdkfd amd_iommu_v2 amdgpu radeon chash i2c_algo_bit drm_kms_helper syscopyarea serio_raw sysfillrect sysimgblt fb_sys_fops ahci ttm libahci drm video CPU: 3 PID: 2177 Comm: rmmod Not tainted 4.15.0-5-generic #6+dev94.b4287e5bem1-Endless Hardware name: ASUSTeK COMPUTER INC. X555DG/X555DG, BIOS 5.011 05/05/2015 RIP: 0010:__queue_work+0x8c/0x410 RSP: 0018:ffffbe8cc249fcd8 EFLAGS: 00010086 RAX: ffff992ac6810800 RBX: 0000000000000000 RCX: 0000000000000008 RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff992ac6400e18 RBP: ffffbe8cc249fd18 R08: ffff992ac6400db0 R09: 0000000000000000 R10: 0000000000000040 R11: ffff992ac6400dd8 R12: 0000000000002000 R13: ffff992abd762e00 R14: ffff992abd763e38 R15: 000000000001ebe0 FS: 00007f318203e700(0000) GS:ffff992aced80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001c720e000 CR4: 00000000001406e0 Call Trace: queue_work_on+0x38/0x40 led_state_set+0x2c/0x40 [asus_wireless] led_set_brightness_nopm+0x14/0x40 led_set_brightness+0x37/0x60 led_trigger_set+0xfc/0x1d0 led_classdev_unregister+0x32/0xd0 devm_led_classdev_release+0x11/0x20 release_nodes+0x109/0x1f0 devres_release_all+0x3c/0x50 device_release_driver_internal+0x16d/0x220 driver_detach+0x3f/0x80 bus_remove_driver+0x55/0xd0 driver_unregister+0x2c/0x40 acpi_bus_unregister_driver+0x15/0x20 asus_wireless_driver_exit+0x10/0xb7c [asus_wireless] SyS_delete_module+0x1da/0x2b0 entry_SYSCALL_64_fastpath+0x24/0x87 RIP: 0033:0x7f3181b65fd7 RSP: 002b:00007ffe74bcbe18 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3181b65fd7 RDX: 000000000000000a RSI: 0000000000000800 RDI: 0000555ea2559258 RBP: 0000555ea25591f0 R08: 00007ffe74bcad91 R09: 000000000000000a R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000003 R13: 00007ffe74bcae00 R14: 0000000000000000 R15: 0000555ea25591f0 Code: 01 00 00 02 0f 85 7d 01 00 00 48 63 45 d4 48 c7 c6 00 f4 fa 87 49 8b 9d 08 01 00 00 48 03 1c c6 4c 89 f7 e8 87 fb ff ff 48 85 c0 <48> 8b 3b 0f 84 c5 01 00 00 48 39 f8 0f 84 bc 01 00 00 48 89 c7 RIP: __queue_work+0x8c/0x410 RSP: ffffbe8cc249fcd8 CR2: 0000000000000000 ---[ end trace 7aa4f4a232e9c39c ]--- Unregistering the led device on the remove callback before destroying the workqueue avoids this problem. https://bugzilla.kernel.org/show_bug.cgi?id=196097 Reported-by: Dun Hum Cc: stable@vger.kernel.org Signed-off-by: João Paulo Rechi Vita Signed-off-by: Darren Hart (VMware) Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/asus-wireless.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-wireless.c b/drivers/platform/x86/asus-wireless.c index 18716025b1db..c0983281fca4 100644 --- a/drivers/platform/x86/asus-wireless.c +++ b/drivers/platform/x86/asus-wireless.c @@ -145,8 +145,10 @@ static int asus_wireless_remove(struct acpi_device *adev) { struct asus_wireless_data *data = acpi_driver_data(adev); - if (data->wq) + if (data->wq) { + devm_led_classdev_unregister(&adev->dev, &data->led); destroy_workqueue(data->wq); + } return 0; } -- cgit v1.2.3 From 1899f679355d34d18447e76fa76eae16299fddda Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Wed, 8 Mar 2017 22:03:17 +0200 Subject: IB/device: Convert ib-comp-wq to be CPU-bound commit b7363e67b23e04c23c2a99437feefac7292a88bc upstream. This workqueue is used by our storage target mode ULPs via the new CQ API. Recent observations when working with very high-end flash storage devices reveal that UNBOUND workqueue threads can migrate between cpu cores and even numa nodes (although some numa locality is accounted for). While this attribute can be useful in some workloads, it does not fit in very nicely with the normal run-to-completion model we usually use in our target-mode ULPs and the block-mq irq<->cpu affinity facilities. The whole block-mq concept is that the completion will land on the same cpu where the submission was performed. The fact that our submitter thread is migrating cpus can break this locality. We assume that as a target mode ULP, we will serve multiple initiators/clients and we can spread the load enough without having to use unbound kworkers. Also, while we're at it, expose this workqueue via sysfs which is harmless and can be useful for debug. Signed-off-by: Sagi Grimberg Reviewed-by: Bart Van Assche -- Signed-off-by: Doug Ledford Cc: Raju Rangoju Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/device.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 760ef603a468..15f4bdf89fe1 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -999,8 +999,7 @@ static int __init ib_core_init(void) return -ENOMEM; ib_comp_wq = alloc_workqueue("ib-comp-wq", - WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM, - WQ_UNBOUND_MAX_ACTIVE); + WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_SYSFS, 0); if (!ib_comp_wq) { ret = -ENOMEM; goto err; -- cgit v1.2.3 From 31d04ca1eb232077e7d8032bc845bba6e6465d22 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 29 Mar 2018 13:29:12 -0500 Subject: gpioib: do not free unrequested descriptors commit ab3dbcf78f60f46d6a0ad63b1f4b690b7a427140 upstream. If the main loop in linehandle_create() encounters an error, it unwinds completely by freeing all previously requested GPIO descriptors. However, if the error occurs in the beginning of the loop before that GPIO is requested, then the exit code attempts to free a null descriptor. If extrachecks is enabled, gpiod_free() triggers a WARN_ON. Instead, keep a separate count of legitimate GPIOs so that only those are freed. Cc: stable@vger.kernel.org Fixes: d7c51b47ac11 ("gpio: userspace ABI for reading/writing GPIO lines") Reviewed-by: Bjorn Andersson Signed-off-by: Timur Tabi Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpiolib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4f54ff45e09e..68102e262922 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -425,7 +425,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) struct gpiohandle_request handlereq; struct linehandle_state *lh; struct file *file; - int fd, i, ret; + int fd, i, count = 0, ret; if (copy_from_user(&handlereq, ip, sizeof(handlereq))) return -EFAULT; @@ -471,6 +471,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) if (ret) goto out_free_descs; lh->descs[i] = desc; + count = i; if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) set_bit(FLAG_ACTIVE_LOW, &desc->flags); @@ -537,7 +538,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) out_put_unused_fd: put_unused_fd(fd); out_free_descs: - for (; i >= 0; i--) + for (i = 0; i < count; i++) gpiod_free(lh->descs[i]); kfree(lh->label); out_free_lh: -- cgit v1.2.3 From 2b0e672598f9ae572b69898cb235fbeffc3e2f8e Mon Sep 17 00:00:00 2001 From: Govert Overgaauw Date: Fri, 6 Apr 2018 14:41:35 +0200 Subject: gpio: fix aspeed_gpio unmask irq commit f241632fd087d3d9fbd5450f4d8c8604badd8348 upstream. The unmask function disables all interrupts in a bank when unmasking an interrupt. Only disable the given interrupt. Cc: stable@vger.kernel.org Signed-off-by: Govert Overgaauw Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-aspeed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 03a5925a423c..a9daf7121e6e 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -256,7 +256,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) if (set) reg |= bit; else - reg &= bit; + reg &= ~bit; iowrite32(reg, addr); spin_unlock_irqrestore(&gpio->lock, flags); -- cgit v1.2.3 From 63e2ae9d75d4c348f47600dcef0f3d90eef7f34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 16 Apr 2018 13:17:53 +0200 Subject: gpio: fix error path in lineevent_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f001cc351ad3309ec8736c374e90e5a4bc472d41 upstream. If gpiod_request() fails the cleanup must not call gpiod_free(). Cc: stable@vger.kernel.org Fixes: 61f922db7221 ("gpio: userspace ABI for reading GPIO line events") Signed-off-by: Uwe Kleine-König Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 68102e262922..56b24198741c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -795,7 +795,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) desc = &gdev->descs[offset]; ret = gpiod_request(desc, le->label); if (ret) - goto out_free_desc; + goto out_free_label; le->desc = desc; le->eflags = eflags; -- cgit v1.2.3 From b2692091a9f418ed918ed00e97f31eeb11860f27 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 26 Apr 2018 22:32:21 +0200 Subject: libata: Apply NOLPM quirk for SanDisk SD7UB3Q*G1001 SSDs commit 184add2ca23ce5edcac0ab9c3b9be13f91e7b567 upstream. Richard Jones has reported that using med_power_with_dipm on a T450s with a Sandisk SD7UB3Q256G1001 SSD (firmware version X2180501) is causing the machine to hang. Switching the LPM to max_performance fixes this, so it seems that this Sandisk SSD does not handle LPM well. Note in the past there have been bug-reports about the following Sandisk models not working with min_power, so we may need to extend the quirk list in the future: name - firmware Sandisk SD6SB2M512G1022I - X210400 Sandisk SD6PP4M-256G-1006 - A200906 Cc: stable@vger.kernel.org Cc: Richard W.M. Jones Reported-and-tested-by: Richard W.M. Jones Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e08c09fa5da0..4fe3ec122bf0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4422,6 +4422,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM, }, + /* Sandisk devices which are known to not handle LPM well */ + { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, + /* devices that don't properly handle queued TRIM commands */ { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, -- cgit v1.2.3 From 0e79ef256d4634699b2ed3b872176ceffd904be5 Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 20 Apr 2018 14:38:46 +0200 Subject: can: kvaser_usb: Increase correct stats counter in kvaser_usb_rx_can_msg() commit 6ee00865ffe4e8c8ba4a68d26db53c7ec09bbb89 upstream. Increase rx_dropped, if alloc_can_skb() fails, not tx_dropped. Signed-off-by: Jimmy Assarsson Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/usb/kvaser_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index c9d61a6dfb7a..3a75352f632b 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1179,7 +1179,7 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, skb = alloc_can_skb(priv->netdev, &cf); if (!skb) { - stats->tx_dropped++; + stats->rx_dropped++; return; } -- cgit v1.2.3 From 87994a2165ec29dbef64029b26315b1a1debf7b9 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 7 May 2018 14:13:03 +0200 Subject: drm/vc4: Fix scaling of uni-planar formats commit 9a0e9802217291e54c4dd1fc5462f189a4be14ec upstream. When using uni-planar formats (like RGB), the scaling parameters are stored in plane 0, not plane 1. Fixes: fc04023fafec ("drm/vc4: Add support for YUV planes.") Cc: stable@vger.kernel.org Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20180507121303.5610-1-boris.brezillon@bootlin.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 881bf489478b..75056553b06c 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -533,7 +533,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * the scl fields here. */ if (num_planes == 1) { - scl0 = vc4_get_scl_field(state, 1); + scl0 = vc4_get_scl_field(state, 0); scl1 = scl0; } else { scl0 = vc4_get_scl_field(state, 1); -- cgit v1.2.3 From 28d832be7e9fbf6f18e2d931db116980eee5eeff Mon Sep 17 00:00:00 2001 From: Florent Flament Date: Thu, 19 Apr 2018 19:07:00 +0300 Subject: drm/i915: Fix drm:intel_enable_lvds ERROR message in kernel log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e8f48f96db7e482995743f461b3e8a5c1a102533 upstream. Fix `[drm:intel_enable_lvds] *ERROR* timed out waiting for panel to power on` in kernel log at boot time. Toshiba Satellite Z930 laptops needs between 1 and 2 seconds to power on its screen during Intel i915 DRM initialization. This currently results in a `[drm:intel_enable_lvds] *ERROR* timed out waiting for panel to power on` message appearing in the kernel log during boot time and when stopping the machine. This change increases the timeout of the `intel_enable_lvds` function from 1 to 5 seconds, letting enough time for the Satellite 930 LCD screen to power on, and suppressing the error message from the kernel log. This patch has been successfully tested on Linux 4.14 running on a Toshiba Satellite Z930. [vsyrjala: bump the timeout from 2 to 5 seconds to match the DP code and properly cover the max hw timeout of ~4 seconds, and drop the comment about the specific machine since this is not a particulary surprising issue, nor specific to that one machine] Signed-off-by: Florent Flament Cc: stable@vger.kernel.org Cc: Pavel Petrovic Cc: Sérgio M. Basto Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103414 References: https://bugzilla.kernel.org/show_bug.cgi?id=57591 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180419160700.19828-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula (cherry picked from commit 280b54ade5914d3b4abe4f0ebe083ddbd4603246) Signed-off-by: Joonas Lahtinen Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_lvds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e1d47d51ea47..3517c0ed984a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -321,7 +321,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder, I915_WRITE(PP_CONTROL(0), I915_READ(PP_CONTROL(0)) | PANEL_POWER_ON); POSTING_READ(lvds_encoder->reg); - if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 1000)) + + if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 5000)) DRM_ERROR("timed out waiting for panel to power on\n"); intel_panel_enable_backlight(intel_connector); -- cgit v1.2.3 From ad43aede80e2faf876d6f0c4d27e462f8e0380dd Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 3 May 2018 13:17:12 -0500 Subject: atm: zatm: Fix potential Spectre v1 commit 2be147f7459db5bbf292e0a6f135037b55e20b39 upstream. pool can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability. This issue was detected with the help of Smatch: drivers/atm/zatm.c:1462 zatm_ioctl() warn: potential spectre issue 'zatm_dev->pool_info' (local cap) Fix this by sanitizing pool before using it to index zatm_dev->pool_info Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1]. [1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/atm/zatm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index d3dc95484161..81bfeec67b77 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1458,6 +1459,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) return -EFAULT; if (pool < 0 || pool > ZATM_LAST_POOL) return -EINVAL; + pool = array_index_nospec(pool, + ZATM_LAST_POOL + 1); spin_lock_irqsave(&zatm_dev->lock, flags); info = zatm_dev->pool_info[pool]; if (cmd == ZATM_GETPOOLZ) { -- cgit v1.2.3 From c7a2c159d6beff177aa9df5037b30a5a9ec08d1b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 26 Apr 2018 14:18:19 +0200 Subject: Revert "Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174" commit 544a591668813583021474fa5c7ff4942244d654 upstream. Commit f44cb4b19ed4 ("Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174") is causing bluetooth to no longer work for several people, see: https://bugzilla.redhat.com/show_bug.cgi?id=1568911 So lets revert it for now and try to find another solution for devices which need the modified quirk. Cc: stable@vger.kernel.org Cc: Takashi Iwai Signed-off-by: Hans de Goede Signed-off-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/btusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f8ba5c714df5..3257647d4f74 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -217,6 +217,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, @@ -249,7 +250,6 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, /* QCA ROME chipset */ - { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, -- cgit v1.2.3 From 3cc96a4acf139c30ff5b4d0312fddaab082db699 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 commit 88fc6f73fddf64eb507b04f7b2bd01d7291db514 upstream. 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 Signed-off-by: Greg Kroah-Hartman --- 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 ad1186dd6132..0689da4c869e 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 From 5d1639dae65f6c8b1a71a84e11d29696b7915d34 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() commit c8da6cdef57b459ac0fd5d9d348f8460a575ae90 upstream. 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 Signed-off-by: Greg Kroah-Hartman --- 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 0689da4c869e..a45810b43f70 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 From 205cd52bbee7fe6452912fe01ceade970bccc926 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 May 2018 13:30:57 +0200 Subject: 8139too: Use disable_irq_nosync() in rtl8139_poll_controller() [ Upstream commit af3e0fcf78879f718c5f73df0814951bd7057d34 ] Use disable_irq_nosync() instead of disable_irq() as this might be called in atomic context with netpoll. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/realtek/8139too.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index da4c2d8a4173..1420dfb56bac 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -2233,7 +2233,7 @@ static void rtl8139_poll_controller(struct net_device *dev) struct rtl8139_private *tp = netdev_priv(dev); const int irq = tp->pci_dev->irq; - disable_irq(irq); + disable_irq_nosync(irq); rtl8139_interrupt(irq, dev); enable_irq(irq); } -- cgit v1.2.3 From 1ed74a5b26c9d5f6e2754008d12a5117f0ac1fc2 Mon Sep 17 00:00:00 2001 From: Rob Taglang Date: Thu, 3 May 2018 17:13:06 -0400 Subject: net: ethernet: sun: niu set correct packet size in skb [ Upstream commit 14224923c3600bae2ac4dcae3bf0c3d4dc2812be ] Currently, skb->len and skb->data_len are set to the page size, not the packet size. This causes the frame check sequence to not be located at the "end" of the packet resulting in ethernet frame check errors. The driver does work currently, but stricter kernel facing networking solutions like OpenVSwitch will drop these packets as invalid. These changes set the packet size correctly so that these errors no longer occur. The length does not include the frame check sequence, so that subtraction was removed. Tested on Oracle/SUN Multithreaded 10-Gigabit Ethernet Network Controller [108e:abcd] and validated in wireshark. Signed-off-by: Rob Taglang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/sun/niu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index a2371aa14a49..e45e2f14fb94 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -3442,7 +3442,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, len = (val & RCR_ENTRY_L2_LEN) >> RCR_ENTRY_L2_LEN_SHIFT; - len -= ETH_FCS_LEN; + append_size = len + ETH_HLEN + ETH_FCS_LEN; addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << RCR_ENTRY_PKT_BUF_ADDR_SHIFT; @@ -3452,7 +3452,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, RCR_ENTRY_PKTBUFSZ_SHIFT]; off = addr & ~PAGE_MASK; - append_size = rcr_size; if (num_rcr == 1) { int ptype; @@ -3465,7 +3464,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, else skb_checksum_none_assert(skb); } else if (!(val & RCR_ENTRY_MULTI)) - append_size = len - skb->len; + append_size = append_size - skb->len; niu_rx_skb_append(skb, page, off, append_size, rcr_size); if ((page->index + rp->rbr_block_size) - rcr_size == addr) { -- cgit v1.2.3 From b26c7becd7f0c4ac7c45e0ae69cbce3e7f7bf0a7 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Tue, 1 May 2018 12:41:22 -0500 Subject: net: ethernet: ti: cpsw: fix packet leaking in dual_mac mode [ Upstream commit 5e5add172ea81152d518b161ec5706503ad3d799 ] In dual_mac mode packets arrived on one port should not be forwarded by switch hw to another port. Only Linux Host can forward packets between ports. The below test case (reported in [1]) shows that packet arrived on one port can be leaked to anoter (reproducible with dual port evms): - connect port 1 (eth0) to linux Host 0 and run tcpdump or Wireshark - connect port 2 (eth1) to linux Host 1 with vlan 1 configured - ping from Host 1 through vlan 1 interface. ARP packets will be seen on Host 0. Issue happens because dual_mac mode is implemnted using two vlans: 1 (Port 1+Port 0) and 2 (Port 2+Port 0), so there are vlan records created for for each vlan. By default, the ALE will find valid vlan record in its table when vlan 1 tagged packet arrived on Port 2 and so forwards packet to all ports which are vlan 1 members (like Port. To avoid such behaviorr the ALE VLAN ID Ingress Check need to be enabled for each external CPSW port (ALE_PORTCTLn.VID_INGRESS_CHECK) so ALE will drop ingress packets if Rx port is not VLAN member. Signed-off-by: Grygorii Strashko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ti/cpsw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index de336897a28a..d7cb205fe7e2 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1141,6 +1141,8 @@ static inline void cpsw_add_dual_emac_def_ale_entries( cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, ALE_VLAN | ALE_SECURE, slave->port_vlan); + cpsw_ale_control_set(cpsw->ale, slave_port, + ALE_PORT_DROP_UNKNOWN_VLAN, 1); } static void soft_reset_slave(struct cpsw_slave *slave) -- cgit v1.2.3 From a73d97e2ab241a867cbab2c511fb41163d1fef67 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Wed, 9 May 2018 18:35:13 +0300 Subject: net/mlx4_en: Verify coalescing parameters are in range [ Upstream commit 6ad4e91c6d796b38a7f0e724db1de28eeb122bad ] Add check of coalescing parameters received through ethtool are within range of values supported by the HW. Driver gets the coalescing rx/tx-usecs and rx/tx-frames as set by the users through ethtool. The ethtool support up to 32 bit value for each. However, mlx4 modify cq limits the coalescing time parameter and coalescing frames parameters to 16 bits. Return out of range error if user tries to set these parameters to higher values. Change type of sample-interval and adaptive_rx_coal parameters in mlx4 driver to u32 as the ethtool holds them as u32 and these parameters are not limited due to mlx4 HW. Fixes: c27a02cd94d6 ('mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC') Signed-off-by: Moshe Shemesh Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 16 ++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 7 +++++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 24977cc881d2..9a4c4f8281bd 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -970,6 +970,22 @@ static int mlx4_en_set_coalesce(struct net_device *dev, if (!coal->tx_max_coalesced_frames_irq) return -EINVAL; + if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || + coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || + coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME || + coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) { + netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n", + __func__, MLX4_EN_MAX_COAL_TIME); + return -ERANGE; + } + + if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS || + coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) { + netdev_info(dev, "%s: maximum coalesced frames supported is %d\n", + __func__, MLX4_EN_MAX_COAL_PKTS); + return -ERANGE; + } + priv->rx_frames = (coal->rx_max_coalesced_frames == MLX4_EN_AUTO_CONF) ? MLX4_EN_RX_COAL_TARGET : diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 18f221d8a04d..247d340be743 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -141,6 +141,9 @@ enum { #define MLX4_EN_TX_COAL_PKTS 16 #define MLX4_EN_TX_COAL_TIME 0x10 +#define MLX4_EN_MAX_COAL_PKTS U16_MAX +#define MLX4_EN_MAX_COAL_TIME U16_MAX + #define MLX4_EN_RX_RATE_LOW 400000 #define MLX4_EN_RX_COAL_TIME_LOW 0 #define MLX4_EN_RX_RATE_HIGH 450000 @@ -543,8 +546,8 @@ struct mlx4_en_priv { u16 rx_usecs_low; u32 pkt_rate_high; u16 rx_usecs_high; - u16 sample_interval; - u16 adaptive_rx_coal; + u32 sample_interval; + u32 adaptive_rx_coal; u32 msg_enable; u32 loopback_ok; u32 validate_loopback; -- cgit v1.2.3 From a541ccf5688da9312f690d988db14f598a4e6b71 Mon Sep 17 00:00:00 2001 From: Adi Nissim Date: Wed, 25 Apr 2018 11:21:32 +0300 Subject: net/mlx5: E-Switch, Include VF RDMA stats in vport statistics [ Upstream commit 88d725bbb43cd63a40c8ef70dd373f1d38ead2e3 ] The host side reporting of VF vport statistics didn't include the VF RDMA traffic. Fixes: 3b751a2a418a ("net/mlx5: E-Switch, Introduce get vf statistics") Signed-off-by: Adi Nissim Reported-by: Ariel Almog Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index a8966e6dbe1b..5d6eab19a9d8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1924,26 +1924,35 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, memset(vf_stats, 0, sizeof(*vf_stats)); vf_stats->rx_packets = MLX5_GET_CTR(out, received_eth_unicast.packets) + + MLX5_GET_CTR(out, received_ib_unicast.packets) + MLX5_GET_CTR(out, received_eth_multicast.packets) + + MLX5_GET_CTR(out, received_ib_multicast.packets) + MLX5_GET_CTR(out, received_eth_broadcast.packets); vf_stats->rx_bytes = MLX5_GET_CTR(out, received_eth_unicast.octets) + + MLX5_GET_CTR(out, received_ib_unicast.octets) + MLX5_GET_CTR(out, received_eth_multicast.octets) + + MLX5_GET_CTR(out, received_ib_multicast.octets) + MLX5_GET_CTR(out, received_eth_broadcast.octets); vf_stats->tx_packets = MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + + MLX5_GET_CTR(out, transmitted_ib_unicast.packets) + MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + + MLX5_GET_CTR(out, transmitted_ib_multicast.packets) + MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); vf_stats->tx_bytes = MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + + MLX5_GET_CTR(out, transmitted_ib_unicast.octets) + MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + + MLX5_GET_CTR(out, transmitted_ib_multicast.octets) + MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); vf_stats->multicast = - MLX5_GET_CTR(out, received_eth_multicast.packets); + MLX5_GET_CTR(out, received_eth_multicast.packets) + + MLX5_GET_CTR(out, received_ib_multicast.packets); vf_stats->broadcast = MLX5_GET_CTR(out, received_eth_broadcast.packets); -- cgit v1.2.3 From 7b863f6bd3c29a3d6b6a0eb766f915d32a2104c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 2 May 2018 22:22:54 +0200 Subject: qmi_wwan: do not steal interfaces from class drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5697db4a696c41601a1d15c1922150b4dbf5726c ] The USB_DEVICE_INTERFACE_NUMBER matching macro assumes that the { vendorid, productid, interfacenumber } set uniquely identifies one specific function. This has proven to fail for some configurable devices. One example is the Quectel EM06/EP06 where the same interface number can be either QMI or MBIM, without the device ID changing either. Fix by requiring the vendor-specific class for interface number based matching. Functions of other classes can and should use class based matching instead. Fixes: 03304bcb5ec4 ("net: qmi_wwan: use fixed interface number matching") Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 1029bd234c22..3e893fe890a0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1039,6 +1039,18 @@ static int qmi_wwan_probe(struct usb_interface *intf, id->driver_info = (unsigned long)&qmi_wwan_info; } + /* There are devices where the same interface number can be + * configured as different functions. We should only bind to + * vendor specific functions when matching on interface number + */ + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER && + desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) { + dev_dbg(&intf->dev, + "Rejecting interface number match for class %02x\n", + desc->bInterfaceClass); + return -ENODEV; + } + /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); -- cgit v1.2.3 From 4a5de2f99caf699145691a0d55a8812c52a7c8df Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 7 May 2018 21:11:21 +0200 Subject: r8169: fix powering up RTL8168h [ Upstream commit 3148dedfe79e422f448a10250d3e2cdf8b7ee617 ] Since commit a92a08499b1f "r8169: improve runtime pm in general and suspend unused ports" interfaces w/o link are runtime-suspended after 10s. On systems where drivers take longer to load this can lead to the situation that the interface is runtime-suspended already when it's initially brought up. This shouldn't be a problem because rtl_open() resumes MAC/PHY. However with at least one chip version the interface doesn't properly come up, as reported here: https://bugzilla.kernel.org/show_bug.cgi?id=199549 The vendor driver uses a delay to give certain chip versions some time to resume before starting the PHY configuration. So let's do the same. I don't know which chip versions may be affected, therefore apply this delay always. This patch was reported to fix the issue for RTL8168h. I was able to reproduce the issue on an Asus H310I-Plus which also uses a RTL8168h. Also in my case the patch fixed the issue. Reported-by: Slava Kardakov Tested-by: Slava Kardakov Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/realtek/r8169.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index dbb63640bc6e..59b932db0d42 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -4861,6 +4861,9 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) static void rtl_pll_power_up(struct rtl8169_private *tp) { rtl_generic_op(tp, tp->pll_power_ops.up); + + /* give MAC/PHY some time to resume */ + msleep(20); } static void rtl_init_pll_power_ops(struct rtl8169_private *tp) -- cgit v1.2.3 From d979320029f97adc7c2112d85fc626a71fe2366a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 3 May 2018 20:04:27 -0400 Subject: tg3: Fix vunmap() BUG_ON() triggered from tg3_free_consistent(). [ Upstream commit d89a2adb8bfe6f8949ff389acdb9fa298b6e8e12 ] tg3_free_consistent() calls dma_free_coherent() to free tp->hw_stats under spinlock and can trigger BUG_ON() in vunmap() because vunmap() may sleep. Fix it by removing the spinlock and relying on the TG3_FLAG_INIT_COMPLETE flag to prevent race conditions between tg3_get_stats64() and tg3_free_consistent(). TG3_FLAG_INIT_COMPLETE is always cleared under tp->lock before tg3_free_consistent() and therefore tg3_get_stats64() can safely access tp->hw_stats under tp->lock if TG3_FLAG_INIT_COMPLETE is set. Fixes: f5992b72ebe0 ("tg3: Fix race condition in tg3_get_stats64().") Reported-by: Zumeng Chen Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/tg3.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 795a133fb074..4ffbe850d746 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8720,14 +8720,15 @@ static void tg3_free_consistent(struct tg3 *tp) tg3_mem_rx_release(tp); tg3_mem_tx_release(tp); - /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ - tg3_full_lock(tp, 0); + /* tp->hw_stats can be referenced safely: + * 1. under rtnl_lock + * 2. or under tp->lock if TG3_FLAG_INIT_COMPLETE is set. + */ if (tp->hw_stats) { dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } - tg3_full_unlock(tp); } /* @@ -14161,7 +14162,7 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, struct tg3 *tp = netdev_priv(dev); spin_lock_bh(&tp->lock); - if (!tp->hw_stats) { + if (!tp->hw_stats || !tg3_flag(tp, INIT_COMPLETE)) { *stats = tp->net_stats_prev; spin_unlock_bh(&tp->lock); return stats; -- cgit v1.2.3 From 89f502a4c07ed6b9a69b6c81146f4db331224086 Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Wed, 9 May 2018 19:32:10 -0400 Subject: bonding: do not allow rlb updates to invalid mac [ Upstream commit 4fa8667ca3989ce14cf66301fa251544fbddbdd0 ] Make sure multicast, broadcast, and zero mac's cannot be the output of rlb updates, which should all be directed arps. Receive load balancing will be collapsed if any of these happen, as the switch will broadcast. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_alb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 551f0f8dead3..7b85c508c273 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -450,7 +450,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) { int i; - if (!client_info->slave) + if (!client_info->slave || !is_valid_ether_addr(client_info->mac_dst)) return; for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { -- cgit v1.2.3 From 8274cb813b5dcb27de72bf7abf0a2ebad4cf95dd Mon Sep 17 00:00:00 2001 From: Talat Batheesh Date: Sun, 15 Apr 2018 11:26:19 +0300 Subject: net/mlx5: Avoid cleaning flow steering table twice during error flow [ Upstream commit 9c26f5f89d01ca21560c6b8a8e4054c271cc3a9c ] When we fail to initialize the RX root namespace, we need to clean only that and not the entire flow steering. Currently the code may try to clean the flow steering twice on error witch leads to null pointer deference. Make sure we clean correctly. Fixes: fba53f7b5719 ("net/mlx5: Introduce mlx5_flow_steering structure") Signed-off-by: Talat Batheesh Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 331a6ca4856d..5f3402ba9916 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -153,6 +153,7 @@ static void del_rule(struct fs_node *node); static void del_flow_table(struct fs_node *node); static void del_flow_group(struct fs_node *node); static void del_fte(struct fs_node *node); +static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns); static void tree_init_node(struct fs_node *node, unsigned int refcount, @@ -1690,24 +1691,28 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) static int init_root_ns(struct mlx5_flow_steering *steering) { + int err; steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); if (!steering->root_ns) - goto cleanup; + return -ENOMEM; - if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) - goto cleanup; + err = init_root_tree(steering, &root_fs, &steering->root_ns->ns.node); + if (err) + goto out_err; set_prio_attrs(steering->root_ns); - if (create_anchor_flow_table(steering)) - goto cleanup; + err = create_anchor_flow_table(steering); + if (err) + goto out_err; return 0; -cleanup: - mlx5_cleanup_fs(steering->dev); - return -ENOMEM; +out_err: + cleanup_root_ns(steering->root_ns); + steering->root_ns = NULL; + return err; } static void clean_tree(struct fs_node *node) -- cgit v1.2.3 From d7bfa99fcc7fdc5a6669ef63c60dc4c3dacb7020 Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Wed, 9 May 2018 19:32:11 -0400 Subject: bonding: send learning packets for vlans on slave [ Upstream commit 21706ee8a47d3ede7fdae0be6d7c0a0e31a83229 ] There was a regression at some point from the intended functionality of commit f60c3704e87d ("bonding: Fix alb mode to only use first level vlans.") Given the return value vlan_get_encap_level() we need to store the nest level of the bond device, and then compare the vlan's encap level to this. Without this, this check always fails and learning packets are never sent. In addition, this same commit caused a regression in the behavior of balance_alb, which requires learning packets be sent for all interfaces using the slave's mac in order to load balance properly. For vlan's that have not set a user mac, we can send after checking one bit. Otherwise we need send the set mac, albeit defeating rx load balancing for that vlan. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_alb.c | 13 ++++++++----- drivers/net/bonding/bond_main.c | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 7b85c508c273..91d8a48e53c3 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -944,6 +944,10 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], skb->priority = TC_PRIO_CONTROL; skb->dev = slave->dev; + netdev_dbg(slave->bond->dev, + "Send learning packet: dev %s mac %pM vlan %d\n", + slave->dev->name, mac_addr, vid); + if (vid) __vlan_hwaccel_put_tag(skb, vlan_proto, vid); @@ -966,14 +970,13 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], */ rcu_read_lock(); netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { - if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { - if (strict_match && - ether_addr_equal_64bits(mac_addr, - upper->dev_addr)) { + if (is_vlan_dev(upper) && + bond->nest_level == vlan_get_encap_level(upper) - 1) { + if (upper->addr_assign_type == NET_ADDR_STOLEN) { alb_send_lp_vid(slave, mac_addr, vlan_dev_vlan_proto(upper), vlan_dev_vlan_id(upper)); - } else if (!strict_match) { + } else { alb_send_lp_vid(slave, upper->dev_addr, vlan_dev_vlan_proto(upper), vlan_dev_vlan_id(upper)); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 13a015b8052b..1a139d0f2232 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1732,6 +1732,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (bond_mode_uses_xmit_hash(bond)) bond_update_slave_arr(bond, NULL); + bond->nest_level = dev_get_nest_level(bond_dev); + netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", slave_dev->name, bond_is_active_slave(new_slave) ? "an active" : "a backup", -- cgit v1.2.3 From 8c5e7b071be1b530fc9ce574c4ccd310387ad034 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 2 Sep 2017 23:13:55 +0300 Subject: serial: sccnxp: Fix error handling in sccnxp_probe() commit c91261437985d481c472639d4397931d77f5d4e9 upstream. sccnxp_probe() returns result of regulator_disable() that may lead to returning zero, while device is not properly initialized. Also the driver enables clocks, but it does not disable it. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sccnxp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index cdd2f942317c..b9c7a904c1ea 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; uartclk = 0; } else { - clk_prepare_enable(clk); + ret = clk_prepare_enable(clk); + if (ret) + goto err_out; + + ret = devm_add_action_or_reset(&pdev->dev, + (void(*)(void *))clk_disable_unprepare, + clk); + if (ret) + goto err_out; + uartclk = clk_get_rate(clk); } @@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) uart_unregister_driver(&s->uart); err_out: if (!IS_ERR(s->regulator)) - return regulator_disable(s->regulator); + regulator_disable(s->regulator); return ret; } -- cgit v1.2.3 From 61e8f6676e598f173a540a27ce8ca09675a68535 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 23 Aug 2017 14:41:50 -0700 Subject: nfp: TX time stamp packets before HW doorbell is rung commit 46f1c52e66dbc0d7a99f7c2a3c9debb497fe7b7b upstream. TX completion may happen any time after HW queue was kicked. We can't access the skb afterwards. Move the time stamping before ringing the doorbell. Fixes: 4c3523623dc0 ("net: add driver for Netronome NFP4000/NFP6000 NIC VFs") Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller Cc: Willy Tarreau Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 4ca82bd8c4f0..eee6e59e6cf3 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -854,6 +854,8 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) netdev_tx_sent_queue(nd_q, txbuf->real_len); + skb_tx_timestamp(skb); + tx_ring->wr_p += nr_frags + 1; if (nfp_net_tx_ring_should_stop(tx_ring)) nfp_net_tx_ring_stop(nd_q, tx_ring); @@ -866,8 +868,6 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) tx_ring->wr_ptr_add = 0; } - skb_tx_timestamp(skb); - return NETDEV_TX_OK; err_unmap: -- cgit v1.2.3