5.3.7-stable review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 5.3.7-stable review
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.3.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.3.7-rc1
Oleksandr Suvorov <[email protected]>
ASoC: sgtl5000: add ADC mute control
Colin Ian King <[email protected]>
efi/tpm: Fix sanity check of unsigned tbl_size being less than zero
Jens Axboe <[email protected]>
io_uring: only flush workqueues on fileset removal
Janakarajan Natarajan <[email protected]>
x86/asm: Fix MWAITX C-state hint value
Paul Burton <[email protected]>
mtd: rawnand: au1550nd: Fix au_read_buf16() prototype
Nuno Sá <[email protected]>
hwmon: Fix HWMON_P_MIN_ALARM mask
Steven Rostedt (VMware) <[email protected]>
tracing: Get trace_array reference for available_tracers files
Steven Rostedt (VMware) <[email protected]>
ftrace: Get a reference counter for the trace_array on filter files
Srivatsa S. Bhat (VMware) <[email protected]>
tracing/hwlat: Don't ignore outer-loop duration when calculating max_latency
Srivatsa S. Bhat (VMware) <[email protected]>
tracing/hwlat: Report total time spent in all NMIs during the sample
Masayoshi Mizuma <[email protected]>
arm64/sve: Fix wrong free for task->thread.sve_state
Johan Hovold <[email protected]>
media: stkwebcam: fix runtime PM after driver unbind
Rob Clark <[email protected]>
drm/msm: Use the correct dma_sync calls harder
Chris Wilson <[email protected]>
drm/i915: Mark contents as dirty on a write fault
Kenneth Graunke <[email protected]>
drm/i915: Whitelist COMMON_SLICE_CHICKEN2
Ville Syrjälä <[email protected]>
drm/i915: Bump skl+ max plane width to 5k for linear/x-tiled
Al Viro <[email protected]>
Fix the locking in dcache_readdir() and friends
Marco Felsch <[email protected]>
iio: light: fix vcnl4000 devicetree hooks
Jeremy Linton <[email protected]>
arm64: topology: Use PPTT to determine if PE is a thread
Jeremy Linton <[email protected]>
ACPI/PPTT: Add support for ACPI 6.3 thread flag
Adit Ranadive <[email protected]>
RDMA/vmw_pvrdma: Free SRQ only once
Jiaxun Yang <[email protected]>
MIPS: elf_hwcap: Export userspace ASEs
Paul Burton <[email protected]>
MIPS: Disable Loongson MMI instructions for kernel build
Trond Myklebust <[email protected]>
NFS: Fix O_DIRECT accounting of number of bytes read/written
Josef Bacik <[email protected]>
btrfs: fix uninitialized ret in ref-verify
Josef Bacik <[email protected]>
btrfs: fix incorrect updating of log root tree
Filipe Manana <[email protected]>
Btrfs: fix memory leak due to concurrent append writes with fiemap
Zygo Blaxell <[email protected]>
btrfs: fix balance convert to single on 32-bit host CPUs
Josef Bacik <[email protected]>
btrfs: allocate new inode in NOFS context
Qu Wenruo <[email protected]>
btrfs: relocation: fix use-after-free on dead relocation roots
Bartosz Golaszewski <[email protected]>
gpiolib: don't clear FLAG_IS_OUT when emulating open-drain/open-source
Marco Felsch <[email protected]>
gpio: fix getting nonexclusive gpiods from DT
Brian Norris <[email protected]>
firmware: google: increment VPD key_len properly
Mohamad Heib <[email protected]>
IB/core: Fix wrong iterating on ports
Dan Carpenter <[email protected]>
mm/vmpressure.c: fix a signedness bug in vmpressure_register_event()
Qian Cai <[email protected]>
mm/page_alloc.c: fix a crash in free_pages_prepare()
Vitaly Wool <[email protected]>
mm/z3fold.c: claim page in the beginning of free
Michal Hocko <[email protected]>
kernel/sysctl.c: do not override max_threads provided by userspace
Dave Wysochanski <[email protected]>
cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic
Pavel Shilovsky <[email protected]>
CIFS: Force reval dentry if LOOKUP_REVAL flag is set
Pavel Shilovsky <[email protected]>
CIFS: Force revalidate inode when dentry is stale
Pavel Shilovsky <[email protected]>
CIFS: Gracefully handle QueryInfo errors during open
Ondrej Mosnacek <[email protected]>
selinux: fix context string corruption in convert_context()
Harshad Shirwadkar <[email protected]>
blk-wbt: fix performance regression in wbt scale_up/scale_down
Chris Wilson <[email protected]>
drm/i915: Perform GGTT restore much earlier during resume
Steve MacLean <[email protected]>
perf inject jit: Fix JIT_CODE_MOVE filename
Ian Rogers <[email protected]>
perf llvm: Don't access out-of-scope array
Jerry Snitselaar <[email protected]>
efi/tpm: Only set 'efi_tpm_final_log_size' after successful event log parsing
Peter Jones <[email protected]>
efi/tpm: Don't traverse an event log with no events
Peter Jones <[email protected]>
efi/tpm: Don't access event->count when it isn't mapped
Ard Biesheuvel <[email protected]>
efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified
Stefan Popa <[email protected]>
iio: accel: adxl372: Perform a reset at start up
Stefan Popa <[email protected]>
iio: accel: adxl372: Fix push to buffers lost samples
Stefan Popa <[email protected]>
iio: accel: adxl372: Fix/remove limitation for FIFO samples
Marco Felsch <[email protected]>
iio: light: add missing vcnl4040 of_compatible
David Frey <[email protected]>
iio: light: opt3001: fix mutex unlock race
Fabrice Gasnier <[email protected]>
iio: adc: stm32-adc: fix a race when using several adcs with dma and irq
Fabrice Gasnier <[email protected]>
iio: adc: stm32-adc: move registers definitions
Hans de Goede <[email protected]>
iio: adc: axp288: Override TS pin bias current for some models
Marco Felsch <[email protected]>
iio: adc: ad799x: fix probe error handling
Andreas Klinger <[email protected]>
iio: adc: hx711: fix bug in sampling of data
Navid Emamdoost <[email protected]>
staging: vt6655: Fix memory leak in vt6655_probe
Denis Efremov <[email protected]>
staging: rtl8188eu: fix HighestRate check in odm_ARFBRefresh_8188E()
Navid Emamdoost <[email protected]>
Staging: fbtft: fix memory leak in fbtft_framebuffer_alloc
Takashi Iwai <[email protected]>
staging: bcm2835-audio: Fix draining behavior regression
Noralf Trønnes <[email protected]>
staging/fbtft: Depend on OF
Bruce Chen <[email protected]>
gpio: eic: sprd: Fix the incorrect EIC offset when toggling
Alexander Usyskin <[email protected]>
mei: avoid FW version request on Ibex Peak and earlier
Tomas Winkler <[email protected]>
mei: me: add comet point (lake) LP device ids
Johan Hovold <[email protected]>
USB: legousbtower: fix use-after-free on release
Johan Hovold <[email protected]>
USB: legousbtower: fix open after failed reset request
Johan Hovold <[email protected]>
USB: legousbtower: fix potential NULL-deref on disconnect
Johan Hovold <[email protected]>
USB: legousbtower: fix deadlock on disconnect
Johan Hovold <[email protected]>
USB: legousbtower: fix slab info leak at probe
Heikki Krogerus <[email protected]>
usb: typec: ucsi: displayport: Fix for the mode entering routine
Heikki Krogerus <[email protected]>
usb: typec: ucsi: ccg: Remove run_isr flag
Dan Carpenter <[email protected]>
usb: typec: tcpm: usb: typec: tcpm: Fix a signedness bug in tcpm_fw_get_caps()
Yoshihiro Shimoda <[email protected]>
usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior
Yoshihiro Shimoda <[email protected]>
usb: renesas_usbhs: gadget: Do not discard queues in usb_ep_set_{halt,wedge}()
[email protected] <[email protected]>
USB: dummy-hcd: fix power budget for SuperSpeed mode
Johan Hovold <[email protected]>
USB: microtek: fix info-leak at probe
Johan Hovold <[email protected]>
USB: usblcd: fix I/O after disconnect
Johan Hovold <[email protected]>
USB: serial: fix runtime PM after driver unbind
Reinhard Speyerer <[email protected]>
USB: serial: option: add support for Cinterion CLS8 devices
Daniele Palmas <[email protected]>
USB: serial: option: add Telit FN980 compositions
Beni Mahler <[email protected]>
USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20
Johan Hovold <[email protected]>
USB: serial: keyspan: fix NULL-derefs on open() and write()
Michal Simek <[email protected]>
serial: uartps: Fix uartps_major handling
Randy Dunlap <[email protected]>
serial: uartlite: fix exit path null pointer
Johan Hovold <[email protected]>
USB: ldusb: fix NULL-derefs on driver unbind
Johan Hovold <[email protected]>
USB: chaoskey: fix use-after-free on release
Johan Hovold <[email protected]>
USB: usblp: fix runtime PM after driver unbind
Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free after driver unbind
Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free on release
Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free on disconnect
Johan Hovold <[email protected]>
USB: adutux: fix use-after-free on release
Johan Hovold <[email protected]>
USB: adutux: fix NULL-derefs on disconnect
Johan Hovold <[email protected]>
USB: adutux: fix use-after-free on disconnect
Mathias Nyman <[email protected]>
xhci: Fix NULL pointer dereference in xhci_clear_tt_buffer_complete()
Kai-Heng Feng <[email protected]>
xhci: Increase STS_SAVE timeout in xhci_suspend()
Bill Kuzeja <[email protected]>
xhci: Prevent deadlock when xhci adapter breaks during init
Rick Tseng <[email protected]>
usb: xhci: wait for CNR controller not ready bit in xhci resume
Mathias Nyman <[email protected]>
xhci: Fix USB 3.1 capability detection on early xHCI 1.1 spec based hosts
Jan Schmidt <[email protected]>
xhci: Check all endpoints for LPM timeout
Mathias Nyman <[email protected]>
xhci: Prevent device initiated U1/U2 link pm if exit latency is too long
Mathias Nyman <[email protected]>
xhci: Fix false warning message about wrong bounce buffer write length
Johan Hovold <[email protected]>
USB: usb-skeleton: fix NULL-deref on disconnect
Johan Hovold <[email protected]>
USB: usb-skeleton: fix runtime PM after driver unbind
Johan Hovold <[email protected]>
USB: yurex: fix NULL-derefs on disconnect
Alan Stern <[email protected]>
USB: yurex: Don't retry on unexpected errors
Bastien Nocera <[email protected]>
USB: rio500: Remove Rio 500 kernel driver
Will Deacon <[email protected]>
panic: ensure preemption is disabled during panic()
-------------
Diffstat:
Documentation/usb/rio.rst | 109 ---- MAINTAINERS | 7 - Makefile | 4 +- arch/arm/configs/badge4_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/pxa_defconfig | 1 - arch/arm/configs/s3c2410_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm64/kernel/process.c | 32 +- arch/arm64/kernel/topology.c | 19 +- arch/mips/configs/mtx1_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/include/uapi/asm/hwcap.h | 11 + arch/mips/kernel/cpu-probe.c | 33 ++ arch/mips/loongson64/Platform | 4 + arch/mips/vdso/Makefile | 1 + arch/x86/include/asm/mwait.h | 2 +- arch/x86/lib/delay.c | 4 +- block/blk-rq-qos.c | 14 +- block/blk-rq-qos.h | 4 +- block/blk-wbt.c | 6 +- drivers/acpi/pptt.c | 52 ++ drivers/firmware/efi/efi.c | 3 + drivers/firmware/efi/tpm.c | 26 +- drivers/firmware/google/vpd_decode.c | 2 +- drivers/gpio/gpio-eic-sprd.c | 7 +- drivers/gpio/gpiolib.c | 29 +- drivers/gpu/drm/i915/display/intel_display.c | 15 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 6 +- drivers/gpu/drm/i915/gem/i915_gem_pm.c | 3 - drivers/gpu/drm/i915/gt/intel_workarounds.c | 3 + drivers/gpu/drm/i915/i915_drv.c | 5 + drivers/gpu/drm/i915/selftests/i915_gem.c | 6 + drivers/gpu/drm/msm/msm_gem.c | 4 +- drivers/iio/accel/adxl372.c | 22 +- drivers/iio/adc/ad799x.c | 4 +- drivers/iio/adc/axp288_adc.c | 32 ++ drivers/iio/adc/hx711.c | 10 +- drivers/iio/adc/stm32-adc-core.c | 70 +-- drivers/iio/adc/stm32-adc-core.h | 137 +++++ drivers/iio/adc/stm32-adc.c | 109 ---- drivers/iio/light/opt3001.c | 6 +- drivers/iio/light/vcnl4000.c | 14 +- drivers/infiniband/core/security.c | 2 +- drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | 2 - drivers/media/usb/stkwebcam/stk-webcam.c | 3 +- drivers/misc/mei/bus-fixup.c | 14 +- drivers/misc/mei/hw-me-regs.h | 3 + drivers/misc/mei/hw-me.c | 21 +- drivers/misc/mei/hw-me.h | 8 +- drivers/misc/mei/mei_dev.h | 4 + drivers/misc/mei/pci-me.c | 13 +- drivers/mtd/nand/raw/au1550nd.c | 5 +- drivers/staging/fbtft/Kconfig | 2 +- drivers/staging/fbtft/fbtft-core.c | 7 +- .../staging/rtl8188eu/hal/hal8188e_rate_adaptive.c | 2 +- .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 +- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 + drivers/staging/vt6655/device_main.c | 4 +- drivers/tty/serial/uartlite.c | 3 +- drivers/tty/serial/xilinx_uartps.c | 8 +- drivers/usb/class/usblp.c | 8 +- drivers/usb/gadget/udc/dummy_hcd.c | 3 +- drivers/usb/host/xhci-ring.c | 4 +- drivers/usb/host/xhci.c | 78 ++- drivers/usb/image/microtek.c | 4 + drivers/usb/misc/Kconfig | 10 - drivers/usb/misc/Makefile | 1 - drivers/usb/misc/adutux.c | 24 +- drivers/usb/misc/chaoskey.c | 5 +- drivers/usb/misc/iowarrior.c | 16 +- drivers/usb/misc/ldusb.c | 24 +- drivers/usb/misc/legousbtower.c | 58 +-- drivers/usb/misc/rio500.c | 561 --------------------- drivers/usb/misc/rio500_usb.h | 20 - drivers/usb/misc/usblcd.c | 33 +- drivers/usb/misc/yurex.c | 18 +- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/fifo.c | 2 +- drivers/usb/renesas_usbhs/fifo.h | 1 + drivers/usb/renesas_usbhs/mod_gadget.c | 18 +- drivers/usb/renesas_usbhs/pipe.c | 15 + drivers/usb/renesas_usbhs/pipe.h | 1 + drivers/usb/serial/ftdi_sio.c | 3 + drivers/usb/serial/ftdi_sio_ids.h | 9 + drivers/usb/serial/keyspan.c | 4 +- drivers/usb/serial/option.c | 11 + drivers/usb/serial/usb-serial.c | 5 +- drivers/usb/typec/tcpm/tcpm.c | 14 +- drivers/usb/typec/ucsi/displayport.c | 2 + drivers/usb/typec/ucsi/ucsi_ccg.c | 42 +- drivers/usb/usb-skeleton.c | 15 +- fs/btrfs/file.c | 13 +- fs/btrfs/inode.c | 3 + fs/btrfs/ref-verify.c | 2 +- fs/btrfs/relocation.c | 9 +- fs/btrfs/tree-log.c | 36 +- fs/btrfs/volumes.c | 6 +- fs/cifs/dir.c | 8 +- fs/cifs/file.c | 33 +- fs/cifs/inode.c | 4 + fs/io_uring.c | 3 +- fs/libfs.c | 134 ++--- fs/nfs/direct.c | 78 +-- include/linux/acpi.h | 5 + include/linux/hwmon.h | 2 +- include/linux/tpm_eventlog.h | 16 +- kernel/fork.c | 4 +- kernel/panic.c | 1 + kernel/trace/ftrace.c | 27 +- kernel/trace/trace.c | 17 +- kernel/trace/trace_hwlat.c | 4 +- mm/page_alloc.c | 8 +- mm/vmpressure.c | 20 +- mm/z3fold.c | 10 +- security/selinux/ss/services.c | 9 +- sound/soc/codecs/sgtl5000.c | 1 + tools/perf/util/jitdump.c | 6 +- tools/perf/util/llvm-utils.c | 6 +- 119 files changed, 1117 insertions(+), 1286 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/112 panic: ensure preemption is disabled during panic()
From: Will Deacon <[email protected]>
commit 20bb759a66be52cf4a9ddd17fddaf509e11490cd upstream.
Calling 'panic()' on a kernel with CONFIG_PREEMPT=y can leave the calling CPU in an infinite loop, but with interrupts and preemption enabled. From this state, userspace can continue to be scheduled, despite the system being "dead" as far as the kernel is concerned.
This is easily reproducible on arm64 when booting with "nosmp" on the command line; a couple of shell scripts print out a periodic "Ping" message whilst another triggers a crash by writing to /proc/sysrq-trigger:
| sysrq: Trigger a crash | Kernel panic - not syncing: sysrq triggered crash | CPU: 0 PID: 1 Comm: init Not tainted 5.2.15 #1 | Hardware name: linux,dummy-virt (DT) | Call trace: | dump_backtrace+0x0/0x148 | show_stack+0x14/0x20 | dump_stack+0xa0/0xc4 | panic+0x140/0x32c | sysrq_handle_reboot+0x0/0x20 | __handle_sysrq+0x124/0x190 | write_sysrq_trigger+0x64/0x88 | proc_reg_write+0x60/0xa8 | __vfs_write+0x18/0x40 | vfs_write+0xa4/0x1b8 | ksys_write+0x64/0xf0 | __arm64_sys_write+0x14/0x20 | el0_svc_common.constprop.0+0xb0/0x168 | el0_svc_handler+0x28/0x78 | el0_svc+0x8/0xc | Kernel Offset: disabled | CPU features: 0x0002,24002004 | Memory Limit: none | ---[ end Kernel panic - not syncing: sysrq triggered crash ]--- | Ping 2! | Ping 1! | Ping 1! | Ping 2!
The issue can also be triggered on x86 kernels if CONFIG_SMP=n, otherwise local interrupts are disabled in 'smp_send_stop()'.
Disable preemption in 'panic()' before re-enabling interrupts.
--- kernel/panic.c | 1 + 1 file changed, 1 insertion(+)
kernel/panic.c +1 -0
@@ -179,6 +179,7 @@ void panic(const char *fmt, ...)* after setting panic_cpu) from invoking panic() again. */ local_irq_disable (); +preempt_disable_notrace ();/* * It's possible to come here directly from a panic-assertion and
Greg Kroah-Hartman
maintainerPATCH 2/112 USB: rio500: Remove Rio 500 kernel driver
In reply to Greg Kroah-HartmanFrom: Bastien Nocera <[email protected]>
commit 015664d15270a112c2371d812f03f7c579b35a73 upstream.
The Rio500 kernel driver has not been used by Rio500 owners since 2001 not long after the rio500 project added support for a user-space USB stack through the very first versions of usbdevfs and then libusb.
Support for the kernel driver was removed from the upstream utilities in 2008:
https://gitlab.freedesktop.org/hadess/rio500/commit/943f624ab721eb8281c287650fcc9e2026f6f5db
--- Documentation/usb/rio.rst | 109 ------- MAINTAINERS | 7 arch/arm/configs/badge4_defconfig | 1 arch/arm/configs/corgi_defconfig | 1 arch/arm/configs/pxa_defconfig | 1 arch/arm/configs/s3c2410_defconfig | 1 arch/arm/configs/spitz_defconfig | 1 arch/mips/configs/mtx1_defconfig | 1 arch/mips/configs/rm200_defconfig | 1 drivers/usb/misc/Kconfig | 10 drivers/usb/misc/Makefile | 1 drivers/usb/misc/rio500.c | 561 ------------------------------------- drivers/usb/misc/rio500_usb.h | 20 - 13 files changed, 715 deletions(-)
Documentation/usb/rio.rst deleted +0 -109
@@ -1,109 +0,0 @@ -============ -Diamonds Rio -============ - -Copyright (C) 1999, 2000 Bruce Tenison - -Portions Copyright (C) 1999, 2000 David Nelson - -Thanks to David Nelson for guidance and the usage of the scanner.txt -and scanner.c files to model our driver and this informative file. - -Mar. 2, 2000 - -Changes -======= - -- Initial Revision - - -Overview -======== - -This README will address issues regarding how to configure the kernel -to access a RIO 500 mp3 player. -Before I explain how to use this to access the Rio500 please be warned: - -.. warning:: - - Please note that this software is still under development. The authors - are in no way responsible for any damage that may occur, no matter how - inconsequential. - -It seems that the Rio has a problem when sending .mp3 with low batteries. -I suggest when the batteries are low and you want to transfer stuff that you -replace it with a fresh one. In my case, what happened is I lost two 16kb -blocks (they are no longer usable to store information to it). But I don't -know if that's normal or not; it could simply be a problem with the flash -memory. - -In an extreme case, I left my Rio playing overnight and the batteries wore -down to nothing and appear to have corrupted the flash memory. My RIO -needed to be replaced as a result. Diamond tech support is aware of the -problem. Do NOT allow your batteries to wear down to nothing before -changing them. It appears RIO 500 firmware does not handle low battery -power well at all. - -On systems with OHCI controllers, the kernel OHCI code appears to have -power on problems with some chipsets. If you are having problems -connecting to your RIO 500, try turning it on first and then plugging it -into the USB cable. - -Contact Information -------------------- - - The main page for the project is hosted at sourceforge.net in the following - URL: <http://rio500.sourceforge.net>. You can also go to the project's - sourceforge home page at: <http://sourceforge.net/projects/rio500/>. - There is also a mailing list: [email protected] - -Authors -------- - -Most of the code was written by Cesar Miquel <[email protected]>. Keith -Clayton <[email protected]> is incharge of the PPC port and making sure -things work there. Bruce Tenison <[email protected]> is adding support -for .fon files and also does testing. The program will mostly sure be -re-written and Pete Ikusz along with the rest will re-design it. I would -also like to thank Tri Nguyen <[email protected]> who provided use -with some important information regarding the communication with the Rio. - -Additional Information and userspace tools - - http://rio500.sourceforge.net/ - - -Requirements -============ - -A host with a USB port running a Linux kernel with RIO 500 support enabled. - -The driver is a module called rio500, which should be automatically loaded -as you plug in your device. If that fails you can manually load it with - - modprobe rio500 - -Udev should automatically create a device node as soon as plug in your device. -If that fails, you can manually add a device for the USB rio500:: - - mknod /dev/usb/rio500 c 180 64 - -In that case, set appropriate permissions for /dev/usb/rio500 (don't forget -about group and world permissions). Both read and write permissions are -required for proper operation. - -That's it. The Rio500 Utils at: http://rio500.sourceforge.net should -be able to access the rio500. - -Limits -====== - -You can use only a single rio500 device at a time with your computer. - -Bugs -==== - -If you encounter any problems feel free to drop me an email. - -Bruce Tenison [email protected]
MAINTAINERS +0 -7
@@ -16606,13 +16606,6 @@ W: http://www.linux-usb.org/usbnet S: Maintained F: drivers/net/usb/dm9601.c -USB DIAMOND RIO500 DRIVER -M: Cesar Miquel <[email protected]> -L: [email protected] -W: http://rio500.sourceforge.net -S: Maintained -F: drivers/usb/misc/rio500* - USB EHCI DRIVER M: Alan Stern <[email protected]> L: [email protected]
arch/arm/configs/badge4_defconfig +0 -1
@@ -91,7 +91,6 @@ CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_RIO500=m CONFIG_EXT2_FS=m CONFIG_EXT3_FS=m CONFIG_MSDOS_FS=y
arch/arm/configs/corgi_defconfig +0 -1
@@ -195,7 +195,6 @@ CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYTHERM=m
arch/arm/configs/pxa_defconfig +0 -1
@@ -581,7 +581,6 @@ CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYTHERM=m
arch/arm/configs/s3c2410_defconfig +0 -1
@@ -327,7 +327,6 @@ CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYPRESS_CY7C63=m
arch/arm/configs/spitz_defconfig +0 -1
@@ -189,7 +189,6 @@ CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYTHERM=m
arch/mips/configs/mtx1_defconfig +0 -1
@@ -571,7 +571,6 @@ CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_ADUTUX=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYPRESS_CY7C63=m
arch/mips/configs/rm200_defconfig +0 -1
@@ -315,7 +315,6 @@ CONFIG_USB_SERIAL_SAFE_PADDED=y CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYTHERM=m
drivers/usb/misc/Kconfig +0 -10
@@ -47,16 +47,6 @@ config USB_SEVSEG To compile this driver as a module, choose M here: the module will be called usbsevseg. -config USB_RIO500 - tristate "USB Diamond Rio500 support" - help - Say Y here if you want to connect a USB Rio500 mp3 player to your - computer's USB port. Please read <file:Documentation/usb/rio.rst> - for more information. - - To compile this driver as a module, choose M here: the - module will be called rio500. - config USB_LEGOTOWER tristate "USB Lego Infrared Tower support" help
drivers/usb/misc/Makefile +0 -1
@@ -17,7 +17,6 @@ obj-$(CONFIG_USB_ISIGHTFW) += isight_fi obj-$(CONFIG_USB_LCD) += usblcd.o obj-$(CONFIG_USB_LD) += ldusb.o obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o -obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_EHSET_TEST_FIXTURE) += ehset.o obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
drivers/usb/misc/rio500.c deleted +0 -561
561 lines not on this page · raw message
drivers/usb/misc/rio500_usb.h deleted +0 -20
@@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* ---------------------------------------------------------------------- -Copyright (C) 2000 Cesar Miquel ([email protected]) ----------------------------------------------------------------------- */ - -#define RIO_SEND_COMMAND 0x1 -#define RIO_RECV_COMMAND 0x2 - -#define RIO_DIR_OUT 0x0 -#define RIO_DIR_IN 0x1 - -struct RioCommand { -short length; -int request; -int requesttype; -int value; -int index; -void __user *buffer; -int timeout; -};
Greg Kroah-Hartman
maintainerPATCH 3/112 USB: yurex: Dont retry on unexpected errors
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 32a0721c6620b77504916dac0cea8ad497c4878a upstream.
According to Greg KH, it has been generally agreed that when a USB driver encounters an unknown error (or one it can't handle directly), it should just give up instead of going into a potentially infinite retry loop.
The three codes -EPROTO, -EILSEQ, and -ETIME fall into this category. They can be caused by bus errors such as packet loss or corruption, attempting to communicate with a disconnected device, or by malicious firmware. Nowadays the extent of packet loss or corruption is negligible, so it should be safe for a driver to give up whenever one of these errors occurs.
Although the yurex driver handles -EILSEQ errors in this way, it doesn't do the same for -EPROTO (as discovered by the syzbot fuzzer) or other unrecognized errors. This patch adjusts the driver so that it doesn't log an error message for -EPROTO or -ETIME, and it doesn't retry after any errors.
--- drivers/usb/misc/yurex.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/misc/yurex.c +4 -3
@@ -132,6 +132,7 @@ static void yurex_interrupt(struct urb *switch (status) {case 0 :/*success*/ break ; +/* The device is terminated or messed up, give up */ case -EOVERFLOW : dev_err(&dev->interface->dev, "%s - overflow with length %d, actual length is %d\n",
@@ -140,12 +141,13 @@ static void yurex_interrupt(struct urb *case -ENOENT :case -ESHUTDOWN :case -EILSEQ : -/* The device is terminated, clean up */ +case -EPROTO : +case -ETIME :return ;default :dev_err (&dev->interface->dev,"%s - unknown status received: %d\n" , __func__, status); - goto exit; +return ; }/* handle received message */
@@ -177,7 +179,6 @@ static void yurex_interrupt(struct urb *break ; } -exit: retval =usb_submit_urb (dev->urb,GFP_ATOMIC );if (retval) { dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n",
Greg Kroah-Hartman
maintainerPATCH 4/112 USB: yurex: fix NULL-derefs on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit aafb00a977cf7d81821f7c9d12e04c558c22dc3c upstream.
The driver was using its struct usb_interface pointer as an inverted disconnected flag, but was setting it to NULL without making sure all code paths that used it were done with it.
Before commit ef61eb43ada6 ("USB: yurex: Fix protection fault after device removal") this included the interrupt-in completion handler, but there are further accesses in dev_err and dev_dbg statements in yurex_write() and the driver-data destructor (sic!).
Fix this by unconditionally stopping also the control URB at disconnect and by using a dedicated disconnected flag.
Note that we need to take a reference to the struct usb_interface to avoid a use-after-free in the destructor whenever the device was disconnected while the character device was still open.
--- drivers/usb/misc/yurex.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/usb/misc/yurex.c +7 -4
@@ -60,6 +60,7 @@ struct usb_yurex {struct kref kref;struct mutex io_mutex; + unsigned long disconnected:1;struct fasync_struct *async_queue;wait_queue_head_t waitq;
@@ -107,6 +108,7 @@ static void yurex_delete(struct kref *kr dev->int_buffer, dev->urb->transfer_dma);usb_free_urb (dev->urb); } +usb_put_intf (dev->interface);usb_put_dev (dev->udev);kfree (dev); }
@@ -205,7 +207,7 @@ static int yurex_probe(struct usb_interfinit_waitqueue_head (&dev->waitq); dev->udev =usb_get_dev (interface_to_usbdev (interface)); - dev->interface = interface; + dev->interface =usb_get_intf (interface);/* set up the endpoint information */ iface_desc = interface->cur_altsetting;
@@ -316,8 +318,9 @@ static void yurex_disconnect(struct usb_/* prevent more I/O from starting */ usb_poison_urb (dev->urb); +usb_poison_urb (dev->cntl_urb);mutex_lock (&dev->io_mutex); - dev->interface =NULL ; + dev->disconnected =1 ;mutex_unlock (&dev->io_mutex);/* wakeup waiters */
@@ -405,7 +408,7 @@ static ssize_t yurex_read(struct file *f dev = file->private_data;mutex_lock (&dev->io_mutex); -if (!dev->interface) {/* already disconnected */ +if (dev->disconnected) {/* already disconnected */ mutex_unlock (&dev->io_mutex);return -ENODEV ; }
@@ -440,7 +443,7 @@ static ssize_t yurex_write(struct file * goto error;mutex_lock (&dev->io_mutex); -if (!dev->interface) {/* already disconnected */ +if (dev->disconnected) {/* already disconnected */ mutex_unlock (&dev->io_mutex); retval = -ENODEV ; goto error;
Greg Kroah-Hartman
maintainerPATCH 5/112 USB: usb-skeleton: fix runtime PM after driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5c290a5e42c3387e82de86965784d30e6c5270fd upstream.
Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") USB drivers must always balance their runtime PM gets and puts, including when the driver has already been unbound from the interface.
Leaving the interface with a positive PM usage counter would prevent a later bound driver from suspending the device.
--- drivers/usb/usb-skeleton.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/usb/usb-skeleton.c +3 -5
@@ -71,6 +71,7 @@ static void skel_delete(struct kref *krestruct usb_skel *dev =to_skel_dev (kref);usb_free_urb (dev->bulk_in_urb); +usb_put_intf (dev->interface);usb_put_dev (dev->udev);kfree (dev->bulk_in_buffer);kfree (dev);
@@ -122,10 +123,7 @@ static int skel_release(struct inode *inreturn -ENODEV ;/* allow the device to be autosuspended */ -mutex_lock (&dev->io_mutex); -if (dev->interface) -usb_autopm_put_interface (dev->interface); -mutex_unlock (&dev->io_mutex); +usb_autopm_put_interface (dev->interface);/* decrement the count on our device */ kref_put (&dev->kref, skel_delete);
@@ -505,7 +503,7 @@ static int skel_probe(struct usb_interfainit_waitqueue_head (&dev->bulk_in_wait); dev->udev =usb_get_dev (interface_to_usbdev (interface)); - dev->interface = interface; + dev->interface =usb_get_intf (interface);/* set up the endpoint information */ /* use only the first bulk-in and bulk-out endpoints */
Greg Kroah-Hartman
maintainerPATCH 6/112 USB: usb-skeleton: fix NULL-deref on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit bed5ef230943863b9abf5eae226a20fad9a8ff71 upstream.
The driver was using its struct usb_interface pointer as an inverted disconnected flag and was setting it to NULL before making sure all completion handlers had run. This could lead to NULL-pointer dereferences in the dev_err() statements in the completion handlers which relies on said pointer.
Fix this by using a dedicated disconnected flag.
Note that this is also addresses a NULL-pointer dereference at release() and a struct usb_interface reference leak introduced by a recent runtime PM fix, which depends on and should have been submitted together with this patch.
--- drivers/usb/usb-skeleton.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/usb-skeleton.c +4 -3
@@ -59,6 +59,7 @@ struct usb_skel {spinlock_t err_lock;/* lock for errors */ struct kref kref;struct mutex io_mutex;/* synchronize I/O with disconnect */ + unsigned long disconnected:1;wait_queue_head_t bulk_in_wait;/* to wait for an ongoing read */ };#define to_skel_dev (d) container_of(d, struct usb_skel, kref)
@@ -236,7 +237,7 @@ static ssize_t skel_read(struct file *fiif (rv <0 )return rv; -if (!dev->interface) {/* disconnect() was called */ +if (dev->disconnected) {/* disconnect() was called */ rv = -ENODEV ; goto exit; }
@@ -418,7 +419,7 @@ static ssize_t skel_write(struct file *f/* this lock makes sure we don't submit URBs to gone devices */ mutex_lock (&dev->io_mutex); -if (!dev->interface) {/* disconnect() was called */ +if (dev->disconnected) {/* disconnect() was called */ mutex_unlock (&dev->io_mutex); retval = -ENODEV ; goto error;
@@ -569,7 +570,7 @@ static void skel_disconnect(struct usb_i/* prevent more I/O from starting */ mutex_lock (&dev->io_mutex); - dev->interface =NULL ; + dev->disconnected =1 ;mutex_unlock (&dev->io_mutex);usb_kill_anchored_urbs (&dev->submitted);
Greg Kroah-Hartman
maintainerPATCH 7/112 xhci: Fix false warning message about wrong bounce buffer write length
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit c03101ff4f74bb30679c1a03d551ecbef1024bf6 upstream.
The check printing out the "WARN Wrong bounce buffer write length:" uses incorrect values when comparing bytes written from scatterlist to bounce buffer. Actual copied lengths are fine.
The used seg->bounce_len will be set to equal new_buf_len a few lines later in the code, but is incorrect when doing the comparison.
The patch which added this false warning was backported to 4.8+ kernels so this should be backported as far as well.
--- drivers/usb/host/xhci-ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/host/xhci-ring.c +2 -2
@@ -3202,10 +3202,10 @@ static int xhci_align_td(struct xhci_hcdif (usb_urb_dir_out (urb)) { len =sg_pcopy_to_buffer (urb->sg, urb->num_sgs, seg->bounce_buf, new_buff_len, enqd_len); -if (len != seg->bounce_len) +if (len != new_buff_len)xhci_warn (xhci,"WARN Wrong bounce buffer write length: %zu != %d\n" , - len, seg->bounce_len); + len, new_buff_len); seg->bounce_dma =dma_map_single (dev, seg->bounce_buf, max_pkt,DMA_TO_DEVICE ); }else {
Greg Kroah-Hartman
maintainerPATCH 8/112 xhci: Prevent device initiated U1/U2 link pm if exit latency is too long
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit cd9d9491e835a845c1a98b8471f88d26285e0bb9 upstream.
If host/hub initiated link pm is prevented by a driver flag we still must ensure that periodic endpoints have longer service intervals than link pm exit latency before allowing device initiated link pm.
Fix this by continue walking and checking endpoint service interval if xhci_get_timeout_no_hub_lpm() returns anything else than USB3_LPM_DISABLED
While at it fix the split line error message
--- drivers/usb/host/xhci.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/host/xhci.c +6 -4
@@ -4789,10 +4789,12 @@ static u16 xhci_calculate_lpm_timeout(stif (intf->dev.driver) { driver =to_usb_driver (intf->dev.driver);if (driver && driver->disable_hub_initiated_lpm) { -dev_dbg (&udev->dev,"Hub-initiated %s disabled " -"at request of driver %s\n" , - state_name, driver->name); -return xhci_get_timeout_no_hub_lpm (udev, state); +dev_dbg (&udev->dev,"Hub-initiated %s disabled at request of driver %s\n" , + state_name, driver->name); + timeout =xhci_get_timeout_no_hub_lpm (udev, + state); +if (timeout ==USB3_LPM_DISABLED ) +return timeout; } }
Greg Kroah-Hartman
maintainerPATCH 9/112 xhci: Check all endpoints for LPM timeout
In reply to Greg Kroah-HartmanFrom: Jan Schmidt <[email protected]>
commit d500c63f80f2ea08ee300e57da5f2af1c13875f5 upstream.
If an endpoint is encountered that returns USB3_LPM_DEVICE_INITIATED, keep checking further endpoints, as there might be periodic endpoints later that return USB3_LPM_DISABLED due to shorter service intervals.
Without this, the code can set too high a maximum-exit-latency and prevent the use of multiple USB3 cameras that should be able to work.
--- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/host/xhci.c +4 -4
@@ -4673,12 +4673,12 @@ static int xhci_update_timeout_for_endpo alt_timeout =xhci_call_host_update_timeout_for_endpoint (xhci, udev, desc, state, timeout); -/* If we found we can't enable hub-initiated LPM, or +/* If we found we can't enable hub-initiated LPM, and * the U1 or U2 exit latency was too high to allow -* device-initiated LPM as well, just stop searching. +* device-initiated LPM as well, then we will disable LPM +* for this device, so stop searching any further. */ -if (alt_timeout ==USB3_LPM_DISABLED || - alt_timeout ==USB3_LPM_DEVICE_INITIATED ) { +if (alt_timeout ==USB3_LPM_DISABLED ) { *timeout = alt_timeout;return -E2BIG ; }
Greg Kroah-Hartman
maintainerPATCH 10/112 xhci: Fix USB 3.1 capability detection on early xHCI 1.1 spec based hosts
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit 47f50d61076523e1a0d5a070062c2311320eeca8 upstream.
Early xHCI 1.1 spec did not mention USB 3.1 capable hosts should set sbrn to 0x31, or that the minor revision is a two digit BCD containing minor and sub-minor numbers.
This was later clarified in xHCI 1.2.
Some USB 3.1 capable hosts therefore have sbrn set to 0x30, or minor revision set to 0x1 instead of 0x10.
Detect the USB 3.1 capability correctly for these hosts as well
--- drivers/usb/host/xhci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/usb/host/xhci.c +11 -4
@@ -5078,11 +5078,18 @@ int xhci_gen_setup(struct usb_hcd *hcd, hcd->has_tt =1 ; }else {/* -* Some 3.1 hosts return sbrn 0x30, use xhci supported protocol -* minor revision instead of sbrn. Minor revision is a two digit -* BCD containing minor and sub-minor numbers, only show minor. +* Early xHCI 1.1 spec did not mention USB 3.1 capable hosts +* should return 0x31 for sbrn, or that the minor revision +* is a two digit BCD containig minor and sub-minor numbers. +* This was later clarified in xHCI 1.2. +* +* Some USB 3.1 capable hosts therefore have sbrn 0x30, and +* minor revision set to 0x1 instead of 0x10. */ - minor_rev = xhci->usb3_rhub.min_rev /0x10 ; +if (xhci->usb3_rhub.min_rev ==0x1 ) + minor_rev =1 ; +else + minor_rev = xhci->usb3_rhub.min_rev /0x10 ;switch (minor_rev) {case 2 :
Greg Kroah-Hartman
maintainerPATCH 11/112 usb: xhci: wait for CNR controller not ready bit in xhci resume
In reply to Greg Kroah-HartmanFrom: Rick Tseng <[email protected]>
commit a70bcbc322837eda1ab5994d12db941dc9733a7d upstream.
NVIDIA 3.1 xHCI card would lose power when moving power state into D3Cold. Thus we need to wait for CNR bit to clear in xhci resume, just as in xhci init.
--- drivers/usb/host/xhci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/usb/host/xhci.c +12 -0
@@ -1108,6 +1108,18 @@ int xhci_resume(struct xhci_hcd *xhci, b hibernated = true;if (!hibernated) { +/* +* Some controllers might lose power during suspend, so wait +* for controller not ready bit to clear, just as in xHC init. +*/ + retval =xhci_handshake (&xhci->op_regs->status, +STS_CNR ,0 ,10 *1000 *1000 ); +if (retval) { +xhci_warn (xhci,"Controller not ready at resume %d\n" , + retval); +spin_unlock_irq (&xhci->lock); +return retval; + }/* step 1: restore register */ xhci_restore_registers (xhci);/* step 2: initialize command ring buffer */
Greg Kroah-Hartman
maintainerPATCH 12/112 xhci: Prevent deadlock when xhci adapter breaks during init
In reply to Greg Kroah-HartmanFrom: Bill Kuzeja <[email protected]>
commit 8de66b0e6a56ff10dd00d2b0f2ae52e300178587 upstream.
The system can hit a deadlock if an xhci adapter breaks while initializing. The deadlock is between two threads: thread 1 is tearing down the adapter and is stuck in usb_unlocked_disable_lpm waiting to lock the hcd->handwidth_mutex. Thread 2 is holding this mutex (while still trying to add a usb device), but is stuck in xhci_endpoint_reset waiting for a stop or config command to complete. A reboot is required to resolve.
It turns out when calling xhci_queue_stop_endpoint and xhci_queue_configure_endpoint in xhci_endpoint_reset, the return code is not checked for errors. If the timing is right and the adapter dies just before either of these commands get issued, we hang indefinitely waiting for a completion on a command that didn't get issued.
This wasn't a problem before the following fix because we didn't send commands in xhci_endpoint_reset:
commit f5249461b504 ("xhci: Clear the host side toggle manually when
endpoint is soft reset")
With the patch I am submitting, a duration test which breaks adapters during initialization (and which deadlocks with the standard kernel) runs without issue.
--- drivers/usb/host/xhci.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.c +21 -2
@@ -3095,6 +3095,7 @@ static void xhci_endpoint_reset(struct uunsigned int ep_index;unsigned long flags;u32 ep_flag; +int err; xhci =hcd_to_xhci (hcd);if (!host_ep->hcpriv)
@@ -3154,7 +3155,17 @@ static void xhci_endpoint_reset(struct uxhci_free_command (xhci, cfg_cmd); goto cleanup; } -xhci_queue_stop_endpoint (xhci, stop_cmd, udev->slot_id, ep_index,0 ); + + err =xhci_queue_stop_endpoint (xhci, stop_cmd, udev->slot_id, + ep_index,0 ); +if (err <0 ) { +spin_unlock_irqrestore (&xhci->lock, flags); +xhci_free_command (xhci, cfg_cmd); +xhci_dbg (xhci,"%s: Failed to queue stop ep command, %d " , + __func__, err); + goto cleanup; + } +xhci_ring_cmd_db (xhci);spin_unlock_irqrestore (&xhci->lock, flags);
@@ -3168,8 +3179,16 @@ static void xhci_endpoint_reset(struct u ctrl_ctx, ep_flag, ep_flag);xhci_endpoint_copy (xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index); -xhci_queue_configure_endpoint (xhci, cfg_cmd, cfg_cmd->in_ctx->dma, + err =xhci_queue_configure_endpoint (xhci, cfg_cmd, cfg_cmd->in_ctx->dma, udev->slot_id, false); +if (err <0 ) { +spin_unlock_irqrestore (&xhci->lock, flags); +xhci_free_command (xhci, cfg_cmd); +xhci_dbg (xhci,"%s: Failed to queue config ep command, %d " , + __func__, err); + goto cleanup; + } +xhci_ring_cmd_db (xhci);spin_unlock_irqrestore (&xhci->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 13/112 xhci: Increase STS_SAVE timeout in xhci_suspend()
In reply to Greg Kroah-HartmanFrom: Kai-Heng Feng <[email protected]>
commit ac343366846a445bb81f0a0e8f16abb8bd5d5d88 upstream.
After commit f7fac17ca925 ("xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()"), ASMedia xHCI may fail to suspend.
Although the algorithms are essentially the same, the old max timeout is (usec + usec * time of doing readl()), and the new max timeout is just usec, which is much less than the old one.
Increase the timeout to make ASMedia xHCI able to suspend again.
--- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci.c +1 -1
@@ -1032,7 +1032,7 @@ int xhci_suspend(struct xhci_hcd *xhci,writel (command, &xhci->op_regs->command); xhci->broken_suspend =0 ;if (xhci_handshake (&xhci->op_regs->status, -STS_SAVE ,0 ,10 *1000 )) { +STS_SAVE ,0 ,20 *1000 )) {/* * AMD SNPS xHC 3.0 occasionally does not clear the * SSS bit of USBSTS and when driver tries to poll
Greg Kroah-Hartman
maintainerPATCH 14/112 xhci: Fix NULL pointer dereference in xhci_clear_tt_buffer_complete()
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit cfbb8a84c2d2ef49bccacb511002bca4f6053555 upstream.
udev stored in ep->hcpriv might be NULL if tt buffer is cleared due to a halted control endpoint during device enumeration
xhci_clear_tt_buffer_complete is called by hub_tt_work() once it's scheduled, and by then usb core might have freed and allocated a new udev for the next enumeration attempt.
--- drivers/usb/host/xhci.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/usb/host/xhci.c +8 -0
@@ -5237,8 +5237,16 @@ static void xhci_clear_tt_buffer_completunsigned int ep_index;unsigned long flags; +/* +* udev might be NULL if tt buffer is cleared during a failed device +* enumeration due to a halted control endpoint. Usb core might +* have allocated a new udev for the next enumeration attempt. +*/ + xhci =hcd_to_xhci (hcd); udev = (struct usb_device *)ep->hcpriv; +if (!udev) +return ; slot_id = udev->slot_id; ep_index =xhci_get_endpoint_index (&ep->desc);
Greg Kroah-Hartman
maintainerPATCH 15/112 USB: adutux: fix use-after-free on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 44efc269db7929f6275a1fa927ef082e533ecde0 upstream.
The driver was clearing its struct usb_device pointer, which it used as an inverted disconnected flag, before deregistering the character device and without serialising against racing release().
This could lead to a use-after-free if a racing release() callback observes the cleared pointer and frees the driver data before disconnect() is finished with it.
This could also lead to NULL-pointer dereferences in a racing open().
--- drivers/usb/misc/adutux.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/misc/adutux.c +4 -3
@@ -762,14 +762,15 @@ static void adu_disconnect(struct usb_in dev =usb_get_intfdata (interface); -mutex_lock (&dev->mtx);/* not interruptible */ - dev->udev =NULL ;/* poison */ usb_deregister_dev (interface, &adu_class); -mutex_unlock (&dev->mtx);mutex_lock (&adutux_mutex);usb_set_intfdata (interface,NULL ); +mutex_lock (&dev->mtx);/* not interruptible */ + dev->udev =NULL ;/* poison */ +mutex_unlock (&dev->mtx); +/* if the device is not opened, then we clean up right now */ if (!dev->open_count)adu_delete (dev);
Greg Kroah-Hartman
maintainerPATCH 16/112 USB: adutux: fix NULL-derefs on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 upstream.
The driver was using its struct usb_device pointer as an inverted disconnected flag, but was setting it to NULL before making sure all completion handlers had run. This could lead to a NULL-pointer dereference in a number of dev_dbg statements in the completion handlers which relies on said pointer.
The pointer was also dereferenced unconditionally in a dev_dbg statement release() something which would lead to a NULL-deref whenever a device was disconnected before the final character-device close if debugging was enabled.
Fix this by unconditionally stopping all I/O and preventing resubmissions by poisoning the interrupt URBs at disconnect and using a dedicated disconnected flag.
This also makes sure that all I/O has completed by the time the disconnect callback returns.
--- drivers/usb/misc/adutux.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/usb/misc/adutux.c +10 -6
@@ -75,6 +75,7 @@ struct adu_device {char serial_number[8 ];int open_count;/* number of times this port has been opened */ + unsigned long disconnected:1;char *read_buffer_primary;int read_buffer_length;
@@ -116,7 +117,7 @@ static void adu_abort_transfers(struct a {unsigned long flags; -if (dev->udev ==NULL ) +if (dev->disconnected)return ;/* shutdown transfer */
@@ -243,7 +244,7 @@ static int adu_open(struct inode *inode, } dev =usb_get_intfdata (interface); -if (!dev || !dev->udev) { +if (!dev) { retval = -ENODEV ; goto exit_no_device; }
@@ -326,7 +327,7 @@ static int adu_release(struct inode *ino }adu_release_internal (dev); -if (dev->udev ==NULL ) { +if (dev->disconnected) {/* the device was unplugged before the file was released */ if (!dev->open_count)/* ... and we're the last user */ adu_delete (dev);
@@ -354,7 +355,7 @@ static ssize_t adu_read(struct file *filreturn -ERESTARTSYS ;/* verify that the device wasn't unplugged */ -if (dev->udev ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;pr_err ("No device or device unplugged %d\n" , retval); goto exit;
@@ -518,7 +519,7 @@ static ssize_t adu_write(struct file *fi goto exit_nolock;/* verify that the device wasn't unplugged */ -if (dev->udev ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;pr_err ("No device or device unplugged %d\n" , retval); goto exit;
@@ -764,11 +765,14 @@ static void adu_disconnect(struct usb_inusb_deregister_dev (interface, &adu_class); +usb_poison_urb (dev->interrupt_in_urb); +usb_poison_urb (dev->interrupt_out_urb); +mutex_lock (&adutux_mutex);usb_set_intfdata (interface,NULL );mutex_lock (&dev->mtx);/* not interruptible */ - dev->udev =NULL ;/* poison */ + dev->disconnected =1 ;mutex_unlock (&dev->mtx);/* if the device is not opened, then we clean up right now */
Greg Kroah-Hartman
maintainerPATCH 17/112 USB: adutux: fix use-after-free on release
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 123a0f125fa3d2104043697baa62899d9e549272 upstream.
The driver was accessing its struct usb_device in its release() callback without holding a reference. This would lead to a use-after-free whenever the device was disconnected while the character device was still open.
--- drivers/usb/misc/adutux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/misc/adutux.c +2 -1
@@ -149,6 +149,7 @@ static void adu_delete(struct adu_devicekfree (dev->read_buffer_secondary);kfree (dev->interrupt_in_buffer);kfree (dev->interrupt_out_buffer); +usb_put_dev (dev->udev);kfree (dev); }
@@ -664,7 +665,7 @@ static int adu_probe(struct usb_interfacmutex_init (&dev->mtx);spin_lock_init (&dev->buflock); - dev->udev = udev; + dev->udev =usb_get_dev (udev);init_waitqueue_head (&dev->read_wait);init_waitqueue_head (&dev->write_wait);
Greg Kroah-Hartman
maintainerPATCH 18/112 USB: iowarrior: fix use-after-free on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit edc4746f253d907d048de680a621e121517f484b upstream.
A recent fix addressing a deadlock on disconnect introduced a new bug by moving the present flag out of the critical section protected by the driver-data mutex. This could lead to a racing release() freeing the driver data before disconnect() is done with it.
Due to insufficient locking a related use-after-free could be triggered also before the above mentioned commit. Specifically, the driver needs to hold the driver-data mutex also while checking the opened flag at disconnect().
--- drivers/usb/misc/iowarrior.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/usb/misc/iowarrior.c +3 -4
@@ -866,8 +866,6 @@ static void iowarrior_disconnect(struct dev =usb_get_intfdata (interface);mutex_lock (&iowarrior_open_disc_lock);usb_set_intfdata (interface,NULL ); -/* prevent device read, write and ioctl */ - dev->present =0 ; minor = dev->minor;mutex_unlock (&iowarrior_open_disc_lock);
@@ -878,8 +876,7 @@ static void iowarrior_disconnect(structmutex_lock (&dev->mutex);/* prevent device read, write and ioctl */ - -mutex_unlock (&dev->mutex); + dev->present =0 ;if (dev->opened) {/* There is a process that holds a filedescriptor to the device ,
@@ -889,8 +886,10 @@ static void iowarrior_disconnect(structusb_kill_urb (dev->int_in_urb);wake_up_interruptible (&dev->read_wait);wake_up_interruptible (&dev->write_wait); +mutex_unlock (&dev->mutex); }else {/* no process is using the device, cleanup now */ +mutex_unlock (&dev->mutex);iowarrior_delete (dev); }
Greg Kroah-Hartman
maintainerPATCH 19/112 USB: iowarrior: fix use-after-free on release
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 80cd5479b525093a56ef768553045741af61b250 upstream.
The driver was accessing its struct usb_interface from its release() callback without holding a reference. This would lead to a use-after-free whenever debugging was enabled and the device was disconnected while its character device was open.
--- drivers/usb/misc/iowarrior.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/misc/iowarrior.c +2 -1
@@ -243,6 +243,7 @@ static inline void iowarrior_delete(strukfree (dev->int_in_buffer);usb_free_urb (dev->int_in_urb);kfree (dev->read_queue); +usb_put_intf (dev->interface);kfree (dev); }
@@ -764,7 +765,7 @@ static int iowarrior_probe(struct usb_ininit_waitqueue_head (&dev->write_wait); dev->udev = udev; - dev->interface = interface; + dev->interface =usb_get_intf (interface); iface_desc = interface->cur_altsetting; dev->product_id =le16_to_cpu (udev->descriptor.idProduct);
Greg Kroah-Hartman
maintainerPATCH 20/112 USB: iowarrior: fix use-after-free after driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit b5f8d46867ca233d773408ffbe691a8062ed718f upstream.
Make sure to stop also the asynchronous write URBs on disconnect() to avoid use-after-free in the completion handler after driver unbind.
--- drivers/usb/misc/iowarrior.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/misc/iowarrior.c +6 -0
@@ -87,6 +87,7 @@ struct iowarrior {char chip_serial[9 ];/* the serial number string of the chip connected */ int report_size;/* number of bytes in a report */ u16 product_id; +struct usb_anchor submitted; };/*--------------*/
@@ -425,11 +426,13 @@ static ssize_t iowarrior_write(struct fi retval = -EFAULT ; goto error; } +usb_anchor_urb (int_out_urb, &dev->submitted); retval =usb_submit_urb (int_out_urb,GFP_KERNEL );if (retval) {dev_dbg (&dev->interface->dev,"submit error %d for urb nr.%d\n" , retval,atomic_read (&dev->write_busy)); +usb_unanchor_urb (int_out_urb); goto error; }/* submit was ok */
@@ -770,6 +773,8 @@ static int iowarrior_probe(struct usb_in iface_desc = interface->cur_altsetting; dev->product_id =le16_to_cpu (udev->descriptor.idProduct); +init_usb_anchor (&dev->submitted); + res =usb_find_last_int_in_endpoint (iface_desc, &dev->int_in_endpoint);if (res) {dev_err (&interface->dev,"no interrupt-in endpoint found\n" );
@@ -885,6 +890,7 @@ static void iowarrior_disconnect(structDeleting the device is postponed until close() was called. */ usb_kill_urb (dev->int_in_urb); +usb_kill_anchored_urbs (&dev->submitted);wake_up_interruptible (&dev->read_wait);wake_up_interruptible (&dev->write_wait);mutex_unlock (&dev->mutex);
Greg Kroah-Hartman
maintainerPATCH 21/112 USB: usblp: fix runtime PM after driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 upstream.
Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") USB drivers must always balance their runtime PM gets and puts, including when the driver has already been unbound from the interface.
Leaving the interface with a positive PM usage counter would prevent a later bound driver from suspending the device.
--- drivers/usb/class/usblp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/usb/class/usblp.c +5 -3
@@ -461,10 +461,12 @@ static int usblp_release(struct inode *imutex_lock (&usblp_mutex); usblp->used =0 ; -if (usblp->present) { +if (usblp->present)usblp_unlink_urbs (usblp); -usb_autopm_put_interface (usblp->intf); - }else /* finish cleanup from disconnect */ + +usb_autopm_put_interface (usblp->intf); + +if (!usblp->present)/* finish cleanup from disconnect */ usblp_cleanup (usblp);mutex_unlock (&usblp_mutex);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 22/112 USB: chaoskey: fix use-after-free on release
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 93ddb1f56ae102f14f9e46a9a9c8017faa970003 upstream.
The driver was accessing its struct usb_interface in its release() callback without holding a reference. This would lead to a use-after-free whenever the device was disconnected while the character device was still open.
--- drivers/usb/misc/chaoskey.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/misc/chaoskey.c +3 -2
@@ -98,6 +98,7 @@ static void chaoskey_free(struct chaoskeusb_free_urb (dev->urb);kfree (dev->name);kfree (dev->buf); +usb_put_intf (dev->interface);kfree (dev); } }
@@ -145,6 +146,8 @@ static int chaoskey_probe(struct usb_intif (dev ==NULL ) goto out; + dev->interface =usb_get_intf (interface); + dev->buf =kmalloc (size,GFP_KERNEL );if (dev->buf ==NULL )
@@ -174,8 +177,6 @@ static int chaoskey_probe(struct usb_int goto out; } - dev->interface = interface; - dev->in_ep = in_ep;if (le16_to_cpu (udev->descriptor.idVendor) !=ALEA_VENDOR_ID )
Greg Kroah-Hartman
maintainerPATCH 23/112 USB: ldusb: fix NULL-derefs on driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 58ecf131e74620305175a7aa103f81350bb37570 upstream.
The driver was using its struct usb_interface pointer as an inverted disconnected flag, but was setting it to NULL before making sure all completion handlers had run. This could lead to a NULL-pointer dereference in a number of dev_dbg, dev_warn and dev_err statements in the completion handlers which relies on said pointer.
Fix this by unconditionally stopping all I/O and preventing resubmissions by poisoning the interrupt URBs at disconnect and using a dedicated disconnected flag.
This also makes sure that all I/O has completed by the time the disconnect callback returns.
--- drivers/usb/misc/ldusb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/usb/misc/ldusb.c +12 -12
@@ -153,6 +153,7 @@ MODULE_PARM_DESC(min_interrupt_out_interstruct ld_usb {struct mutex mutex;/* locks this structure */ struct usb_interface *intf;/* save off the usb interface pointer */ +unsigned long disconnected:1 ;int open_count;/* number of times this port has been opened */
@@ -192,12 +193,10 @@ static void ld_usb_abort_transfers(struc/* shutdown transfer */ if (dev->interrupt_in_running) { dev->interrupt_in_running =0 ; -if (dev->intf) -usb_kill_urb (dev->interrupt_in_urb); +usb_kill_urb (dev->interrupt_in_urb); }if (dev->interrupt_out_busy) -if (dev->intf) -usb_kill_urb (dev->interrupt_out_urb); +usb_kill_urb (dev->interrupt_out_urb); }/**
@@ -205,8 +204,6 @@ static void ld_usb_abort_transfers(struc*/ static void ld_usb_delete (struct ld_usb *dev) { -ld_usb_abort_transfers (dev); -/* free data structures */ usb_free_urb (dev->interrupt_in_urb);usb_free_urb (dev->interrupt_out_urb);
@@ -263,7 +260,7 @@ static void ld_usb_interrupt_in_callback resubmit:/* resubmit if we're still running */ -if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) { +if (dev->interrupt_in_running && !dev->buffer_overflow) { retval =usb_submit_urb (dev->interrupt_in_urb,GFP_ATOMIC );if (retval) { dev_err(&dev->intf->dev,
@@ -392,7 +389,7 @@ static int ld_usb_release(struct inode * retval = -ENODEV ; goto unlock_exit; } -if (dev->intf ==NULL ) { +if (dev->disconnected) {/* the device was unplugged before the file was released */ mutex_unlock (&dev->mutex);/* unlock here as ld_usb_delete frees dev */
@@ -423,7 +420,7 @@ static __poll_t ld_usb_poll(struct file dev = file->private_data; -if (!dev->intf) +if (dev->disconnected)return EPOLLERR |EPOLLHUP ;poll_wait (file, &dev->read_wait, wait);
@@ -462,7 +459,7 @@ static ssize_t ld_usb_read(struct file * }/* verify that the device wasn't unplugged */ -if (dev->intf ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;printk (KERN_ERR "ldusb: No device or device unplugged %d\n" , retval); goto unlock_exit;
@@ -542,7 +539,7 @@ static ssize_t ld_usb_write(struct file }/* verify that the device wasn't unplugged */ -if (dev->intf ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;printk (KERN_ERR "ldusb: No device or device unplugged %d\n" , retval); goto unlock_exit;
@@ -764,6 +761,9 @@ static void ld_usb_disconnect(struct usb/* give back our minor */ usb_deregister_dev (intf, &ld_usb_class); +usb_poison_urb (dev->interrupt_in_urb); +usb_poison_urb (dev->interrupt_out_urb); +mutex_lock (&dev->mutex);/* if the device is not opened, then we clean up right now */
@@ -771,7 +771,7 @@ static void ld_usb_disconnect(struct usbmutex_unlock (&dev->mutex);ld_usb_delete (dev); }else { - dev->intf =NULL ; + dev->disconnected =1 ;/* wake up pollers */ wake_up_interruptible_all (&dev->read_wait);wake_up_interruptible_all (&dev->write_wait);
Greg Kroah-Hartman
maintainerPATCH 24/112 serial: uartlite: fix exit path null pointer
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit a553add0846f355a28ed4e81134012e4a1e280c2 upstream.
Call uart_unregister_driver() conditionally instead of unconditionally, only if it has been previously registered.
This uses driver.state, just as the sh-sci.c driver does.
Fixes this null pointer dereference in tty_unregister_driver(), since the 'driver' argument is null:
general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI RIP: 0010:tty_unregister_driver+0x25/0x1d0
--- drivers/tty/serial/uartlite.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/uartlite.c +2 -1
@@ -897,7 +897,8 @@ static int __init ulite_init(void) static void __exit ulite_exit(void) {platform_driver_unregister (&ulite_platform_driver); -uart_unregister_driver (&ulite_uart_driver); +if (ulite_uart_driver.state) +uart_unregister_driver (&ulite_uart_driver); }module_init (ulite_init);
Greg Kroah-Hartman
maintainerPATCH 25/112 serial: uartps: Fix uartps_major handling
In reply to Greg Kroah-HartmanFrom: Michal Simek <[email protected]>
commit 5e9bd2d70ae7c00a95a22994abf1eef728649e64 upstream.
There are two parts which should be fixed. The first one is to assigned uartps_major at the end of probe() to avoid complicated logic when something fails.
The second part is initialized uartps_major number to 0 when last device is removed. This will ensure that on next probe driver will ask for new dynamic major number.
--- drivers/tty/serial/xilinx_uartps.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/tty/serial/xilinx_uartps.c +7 -1
@@ -1550,7 +1550,6 @@ static int cdns_uart_probe(struct platfo goto err_out_id; } - uartps_major = cdns_uart_uart_driver->tty_driver->major; cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;/*
@@ -1680,6 +1679,7 @@ static int cdns_uart_probe(struct platfo console_port =NULL ;#endif + uartps_major = cdns_uart_uart_driver->tty_driver->major; cdns_uart_data->cts_override =of_property_read_bool (pdev->dev.of_node,"cts-override" );return 0 ;
@@ -1741,6 +1741,12 @@ static int cdns_uart_remove(struct platf console_port =NULL ;#endif +/* If this is last instance major number should be initialized */ +mutex_lock (&bitmap_lock); +if (bitmap_empty (bitmap,MAX_UART_INSTANCES )) + uartps_major =0 ; +mutex_unlock (&bitmap_lock); +uart_unregister_driver (cdns_uart_data->cdns_uart_driver);return rc; }
Greg Kroah-Hartman
maintainerPATCH 26/112 USB: serial: keyspan: fix NULL-derefs on open() and write()
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 upstream.
Fix NULL-pointer dereferences on open() and write() which can be triggered by a malicious USB device.
The current URB allocation helper would fail to initialise the newly allocated URB if the device has unexpected endpoint descriptors, something which could lead NULL-pointer dereferences in a number of open() and write() paths when accessing the URB. For example:
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:usb_clear_halt+0x11/0xc0 ... Call Trace: ? tty_port_open+0x4d/0xd0 keyspan_open+0x70/0x160 [keyspan] serial_port_activate+0x5b/0x80 [usbserial] tty_port_open+0x7b/0xd0 ? check_tty_count+0x43/0xa0 tty_open+0xf1/0x490 BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:keyspan_write+0x14e/0x1f3 [keyspan] ... Call Trace: serial_write+0x43/0xa0 [usbserial] n_tty_write+0x1af/0x4f0 ? do_wait_intr_irq+0x80/0x80 ? process_echoes+0x60/0x60 tty_write+0x13f/0x2f0 BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:keyspan_usa26_send_setup+0x298/0x305 [keyspan] ... Call Trace: keyspan_open+0x10f/0x160 [keyspan] serial_port_activate+0x5b/0x80 [usbserial] tty_port_open+0x7b/0xd0 ? check_tty_count+0x43/0xa0 tty_open+0xf1/0x490
--- drivers/usb/serial/keyspan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/serial/keyspan.c +2 -2
@@ -1741,8 +1741,8 @@ static struct urb *keyspan_setup_urb(str ep_desc =find_ep (serial, endpoint);if (!ep_desc) { -/* leak the urb, something's wrong and the callers don't care */ -return urb; +usb_free_urb (urb); +return NULL ; }if (usb_endpoint_xfer_int (ep_desc)) { ep_type_name ="INT" ;
Greg Kroah-Hartman
maintainerPATCH 27/112 USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20
In reply to Greg Kroah-HartmanFrom: Beni Mahler <[email protected]>
commit 357f16d9e0194cdbc36531ff88b453481560b76a upstream.
Both devices added here have a FTDI chip inside. The device from Echelon is called 'Network Interface' it is actually a LON network gateway.
ID 0403:8348 Future Technology Devices International, Ltd
https://www.eltako.com/fileadmin/downloads/de/datenblatt/Datenblatt_PL-SW-PROF.pdf
ID 0920:7500 Network Interface
https://www.echelon.com/products/u20-usb-network-interface
--- drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio_ids.h | 9 +++++++++ 2 files changed, 12 insertions(+)
drivers/usb/serial/ftdi_sio.c +3 -0
@@ -1030,6 +1030,9 @@ static const struct usb_device_id id_tab/* EZPrototypes devices */ { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, +/* Sienna devices */ + { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, + { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, { } /* Terminating entry */ };
drivers/usb/serial/ftdi_sio_ids.h +9 -0
@@ -39,6 +39,9 @@#define FTDI_LUMEL_PD12_PID 0x6002 +/* Sienna Serial Interface by Secyourit GmbH */ +#define FTDI_SIENNA_PID 0x8348 +/* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */ #define CYBER_CORTEX_AV_PID 0x8698
@@ -689,6 +692,12 @@#define BANDB_ZZ_PROG1_USB_PID 0xBA02/* +* Echelon USB Serial Interface +*/ +#define ECHELON_VID 0x0920 +#define ECHELON_U20_PID 0x7500 + +/* * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI */ #define INTREPID_VID 0x093C
Greg Kroah-Hartman
maintainerPATCH 28/112 USB: serial: option: add Telit FN980 compositions
In reply to Greg Kroah-HartmanFrom: Daniele Palmas <[email protected]>
commit 5eb3f4b87a0e7e949c976f32f296176a06d1a93b upstream.
This patch adds the following Telit FN980 compositions:
0x1050: tty, adb, rmnet, tty, tty, tty, tty 0x1051: tty, adb, mbim, tty, tty, tty, tty 0x1052: rndis, tty, adb, tty, tty, tty, tty 0x1053: tty, adb, ecm, tty, tty, tty, tty
--- drivers/usb/serial/option.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/usb/serial/option.c +8 -0
@@ -1154,6 +1154,14 @@ static const struct usb_device_id option .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff), .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1050, 0xff), /* Telit FN980 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1051, 0xff), /* Telit FN980 (MBIM) */ + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1052, 0xff), /* Telit FN980 (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1053, 0xff), /* Telit FN980 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
Greg Kroah-Hartman
maintainerPATCH 29/112 USB: serial: option: add support for Cinterion CLS8 devices
In reply to Greg Kroah-HartmanFrom: Reinhard Speyerer <[email protected]>
commit dfbac2f4da6a0c4a8f6b4d715a4077a7b8df53ad upstream.
Add support for the serial ports of Cinterion CLS8 devices.
T: Bus=01 Lev=03 Prnt=05 Port=01 Cnt=02 Dev#= 25 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1e2d ProdID=00b0 Rev= 3.18 S: Manufacturer=GEMALTO S: Product=USB Modem C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/option.c +3 -0
@@ -419,6 +419,7 @@ static void option_instat_callback(struc#define CINTERION_PRODUCT_PH8_AUDIO 0x0083#define CINTERION_PRODUCT_AHXX_2RMNET 0x0084#define CINTERION_PRODUCT_AHXX_AUDIO 0x0085 +#define CINTERION_PRODUCT_CLS8 0x00b0/* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c
@@ -1855,6 +1856,8 @@ static const struct usb_device_id option .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_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff), + .driver_info = RSVD(0) | RSVD(4) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
Greg Kroah-Hartman
maintainerPATCH 30/112 USB: serial: fix runtime PM after driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe upstream.
Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") USB drivers must always balance their runtime PM gets and puts, including when the driver has already been unbound from the interface.
Leaving the interface with a positive PM usage counter would prevent a later bound driver from suspending the device.
--- drivers/usb/serial/usb-serial.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/usb/serial/usb-serial.c +1 -4
@@ -314,10 +314,7 @@ static void serial_cleanup(struct tty_st serial = port->serial; owner = serial->type->driver.owner; -mutex_lock (&serial->disc_mutex); -if (!serial->disconnected) -usb_autopm_put_interface (serial->interface); -mutex_unlock (&serial->disc_mutex); +usb_autopm_put_interface (serial->interface);usb_serial_put (serial);module_put (owner);
Greg Kroah-Hartman
maintainerPATCH 31/112 USB: usblcd: fix I/O after disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 upstream.
Make sure to stop all I/O on disconnect by adding a disconnected flag which is used to prevent new I/O from being started and by stopping all ongoing I/O before returning.
This also fixes a potential use-after-free on driver unbind in case the driver data is freed before the completion handler has run.
--- drivers/usb/misc/usblcd.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
drivers/usb/misc/usblcd.c +31 -2
@@ -18,6 +18,7 @@#include <linux/slab.h> #include <linux/errno.h> #include <linux/mutex.h> +#include <linux/rwsem.h> #include <linux/uaccess.h> #include <linux/usb.h>
@@ -57,6 +58,8 @@ struct usb_lcd {using up all RAM */ struct usb_anchor submitted;/* URBs to wait for before suspend */ +struct rw_semaphore io_rwsem; + unsigned long disconnected:1; };#define to_lcd_dev (d) container_of(d, struct usb_lcd, kref)
@@ -142,6 +145,13 @@ static ssize_t lcd_read(struct file *fil dev = file->private_data; +down_read (&dev->io_rwsem); + +if (dev->disconnected) { + retval = -ENODEV ; + goto out_up_io; + } +/* do a blocking bulk read to get data from the device */ retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev,
@@ -158,6 +168,9 @@ static ssize_t lcd_read(struct file *fil retval = bytes_read; } +out_up_io: +up_read (&dev->io_rwsem); +return retval; }
@@ -237,11 +250,18 @@ static ssize_t lcd_write(struct file *fiif (r <0 )return -EINTR ; +down_read (&dev->io_rwsem); + +if (dev->disconnected) { + retval = -ENODEV ; + goto err_up_io; + } +/* create a urb, and a buffer for it, and copy the data to the urb */ urb =usb_alloc_urb (0 ,GFP_KERNEL );if (!urb) { retval = -ENOMEM ; - goto err_no_buf; + goto err_up_io; } buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL,
@@ -278,6 +298,7 @@ static ssize_t lcd_write(struct file *fithe USB core will eventually free it entirely */ usb_free_urb (urb); +up_read (&dev->io_rwsem); exit:return count; error_unanchor:
@@ -285,7 +306,8 @@ error_unanchor: error:usb_free_coherent (dev->udev, count, buf, urb->transfer_dma);usb_free_urb (urb); -err_no_buf: +err_up_io: +up_read (&dev->io_rwsem);up (&dev->limit_sem);return retval; }
@@ -325,6 +347,7 @@ static int lcd_probe(struct usb_interfackref_init (&dev->kref);sema_init (&dev->limit_sem,USB_LCD_CONCURRENT_WRITES ); +init_rwsem (&dev->io_rwsem);init_usb_anchor (&dev->submitted); dev->udev =usb_get_dev (interface_to_usbdev (interface));
@@ -422,6 +445,12 @@ static void lcd_disconnect(struct usb_in/* give back our minor */ usb_deregister_dev (interface, &lcd_class); +down_write (&dev->io_rwsem); + dev->disconnected =1 ; +up_write (&dev->io_rwsem); + +usb_kill_anchored_urbs (&dev->submitted); +/* decrement our usage count */ kref_put (&dev->kref, lcd_delete);
Greg Kroah-Hartman
maintainerPATCH 32/112 USB: microtek: fix info-leak at probe
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 177238c3d47d54b2ed8f0da7a4290db492f4a057 upstream.
Add missing bulk-in endpoint sanity check to prevent uninitialised stack data from being reported to the system log and used as endpoint addresses.
--- drivers/usb/image/microtek.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/image/microtek.c +4 -0
@@ -716,6 +716,10 @@ static int mts_usb_probe(struct usb_inte } +if (ep_in_current != &ep_in_set[2 ]) { +MTS_WARNING ("couldn't find two input bulk endpoints. Bailing out.\n" ); +return -ENODEV ; + }if ( ep_out ==-1 ) {MTS_WARNING ("couldn't find an output bulk endpoint. Bailing out.\n" );
Greg Kroah-Hartman
maintainerPATCH 33/112 USB: dummy-hcd: fix power budget for SuperSpeed mode
In reply to Greg Kroah-HartmanFrom: [email protected] <[email protected]>
commit 2636d49b64671d3d90ecc4daf971b58df3956519 upstream.
The power budget for SuperSpeed mode should be 900 mA according to USB specification, so set the power budget to 900mA for dummy_start_ss which is only used for SuperSpeed mode.
If the max power consumption of SuperSpeed device is larger than 500 mA, insufficient available bus power error happens in usb_choose_configuration function when the device connects to dummy hcd.
--- drivers/usb/gadget/udc/dummy_hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/gadget/udc/dummy_hcd.c +2 -1
@@ -48,6 +48,7 @@#define DRIVER_VERSION "02 May 2005"#define POWER_BUDGET 500/* in mA; use 8 for low-power port testing */ +#define POWER_BUDGET_3 900/* in mA */ static const char driver_name[] ="dummy_hcd" ;static const char driver_desc[] ="USB Host+Gadget Emulator" ;
@@ -2432,7 +2433,7 @@ static int dummy_start_ss(struct dummy_h dum_hcd->rh_state =DUMMY_RH_RUNNING ; dum_hcd->stream_en_ep =0 ;INIT_LIST_HEAD (&dum_hcd->urbp_list); -dummy_hcd_to_hcd (dum_hcd)->power_budget =POWER_BUDGET ; +dummy_hcd_to_hcd (dum_hcd)->power_budget =POWER_BUDGET_3 ;dummy_hcd_to_hcd (dum_hcd)->state =HC_STATE_RUNNING ;dummy_hcd_to_hcd (dum_hcd)->uses_new_polling =1 ;#ifdef CONFIG_USB_OTG
Greg Kroah-Hartman
maintainerPATCH 34/112 usb: renesas_usbhs: gadget: Do not discard queues in usb_ep_set_{halt,wedge}()
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
commit 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 upstream.
The commit 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area") had added a usbhsg_pipe_disable() calling into __usbhsg_ep_set_halt_wedge() accidentally. But, this driver should not call the usbhsg_pipe_disable() because the function discards all queues. So, this patch removes it.
--- drivers/usb/renesas_usbhs/mod_gadget.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/renesas_usbhs/mod_gadget.c +0 -2
@@ -723,8 +723,6 @@ static int __usbhsg_ep_set_halt_wedge(ststruct device *dev =usbhsg_gpriv_to_dev (gpriv);unsigned long flags; -usbhsg_pipe_disable (uep); -dev_dbg (dev,"set halt %d (pipe %d)\n" , halt,usbhs_pipe_number (pipe));
Greg Kroah-Hartman
maintainerPATCH 35/112 usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
commit 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec upstream.
According to usb_ep_set_halt()'s description, __usbhsg_ep_set_halt_wedge() should return -EAGAIN if the IN endpoint has any queue or data. Otherwise, this driver is possible to cause just STALL without sending a short packet data on g_mass_storage driver, and then a few resetting a device happens on a host side during a usb enumaration.
--- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/fifo.c | 2 +- drivers/usb/renesas_usbhs/fifo.h | 1 + drivers/usb/renesas_usbhs/mod_gadget.c | 16 +++++++++++++++- drivers/usb/renesas_usbhs/pipe.c | 15 +++++++++++++++ drivers/usb/renesas_usbhs/pipe.h | 1 + 6 files changed, 34 insertions(+), 2 deletions(-)
drivers/usb/renesas_usbhs/common.h +1 -0
@@ -211,6 +211,7 @@ struct usbhs_priv;/* DCPCTR */ #define BSTS (1 << 15)/* Buffer Status */ #define SUREQ (1 << 14)/* Sending SETUP Token */ +#define INBUFM (1 << 14)/* (PIPEnCTR) Transfer Buffer Monitor */ #define CSSTS (1 << 12)/* CSSTS Status */ #define ACLRM (1 << 9)/* Buffer Auto-Clear Mode */ #define SQCLR (1 << 8)/* Toggle Bit Clear */
drivers/usb/renesas_usbhs/fifo.c +1 -1
@@ -89,7 +89,7 @@ static void __usbhsf_pkt_del(struct usbhlist_del_init (&pkt->node); } -static struct usbhs_pkt *__usbhsf_pkt_get (struct usbhs_pipe *pipe) +struct usbhs_pkt *__usbhsf_pkt_get (struct usbhs_pipe *pipe) { return list_first_entry_or_null(&pipe->list, struct usbhs_pkt, node); }
drivers/usb/renesas_usbhs/fifo.h +1 -0
@@ -97,5 +97,6 @@ void usbhs_pkt_push(struct usbhs_pipe *p void *buf, int len, int zero, int sequence);struct usbhs_pkt *usbhs_pkt_pop (struct usbhs_pipe *pipe,struct usbhs_pkt *pkt);void usbhs_pkt_start (struct usbhs_pipe *pipe); +struct usbhs_pkt *__usbhsf_pkt_get (struct usbhs_pipe *pipe);#endif /* RENESAS_USB_FIFO_H */
drivers/usb/renesas_usbhs/mod_gadget.c +15 -1
@@ -722,6 +722,7 @@ static int __usbhsg_ep_set_halt_wedge(ststruct usbhs_priv *priv =usbhsg_gpriv_to_priv (gpriv);struct device *dev =usbhsg_gpriv_to_dev (gpriv);unsigned long flags; +int ret =0 ;dev_dbg (dev,"set halt %d (pipe %d)\n" , halt,usbhs_pipe_number (pipe));
@@ -729,6 +730,18 @@ static int __usbhsg_ep_set_halt_wedge(st/******************** spin lock ********************/ usbhs_lock (priv, flags); +/* +* According to usb_ep_set_halt()'s description, this function should +* return -EAGAIN if the IN endpoint has any queue or data. Note +* that the usbhs_pipe_is_dir_in() returns false if the pipe is an +* IN endpoint in the gadget mode. +*/ +if (!usbhs_pipe_is_dir_in (pipe) && (__usbhsf_pkt_get (pipe) || +usbhs_pipe_contains_transmittable_data (pipe))) { + ret = -EAGAIN ; + goto out; + } +if (halt)usbhs_pipe_stall (pipe);else
@@ -739,10 +752,11 @@ static int __usbhsg_ep_set_halt_wedge(stelse usbhsg_status_clr (gpriv,USBHSG_STATUS_WEDGE ); +out:usbhs_unlock (priv, flags);/******************** spin unlock ******************/ -return 0 ; +return ret; }static int usbhsg_ep_set_halt (struct usb_ep *ep,int value)
drivers/usb/renesas_usbhs/pipe.c +15 -0
@@ -277,6 +277,21 @@ int usbhs_pipe_is_accessible(struct usbhreturn -EBUSY ; } +bool usbhs_pipe_contains_transmittable_data (struct usbhs_pipe *pipe) +{ +u16 val; + +/* Do not support for DCP pipe */ +if (usbhs_pipe_is_dcp (pipe)) +return false; + + val =usbhsp_pipectrl_get (pipe); +if (val &INBUFM ) +return true; + +return false; +} +/* * PID ctrl */
drivers/usb/renesas_usbhs/pipe.h +1 -0
@@ -83,6 +83,7 @@ void usbhs_pipe_clear(struct usbhs_pipevoid usbhs_pipe_clear_without_sequence (struct usbhs_pipe *pipe,int needs_bfre,int bfre_enable);int usbhs_pipe_is_accessible (struct usbhs_pipe *pipe); +bool usbhs_pipe_contains_transmittable_data (struct usbhs_pipe *pipe);void usbhs_pipe_enable (struct usbhs_pipe *pipe);void usbhs_pipe_disable (struct usbhs_pipe *pipe);void usbhs_pipe_stall (struct usbhs_pipe *pipe);
Greg Kroah-Hartman
maintainerPATCH 36/112 usb: typec: tcpm: usb: typec: tcpm: Fix a signedness bug in tcpm_fw_get_caps()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 7101949f36fc77b530b73e4c6bd0066a2740d75b upstream.
The "port->typec_caps.data" and "port->typec_caps.type" variables are enums and in this context GCC will treat them as an unsigned int so they can never be less than zero.
--- drivers/usb/typec/tcpm/tcpm.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/usb/typec/tcpm/tcpm.c +8 -6
@@ -4416,18 +4416,20 @@ static int tcpm_fw_get_caps(struct tcpm_/* USB data support is optional */ ret =fwnode_property_read_string (fwnode,"data-role" , &cap_str);if (ret ==0 ) { - port->typec_caps.data =typec_find_port_data_role (cap_str); -if (port->typec_caps.data <0 ) -return -EINVAL ; + ret =typec_find_port_data_role (cap_str); +if (ret <0 ) +return ret; + port->typec_caps.data = ret; } ret =fwnode_property_read_string (fwnode,"power-role" , &cap_str);if (ret <0 )return ret; - port->typec_caps.type =typec_find_port_power_role (cap_str); -if (port->typec_caps.type <0 ) -return -EINVAL ; + ret =typec_find_port_power_role (cap_str); +if (ret <0 ) +return ret; + port->typec_caps.type = ret; port->port_type = port->typec_caps.type;if (port->port_type ==TYPEC_PORT_SNK )
Greg Kroah-Hartman
maintainerPATCH 37/112 usb: typec: ucsi: ccg: Remove run_isr flag
In reply to Greg Kroah-HartmanFrom: Heikki Krogerus <[email protected]>
commit 8530e4e20ec2355c273f4dba9002969e68275e5f upstream.
The "run_isr" flag is used for preventing the driver from calling the interrupt service routine in its runtime resume callback when the driver is expecting completion to a command, but what that basically does is that it hides the real problem. The real problem is that the controller is allowed to suspend in the middle of command execution.
As a more appropriate fix for the problem, using autosuspend delay time that matches UCSI_TIMEOUT_MS (5s). That prevents the controller from suspending while still in the middle of executing a command.
This fixes a potential deadlock. Both ccg_read() and ccg_write() are called with the mutex already taken at least from ccg_send_command(). In ccg_read() and ccg_write, the mutex is only acquired so that run_isr flag can be set.
--- drivers/usb/typec/ucsi/ucsi_ccg.c | 42 +++----------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-)
drivers/usb/typec/ucsi/ucsi_ccg.c +4 -38
@@ -195,7 +195,6 @@ struct ucsi_ccg {/* fw build with vendor information */ u16 fw_build; -bool run_isr;/* flag to call ISR routine during resume */ struct work_struct pm_work; };
@@ -224,18 +223,6 @@ static int ccg_read(struct ucsi_ccg *uc,if (quirks && quirks->max_read_len) max_read_len = quirks->max_read_len; -if (uc->fw_build ==CCG_FW_BUILD_NVIDIA && - uc->fw_version <=CCG_OLD_FW_VERSION ) { -mutex_lock (&uc->lock); -/* -* Do not schedule pm_work to run ISR in -* ucsi_ccg_runtime_resume() after pm_runtime_get_sync() -* since we are already in ISR path. -*/ - uc->run_isr = false; -mutex_unlock (&uc->lock); - } -pm_runtime_get_sync (uc->dev);while (rem_len >0 ) { msgs[1 ].buf = &data[len - rem_len];
@@ -278,18 +265,6 @@ static int ccg_write(struct ucsi_ccg *uc msgs[0 ].len = len +sizeof (rab); msgs[0 ].buf = buf; -if (uc->fw_build ==CCG_FW_BUILD_NVIDIA && - uc->fw_version <=CCG_OLD_FW_VERSION ) { -mutex_lock (&uc->lock); -/* -* Do not schedule pm_work to run ISR in -* ucsi_ccg_runtime_resume() after pm_runtime_get_sync() -* since we are already in ISR path. -*/ - uc->run_isr = false; -mutex_unlock (&uc->lock); - } -pm_runtime_get_sync (uc->dev); status =i2c_transfer (client->adapter, msgs,ARRAY_SIZE (msgs));if (status <0 ) {
@@ -1133,7 +1108,6 @@ static int ucsi_ccg_probe(struct i2c_cli uc->ppm.sync = ucsi_ccg_sync; uc->dev = dev; uc->client = client; - uc->run_isr = true;mutex_init (&uc->lock);INIT_WORK (&uc->work, ccg_update_firmware);INIT_WORK (&uc->pm_work, ccg_pm_workaround_work);
@@ -1195,6 +1169,8 @@ static int ucsi_ccg_probe(struct i2c_clipm_runtime_set_active (uc->dev);pm_runtime_enable (uc->dev); +pm_runtime_use_autosuspend (uc->dev); +pm_runtime_set_autosuspend_delay (uc->dev,5000 );pm_runtime_idle (uc->dev);return 0 ;
@@ -1237,7 +1213,6 @@ static int ucsi_ccg_runtime_resume(struc {struct i2c_client *client =to_i2c_client (dev);struct ucsi_ccg *uc =i2c_get_clientdata (client); -bool schedule = true;/* * Firmware version 3.1.10 or earlier, built for NVIDIA has known issue
@@ -1245,17 +1220,8 @@ static int ucsi_ccg_runtime_resume(struc* Schedule a work to call ISR as a workaround. */ if (uc->fw_build ==CCG_FW_BUILD_NVIDIA && - uc->fw_version <=CCG_OLD_FW_VERSION ) { -mutex_lock (&uc->lock); -if (!uc->run_isr) { - uc->run_isr = true; - schedule = false; - } -mutex_unlock (&uc->lock); - -if (schedule) -schedule_work (&uc->pm_work); - } + uc->fw_version <=CCG_OLD_FW_VERSION ) +schedule_work (&uc->pm_work);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 38/112 usb: typec: ucsi: displayport: Fix for the mode entering routine
In reply to Greg Kroah-HartmanFrom: Heikki Krogerus <[email protected]>
commit f2372b87c386871b16d7dbda680d98d4092ab708 upstream.
Making sure that ucsi_displayport_enter() function does not return an error if the displayport alternate mode has already been entered. It's normal that the firmware (or controller) has already entered the alternate mode by the time the operating system is notified about the device.
--- drivers/usb/typec/ucsi/displayport.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/typec/ucsi/displayport.c +2 -0
@@ -75,6 +75,8 @@ static int ucsi_displayport_enter(structif (cur !=0xff ) {mutex_unlock (&dp->con->lock); +if (dp->con->port_altmode[cur] == alt) +return 0 ;return -EBUSY ; }
Greg Kroah-Hartman
maintainerPATCH 39/112 USB: legousbtower: fix slab info leak at probe
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 1d427be4a39defadda6dd8f4659bc17f7591740f upstream.
Make sure to check for short transfers when retrieving the version information at probe to avoid leaking uninitialised slab data when logging it.
--- drivers/usb/misc/legousbtower.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/misc/legousbtower.c +4 -2
@@ -891,8 +891,10 @@ static int tower_probe (struct usb_inter get_version_reply,sizeof (*get_version_reply), 1000); -if (result <0 ) { -dev_err (idev,"LEGO USB Tower get version control request failed\n" ); +if (result <sizeof (*get_version_reply)) { +if (result >=0 ) + result = -EIO ; +dev_err (idev,"get version request failed: %d\n" , result); retval = result; goto error; }
Greg Kroah-Hartman
maintainerPATCH 40/112 USB: legousbtower: fix deadlock on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 33a7813219f208f4952ece60ee255fd983272dec upstream.
Fix a potential deadlock if disconnect races with open.
Since commit d4ead16f50f9 ("USB: prevent char device open/deregister race") core holds an rw-semaphore while open is called and when releasing the minor number during deregistration. This can lead to an ABBA deadlock if a driver takes a lock in open which it also holds during deregistration.
This effectively reverts commit 78663ecc344b ("USB: disconnect open race in legousbtower") which needlessly introduced this issue after a generic fix for this race had been added to core by commit d4ead16f50f9 ("USB:
prevent char device open/deregister race").
--- drivers/usb/misc/legousbtower.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-)
drivers/usb/misc/legousbtower.c +2 -17
@@ -179,7 +179,6 @@ static const struct usb_device_id tower_ };MODULE_DEVICE_TABLE (usb, tower_table); -static DEFINE_MUTEX (open_disc_mutex);#define LEGO_USB_TOWER_MINOR_BASE 160
@@ -332,18 +331,14 @@ static int tower_open (struct inode *ino goto exit; } -mutex_lock (&open_disc_mutex); dev =usb_get_intfdata (interface); -if (!dev) { -mutex_unlock (&open_disc_mutex); retval = -ENODEV ; goto exit; }/* lock this device */ if (mutex_lock_interruptible (&dev->lock)) { -mutex_unlock (&open_disc_mutex); retval = -ERESTARTSYS ; goto exit; }
@@ -351,12 +346,10 @@ static int tower_open (struct inode *ino/* allow opening only once */ if (dev->open_count) { -mutex_unlock (&open_disc_mutex); retval = -EBUSY ; goto unlock_exit; } dev->open_count =1 ; -mutex_unlock (&open_disc_mutex);/* reset the tower */ result = usb_control_msg (dev->udev,
@@ -423,10 +416,9 @@ static int tower_release (struct inode *if (dev ==NULL ) { retval = -ENODEV ; - goto exit_nolock; + goto exit; } -mutex_lock (&open_disc_mutex);if (mutex_lock_interruptible (&dev->lock)) { retval = -ERESTARTSYS ; goto exit;
@@ -456,10 +448,7 @@ static int tower_release (struct inode * unlock_exit:mutex_unlock (&dev->lock); - exit: -mutex_unlock (&open_disc_mutex); -exit_nolock:return retval; }
@@ -912,7 +901,6 @@ static int tower_probe (struct usb_interif (retval) {/* something prevented us from registering this driver */ dev_err (idev,"Not able to get a minor for this device.\n" ); -usb_set_intfdata (interface,NULL ); goto error; } dev->minor = interface->minor;
@@ -944,16 +932,13 @@ static void tower_disconnect (struct usbint minor; dev =usb_get_intfdata (interface); -mutex_lock (&open_disc_mutex); -usb_set_intfdata (interface,NULL ); minor = dev->minor; -/* give back our minor */ +/* give back our minor and prevent further open() */ usb_deregister_dev (interface, &tower_class);mutex_lock (&dev->lock); -mutex_unlock (&open_disc_mutex);/* if the device is not opened, then we clean up right now */ if (!dev->open_count) {
Greg Kroah-Hartman
maintainerPATCH 41/112 USB: legousbtower: fix potential NULL-deref on disconnect
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit cd81e6fa8e033e7bcd59415b4a65672b4780030b upstream.
The driver is using its struct usb_device pointer as an inverted disconnected flag, but was setting it to NULL before making sure all completion handlers had run. This could lead to a NULL-pointer dereference in a number of dev_dbg and dev_err statements in the completion handlers which relies on said pointer.
Fix this by unconditionally stopping all I/O and preventing resubmissions by poisoning the interrupt URBs at disconnect and using a dedicated disconnected flag.
This also makes sure that all I/O has completed by the time the disconnect callback returns.
--- drivers/usb/misc/legousbtower.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/usb/misc/legousbtower.c +15 -11
@@ -190,6 +190,7 @@ struct lego_usb_tower {unsigned char minor;/* the starting minor number for this device */ int open_count;/* number of times this port has been opened */ + unsigned long disconnected:1;char * read_buffer;size_t read_buffer_length;/* this much came in */
@@ -289,8 +290,6 @@ static inline void lego_usb_tower_debug_*/ static inline void tower_delete (struct lego_usb_tower *dev) { -tower_abort_transfers (dev); -/* free data structures */ usb_free_urb (dev->interrupt_in_urb);usb_free_urb (dev->interrupt_out_urb);
@@ -430,7 +429,8 @@ static int tower_release (struct inode * retval = -ENODEV ; goto unlock_exit; } -if (dev->udev ==NULL ) { + +if (dev->disconnected) {/* the device was unplugged before the file was released */ /* unlock here as tower_delete frees dev */
@@ -466,10 +466,9 @@ static void tower_abort_transfers (strucif (dev->interrupt_in_running) { dev->interrupt_in_running =0 ;mb (); -if (dev->udev) -usb_kill_urb (dev->interrupt_in_urb); +usb_kill_urb (dev->interrupt_in_urb); } -if (dev->interrupt_out_busy && dev->udev) +if (dev->interrupt_out_busy)usb_kill_urb (dev->interrupt_out_urb); }
@@ -505,7 +504,7 @@ static __poll_t tower_poll (struct file dev = file->private_data; -if (!dev->udev) +if (dev->disconnected)return EPOLLERR |EPOLLHUP ;poll_wait (file, &dev->read_wait, wait);
@@ -552,7 +551,7 @@ static ssize_t tower_read (struct file * }/* verify that the device wasn't unplugged */ -if (dev->udev ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;pr_err ("No device or device unplugged %d\n" , retval); goto unlock_exit;
@@ -638,7 +637,7 @@ static ssize_t tower_write (struct file }/* verify that the device wasn't unplugged */ -if (dev->udev ==NULL ) { +if (dev->disconnected) { retval = -ENODEV ;pr_err ("No device or device unplugged %d\n" , retval); goto unlock_exit;
@@ -748,7 +747,7 @@ static void tower_interrupt_in_callback resubmit:/* resubmit if we're still running */ -if (dev->interrupt_in_running && dev->udev) { +if (dev->interrupt_in_running) { retval =usb_submit_urb (dev->interrupt_in_urb,GFP_ATOMIC );if (retval) dev_err(&dev->udev->dev,
@@ -813,6 +812,7 @@ static int tower_probe (struct usb_inter dev->udev = udev; dev->open_count =0 ; + dev->disconnected =0 ; dev->read_buffer =NULL ; dev->read_buffer_length =0 ;
@@ -938,6 +938,10 @@ static void tower_disconnect (struct usb/* give back our minor and prevent further open() */ usb_deregister_dev (interface, &tower_class); +/* stop I/O */ +usb_poison_urb (dev->interrupt_in_urb); +usb_poison_urb (dev->interrupt_out_urb); +mutex_lock (&dev->lock);/* if the device is not opened, then we clean up right now */
@@ -945,7 +949,7 @@ static void tower_disconnect (struct usbmutex_unlock (&dev->lock);tower_delete (dev); }else { - dev->udev =NULL ; + dev->disconnected =1 ;/* wake up pollers */ wake_up_interruptible_all (&dev->read_wait);wake_up_interruptible_all (&dev->write_wait);
Greg Kroah-Hartman
maintainerPATCH 42/112 USB: legousbtower: fix open after failed reset request
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 0b074f6986751361ff442bc1127c1648567aa8d6 upstream.
The driver would return with a nonzero open count in case the reset control request failed. This would prevent any further attempts to open the char dev until the device was disconnected.
Fix this by incrementing the open count only on successful open.
--- drivers/usb/misc/legousbtower.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/misc/legousbtower.c +2 -2
@@ -348,7 +348,6 @@ static int tower_open (struct inode *ino retval = -EBUSY ; goto unlock_exit; } - dev->open_count =1 ;/* reset the tower */ result = usb_control_msg (dev->udev,
@@ -388,13 +387,14 @@ static int tower_open (struct inode *inodev_err (&dev->udev->dev,"Couldn't submit interrupt_in_urb %d\n" , retval); dev->interrupt_in_running =0 ; - dev->open_count =0 ; goto unlock_exit; }/* save device in the file's private structure */ file->private_data = dev; + dev->open_count =1 ; + unlock_exit:mutex_unlock (&dev->lock);
Greg Kroah-Hartman
maintainerPATCH 43/112 USB: legousbtower: fix use-after-free on release
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 726b55d0e22ca72c69c947af87785c830289ddbc upstream.
The driver was accessing its struct usb_device in its release() callback without holding a reference. This would lead to a use-after-free whenever the device was disconnected while the character device was still open.
--- drivers/usb/misc/legousbtower.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/misc/legousbtower.c +2 -1
@@ -296,6 +296,7 @@ static inline void tower_delete (structkfree (dev->read_buffer);kfree (dev->interrupt_in_buffer);kfree (dev->interrupt_out_buffer); +usb_put_dev (dev->udev);kfree (dev); }
@@ -810,7 +811,7 @@ static int tower_probe (struct usb_intermutex_init (&dev->lock); - dev->udev = udev; + dev->udev =usb_get_dev (udev); dev->open_count =0 ; dev->disconnected =0 ;
Greg Kroah-Hartman
maintainerPATCH 44/112 mei: me: add comet point (lake) LP device ids
In reply to Greg Kroah-HartmanFrom: Tomas Winkler <[email protected]>
commit 4d86dfd38285c83a6df01093b8547f742e3b2470 upstream.
Add Comet Point devices IDs for Comet Lake U platforms.
--- drivers/misc/mei/hw-me-regs.h | 3 +++ drivers/misc/mei/pci-me.c | 3 +++ 2 files changed, 6 insertions(+)
drivers/misc/mei/hw-me-regs.h +3 -0
@@ -79,6 +79,9 @@#define MEI_DEV_ID_CNP_H 0xA360/* Cannon Point H */ #define MEI_DEV_ID_CNP_H_4 0xA364/* Cannon Point H 4 (iTouch) */ +#define MEI_DEV_ID_CMP_LP 0x02e0/* Comet Point LP */ +#define MEI_DEV_ID_CMP_LP_3 0x02e4/* Comet Point LP 3 (iTouch) */ +#define MEI_DEV_ID_ICP_LP 0x34E0/* Ice Lake Point LP */ #define MEI_DEV_ID_TGP_LP 0xA0E0/* Tiger Lake Point LP */
drivers/misc/mei/pci-me.c +3 -0
@@ -96,6 +96,9 @@ static const struct pci_device_id mei_me {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)},
Greg Kroah-Hartman
maintainerPATCH 45/112 mei: avoid FW version request on Ibex Peak and earlier
In reply to Greg Kroah-HartmanFrom: Alexander Usyskin <[email protected]>
commit f8204f0ddd62966a0e79c2804963a21e3540dd82 upstream.
The fixed MKHI client on PCH 6 gen platforms
does not support fw version retrieval.
The error is not fatal, but it fills up the kernel logs and slows down the driver start.
This patch disables requesting FW version on GEN6 and earlier platforms.
Fixes warning:
[ 15.964298] mei mei::55213584-9a29-4916-badf-0fb7ed682aeb:01: Could not read FW version [ 15.964301] mei mei::55213584-9a29-4916-badf-0fb7ed682aeb:01: version command failed -5
--- drivers/misc/mei/bus-fixup.c | 14 +++++++++++--- drivers/misc/mei/hw-me.c | 21 ++++++++++++++++++--- drivers/misc/mei/hw-me.h | 8 ++++++-- drivers/misc/mei/mei_dev.h | 4 ++++ drivers/misc/mei/pci-me.c | 10 +++++----- 5 files changed, 44 insertions(+), 13 deletions(-)
drivers/misc/mei/bus-fixup.c +11 -3
@@ -218,13 +218,21 @@ static void mei_mkhi_fix(struct mei_cl_d {int ret; +/* No need to enable the client if nothing is needed from it */ +if (!cldev->bus->fw_f_fw_ver_supported && + !cldev->bus->hbm_f_os_supported) +return ; + ret =mei_cldev_enable (cldev);if (ret)return ; - ret =mei_fwver (cldev); -if (ret <0 ) -dev_err (&cldev->dev,"FW version command failed %d\n" , ret); +if (cldev->bus->fw_f_fw_ver_supported) { + ret =mei_fwver (cldev); +if (ret <0 ) +dev_err (&cldev->dev,"FW version command failed %d\n" , + ret); + }if (cldev->bus->hbm_f_os_supported) { ret =mei_osver (cldev);
drivers/misc/mei/hw-me.c +18 -3
@@ -1355,6 +1355,8 @@ static bool mei_me_fw_type_sps(struct pc#define MEI_CFG_FW_SPS \ .quirk_probe = mei_me_fw_type_sps +#define MEI_CFG_FW_VER_SUPP \ + .fw_ver_supported = 1#define MEI_CFG_ICH_HFS \ .fw_status.count = 0
@@ -1392,31 +1394,41 @@ static const struct mei_cfg mei_me_ich10 MEI_CFG_ICH10_HFS, }; -/* PCH devices */ -static const struct mei_cfg mei_me_pch_cfg = { +/* PCH6 devices */ +static const struct mei_cfg mei_me_pch6_cfg = {MEI_CFG_PCH_HFS , }; +/* PCH7 devices */ +static const struct mei_cfg mei_me_pch7_cfg = { +MEI_CFG_PCH_HFS , +MEI_CFG_FW_VER_SUPP , +}; +/* PCH Cougar Point and Patsburg with quirk for Node Manager exclusion */ static const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {MEI_CFG_PCH_HFS , +MEI_CFG_FW_VER_SUPP ,MEI_CFG_FW_NM , };/* PCH8 Lynx Point and newer devices */ static const struct mei_cfg mei_me_pch8_cfg = {MEI_CFG_PCH8_HFS , +MEI_CFG_FW_VER_SUPP , };/* PCH8 Lynx Point with quirk for SPS Firmware exclusion */ static const struct mei_cfg mei_me_pch8_sps_cfg = {MEI_CFG_PCH8_HFS , +MEI_CFG_FW_VER_SUPP ,MEI_CFG_FW_SPS , };/* Cannon Lake and newer devices */ static const struct mei_cfg mei_me_pch12_cfg = {MEI_CFG_PCH8_HFS , +MEI_CFG_FW_VER_SUPP ,MEI_CFG_DMA_128 , };
@@ -1428,7 +1440,8 @@ static const struct mei_cfg *const mei_c [MEI_ME_UNDEF_CFG] = NULL, [MEI_ME_ICH_CFG] = &mei_me_ich_cfg, [MEI_ME_ICH10_CFG] = &mei_me_ich10_cfg, - [MEI_ME_PCH_CFG] = &mei_me_pch_cfg, + [MEI_ME_PCH6_CFG] = &mei_me_pch6_cfg, + [MEI_ME_PCH7_CFG] = &mei_me_pch7_cfg, [MEI_ME_PCH_CPT_PBG_CFG] = &mei_me_pch_cpt_pbg_cfg, [MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg, [MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg,
@@ -1473,6 +1486,8 @@ struct mei_device *mei_me_dev_init(strucmei_device_init (dev, &pdev->dev, &mei_me_hw_ops); hw->cfg = cfg; + dev->fw_f_fw_ver_supported = cfg->fw_ver_supported; +return dev; }
drivers/misc/mei/hw-me.h +6 -2
@@ -20,11 +20,13 @@* @fw_status: FW status * @quirk_probe: device exclusion quirk * @dma_size: device DMA buffers size +* @fw_ver_supported: is fw version retrievable from FW */ struct mei_cfg {const struct mei_fw_status fw_status;bool (*quirk_probe)(struct pci_dev *pdev);size_t dma_size[DMA_DSCR_NUM ]; +u32 fw_ver_supported:1 ; };
@@ -62,7 +64,8 @@ struct mei_me_hw {* @MEI_ME_UNDEF_CFG: Lower sentinel. * @MEI_ME_ICH_CFG: I/O Controller Hub legacy devices. * @MEI_ME_ICH10_CFG: I/O Controller Hub platforms Gen10 -* @MEI_ME_PCH_CFG: Platform Controller Hub platforms (Up to Gen8). +* @MEI_ME_PCH6_CFG: Platform Controller Hub platforms (Gen6). +* @MEI_ME_PCH7_CFG: Platform Controller Hub platforms (Gen7). * @MEI_ME_PCH_CPT_PBG_CFG:Platform Controller Hub workstations * with quirk for Node Manager exclusion. * @MEI_ME_PCH8_CFG: Platform Controller Hub Gen8 and newer
@@ -77,7 +80,8 @@ enum mei_cfg_idx {MEI_ME_UNDEF_CFG ,MEI_ME_ICH_CFG ,MEI_ME_ICH10_CFG , -MEI_ME_PCH_CFG , +MEI_ME_PCH6_CFG , +MEI_ME_PCH7_CFG ,MEI_ME_PCH_CPT_PBG_CFG ,MEI_ME_PCH8_CFG , MEI_ME_PCH8_SPS_CFG,
drivers/misc/mei/mei_dev.h +4 -0
@@ -426,6 +426,8 @@ struct mei_fw_version {* * @fw_ver : FW versions * +* @fw_f_fw_ver_supported : fw feature: fw version supported +* * @me_clients_rwsem: rw lock over me_clients list * @me_clients : list of FW clients * @me_clients_map : FW clients bit map
@@ -506,6 +508,8 @@ struct mei_device {struct mei_fw_version fw_ver[MEI_MAX_FW_VER_BLOCKS ]; + unsigned int fw_f_fw_ver_supported:1; +struct rw_semaphore me_clients_rwsem;struct list_head me_clients;DECLARE_BITMAP (me_clients_map,MEI_CLIENTS_MAX );
drivers/misc/mei/pci-me.c +5 -5
@@ -61,13 +61,13 @@ static const struct pci_device_id mei_me {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, MEI_ME_ICH10_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, MEI_ME_ICH10_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH6_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH6_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH7_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH7_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH7_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)},
Greg Kroah-Hartman
maintainerPATCH 46/112 gpio: eic: sprd: Fix the incorrect EIC offset when toggling
In reply to Greg Kroah-HartmanFrom: Bruce Chen <[email protected]>
commit e91aafcb51f3c5001ae76c3ee027beb0b8506447 upstream.
When toggling the level trigger to emulate the edge trigger, the EIC offset is incorrect without adding the corresponding bank index, thus fix it.
--- drivers/gpio/gpio-eic-sprd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpio/gpio-eic-sprd.c +4 -3
@@ -530,11 +530,12 @@ static void sprd_eic_handle_one_type(str }for_each_set_bit (n, ®,SPRD_EIC_PER_BANK_NR ) { - girq =irq_find_mapping (chip->irq.domain, - bank *SPRD_EIC_PER_BANK_NR + n); +u32 offset = bank *SPRD_EIC_PER_BANK_NR + n; + + girq =irq_find_mapping (chip->irq.domain, offset);generic_handle_irq (girq); -sprd_eic_toggle_trigger (chip, girq, n); +sprd_eic_toggle_trigger (chip, girq, offset); } } }
Greg Kroah-Hartman
maintainerPATCH 47/112 staging/fbtft: Depend on OF
In reply to Greg Kroah-HartmanFrom: Noralf Trønnes <[email protected]>
commit 63f2b1677fba11c5bd02089f25c13421948905f5 upstream.
Commit c440eee1a7a1 ("Staging: fbtft: Switch to the gpio descriptor interface") removed setting gpios via platform data. This means that fbtft will now only work with Device Tree so set the dependency.
This also prevents a NULL pointer deref on non-DT platform because fbtftops.request_gpios is not set in that case anymore.
--- drivers/staging/fbtft/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/fbtft/Kconfig +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 menuconfig FB_TFT tristate "Support for small TFT LCD display modules" - depends on FB && SPI + depends on FB && SPI && OF depends on GPIOLIB || COMPILE_TEST select FB_SYS_FILLRECT select FB_SYS_COPYAREA
Greg Kroah-Hartman
maintainerPATCH 48/112 staging: bcm2835-audio: Fix draining behavior regression
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 2eed19b99c8e95ff87afe6c140ed895c3fac5937 upstream.
The PCM draining behavior got broken since the recent refactoring, and this turned out to be the incorrect expectation of the firmware behavior regarding "draining". While I expected the "drain" flag at the stop operation would do processing the queued samples, it seems rather dropping the samples.
As a quick fix, just drop the SNDRV_PCM_INFO_DRAIN_TRIGGER flag, so that the driver uses the normal PCM draining procedure. Also, put some caution comment to the function for future readers not to fall into the same pitfall.
--- drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 ++-- drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +2 -2
@@ -12,7 +12,7 @@static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED |SNDRV_PCM_INFO_BLOCK_TRANSFER |SNDRV_PCM_INFO_MMAP |SNDRV_PCM_INFO_MMAP_VALID | -SNDRV_PCM_INFO_DRAIN_TRIGGER |SNDRV_PCM_INFO_SYNC_APPLPTR ), +SNDRV_PCM_INFO_SYNC_APPLPTR ), .formats =SNDRV_PCM_FMTBIT_U8 |SNDRV_PCM_FMTBIT_S16_LE , .rates =SNDRV_PCM_RATE_CONTINUOUS |SNDRV_PCM_RATE_8000_48000 , .rate_min =8000 ,
@@ -29,7 +29,7 @@ static const struct snd_pcm_hardware sndstatic const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED |SNDRV_PCM_INFO_BLOCK_TRANSFER |SNDRV_PCM_INFO_MMAP |SNDRV_PCM_INFO_MMAP_VALID | -SNDRV_PCM_INFO_DRAIN_TRIGGER |SNDRV_PCM_INFO_SYNC_APPLPTR ), +SNDRV_PCM_INFO_SYNC_APPLPTR ), .formats =SNDRV_PCM_FMTBIT_S16_LE , .rates =SNDRV_PCM_RATE_CONTINUOUS |SNDRV_PCM_RATE_44100 |SNDRV_PCM_RATE_48000 ,
drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +1 -0
@@ -289,6 +289,7 @@ int bcm2835_audio_stop(struct bcm2835_al VC_AUDIO_MSG_TYPE_STOP, false); } +/* FIXME: this doesn't seem working as expected for "draining" */ int bcm2835_audio_drain (struct bcm2835_alsa_stream *alsa_stream) {struct vc_audio_msg m = {
Greg Kroah-Hartman
maintainerPATCH 49/112 Staging: fbtft: fix memory leak in fbtft_framebuffer_alloc
In reply to Greg Kroah-HartmanFrom: Navid Emamdoost <[email protected]>
commit 5bdea6060618cfcf1459dca137e89aee038ac8b9 upstream.
In fbtft_framebuffer_alloc the error handling path should take care of releasing frame buffer after it is allocated via framebuffer_alloc, too. Therefore, in two failure cases the goto destination is changed to address this issue.
--- drivers/staging/fbtft/fbtft-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/staging/fbtft/fbtft-core.c +5 -2
@@ -714,7 +714,7 @@ struct fb_info *fbtft_framebuffer_alloc(if (par->gamma.curves && gamma) {if (fbtft_gamma_parse_str (par, par->gamma.curves, gamma,strlen (gamma))) - goto alloc_fail; + goto release_framebuf; }/* Transmit buffer */
@@ -731,7 +731,7 @@ struct fb_info *fbtft_framebuffer_alloc(if (txbuflen >0 ) { txbuf =devm_kzalloc (par->info->device, txbuflen,GFP_KERNEL );if (!txbuf) - goto alloc_fail; + goto release_framebuf; par->txbuf.buf = txbuf; par->txbuf.len = txbuflen; }
@@ -753,6 +753,9 @@ struct fb_info *fbtft_framebuffer_alloc(return info; +release_framebuf: +framebuffer_release (info); + alloc_fail:vfree (vmem);
Greg Kroah-Hartman
maintainerPATCH 50/112 staging: rtl8188eu: fix HighestRate check in odm_ARFBRefresh_8188E()
In reply to Greg Kroah-HartmanFrom: Denis Efremov <[email protected]>
commit 22d67a01d8d89552b989c9651419824bb4111200 upstream.
It's incorrect to compare HighestRate with 0x0b twice in the following manner "if (HighestRate > 0x0b) ... else if (HighestRate > 0x0b) ...". The "else if" branch is constantly false. The second comparision should be with 0x03 according to the max_rate_idx in ODM_RAInfo_Init().
--- drivers/staging/rtl8188eu/hal/hal8188e_rate_adaptive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8188eu/hal/hal8188e_rate_adaptive.c +1 -1
@@ -409,7 +409,7 @@ static int odm_ARFBRefresh_8188E(struct pRaInfo->PTModeSS =3 ; else if (pRaInfo->HighestRate > 0x0b) pRaInfo->PTModeSS = 2; - else if (pRaInfo->HighestRate > 0x0b) + else if (pRaInfo->HighestRate > 0x03) pRaInfo->PTModeSS = 1; else pRaInfo->PTModeSS = 0;
Greg Kroah-Hartman
maintainerPATCH 51/112 staging: vt6655: Fix memory leak in vt6655_probe
In reply to Greg Kroah-HartmanFrom: Navid Emamdoost <[email protected]>
commit 80b15db5e1e9c3300de299b2d43d1aafb593e6ac upstream.
In vt6655_probe, if vnt_init() fails the cleanup code needs to be called like other error handling cases. The call to device_free_info() is added.
--- drivers/staging/vt6655/device_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/staging/vt6655/device_main.c +3 -1
@@ -1748,8 +1748,10 @@ vt6655_probe(struct pci_dev *pcid, const priv->hw->max_signal =100 ; -if (vnt_init (priv)) +if (vnt_init (priv)) { +device_free_info (priv);return -ENODEV ; + }device_print_info (priv);pci_set_drvdata (pcid, priv);
Greg Kroah-Hartman
maintainerPATCH 52/112 iio: adc: hx711: fix bug in sampling of data
In reply to Greg Kroah-HartmanFrom: Andreas Klinger <[email protected]>
commit 4043ecfb5fc4355a090111e14faf7945ff0fdbd5 upstream.
Fix bug in sampling function hx711_cycle() when interrupt occures while PD_SCK is high. If PD_SCK is high for at least 60 us power down mode of the sensor is entered which in turn leads to a wrong measurement.
Switch off interrupts during a PD_SCK high period and move query of DOUT to the latest point of time which is at the end of PD_SCK low period.
This bug exists in the driver since it's initial addition. The more interrupts on the system the higher is the probability that it happens.
--- drivers/iio/adc/hx711.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/iio/adc/hx711.c +5 -5
@@ -100,14 +100,14 @@ struct hx711_data {static int hx711_cycle (struct hx711_data *hx711_data) { -int val; +unsigned long flags;/* * if preempted for more then 60us while PD_SCK is high: * hx711 is going in reset * ==> measuring is false */ -preempt_disable (); +local_irq_save (flags);gpiod_set_value (hx711_data->gpiod_pd_sck,1 );/*
@@ -117,7 +117,6 @@ static int hx711_cycle(struct hx711_data*/ ndelay (hx711_data->data_ready_delay_ns); - val =gpiod_get_value (hx711_data->gpiod_dout);/* * here we are not waiting for 0.2 us as suggested by the datasheet, * because the oscilloscope showed in a test scenario
@@ -125,7 +124,7 @@ static int hx711_cycle(struct hx711_data* and 0.56 us for PD_SCK low on TI Sitara with 800 MHz */ gpiod_set_value (hx711_data->gpiod_pd_sck,0 ); -preempt_enable (); +local_irq_restore (flags);/* * make it a square wave for addressing cases with capacitance on
@@ -133,7 +132,8 @@ static int hx711_cycle(struct hx711_data*/ ndelay (hx711_data->data_ready_delay_ns); -return val; +/* sample as late as possible */ +return gpiod_get_value (hx711_data->gpiod_dout); }static int hx711_read (struct hx711_data *hx711_data)
Greg Kroah-Hartman
maintainerPATCH 53/112 iio: adc: ad799x: fix probe error handling
In reply to Greg Kroah-HartmanFrom: Marco Felsch <[email protected]>
commit c62dd44901cfff12acc5792bf3d2dec20bcaf392 upstream.
Since commit 0f7ddcc1bff1 ("iio:adc:ad799x: Write default config on probe and reset alert status on probe") the error path is wrong since it leaves the vref regulator on. Fix this by disabling both regulators.
--- drivers/iio/adc/ad799x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/ad799x.c +2 -2
@@ -810,10 +810,10 @@ static int ad799x_probe(struct i2c_clien ret =ad799x_write_config (st, st->chip_config->default_config);if (ret <0 ) - goto error_disable_reg; + goto error_disable_vref; ret =ad799x_read_config (st);if (ret <0 ) - goto error_disable_reg; + goto error_disable_vref; st->config = ret; ret = iio_triggered_buffer_setup(indio_dev, NULL,
Greg Kroah-Hartman
maintainerPATCH 54/112 iio: adc: axp288: Override TS pin bias current for some models
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 972917419a0ba25afbf69d5d8c9fa644d676f887 upstream.
Since commit 9bcf15f75cac ("iio: adc: axp288: Fix TS-pin handling") we preserve the bias current set by the firmware at boot. This fixes issues we were seeing on various models, but it seems our old hardcoded 80ųA bias current was working around a firmware bug on at least one model laptop.
In order to both have our cake and eat it, this commit adds a dmi based list of models where we need to override the firmware set bias current and adds the one model we now know needs this to it: The Lenovo Ideapad 100S (11 inch version).
--- drivers/iio/adc/axp288_adc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
drivers/iio/adc/axp288_adc.c +32 -0
@@ -7,6 +7,7 @@* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include <linux/dmi.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h>
@@ -25,6 +26,11 @@#define AXP288_ADC_EN_MASK 0xF0#define AXP288_ADC_TS_ENABLE 0x01 +#define AXP288_ADC_TS_BIAS_MASK GENMASK(5, 4) +#define AXP288_ADC_TS_BIAS_20UA (0 << 4) +#define AXP288_ADC_TS_BIAS_40UA (1 << 4) +#define AXP288_ADC_TS_BIAS_60UA (2 << 4) +#define AXP288_ADC_TS_BIAS_80UA (3 << 4)#define AXP288_ADC_TS_CURRENT_ON_OFF_MASK GENMASK(1, 0)#define AXP288_ADC_TS_CURRENT_OFF (0 << 0)#define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING (1 << 0)
@@ -177,10 +183,36 @@ static int axp288_adc_read_raw(struct iireturn ret; } +/* +* We rely on the machine's firmware to correctly setup the TS pin bias current +* at boot. This lists systems with broken fw where we need to set it ourselves. +*/ +static const struct dmi_system_id axp288_adc_ts_bias_override[] = { + { +/* Lenovo Ideapad 100S (11 inch) */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_MATCH (DMI_PRODUCT_VERSION ,"Lenovo ideapad 100S-11IBY" ), + }, + .driver_data = (void *)(uintptr_t )AXP288_ADC_TS_BIAS_80UA , + }, + {} +}; +static int axp288_adc_initialize (struct axp288_adc_info *info) { +const struct dmi_system_id *bias_override;int ret, adc_enable_val; + bias_override =dmi_first_match (axp288_adc_ts_bias_override); +if (bias_override) { + ret =regmap_update_bits (info->regmap,AXP288_ADC_TS_PIN_CTRL , +AXP288_ADC_TS_BIAS_MASK , + (uintptr_t )bias_override->driver_data); +if (ret) +return ret; + } +/* * Determine if the TS pin is enabled and set the TS current-source * accordingly.
Greg Kroah-Hartman
maintainerPATCH 55/112 iio: adc: stm32-adc: move registers definitions
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
commit 31922f62bb527d749b99dbc776e514bcba29b7fe upstream.
Move STM32 ADC registers definitions to common header.
This is precursor patch to:
- iio: adc: stm32-adc: fix a race when using several adcs with dma and irq
It keeps registers definitions as a whole block, to ease readability and allow simple access path to EOC bits (readl) in stm32-adc-core driver.
--- drivers/iio/adc/stm32-adc-core.c | 27 ------- drivers/iio/adc/stm32-adc-core.h | 136 +++++++++++++++++++++++++++++++++++++++ drivers/iio/adc/stm32-adc.c | 109 ------------------------------- 3 files changed, 136 insertions(+), 136 deletions(-)
drivers/iio/adc/stm32-adc-core.c +0 -27
@@ -22,33 +22,6 @@#include "stm32-adc-core.h" -/* STM32F4 - common registers for all ADC instances: 1, 2 & 3 */ -#define STM32F4_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) -#define STM32F4_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x04) - -/* STM32F4_ADC_CSR - bit fields */ -#define STM32F4_EOC3 BIT(17) -#define STM32F4_EOC2 BIT(9) -#define STM32F4_EOC1 BIT(1) - -/* STM32F4_ADC_CCR - bit fields */ -#define STM32F4_ADC_ADCPRE_SHIFT 16 -#define STM32F4_ADC_ADCPRE_MASK GENMASK(17, 16) - -/* STM32H7 - common registers for all ADC instances */ -#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) -#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) - -/* STM32H7_ADC_CSR - bit fields */ -#define STM32H7_EOC_SLV BIT(18) -#define STM32H7_EOC_MST BIT(2) - -/* STM32H7_ADC_CCR - bit fields */ -#define STM32H7_PRESC_SHIFT 18 -#define STM32H7_PRESC_MASK GENMASK(21, 18) -#define STM32H7_CKMODE_SHIFT 16 -#define STM32H7_CKMODE_MASK GENMASK(17, 16) -#define STM32_ADC_CORE_SLEEP_DELAY_MS 2000/**
drivers/iio/adc/stm32-adc-core.h +136 -0
142 lines not on this page · raw message
drivers/iio/adc/stm32-adc.c +0 -109
115 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 56/112 iio: adc: stm32-adc: fix a race when using several adcs with dma and irq
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
commit dcb10920179ab74caf88a6f2afadecfc2743b910 upstream.
End of conversion may be handled by using IRQ or DMA. There may be a race when two conversions complete at the same time on several ADCs. EOC can be read as 'set' for several ADCs, with:
- an ADC configured to use IRQs. EOCIE bit is set. The handler is normally called in this case.
- an ADC configured to use DMA. EOCIE bit isn't set. EOC triggers the DMA request instead. It's then automatically cleared by DMA read. But the handler gets called due to status bit is temporarily set (IRQ triggered by the other ADC).
So both EOC status bit in CSR and EOCIE control bit must be checked before invoking the interrupt handler (e.g. call ISR only for IRQ-enabled ADCs).
--- drivers/iio/adc/stm32-adc-core.c | 43 ++++++++++++++++++++++++++++++++++++--- drivers/iio/adc/stm32-adc-core.h | 1 2 files changed, 41 insertions(+), 3 deletions(-)
drivers/iio/adc/stm32-adc-core.c +40 -3
@@ -31,6 +31,8 @@* @eoc1: adc1 end of conversion flag in @csr * @eoc2: adc2 end of conversion flag in @csr * @eoc3: adc3 end of conversion flag in @csr +* @ier: interrupt enable register offset for each adc +* @eocie_msk: end of conversion interrupt enable mask in @ier */ struct stm32_adc_common_regs {u32 csr;
@@ -38,6 +40,8 @@ struct stm32_adc_common_regs {u32 eoc1_msk;u32 eoc2_msk;u32 eoc3_msk; +u32 ier; +u32 eocie_msk; };struct stm32_adc_priv ;
@@ -251,6 +255,8 @@ static const struct stm32_adc_common_reg .eoc1_msk = STM32F4_EOC1, .eoc2_msk = STM32F4_EOC2, .eoc3_msk = STM32F4_EOC3, + .ier = STM32F4_ADC_CR1, + .eocie_msk = STM32F4_EOCIE, };/* STM32H7 common registers definitions */
@@ -259,8 +265,24 @@ static const struct stm32_adc_common_reg .ccr = STM32H7_ADC_CCR, .eoc1_msk = STM32H7_EOC_MST, .eoc2_msk = STM32H7_EOC_SLV, + .ier = STM32H7_ADC_IER, + .eocie_msk = STM32H7_EOCIE, }; +static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS ] = { +0 ,STM32_ADC_OFFSET ,STM32_ADC_OFFSET *2 , +}; + +static unsigned int stm32_adc_eoc_enabled (struct stm32_adc_priv *priv, +unsigned int adc) +{ +u32 ier, offset = stm32_adc_offset[adc]; + + ier =readl_relaxed (priv->common.base + offset + priv->cfg->regs->ier); + +return ier & priv->cfg->regs->eocie_msk; +} +/* ADC common interrupt for all instances */ static void stm32_adc_irq_handler (struct irq_desc *desc) {
@@ -271,13 +293,28 @@ static void stm32_adc_irq_handler(structchained_irq_enter (chip, desc); status =readl_relaxed (priv->common.base + priv->cfg->regs->csr); -if (status & priv->cfg->regs->eoc1_msk) +/* +* End of conversion may be handled by using IRQ or DMA. There may be a +* race here when two conversions complete at the same time on several +* ADCs. EOC may be read 'set' for several ADCs, with: +* - an ADC configured to use DMA (EOC triggers the DMA request, and +* is then automatically cleared by DR read in hardware) +* - an ADC configured to use IRQs (EOCIE bit is set. The handler must +* be called in this case) +* So both EOC status bit in CSR and EOCIE control bit must be checked +* before invoking the interrupt handler (e.g. call ISR only for +* IRQ-enabled ADCs). +*/ +if (status & priv->cfg->regs->eoc1_msk && +stm32_adc_eoc_enabled (priv,0 ))generic_handle_irq (irq_find_mapping (priv->domain,0 )); -if (status & priv->cfg->regs->eoc2_msk) +if (status & priv->cfg->regs->eoc2_msk && +stm32_adc_eoc_enabled (priv,1 ))generic_handle_irq (irq_find_mapping (priv->domain,1 )); -if (status & priv->cfg->regs->eoc3_msk) +if (status & priv->cfg->regs->eoc3_msk && +stm32_adc_eoc_enabled (priv,2 ))generic_handle_irq (irq_find_mapping (priv->domain,2 ));chained_irq_exit (chip, desc);
drivers/iio/adc/stm32-adc-core.h +1 -0
@@ -25,6 +25,7 @@* -------------------------------------------------------- */ #define STM32_ADC_MAX_ADCS 3 +#define STM32_ADC_OFFSET 0x100#define STM32_ADCX_COMN_OFFSET 0x300/* STM32F4 - Registers for each ADC instance */
Greg Kroah-Hartman
maintainerPATCH 57/112 iio: light: opt3001: fix mutex unlock race
In reply to Greg Kroah-HartmanFrom: David Frey <[email protected]>
commit 82f3015635249a8c8c45bac303fd84905066f04f upstream.
When an end-of-conversion interrupt is received after performing a single-shot reading of the light sensor, the driver was waking up the result ready queue before checking opt->ok_to_ignore_lock to determine if it should unlock the mutex. The problem occurred in the case where the other thread woke up and changed the value of opt->ok_to_ignore_lock to false prior to the interrupt thread performing its read of the variable. In this case, the mutex would be unlocked twice.
--- drivers/iio/light/opt3001.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/light/opt3001.c +5 -1
@@ -686,6 +686,7 @@ static irqreturn_t opt3001_irq(int irq,struct iio_dev *iio = _iio;struct opt3001 *opt =iio_priv (iio);int ret; +bool wake_result_ready_queue = false;if (!opt->ok_to_ignore_lock)mutex_lock (&opt->lock);
@@ -720,13 +721,16 @@ static irqreturn_t opt3001_irq(int irq, } opt->result = ret; opt->result_ready = true; -wake_up (&opt->result_ready_queue); + wake_result_ready_queue = true; } out:if (!opt->ok_to_ignore_lock)mutex_unlock (&opt->lock); +if (wake_result_ready_queue) +wake_up (&opt->result_ready_queue); +return IRQ_HANDLED ; }
Greg Kroah-Hartman
maintainerPATCH 58/112 iio: light: add missing vcnl4040 of_compatible
In reply to Greg Kroah-HartmanFrom: Marco Felsch <[email protected]>
commit 7fd1c2606508eb384992251e87d50591393a48d0 upstream.
Commit 5a441aade5b3 ("iio: light: vcnl4000 add support for the VCNL4040 proximity and light sensor") added the support for the vcnl4040 but forgot to add the of_compatible. Fix this by adding it now.
--- drivers/iio/light/vcnl4000.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/iio/light/vcnl4000.c +4 -0
@@ -409,6 +409,10 @@ static const struct of_device_id vcnl_40 .data = "VCNL4020", }, { + .compatible = "vishay,vcnl4040", + .data = (void *)VCNL4040, + }, + { .compatible = "vishay,vcnl4200", .data = "VCNL4200", },
Greg Kroah-Hartman
maintainerPATCH 59/112 iio: accel: adxl372: Fix/remove limitation for FIFO samples
In reply to Greg Kroah-HartmanFrom: Stefan Popa <[email protected]>
commit d202ce4787e446556c6b9d01f84734c3f8174ba3 upstream.
Currently, the driver sets the FIFO_SAMPLES register with the number of sample sets (maximum of 170 for 3 axis data, 256 for 2-axis and 512 for single axis). However, the FIFO_SAMPLES register should store the number of samples, regardless of how the FIFO format is configured.
--- drivers/iio/accel/adxl372.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/iio/accel/adxl372.c +8 -3
@@ -474,12 +474,17 @@ static int adxl372_configure_fifo(structif (ret <0 )return ret; - fifo_samples = st->watermark &0xFF ; +/* +* watermark stores the number of sets; we need to write the FIFO +* registers with the number of samples +*/ + fifo_samples = (st->watermark * st->fifo_set_size); fifo_ctl =ADXL372_FIFO_CTL_FORMAT_MODE (st->fifo_format) |ADXL372_FIFO_CTL_MODE_MODE (st->fifo_mode) | -ADXL372_FIFO_CTL_SAMPLES_MODE (st->watermark); +ADXL372_FIFO_CTL_SAMPLES_MODE (fifo_samples); - ret =regmap_write (st->regmap,ADXL372_FIFO_SAMPLES , fifo_samples); + ret =regmap_write (st->regmap, +ADXL372_FIFO_SAMPLES , fifo_samples &0xFF );if (ret <0 )return ret;
Greg Kroah-Hartman
maintainerPATCH 60/112 iio: accel: adxl372: Fix push to buffers lost samples
In reply to Greg Kroah-HartmanFrom: Stefan Popa <[email protected]>
commit 62df81b74393079debf04961c48cb22268fc5fab upstream.
One in two sample sets was lost by multiplying fifo_set_size with sizeof(u16). Also, the double number of available samples were pushed to the iio buffers.
--- drivers/iio/accel/adxl372.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/accel/adxl372.c +1 -2
@@ -553,8 +553,7 @@ static irqreturn_t adxl372_trigger_handl goto err;/* Each sample is 2 bytes */ -for (i =0 ; i < fifo_entries *sizeof (u16); - i += st->fifo_set_size *sizeof (u16)) +for (i =0 ; i < fifo_entries; i += st->fifo_set_size)iio_push_to_buffers (indio_dev, &st->fifo_buf[i]); } err:
Greg Kroah-Hartman
maintainerPATCH 61/112 iio: accel: adxl372: Perform a reset at start up
In reply to Greg Kroah-HartmanFrom: Stefan Popa <[email protected]>
commit d9a997bd4d762d5bd8cc548d762902f58b5e0a74 upstream.
We need to perform a reset a start up to make sure that the chip is in a consistent state. This reset also disables all the interrupts which should only be enabled together with the iio buffer. Not doing this, was sometimes causing unwanted interrupts to trigger.
--- drivers/iio/accel/adxl372.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/iio/accel/adxl372.c +8 -0
@@ -575,6 +575,14 @@ static int adxl372_setup(struct adxl372_return -ENODEV ; } +/* +* Perform a software reset to make sure the device is in a consistent +* state after start up. +*/ + ret =regmap_write (st->regmap,ADXL372_RESET ,ADXL372_RESET_CODE ); +if (ret <0 ) +return ret; + ret =adxl372_set_op_mode (st,ADXL372_STANDBY );if (ret <0 )return ret;
Greg Kroah-Hartman
maintainerPATCH 62/112 efivar/ssdt: Dont iterate over EFI vars if no SSDT override was specified
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit c05f8f92b701576b615f30aac31fabdc0648649b upstream.
The kernel command line option efivar_ssdt= allows the name to be specified of an EFI variable containing an ACPI SSDT table that should be loaded into memory by the OS, and treated as if it was provided by the firmware.
Currently, that code will always iterate over the EFI variables and compare each name with the provided name, even if the command line option wasn't set to begin with.
So bail early when no variable name was provided. This works around a boot regression on the 2012 Mac Pro, as reported by Scott.
--- drivers/firmware/efi/efi.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/firmware/efi/efi.c +3 -0
@@ -282,6 +282,9 @@ static __init int efivar_ssdt_load(void)void *data;int ret; +if (!efivar_ssdt[0 ]) +return 0 ; + ret =efivar_init (efivar_ssdt_iter, &entries, true, &entries);list_for_each_entry_safe (entry, aux, &entries, list) {
Greg Kroah-Hartman
maintainerPATCH 63/112 efi/tpm: Dont access event->count when it isnt mapped
In reply to Greg Kroah-HartmanFrom: Peter Jones <[email protected]>
commit 047d50aee341d940350897c85799e56ae57c3849 upstream.
Some machines generate a lot of event log entries. When we're iterating over them, the code removes the old mapping and adds a new one, so once we cross the page boundary we're unmapping the page with the count on it. Hilarity ensues.
This patch keeps the info from the header in local variables so we don't need to access that page again or keep track of if it's mapped.
--- include/linux/tpm_eventlog.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
include/linux/tpm_eventlog.h +11 -3
@@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_sizeu16 halg;int i;int j; +u32 count, event_type; marker = event; marker_start = marker;
@@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size } event = (struct tcg_pcr_event2_head *)mapping; +/* +* The loop below will unmap these fields if the log is larger than +* one page, so save them here for reference: +*/ + count =READ_ONCE (event->count); + event_type =READ_ONCE (event->event_type); efispecid = (struct tcg_efi_specid_event_head *)event_header->event;/* Check if event is malformed. */ -if (event->count > efispecid->num_algs) { +if (count > efispecid->num_algs) { size =0 ; goto out; } -for (i =0 ; i < event->count; i++) { +for (i =0 ; i < count; i++) { halg_size =sizeof (event->digests[i].alg_id);/* Map the digest's algorithm identifier */
@@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size + event_field->event_size; size = marker - marker_start; -if ((event->event_type ==0 ) && (event_field->event_size ==0 )) +if (event_type ==0 && event_field->event_size ==0 ) size =0 ; + out:if (do_mapping)TPM_MEMUNMAP (mapping, mapping_size);
Greg Kroah-Hartman
maintainerPATCH 64/112 efi/tpm: Dont traverse an event log with no events
In reply to Greg Kroah-HartmanFrom: Peter Jones <[email protected]>
commit 05c8c1ff81ed2eb9bad7c27cf92e55c864c16df8 upstream.
When there are no entries to put into the final event log, some machines will return the template they would have populated anyway. In this case the nr_events field is 0, but the rest of the log is just garbage.
This patch stops us from trying to iterate the table with __calc_tpm2_event_size() when the number of events in the table is 0.
--- drivers/firmware/efi/tpm.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/firmware/efi/tpm.c +10 -5
@@ -75,11 +75,16 @@ int __init efi_tpm_eventlog_init(void) goto out; } - tbl_size =tpm2_calc_event_log_size ((void *)efi.tpm_final_log - +sizeof (final_tbl->version) - +sizeof (final_tbl->nr_events), - final_tbl->nr_events, - log_tbl->log); + tbl_size =0 ; +if (final_tbl->nr_events !=0 ) { +void *events = (void *)efi.tpm_final_log + +sizeof (final_tbl->version) + +sizeof (final_tbl->nr_events); + + tbl_size =tpm2_calc_event_log_size (events, + final_tbl->nr_events, + log_tbl->log); + }memblock_reserve ((unsigned long )final_tbl, tbl_size +sizeof (*final_tbl));early_memunmap (final_tbl,sizeof (*final_tbl));
Greg Kroah-Hartman
maintainerPATCH 65/112 efi/tpm: Only set efi_tpm_final_log_size after successful event log parsing
In reply to Greg Kroah-HartmanFrom: Jerry Snitselaar <[email protected]>
commit e658c82be5561412c5e83b5e74e9da4830593f3e upstream.
If __calc_tpm2_event_size() fails to parse an event it will return 0, resulting tpm2_calc_event_log_size() returning -1. Currently there is no check of this return value, and 'efi_tpm_final_log_size' can end up being set to this negative value resulting in a crash like this one:
BUG: unable to handle page fault for address: ffffbc8fc00866ad #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page RIP: 0010:memcpy_erms+0x6/0x10 Call Trace: tpm_read_log_efi() tpm_bios_log_setup() tpm_chip_register() tpm_tis_core_init.cold.9+0x28c/0x466 tpm_tis_plat_probe() platform_drv_probe() ...
Also __calc_tpm2_event_size() returns a size of 0 when it fails to parse an event, so update function documentation to reflect this.
The root cause of the issue that caused the failure of event parsing in this case is resolved by Peter Jone's patchset dealing with large event logs where crossing over a page boundary causes the page with the event count to be unmapped.
--- drivers/firmware/efi/tpm.c | 9 ++++++++- include/linux/tpm_eventlog.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/firmware/efi/tpm.c +8 -1
@@ -85,11 +85,18 @@ int __init efi_tpm_eventlog_init(void) final_tbl->nr_events, log_tbl->log); } + +if (tbl_size <0 ) { +pr_err (FW_BUG "Failed to parse event in TPM Final Events Log\n" ); + goto out_calc; + } +memblock_reserve ((unsigned long )final_tbl, tbl_size +sizeof (*final_tbl)); -early_memunmap (final_tbl,sizeof (*final_tbl)); efi_tpm_final_log_size = tbl_size; +out_calc: +early_memunmap (final_tbl,sizeof (*final_tbl)); out:early_memunmap (log_tbl,sizeof (*log_tbl));return ret;
include/linux/tpm_eventlog.h +1 -1
@@ -152,7 +152,7 @@ struct tcg_algorithm_info {* total. Once we've done this we know the offset of the data length field, * and can calculate the total size of the event. * -* Return: size of the event on success, <0 on failure +* Return: size of the event on success, 0 on failure */ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
Greg Kroah-Hartman
maintainerPATCH 66/112 perf llvm: Dont access out-of-scope array
In reply to Greg Kroah-HartmanFrom: Ian Rogers <[email protected]>
commit 7d4c85b7035eb2f9ab217ce649dcd1bfaf0cacd3 upstream.
The 'test_dir' variable is assigned to the 'release' array which is out-of-scope 3 lines later.
Extend the scope of the 'release' array so that an out-of-scope array isn't accessed.
Bug detected by clang's address sanitizer.
--- tools/perf/util/llvm-utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/llvm-utils.c +3 -3
@@ -231,14 +231,14 @@ static int detect_kbuild_dir(char **kbuiconst char *prefix_dir ="" ;const char *suffix_dir ="" ; +/* _UTSNAME_LENGTH is 65 */ +char release[128 ]; +char *autoconf_path;int err;if (!test_dir) { -/* _UTSNAME_LENGTH is 65 */ -char release[128 ]; - err =fetch_kernel_version (NULL , release,sizeof (release));if (err)
Greg Kroah-Hartman
maintainerPATCH 67/112 perf inject jit: Fix JIT_CODE_MOVE filename
In reply to Greg Kroah-HartmanFrom: Steve MacLean <[email protected]>
commit b59711e9b0d22fd47abfa00602fd8c365cdd3ab7 upstream.
During perf inject --jit, JIT_CODE_MOVE records were injecting MMAP records with an incorrect filename. Specifically it was missing the ".so" suffix.
Further the JIT_CODE_LOAD record were silently truncating the jr->load.code_index field to 32 bits before generating the filename.
Make both records emit the same filename based on the full 64 bit code_index field.
--- tools/perf/util/jitdump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/jitdump.c +3 -3
@@ -396,7 +396,7 @@ static int jit_repipe_code_load(struct jsize_t size;u16 idr_size;const char *sym; -uint32_t count; +uint64_t count;int ret, csize, usize;pid_t pid, tid;struct {
@@ -419,7 +419,7 @@ static int jit_repipe_code_load(struct jreturn -1 ; filename = event->mmap2.filename; - size =snprintf (filename,PATH_MAX ,"%s/jitted-%d-%u.so" , + size =snprintf (filename,PATH_MAX ,"%s/jitted-%d-%" PRIu64".so" , jd->dir, pid, count);
@@ -530,7 +530,7 @@ static int jit_repipe_code_move(struct jreturn -1 ; filename = event->mmap2.filename; - size =snprintf (filename,PATH_MAX ,"%s/jitted-%d-%" PRIu64, + size =snprintf (filename,PATH_MAX ,"%s/jitted-%d-%" PRIu64".so" , jd->dir, pid, jr->move.code_index);
Greg Kroah-Hartman
maintainerPATCH 68/112 drm/i915: Perform GGTT restore much earlier during resume
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit 6c76a93c453643e11a1063906c7c39168dd8d163 upstream.
As soon as we re-enable the various functions within the HW, they may go off and read data via a GGTT offset. Hence, if we have not yet restored the GGTT PTE before then, they may read and even *write* random locations in memory.
Detected by DMAR faults during resume.
--- drivers/gpu/drm/i915/gem/i915_gem_pm.c | 3 --- drivers/gpu/drm/i915/i915_drv.c | 5 +++++ drivers/gpu/drm/i915/selftests/i915_gem.c | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/gem/i915_gem_pm.c +0 -3
@@ -250,9 +250,6 @@ void i915_gem_resume(struct drm_i915_primutex_lock (&i915->drm.struct_mutex);intel_uncore_forcewake_get (&i915->uncore,FORCEWAKE_ALL ); -i915_gem_restore_gtt_mappings (i915); -i915_gem_restore_fences (i915); -if (i915_gem_init_hw (i915)) goto err_wedged;
drivers/gpu/drm/i915/i915_drv.c +5 -0
@@ -2238,6 +2238,11 @@ static int i915_drm_resume(struct drm_deif (ret)DRM_ERROR ("failed to re-enable GGTT\n" ); +mutex_lock (&dev_priv->drm.struct_mutex); +i915_gem_restore_gtt_mappings (dev_priv); +i915_gem_restore_fences (dev_priv); +mutex_unlock (&dev_priv->drm.struct_mutex); +intel_csr_ucode_resume (dev_priv);i915_restore_state (dev_priv);
drivers/gpu/drm/i915/selftests/i915_gem.c +6 -0
@@ -117,6 +117,12 @@ static void pm_resume(struct drm_i915_pr with_intel_runtime_pm(&i915->runtime_pm, wakeref) {intel_gt_sanitize (i915, false);i915_gem_sanitize (i915); + +mutex_lock (&i915->drm.struct_mutex); +i915_gem_restore_gtt_mappings (i915); +i915_gem_restore_fences (i915); +mutex_unlock (&i915->drm.struct_mutex); +i915_gem_resume (i915); } }
Greg Kroah-Hartman
maintainerPATCH 69/112 blk-wbt: fix performance regression in wbt scale_up/scale_down
In reply to Greg Kroah-HartmanFrom: Harshad Shirwadkar <[email protected]>
commit b84477d3ebb96294f87dc3161e53fa8fe22d9bfd upstream.
scale_up wakes up waiters after scaling up. But after scaling max, it should not wake up more waiters as waiters will not have anything to do. This patch fixes this by making scale_up (and also scale_down) return when threshold is reached.
This bug causes increased fdatasync latency when fdatasync and dd conv=sync are performed in parallel on 4.19 compared to 4.14. This bug was introduced during refactoring of blk-wbt code.
--- block/blk-rq-qos.c | 14 +++++++++----- block/blk-rq-qos.h | 4 ++-- block/blk-wbt.c | 6 ++++-- 3 files changed, 15 insertions(+), 9 deletions(-)
block/blk-rq-qos.c +9 -5
@@ -142,24 +142,27 @@ bool rq_depth_calc_max_depth(struct rq_dreturn ret; } -void rq_depth_scale_up (struct rq_depth *rqd) +/* Returns true on success and false if scaling up wasn't possible */ +bool rq_depth_scale_up (struct rq_depth *rqd) {/* * Hit max in previous round, stop here */ if (rqd->scaled_max) -return ; +return false; rqd->scale_step--; rqd->scaled_max =rq_depth_calc_max_depth (rqd); +return true; }/* * Scale rwb down. If 'hard_throttle' is set, do it quicker, since we -* had a latency violation. +* had a latency violation. Returns true on success and returns false if +* scaling down wasn't possible. */ -void rq_depth_scale_down (struct rq_depth *rqd,bool hard_throttle) +bool rq_depth_scale_down (struct rq_depth *rqd,bool hard_throttle) {/* * Stop scaling down when we've hit the limit. This also prevents
@@ -167,7 +170,7 @@ void rq_depth_scale_down(struct rq_depth* keep up. */ if (rqd->max_depth ==1 ) -return ; +return false;if (rqd->scale_step <0 && hard_throttle) rqd->scale_step =0 ;
@@ -176,6 +179,7 @@ void rq_depth_scale_down(struct rq_depth rqd->scaled_max = false;rq_depth_calc_max_depth (rqd); +return true; }struct rq_qos_wait_data {
block/blk-rq-qos.h +2 -2
@@ -125,8 +125,8 @@ void rq_qos_wait(struct rq_wait *rqw, vo acquire_inflight_cb_t *acquire_inflight_cb, cleanup_cb_t *cleanup_cb);bool rq_wait_inc_below (struct rq_wait *rq_wait,unsigned int limit); -void rq_depth_scale_up (struct rq_depth *rqd); -void rq_depth_scale_down (struct rq_depth *rqd,bool hard_throttle); +bool rq_depth_scale_up (struct rq_depth *rqd); +bool rq_depth_scale_down (struct rq_depth *rqd,bool hard_throttle);bool rq_depth_calc_max_depth (struct rq_depth *rqd);void __rq_qos_cleanup (struct rq_qos *rqos,struct bio *bio);
block/blk-wbt.c +4 -2
@@ -308,7 +308,8 @@ static void calc_wb_limits(struct rq_wbstatic void scale_up (struct rq_wb *rwb) { -rq_depth_scale_up (&rwb->rq_depth); +if (!rq_depth_scale_up (&rwb->rq_depth)) +return ;calc_wb_limits (rwb); rwb->unknown_cnt =0 ;rwb_wake_all (rwb);
@@ -317,7 +318,8 @@ static void scale_up(struct rq_wb *rwb)static void scale_down (struct rq_wb *rwb,bool hard_throttle) { -rq_depth_scale_down (&rwb->rq_depth, hard_throttle); +if (!rq_depth_scale_down (&rwb->rq_depth, hard_throttle)) +return ;calc_wb_limits (rwb); rwb->unknown_cnt =0 ;rwb_trace_step (rwb,"scale down" );
Greg Kroah-Hartman
maintainerPATCH 70/112 selinux: fix context string corruption in convert_context()
In reply to Greg Kroah-HartmanFrom: Ondrej Mosnacek <[email protected]>
commit 2a5243937c700ffe6a28e6557a4562a9ab0a17a4 upstream.
string_to_context_struct() may garble the context string, so we need to copy back the contents again from the old context struct to avoid storing the corrupted context.
Since string_to_context_struct() tokenizes (and therefore truncates) the context string and we are later potentially copying it with kstrdup(), this may eventually cause pieces of uninitialized kernel memory to be disclosed to userspace (when copying to userspace based on the stored length and not the null character).
How to reproduce on Fedora and similar:
# dnf install -y memcached
# systemctl start memcached
# semodule -d memcached
# load_policy
# load_policy
# systemctl stop memcached
# ausearch -m AVC
type=AVC msg=audit(1570090572.648:313): avc: denied { signal } for pid=1 comm="systemd" scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=process permissive=0 trawcon=73797374656D5F75007400000000000070BE6E847296FFFF726F6D000096FFFF76--- security/selinux/ss/services.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
security/selinux/ss/services.c +8 -1
@@ -1946,7 +1946,14 @@ static int convert_context(struct contex rc =string_to_context_struct (args->newp,NULL , s, newc,SECSID_NULL );if (rc == -EINVAL ) { -/* Retain string representation for later mapping. */ +/* +* Retain string representation for later mapping. +* +* IMPORTANT: We need to copy the contents of oldc->str +* back into s again because string_to_context_struct() +* may have garbled it. +*/ +memcpy (s, oldc->str, oldc->len);context_init (newc); newc->str = s; newc->len = oldc->len;
Greg Kroah-Hartman
maintainerPATCH 71/112 CIFS: Gracefully handle QueryInfo errors during open
In reply to Greg Kroah-HartmanFrom: Pavel Shilovsky <[email protected]>
commit 30573a82fb179420b8aac30a3a3595aa96a93156 upstream.
Currently if the client identifies problems when processing metadata returned in CREATE response, the open handle is being leaked. This causes multiple problems like a file missing a lease break by that client which causes high latencies to other clients accessing the file. Another side-effect of this is that the file can't be deleted.
Fix this by closing the file after the client hits an error after the file was opened and the open descriptor wasn't returned to the user space. Also convert -ESTALE to -EOPENSTALE to allow the VFS to revalidate a dentry and retry the open.
--- fs/cifs/file.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/cifs/file.c +6 -0
@@ -253,6 +253,12 @@ cifs_nt_open(char *full_path, struct ino rc =cifs_get_inode_info (&inode, full_path, buf, inode->i_sb, xid, fid); +if (rc) { + server->ops->close (xid, tcon, fid); +if (rc == -ESTALE ) + rc = -EOPENSTALE ; + } + out:kfree (buf);return rc;
Greg Kroah-Hartman
maintainerPATCH 72/112 CIFS: Force revalidate inode when dentry is stale
In reply to Greg Kroah-HartmanFrom: Pavel Shilovsky <[email protected]>
commit c82e5ac7fe3570a269c0929bf7899f62048e7dbc upstream.
Currently the client indicates that a dentry is stale when inode numbers or type types between a local inode and a remote file don't match. If this is the case attributes is not being copied from remote to local, so, it is already known that the local copy has stale metadata. That's why the inode needs to be marked for revalidation in order to tell the VFS to lookup the dentry again before openning a file. This prevents unexpected stale errors to be returned to the user space when openning a file.
--- fs/cifs/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/cifs/inode.c +4 -0
@@ -414,6 +414,7 @@ int cifs_get_inode_info_unix(struct inod/* if uniqueid is different, return error */ if (unlikely (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM &&CIFS_I (*pinode)->uniqueid != fattr.cf_uniqueid)) { +CIFS_I (*pinode)->time =0 ;/* force reval */ rc = -ESTALE ; goto cgiiu_exit; }
@@ -421,6 +422,7 @@ int cifs_get_inode_info_unix(struct inod/* if filetype is different, return error */ if (unlikely (((*pinode)->i_mode &S_IFMT ) != (fattr.cf_mode &S_IFMT ))) { +CIFS_I (*pinode)->time =0 ;/* force reval */ rc = -ESTALE ; goto cgiiu_exit; }
@@ -924,6 +926,7 @@ cifs_get_inode_info(struct inode **inode/* if uniqueid is different, return error */ if (unlikely (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM &&CIFS_I (*inode)->uniqueid != fattr.cf_uniqueid)) { +CIFS_I (*inode)->time =0 ;/* force reval */ rc = -ESTALE ; goto cgii_exit; }
@@ -931,6 +934,7 @@ cifs_get_inode_info(struct inode **inode/* if filetype is different, return error */ if (unlikely (((*inode)->i_mode &S_IFMT ) != (fattr.cf_mode &S_IFMT ))) { +CIFS_I (*inode)->time =0 ;/* force reval */ rc = -ESTALE ; goto cgii_exit; }
Greg Kroah-Hartman
maintainerPATCH 73/112 CIFS: Force reval dentry if LOOKUP_REVAL flag is set
In reply to Greg Kroah-HartmanFrom: Pavel Shilovsky <[email protected]>
commit 0b3d0ef9840f7be202393ca9116b857f6f793715 upstream.
Mark inode for force revalidation if LOOKUP_REVAL flag is set. This tells the client to actually send a QueryInfo request to the server to obtain the latest metadata in case a directory or a file were changed remotely. Only do that if the client doesn't have a lease for the file to avoid unneeded round trips to the server.
--- fs/cifs/dir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/cifs/dir.c +7 -1
@@ -738,10 +738,16 @@ cifs_lookup(struct inode *parent_dir_inostatic int cifs_d_revalidate (struct dentry *direntry,unsigned int flags) { +struct inode *inode; +if (flags &LOOKUP_RCU )return -ECHILD ;if (d_really_is_positive (direntry)) { + inode =d_inode (direntry); +if ((flags &LOOKUP_REVAL ) && !CIFS_CACHE_READ (CIFS_I (inode))) +CIFS_I (inode)->time =0 ;/* force reval */ +if (cifs_revalidate_dentry (direntry))return 0 ;else {
@@ -752,7 +758,7 @@ cifs_d_revalidate(struct dentry *direntr* attributes will have been updated by * cifs_revalidate_dentry(). */ -if (IS_AUTOMOUNT (d_inode (direntry)) && +if (IS_AUTOMOUNT (inode) && !(direntry->d_flags &DCACHE_NEED_AUTOMOUNT )) {spin_lock (&direntry->d_lock); direntry->d_flags |=DCACHE_NEED_AUTOMOUNT ;
Greg Kroah-Hartman
maintainerPATCH 74/112 cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic
In reply to Greg Kroah-HartmanFrom: Dave Wysochanski <[email protected]>
commit cb248819d209d113e45fed459773991518e8e80b upstream.
Commit 487317c99477 ("cifs: add spinlock for the openFileList to cifsInodeInfo") added cifsInodeInfo->open_file_lock spin_lock to protect the openFileList, but missed a few places where cifs_inode->openFileList was enumerated. Change these remaining tcon->open_file_lock to cifsInodeInfo->open_file_lock to avoid panic in is_size_safe_to_change.
[17313.245641] RIP: 0010:is_size_safe_to_change+0x57/0xb0 [cifs] [17313.245645] Code: 68 40 48 89 ef e8 19 67 b7 f1 48 8b 43 40 48 8d 4b 40 48 8d 50 f0 48 39 c1 75 0f eb 47 48 8b 42 10 48 8d 50 f0 48 39 c1 74 3a <8b> 80 88 00 00 00 83 c0 01 a8 02 74 e6 48 89 ef c6 07 00 0f 1f 40 [17313.245649] RSP: 0018:ffff94ae1baefa30 EFLAGS: 00010202 [17313.245654] RAX: dead000000000100 RBX: ffff88dc72243300 RCX: ffff88dc72243340 [17313.245657] RDX: dead0000000000f0 RSI: 00000000098f7940 RDI: ffff88dd3102f040 [17313.245659] RBP: ffff88dd3102f040 R08: 0000000000000000 R09: ffff94ae1baefc40 [17313.245661] R10: ffffcdc8bb1c4e80 R11: ffffcdc8b50adb08 R12: 00000000098f7940 [17313.245663] R13: ffff88dc72243300 R14: ffff88dbc8f19600 R15: ffff88dc72243428 [17313.245667] FS: 00007fb145485700(0000) GS:ffff88dd3e000000(0000) knlGS:0000000000000000 [17313.245670] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [17313.245672] CR2: 0000026bb46c6000 CR3: 0000004edb110003 CR4: 00000000007606e0 [17313.245753] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [17313.245756] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [17313.245759] PKRU: 55555554 [17313.245761] Call Trace: [17313.245803] cifs_fattr_to_inode+0x16b/0x580 [cifs] [17313.245838] cifs_get_inode_info+0x35c/0xa60 [cifs] [17313.245852] ? kmem_cache_alloc_trace+0x151/0x1d0 [17313.245885] cifs_open+0x38f/0x990 [cifs] [17313.245921] ? cifs_revalidate_dentry_attr+0x3e/0x350 [cifs] [17313.245953] ? cifsFileInfo_get+0x30/0x30 [cifs] [17313.245960] ? do_dentry_open+0x132/0x330 [17313.245963] do_dentry_open+0x132/0x330 [17313.245969] path_openat+0x573/0x14d0 [17313.245974] do_filp_open+0x93/0x100 [17313.245979] ? __check_object_size+0xa3/0x181 [17313.245986] ? audit_alloc_name+0x7e/0xd0 [17313.245992] do_sys_open+0x184/0x220 [17313.245999] do_syscall_64+0x5b/0x1b0
--- fs/cifs/file.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-)
fs/cifs/file.c +11 -16
@@ -1853,13 +1853,12 @@ struct cifsFileInfo *find_readable_file( {struct cifsFileInfo *open_file =NULL ;struct cifs_sb_info *cifs_sb =CIFS_SB (cifs_inode->vfs_inode.i_sb); -struct cifs_tcon *tcon =cifs_sb_master_tcon (cifs_sb);/* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MULTIUSER )) fsuid_only = false; -spin_lock (&tcon->open_file_lock); +spin_lock (&cifs_inode->open_file_lock);/* we could simply get the first_list_entry since write-only entries are always at the end of the list but since the first entry might have a close pending, we go through the whole list */
@@ -1871,7 +1870,7 @@ struct cifsFileInfo *find_readable_file(/* found a good file */ /* lock it so it will not be closed on us */ cifsFileInfo_get (open_file); -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);return open_file; }/* else might as well continue, and look for another, or simply have the caller reopen it
@@ -1879,7 +1878,7 @@ struct cifsFileInfo *find_readable_file( }else /* write only file */ break ;/* write only files are last so must be done */ } -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);return NULL ; }
@@ -1890,7 +1889,6 @@ cifs_get_writable_file(struct cifsInodeI {struct cifsFileInfo *open_file, *inv_file =NULL ;struct cifs_sb_info *cifs_sb; -struct cifs_tcon *tcon;bool any_available = false;int rc = -EBADF ;unsigned int refind =0 ;
@@ -1910,16 +1908,15 @@ cifs_get_writable_file(struct cifsInodeI } cifs_sb =CIFS_SB (cifs_inode->vfs_inode.i_sb); - tcon =cifs_sb_master_tcon (cifs_sb);/* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MULTIUSER )) fsuid_only = false; -spin_lock (&tcon->open_file_lock); +spin_lock (&cifs_inode->open_file_lock); refind_writable:if (refind >MAX_REOPEN_ATT ) { -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);return rc; }list_for_each_entry (open_file, &cifs_inode->openFileList, flist) {
@@ -1931,7 +1928,7 @@ refind_writable:if (!open_file->invalidHandle) {/* found a good writable file */ cifsFileInfo_get (open_file); -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock); *ret_file = open_file;return 0 ; }else {
@@ -1951,7 +1948,7 @@ refind_writable:cifsFileInfo_get (inv_file); } -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);if (inv_file) { rc =cifs_reopen_file (inv_file, false);
@@ -1966,7 +1963,7 @@ refind_writable:cifsFileInfo_put (inv_file); ++refind; inv_file =NULL ; -spin_lock (&tcon->open_file_lock); +spin_lock (&cifs_inode->open_file_lock); goto refind_writable; }
@@ -4405,17 +4402,15 @@ static int cifs_readpage(struct file *fistatic int is_inode_writable (struct cifsInodeInfo *cifs_inode) {struct cifsFileInfo *open_file; -struct cifs_tcon *tcon = -cifs_sb_master_tcon (CIFS_SB (cifs_inode->vfs_inode.i_sb)); -spin_lock (&tcon->open_file_lock); +spin_lock (&cifs_inode->open_file_lock);list_for_each_entry (open_file, &cifs_inode->openFileList, flist) {if (OPEN_FMODE (open_file->f_flags) &FMODE_WRITE ) { -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);return 1 ; } } -spin_unlock (&tcon->open_file_lock); +spin_unlock (&cifs_inode->open_file_lock);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 75/112 kernel/sysctl.c: do not override max_threads provided by userspace
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
commit b0f53dbc4bc4c371f38b14c391095a3bb8a0bb40 upstream.
Partially revert 16db3d3f1170 ("kernel/sysctl.c: threads-max observe limits") because the patch is causing a regression to any workload which needs to override the auto-tuning of the limit provided by kernel.
set_max_threads is implementing a boot time guesstimate to provide a sensible limit of the concurrently running threads so that runaways will not deplete all the memory. This is a good thing in general but there are workloads which might need to increase this limit for an application to run (reportedly WebSpher MQ is affected) and that is simply not possible after the mentioned change. It is also very dubious to override an admin decision by an estimation that doesn't have any direct relation to correctness of the kernel operation.
Fix this by dropping set_max_threads from sysctl_max_threads so any value is accepted as long as it fits into MAX_THREADS which is important to check because allowing more threads could break internal robust futex restriction. While at it, do not use MIN_THREADS as the lower boundary because it is also only a heuristic for automatic estimation and admin might have a good reason to stop new threads to be created even when below this limit.
This became more severe when we switched x86 from 4k to 8k kernel stacks. Starting since 6538b8ea886e ("x86_64: expand kernel stack to 16K") (3.16) we use THREAD_SIZE_ORDER = 2 and that halved the auto-tuned value.
In the particular case
3.12
kernel.threads-max = 515561
4.4
kernel.threads-max = 200000
Neither of the two values is really insane on 32GB machine.
I am not sure we want/need to tune the max_thread value further. If anything the tuning should be removed altogether if proven not useful in general. But we definitely need a way to override this auto-tuning.
--- kernel/fork.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/fork.c +2 -2
@@ -2939,7 +2939,7 @@ int sysctl_max_threads(struct ctl_tablestruct ctl_table t;int ret;int threads = max_threads; -int min =MIN_THREADS ; +int min =1 ;int max =MAX_THREADS ; t = *table;
@@ -2951,7 +2951,7 @@ int sysctl_max_threads(struct ctl_tableif (ret || !write)return ret; -set_max_threads (threads); + max_threads = threads;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 76/112 mm/z3fold.c: claim page in the beginning of free
In reply to Greg Kroah-HartmanFrom: Vitaly Wool <[email protected]>
commit 5b6807de11445c05b537df8324f5d7ab1c2782f9 upstream.
There's a really hard to reproduce race in z3fold between z3fold_free() and z3fold_reclaim_page(). z3fold_reclaim_page() can claim the page after z3fold_free() has checked if the page was claimed and z3fold_free() will then schedule this page for compaction which may in turn lead to random page faults (since that page would have been reclaimed by then).
Fix that by claiming page in the beginning of z3fold_free() and not forgetting to clear the claim in the end.
--- mm/z3fold.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
mm/z3fold.c +8 -2
@@ -998,9 +998,11 @@ static void z3fold_free(struct z3fold_postruct z3fold_header *zhdr;struct page *page;enum buddy bud; +bool page_claimed; zhdr =handle_to_z3fold_header (handle); page =virt_to_page (zhdr); + page_claimed =test_and_set_bit (PAGE_CLAIMED , &page->private);if (test_bit (PAGE_HEADLESS , &page->private)) {/* if a headless page is under reclaim, just leave.
@@ -1008,7 +1010,7 @@ static void z3fold_free(struct z3fold_po* has not been set before, we release this page * immediately so we don't care about its value any more. */ -if (!test_and_set_bit (PAGE_CLAIMED , &page->private)) { +if (!page_claimed) {spin_lock (&pool->lock);list_del (&page->lru);spin_unlock (&pool->lock);
@@ -1044,13 +1046,15 @@ static void z3fold_free(struct z3fold_poatomic64_dec (&pool->pages_nr);return ; } -if (test_bit (PAGE_CLAIMED , &page->private)) { +if (page_claimed) { +/* the page has not been claimed by us */ z3fold_page_unlock (zhdr);return ; }if (unlikely (PageIsolated (page)) ||test_and_set_bit (NEEDS_COMPACTING , &page->private)) {z3fold_page_unlock (zhdr); +clear_bit (PAGE_CLAIMED , &page->private);return ; }if (zhdr->cpu <0 || !cpu_online (zhdr->cpu)) {
@@ -1060,10 +1064,12 @@ static void z3fold_free(struct z3fold_po zhdr->cpu =-1 ;kref_get (&zhdr->refcount);do_compact_page (zhdr, true); +clear_bit (PAGE_CLAIMED , &page->private);return ; }kref_get (&zhdr->refcount);queue_work_on (zhdr->cpu, pool->compact_wq, &zhdr->work); +clear_bit (PAGE_CLAIMED , &page->private);z3fold_page_unlock (zhdr); }
Greg Kroah-Hartman
maintainerPATCH 77/112 mm/page_alloc.c: fix a crash in free_pages_prepare()
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
commit 234fdce892f905cbc2674349a9eb4873e288e5b3 upstream.
On architectures like s390, arch_free_page() could mark the page unused (set_page_unused()) and any access later would trigger a kernel panic. Fix it by moving arch_free_page() after all possible accessing calls.
Hardware name: IBM 2964 N96 400 (z/VM 6.4.0)
Krnl PSW : 0404e00180000000 0000000026c2b96e (__free_pages_ok+0x34e/0x5d8)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
Krnl GPRS: 0000000088d43af7 0000000000484000 000000000000007c 000000000000000f
000003d080012100 000003d080013fc0 0000000000000000 0000000000100000
00000000275cca48 0000000000000100 0000000000000008 000003d080010000
00000000000001d0 000003d000000000 0000000026c2b78a 000000002717fdb0
Krnl Code: 0000000026c2b95c: ec1100b30659 risbgn %r1,%r1,0,179,6
0000000026c2b962: e32014000036 pfd 2,1024(%r1)
#0000000026c2b968: d7ff10001000 xc 0(256,%r1),0(%r1)
>0000000026c2b96e: 41101100 la %r1,256(%r1)
0000000026c2b972: a737fff8 brctg %r3,26c2b962
0000000026c2b976: d7ff10001000 xc 0(256,%r1),0(%r1)
0000000026c2b97c: e31003400004 lg %r1,832
0000000026c2b982: ebff1430016a asi 5168(%r1),-1
Call Trace:
__free_pages_ok+0x16a/0x5d8)
memblock_free_all+0x206/0x290
mem_init+0x58/0x120
start_kernel+0x2b0/0x570
startup_continue+0x6a/0xc0
INFO: lockdep is turned off.
Last Breaking-Event-Address:
__free_pages_ok+0x372/0x5d8
Kernel panic - not syncing: Fatal exception: panic_on_oops
00: HCPGIR450W CP entered; disabled wait PSW 00020001 80000000 00000000 26A2379CIn the past, only kernel_poison_pages() would trigger this but it needs "page_poison=on" kernel cmdline, and I suspect nobody tested that on s390. Recently, kernel_init_free_pages() (commit 6471384af2a6 ("mm:
security: introduce init_on_alloc=1 and init_on_free=1 boot options")) was added and could trigger this as well.
--- mm/page_alloc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/page_alloc.c +7 -1
@@ -1174,11 +1174,17 @@ static __always_inline bool free_pages_pdebug_check_no_obj_freed (page_address (page),PAGE_SIZE << order); } -arch_free_page (page, order);if (want_init_on_free ())kernel_init_free_pages (page,1 << order);kernel_poison_pages (page,1 << order,0 ); +/* +* arch_free_page() can make the page's contents inaccessible. s390 +* does this. So nothing which can access the page's contents should +* happen after this. +*/ +arch_free_page (page, order); +if (debug_pagealloc_enabled ())kernel_map_pages (page,1 << order,0 );
Greg Kroah-Hartman
maintainerPATCH 78/112 mm/vmpressure.c: fix a signedness bug in vmpressure_register_event()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 518a86713078168acd67cf50bc0b45d54b4cce6c upstream.
The "mode" and "level" variables are enums and in this context GCC will treat them as unsigned ints so the error handling is never triggered.
I also removed the bogus initializer because it isn't required any more and it's sort of confusing.
--- mm/vmpressure.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
mm/vmpressure.c +11 -9
@@ -355,6 +355,9 @@ void vmpressure_prio(gfp_t gfp, struct m* "hierarchy" or "local"). * * To be used as memcg event method. +* +* Return: 0 on success, -ENOMEM on memory failure or -EINVAL if @args could +* not be parsed. */ int vmpressure_register_event (struct mem_cgroup *memcg,struct eventfd_ctx *eventfd,const char *args)
@@ -362,7 +365,7 @@ int vmpressure_register_event(struct memstruct vmpressure *vmpr =memcg_to_vmpressure (memcg);struct vmpressure_event *ev;enum vmpressure_modes mode =VMPRESSURE_NO_PASSTHROUGH ; -enum vmpressure_levels level =-1 ; +enum vmpressure_levels level;char *spec, *spec_orig;char *token;int ret =0 ;
@@ -375,20 +378,18 @@ int vmpressure_register_event(struct mem/* Find required level */ token =strsep (&spec,"," ); - level =match_string (vmpressure_str_levels,VMPRESSURE_NUM_LEVELS , token); -if (level <0 ) { - ret = level; + ret =match_string (vmpressure_str_levels,VMPRESSURE_NUM_LEVELS , token); +if (ret <0 ) goto out; - } + level = ret;/* Find optional mode */ token =strsep (&spec,"," );if (token) { - mode =match_string (vmpressure_str_modes,VMPRESSURE_NUM_MODES , token); -if (mode <0 ) { - ret = mode; + ret =match_string (vmpressure_str_modes,VMPRESSURE_NUM_MODES , token); +if (ret <0 ) goto out; - } + mode = ret; } ev =kzalloc (sizeof (*ev),GFP_KERNEL );
@@ -404,6 +405,7 @@ int vmpressure_register_event(struct memmutex_lock (&vmpr->events_lock);list_add (&ev->node, &vmpr->events);mutex_unlock (&vmpr->events_lock); + ret =0 ; out:kfree (spec_orig);return ret;
Greg Kroah-Hartman
maintainerPATCH 79/112 IB/core: Fix wrong iterating on ports
In reply to Greg Kroah-HartmanFrom: Mohamad Heib <[email protected]>
commit 1cbe866cbcb53338de33cf67262e73f9315a9725 upstream.
rdma_for_each_port is already incrementing the iterator's value it receives therefore, after the first iteration the iterator is increased by 2 which eventually causing wrong queries and possible traces.
Fix the above by removing the old redundant incrementation that was used before rdma_for_each_port() macro.
--- drivers/infiniband/core/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/security.c +1 -1
@@ -426,7 +426,7 @@ int ib_create_qp_security(struct ib_qp *int ret; rdma_for_each_port (dev, i) { - is_ib =rdma_protocol_ib (dev, i++); + is_ib =rdma_protocol_ib (dev, i);if (is_ib)break ; }
Greg Kroah-Hartman
maintainerPATCH 80/112 firmware: google: increment VPD key_len properly
In reply to Greg Kroah-HartmanFrom: Brian Norris <[email protected]>
[ Upstream commit 442f1e746e8187b9deb1590176f6b0ff19686b11 ]
Commit 4b708b7b1a2c ("firmware: google: check if size is valid when decoding VPD data") adds length checks, but the new vpd_decode_entry() function botched the logic -- it adds the key length twice, instead of adding the key and value lengths separately.
On my local system, this means vpd.c's vpd_section_create_attribs() hits an error case after the first attribute it parses, since it's no longer looking at the correct offset. With this patch, I'm back to seeing all the correct attributes in /sys/firmware/vpd/...
--- drivers/firmware/google/vpd_decode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/google/vpd_decode.c +1 -1
@@ -52,7 +52,7 @@ static int vpd_decode_entry(const u32 max_len, const u8 *input_buf,if (max_len - consumed < *entry_len)return VPD_FAIL ; - consumed += decoded_len; + consumed += *entry_len; *_consumed = consumed;return VPD_OK ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 81/112 gpio: fix getting nonexclusive gpiods from DT
In reply to Greg Kroah-HartmanFrom: Marco Felsch <[email protected]>
[ Upstream commit be7ae45cfea97e787234e00e1a9eb341acacd84e ]
Since commit ec757001c818 ("gpio: Enable nonexclusive gpiods from DT nodes") we are able to get GPIOD_FLAGS_BIT_NONEXCLUSIVE marked gpios. Currently the gpiolib uses the wrong flags variable for the check. We need to check the gpiod_flags instead of the of_gpio_flags else we return -EBUSY for GPIOD_FLAGS_BIT_NONEXCLUSIVE marked and requested gpiod's.
--- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpiolib.c +1 -1
@@ -4303,7 +4303,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, transitory = flags &OF_GPIO_TRANSITORY ; ret =gpiod_request (desc, label); -if (ret == -EBUSY && (flags &GPIOD_FLAGS_BIT_NONEXCLUSIVE )) +if (ret == -EBUSY && (dflags &GPIOD_FLAGS_BIT_NONEXCLUSIVE ))return desc;if (ret)return ERR_PTR (ret);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 82/112 gpiolib: dont clear FLAG_IS_OUT when emulating open-drain/open-source
In reply to Greg Kroah-HartmanFrom: Bartosz Golaszewski <[email protected]>
[ Upstream commit e735244e2cf068f98b6384681a38993e0517a838 ]
When emulating open-drain/open-source by not actively driving the output lines - we're simply changing their mode to input. This is wrong as it will then make it impossible to change the value of such line - it's now considered to actually be in input mode. If we want to still use the direction_input() callback for simplicity then we need to set FLAG_IS_OUT manually in gpiod_direction_output() and not clear it in gpio_set_open_drain_value_commit() and gpio_set_open_source_value_commit().
--- drivers/gpio/gpiolib.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
drivers/gpio/gpiolib.c +19 -8
@@ -2775,8 +2775,10 @@ int gpiod_direction_output(struct gpio_dif (!ret) goto set_output_value;/* Emulate open drain by not actively driving the line high */ -if (value) -return gpiod_direction_input (desc); +if (value) { + ret =gpiod_direction_input (desc); + goto set_output_flag; + } }else if (test_bit (FLAG_OPEN_SOURCE , &desc->flags)) { ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
@@ -2784,8 +2786,10 @@ int gpiod_direction_output(struct gpio_dif (!ret) goto set_output_value;/* Emulate open source by not actively driving the line low */ -if (!value) -return gpiod_direction_input (desc); +if (!value) { + ret =gpiod_direction_input (desc); + goto set_output_flag; + } }else {gpio_set_config (gc,gpio_chip_hwgpio (desc),PIN_CONFIG_DRIVE_PUSH_PULL );
@@ -2793,6 +2797,17 @@ int gpiod_direction_output(struct gpio_d set_output_value:return gpiod_direction_output_raw_commit (desc, value); + +set_output_flag: +/* +* When emulating open-source or open-drain functionalities by not +* actively driving the line (setting mode to input) we still need to +* set the IS_OUT flag or otherwise we won't be able to set the line +* value anymore. +*/ +if (ret ==0 ) +set_bit (FLAG_IS_OUT , &desc->flags); +return ret; }EXPORT_SYMBOL_GPL (gpiod_direction_output);
@@ -3153,8 +3168,6 @@ static void gpio_set_open_drain_value_coif (value) { err = chip->direction_input (chip, offset); -if (!err) -clear_bit (FLAG_IS_OUT , &desc->flags); }else { err = chip->direction_output (chip, offset,0 );if (!err)
@@ -3184,8 +3197,6 @@ static void gpio_set_open_source_value_cset_bit (FLAG_IS_OUT , &desc->flags); }else { err = chip->direction_input (chip, offset); -if (!err) -clear_bit (FLAG_IS_OUT , &desc->flags); }trace_gpio_direction (desc_to_gpio (desc), !value, err);if (err <0 )
Greg Kroah-Hartman
maintainerPATCH 83/112 btrfs: relocation: fix use-after-free on dead relocation roots
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit 1fac4a54374f7ef385938f3c6cf7649c0fe4f6cd upstream.
[BUG]
One user reported a reproducible KASAN report about use-after-free:
BTRFS info (device sdi1): balance: start -dvrange=1256811659264..1256811659265 BTRFS info (device sdi1): relocating block group 1256811659264 flags data|raid0
==================================================================
BUG: KASAN: use-after-free in btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
Write of size 8 at addr ffff88856f671710 by task kworker/u24:10/261579
CPU: 2 PID: 261579 Comm: kworker/u24:10 Tainted: P OE 5.2.11-arch1-1-kasan #4
Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./X99 Extreme4, BIOS P3.80 04/06/2018
Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs]
Call Trace:
dump_stack+0x7b/0xba
print_address_description+0x6c/0x22e
? btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
__kasan_report.cold+0x1b/0x3b
? btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
kasan_report+0x12/0x17
__asan_report_store8_noabort+0x17/0x20
btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
record_root_in_trans+0x2a0/0x370 [btrfs]
btrfs_record_root_in_trans+0xf4/0x140 [btrfs]
start_transaction+0x1ab/0xe90 [btrfs]
btrfs_join_transaction+0x1d/0x20 [btrfs]
btrfs_finish_ordered_io+0x7bf/0x18a0 [btrfs]
? lock_repin_lock+0x400/0x400
? __kmem_cache_shutdown.cold+0x140/0x1ad
? btrfs_unlink_subvol+0x9b0/0x9b0 [btrfs]
finish_ordered_fn+0x15/0x20 [btrfs]
normal_work_helper+0x1bd/0xca0 [btrfs]
? process_one_work+0x819/0x1720
? kasan_check_read+0x11/0x20
btrfs_endio_write_helper+0x12/0x20 [btrfs]
process_one_work+0x8c9/0x1720
? pwq_dec_nr_in_flight+0x2f0/0x2f0
? worker_thread+0x1d9/0x1030
worker_thread+0x98/0x1030
kthread+0x2bb/0x3b0
? process_one_work+0x1720/0x1720
? kthread_park+0x120/0x120
ret_from_fork+0x35/0x40
Allocated by task 369692:
__kasan_kmalloc.part.0+0x44/0xc0
__kasan_kmalloc.constprop.0+0xba/0xc0
kasan_kmalloc+0x9/0x10
kmem_cache_alloc_trace+0x138/0x260
btrfs_read_tree_root+0x92/0x360 [btrfs]
btrfs_read_fs_root+0x10/0xb0 [btrfs]
create_reloc_root+0x47d/0xa10 [btrfs]
btrfs_init_reloc_root+0x1e2/0x340 [btrfs]
record_root_in_trans+0x2a0/0x370 [btrfs]
btrfs_record_root_in_trans+0xf4/0x140 [btrfs]
start_transaction+0x1ab/0xe90 [btrfs]
btrfs_start_transaction+0x1e/0x20 [btrfs]
__btrfs_prealloc_file_range+0x1c2/0xa00 [btrfs]
btrfs_prealloc_file_range+0x13/0x20 [btrfs]
prealloc_file_extent_cluster+0x29f/0x570 [btrfs]
relocate_file_extent_cluster+0x193/0xc30 [btrfs]
relocate_data_extent+0x1f8/0x490 [btrfs]
relocate_block_group+0x600/0x1060 [btrfs]
btrfs_relocate_block_group+0x3a0/0xa00 [btrfs]
btrfs_relocate_chunk+0x9e/0x180 [btrfs]
btrfs_balance+0x14e4/0x2fc0 [btrfs]
btrfs_ioctl_balance+0x47f/0x640 [btrfs]
btrfs_ioctl+0x119d/0x8380 [btrfs]
do_vfs_ioctl+0x9f5/0x1060
ksys_ioctl+0x67/0x90
__x64_sys_ioctl+0x73/0xb0
do_syscall_64+0xa5/0x370
entry_SYSCALL_64_after_hwframe+0x44/0xa9
Freed by task 369692:
__kasan_slab_free+0x14f/0x210
kasan_slab_free+0xe/0x10
kfree+0xd8/0x270
btrfs_drop_snapshot+0x154c/0x1eb0 [btrfs]
clean_dirty_subvols+0x227/0x340 [btrfs]
relocate_block_group+0x972/0x1060 [btrfs]
btrfs_relocate_block_group+0x3a0/0xa00 [btrfs]
btrfs_relocate_chunk+0x9e/0x180 [btrfs]
btrfs_balance+0x14e4/0x2fc0 [btrfs]
btrfs_ioctl_balance+0x47f/0x640 [btrfs]
btrfs_ioctl+0x119d/0x8380 [btrfs]
do_vfs_ioctl+0x9f5/0x1060
ksys_ioctl+0x67/0x90
__x64_sys_ioctl+0x73/0xb0
do_syscall_64+0xa5/0x370
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The buggy address belongs to the object at ffff88856f671100
which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 1552 bytes inside of
4096-byte region [ffff88856f671100, ffff88856f672100)
The buggy address belongs to the page:
page:ffffea0015bd9c00 refcount:1 mapcount:0 mapping:ffff88864400e600 index:0x0 compound_mapcount: 0
flags: 0x2ffff0000010200(slab|head)
raw: 02ffff0000010200 dead000000000100 dead000000000200 ffff88864400e600
raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88856f671600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88856f671680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88856f671700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88856f671780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88856f671800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
BTRFS info (device sdi1): 1 enospc errors during balance
BTRFS info (device sdi1): balance: ended with status: -28[CAUSE]
The problem happens when finish_ordered_io() get called with balance still running, while the reloc root of that subvolume is already dead. (Tree is swap already done, but tree not yet deleted for possible qgroup usage.)
That means root->reloc_root still exists, but that reloc_root can be under btrfs_drop_snapshot(), thus we shouldn't access it.
The following race could cause the use-after-free problem:
CPU1 | CPU2
--------------------------------------------------------------------------
| relocate_block_group()
| |- unset_reloc_control(rc)
| |- btrfs_commit_transaction()
btrfs_finish_ordered_io() | |- clean_dirty_subvols()
|- btrfs_join_transaction() | |
|- record_root_in_trans() | |
|- btrfs_init_reloc_root() | |
|- if (root->reloc_root) | |
| | |- root->reloc_root = NULL
| | |- btrfs_drop_snapshot(reloc_root);
|- reloc_root->last_trans|
= trans->transid |
^^^^^^^^^^^^^^^^^^^^^^
Use after free[FIX]
Fix it by the following modifications:
- Test if the root has dead reloc tree before accessing root->reloc_root If the root has BTRFS_ROOT_DEAD_RELOC_TREE, then we don't need to create or update root->reloc_tree
- Clear the BTRFS_ROOT_DEAD_RELOC_TREE flag until we have fully dropped reloc tree
To co-operate with above modification, so as long as BTRFS_ROOT_DEAD_RELOC_TREE is still set, we won't try to re-create reloc tree at record_root_in_trans().
--- fs/btrfs/relocation.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/btrfs/relocation.c +8 -1
@@ -1434,6 +1434,13 @@ int btrfs_init_reloc_root(struct btrfs_tint clear_rsv =0 ;int ret; +/* +* The subvolume has reloc tree but the swap is finished, no need to +* create/update the dead reloc tree +*/ +if (test_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state)) +return 0 ; +if (root->reloc_root) { reloc_root = root->reloc_root; reloc_root->last_trans = trans->transid;
@@ -2186,7 +2193,6 @@ static int clean_dirty_subvols(struct re/* Merged subvolume, cleanup its reloc root */ struct btrfs_root *reloc_root = root->reloc_root; -clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state);list_del_init (&root->reloc_dirty_list); root->reloc_root =NULL ;if (reloc_root) {
@@ -2195,6 +2201,7 @@ static int clean_dirty_subvols(struct reif (ret2 <0 && !ret) ret = ret2; } +clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state);btrfs_put_fs_root (root); }else {/* Orphan reloc tree, just clean it up */
Greg Kroah-Hartman
maintainerPATCH 84/112 btrfs: allocate new inode in NOFS context
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 11a19a90870ea5496a8ded69b86f5b476b6d3355 upstream.
A user reported a lockdep splat
======================================================
WARNING: possible circular locking dependency detected 5.2.11-gentoo #2 Not tainted
------------------------------------------------------
kswapd0/711 is trying to acquire lock:
000000007777a663 (sb_internal){.+.+}, at: start_transaction+0x3a8/0x500
but task is already holding lock:
000000000ba86300 (fs_reclaim){+.+.}, at: __fs_reclaim_acquire+0x0/0x30
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (fs_reclaim){+.+.}:
kmem_cache_alloc+0x1f/0x1c0 btrfs_alloc_inode+0x1f/0x260 alloc_inode+0x16/0xa0 new_inode+0xe/0xb0 btrfs_new_inode+0x70/0x610 btrfs_symlink+0xd0/0x420 vfs_symlink+0x9c/0x100 do_symlinkat+0x66/0xe0 do_syscall_64+0x55/0x1c0 entry_SYSCALL_64_after_hwframe+0x49/0xbe
-> #0 (sb_internal){.+.+}:
__sb_start_write+0xf6/0x150 start_transaction+0x3a8/0x500 btrfs_commit_inode_delayed_inode+0x59/0x110 btrfs_evict_inode+0x19e/0x4c0 evict+0xbc/0x1f0 inode_lru_isolate+0x113/0x190 __list_lru_walk_one.isra.4+0x5c/0x100 list_lru_walk_one+0x32/0x50 prune_icache_sb+0x36/0x80 super_cache_scan+0x14a/0x1d0 do_shrink_slab+0x131/0x320 shrink_node+0xf7/0x380 balance_pgdat+0x2d5/0x640 kswapd+0x2ba/0x5e0 kthread+0x147/0x160 ret_from_fork+0x24/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(fs_reclaim);
lock(sb_internal);
lock(fs_reclaim);
lock(sb_internal);
--- fs/btrfs/inode.c | 3 +++ 1 file changed, 3 insertions(+)
fs/btrfs/inode.c +3 -0
@@ -6276,13 +6276,16 @@ static struct inode *btrfs_new_inode(stru32 sizes[2 ];int nitems = name ?2 :1 ;unsigned long ptr; +unsigned int nofs_flag;int ret; path =btrfs_alloc_path ();if (!path)return ERR_PTR (-ENOMEM ); + nofs_flag =memalloc_nofs_save (); inode =new_inode (fs_info->sb); +memalloc_nofs_restore (nofs_flag);if (!inode) {btrfs_free_path (path);return ERR_PTR (-ENOMEM );
Greg Kroah-Hartman
maintainerPATCH 85/112 btrfs: fix balance convert to single on 32-bit host CPUs
In reply to Greg Kroah-HartmanFrom: Zygo Blaxell <[email protected]>
commit 7a54789074a54f64addf5b49bf1994f478337a83 upstream.
Currently, the command:
btrfs balance start -dconvert=single,soft .
on a Raspberry Pi produces the following kernel message:
BTRFS error (device mmcblk0p2): balance: invalid convert data profile single
This fails because we use is_power_of_2(unsigned long) to validate the new data profile, the constant for 'single' profile uses bit 48, and there are only 32 bits in a long on ARM.
Fix by open-coding the check using u64 variables.
Tested by completing the original balance command on several Raspberry Pis.
--- fs/btrfs/volumes.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/volumes.c +5 -1
@@ -3854,7 +3854,11 @@ static int alloc_profile_is_valid(u64 flreturn !extended;/* "0" is valid for usual profiles */ /* true if exactly one bit set */ -return is_power_of_2 (flags); +/* +* Don't use is_power_of_2(unsigned long) because it won't work +* for the single profile (1ULL << 48) on 32-bit CPUs. +*/ +return flags !=0 && (flags & (flags -1 )) ==0 ; }static inline int balance_need_close (struct btrfs_fs_info *fs_info)
Greg Kroah-Hartman
maintainerPATCH 86/112 Btrfs: fix memory leak due to concurrent append writes with fiemap
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit c67d970f0ea8dcc423e112137d34334fa0abb8ec upstream.
When we have a buffered write that starts at an offset greater than or equals to the file's size happening concurrently with a full ranged fiemap, we can end up leaking an extent state structure.
Suppose we have a file with a size of 1Mb, and before the buffered write and fiemap are performed, it has a single extent state in its io tree representing the range from 0 to 1Mb, with the EXTENT_DELALLOC bit set.
The following sequence diagram shows how the memory leak happens if a fiemap a buffered write, starting at offset 1Mb and with a length of 4Kb, are performed concurrently.
CPU 1 CPU 2
extent_fiemap()
--> it's a full ranged fiemap
range from 0 to LLONG_MAX - 1
(9223372036854775807)
--> locks range in the inode's
io tree
--> after this we have 2 extent
states in the io tree:
--> 1 for range [0, 1Mb[ with
the bits EXTENT_LOCKED and
EXTENT_DELALLOC_BITS set
--> 1 for the range
[1Mb, LLONG_MAX[ with
the EXTENT_LOCKED bit set
--> start buffered write at offset
1Mb with a length of 4Kb
btrfs_file_write_iter()
btrfs_buffered_write()
--> cached_state is NULL
lock_and_cleanup_extent_if_need()
--> returns 0 and does not lock
range because it starts
at current i_size / eof
--> cached_state remains NULL
btrfs_dirty_pages()
btrfs_set_extent_delalloc()
(...)
__set_extent_bit()
--> splits extent state for range
[1Mb, LLONG_MAX[ and now we
have 2 extent states:
--> one for the range
[1Mb, 1Mb + 4Kb[ with
EXTENT_LOCKED set
--> another one for the range
[1Mb + 4Kb, LLONG_MAX[ with
EXTENT_LOCKED set as well
--> sets EXTENT_DELALLOC on the
extent state for the range
[1Mb, 1Mb + 4Kb[
--> caches extent state
[1Mb, 1Mb + 4Kb[ into
@cached_state because it has
the bit EXTENT_LOCKED set
--> btrfs_buffered_write() ends up
with a non-NULL cached_state and
never calls anything to release its
reference on it, resulting in a
memory leakFix this by calling free_extent_state() on cached_state if the range was not locked by lock_and_cleanup_extent_if_need().
The same issue can happen if anything else other than fiemap locks a range that covers eof and beyond.
This could be triggered, sporadically, by test case generic/561 from the fstests suite, which makes duperemove run concurrently with fsstress, and duperemove does plenty of calls to fiemap. When CONFIG_BTRFS_DEBUG is set the leak is reported in dmesg/syslog when removing the btrfs module with a message like the following:
[77100.039461] BTRFS: state leak: start 6574080 end 6582271 state 16402 in tree 0 refs 1
Otherwise (CONFIG_BTRFS_DEBUG not set) detectable with kmemleak.
--- fs/btrfs/file.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
fs/btrfs/file.c +12 -1
@@ -1591,7 +1591,6 @@ static noinline ssize_t btrfs_buffered_wstruct btrfs_fs_info *fs_info =btrfs_sb (inode->i_sb);struct btrfs_root *root =BTRFS_I (inode)->root;struct page **pages =NULL ; -struct extent_state *cached_state =NULL ;struct extent_changeset *data_reserved =NULL ;u64 release_bytes =0 ;u64 lockstart;
@@ -1611,6 +1610,7 @@ static noinline ssize_t btrfs_buffered_wreturn -ENOMEM ;while (iov_iter_count (i) >0 ) { +struct extent_state *cached_state =NULL ;size_t offset =offset_in_page (pos);size_t sector_offset; size_t write_bytes = min(iov_iter_count(i),
@@ -1758,9 +1758,20 @@ again:if (copied >0 ) ret =btrfs_dirty_pages (inode, pages, dirty_pages, pos, copied, &cached_state); + +/* +* If we have not locked the extent range, because the range's +* start offset is >= i_size, we might still have a non-NULL +* cached extent state, acquired while marking the extent range +* as delalloc through btrfs_dirty_pages(). Therefore free any +* possible cached extent state to avoid a memory leak. +*/ if (extents_locked)unlock_extent_cached (&BTRFS_I (inode)->io_tree, lockstart, lockend, &cached_state); +else +free_extent_state (cached_state); +btrfs_delalloc_release_extents (BTRFS_I (inode), reserve_bytes, true);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 87/112 btrfs: fix incorrect updating of log root tree
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 4203e968947071586a98b5314fd7ffdea3b4f971 upstream.
We've historically had reports of being unable to mount file systems because the tree log root couldn't be read. Usually this is the "parent transid failure", but could be any of the related errors, including "fsid mismatch" or "bad tree block", depending on which block got allocated.
The modification of the individual log root items are serialized on the per-log root root_mutex. This means that any modification to the per-subvol log root_item is completely protected.
However we update the root item in the log root tree outside of the log root tree log_mutex. We do this in order to allow multiple subvolumes to be updated in each log transaction.
This is problematic however because when we are writing the log root tree out we update the super block with the _current_ log root node information. Since these two operations happen independently of each other, you can end up updating the log root tree in between writing out the dirty blocks and setting the super block to point at the current root.
This means we'll point at the new root node that hasn't been written out, instead of the one we should be pointing at. Thus whatever garbage or old block we end up pointing at complains when we mount the file system later and try to replay the log.
Fix this by copying the log's root item into a local root item copy. Then once we're safely under the log_root_tree->log_mutex we update the root item in the log_root_tree. This way we do not modify the log_root_tree while we're committing it, fixing the problem.
--- fs/btrfs/tree-log.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
fs/btrfs/tree-log.c +27 -9
@@ -2932,7 +2932,8 @@ out:* in the tree of log roots */ static int update_log_root (struct btrfs_trans_handle *trans, -struct btrfs_root *log) +struct btrfs_root *log, +struct btrfs_root_item *root_item) {struct btrfs_fs_info *fs_info = log->fs_info;int ret;
@@ -2940,10 +2941,10 @@ static int update_log_root(struct btrfs_if (log->log_transid ==1 ) {/* insert root item on the first sync */ ret =btrfs_insert_root (trans, fs_info->log_root_tree, - &log->root_key, &log->root_item); + &log->root_key, root_item); }else { ret =btrfs_update_root (trans, fs_info->log_root_tree, - &log->root_key, &log->root_item); + &log->root_key, root_item); }return ret; }
@@ -3041,6 +3042,7 @@ int btrfs_sync_log(struct btrfs_trans_hastruct btrfs_fs_info *fs_info = root->fs_info;struct btrfs_root *log = root->log_root;struct btrfs_root *log_root_tree = fs_info->log_root_tree; +struct btrfs_root_item new_root_item;int log_transid =0 ;struct btrfs_log_ctx root_log_ctx;struct blk_plug plug;
@@ -3104,18 +3106,26 @@ int btrfs_sync_log(struct btrfs_trans_ha goto out; } +/* +* We _must_ update under the root->log_mutex in order to make sure we +* have a consistent view of the log root we are trying to commit at +* this moment. +* +* We _must_ copy this into a local copy, because we are not holding the +* log_root_tree->log_mutex yet. This is important because when we +* commit the log_root_tree we must have a consistent view of the +* log_root_tree when we update the super block to point at the +* log_root_tree bytenr. If we update the log_root_tree here we'll race +* with the commit and possibly point at the new block which we may not +* have written out. +*/ btrfs_set_root_node (&log->root_item, log->node); +memcpy (&new_root_item, &log->root_item,sizeof (new_root_item)); root->log_transid++; log->log_transid = root->log_transid; root->log_start_pid =0 ;/* -* Update or create log root item under the root's log_mutex to prevent -* races with concurrent log syncs that can lead to failure to update -* log root item because it was not created yet. -*/ - ret =update_log_root (trans, log); -/* * IO has been started, blocks of the log tree have WRITTEN flag set * in their headers. new modifications of the log will be written to * new positions. so it's safe to allow log writers to go in.
@@ -3135,6 +3145,14 @@ int btrfs_sync_log(struct btrfs_trans_hamutex_unlock (&log_root_tree->log_mutex);mutex_lock (&log_root_tree->log_mutex); + +/* +* Now we are safe to update the log_root_tree because we're under the +* log_mutex, and we're a current writer so we're holding the commit +* open until we drop the log_mutex. +*/ + ret =update_log_root (trans, log, &new_root_item); +if (atomic_dec_and_test (&log_root_tree->log_writers)) {/* atomic_dec_and_test implies a barrier */ cond_wake_up_nomb (&log_root_tree->log_writer_wait);
Greg Kroah-Hartman
maintainerPATCH 88/112 btrfs: fix uninitialized ret in ref-verify
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit c5f4987e86f6692fdb12533ea1fc7a7bb98e555a upstream.
Coverity caught a case where we could return with a uninitialized value in ret in process_leaf. This is actually pretty likely because we could very easily run into a block group item key and have a garbage value in ret and think there was an errror. Fix this by initializing ret to 0.
--- fs/btrfs/ref-verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/ref-verify.c +1 -1
@@ -500,7 +500,7 @@ static int process_leaf(struct btrfs_roostruct btrfs_extent_data_ref *dref;struct btrfs_shared_data_ref *sref;u32 count; -int i =0 , tree_block_level =0 , ret; +int i =0 , tree_block_level =0 , ret =0 ;struct btrfs_key key;int nritems =btrfs_header_nritems (leaf);
Greg Kroah-Hartman
maintainerPATCH 89/112 NFS: Fix O_DIRECT accounting of number of bytes read/written
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit 031d73ed768a40684f3ca21992265ffdb6a270bf upstream.
When a series of O_DIRECT reads or writes are truncated, either due to eof or due to an error, then we should return the number of contiguous bytes that were received/sent starting at the offset specified by the application.
Currently, we are failing to correctly check contiguity, and so we're failing the generic/465 in xfstests when the race between the read and write RPCs causes the file to get extended while the 2 reads are outstanding. If the first read RPC call wins the race and returns with eof set, we should treat the second read RPC as being truncated.
--- fs/nfs/direct.c | 78 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 35 deletions(-)
fs/nfs/direct.c +43 -35
@@ -123,32 +123,49 @@ static inline int put_dreq(struct nfs_di }static void -nfs_direct_good_bytes (struct nfs_direct_req *dreq,struct nfs_pgio_header *hdr) +nfs_direct_handle_truncated (struct nfs_direct_req *dreq, +const struct nfs_pgio_header *hdr, +ssize_t dreq_len) +{ +struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx]; + +if (!(test_bit (NFS_IOHDR_ERROR , &hdr->flags) || +test_bit (NFS_IOHDR_EOF , &hdr->flags))) +return ; +if (dreq->max_count >= dreq_len) { + dreq->max_count = dreq_len; +if (dreq->count > dreq_len) + dreq->count = dreq_len; + +if (test_bit (NFS_IOHDR_ERROR , &hdr->flags)) + dreq->error = hdr->error; +else /* Clear outstanding error if this is EOF */ + dreq->error =0 ; + } +if (mirror->count > dreq_len) + mirror->count = dreq_len; +} + +static void +nfs_direct_count_bytes (struct nfs_direct_req *dreq, +const struct nfs_pgio_header *hdr) { -int i; -ssize_t count; +struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx]; +loff_t hdr_end = hdr->io_start + hdr->good_bytes; +ssize_t dreq_len =0 ; -WARN_ON_ONCE (dreq->count >= dreq->max_count); +if (hdr_end > dreq->io_start) + dreq_len = hdr_end - dreq->io_start; -if (dreq->mirror_count ==1 ) { - dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; - dreq->count += hdr->good_bytes; - }else { -/* mirrored writes */ - count = dreq->mirrors[hdr->pgio_mirror_idx].count; -if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { - count = hdr->io_start + hdr->good_bytes - dreq->io_start; - dreq->mirrors[hdr->pgio_mirror_idx].count = count; - } -/* update the dreq->count by finding the minimum agreed count from all -* mirrors */ - count = dreq->mirrors[0 ].count; +nfs_direct_handle_truncated (dreq, hdr, dreq_len); -for (i =1 ; i < dreq->mirror_count; i++) - count =min (count, dreq->mirrors[i].count); +if (dreq_len > dreq->max_count) + dreq_len = dreq->max_count; - dreq->count = count; - } +if (mirror->count < dreq_len) + mirror->count = dreq_len; +if (dreq->count < dreq_len) + dreq->count = dreq_len; }/*
@@ -402,20 +419,12 @@ static void nfs_direct_read_completion(sstruct nfs_direct_req *dreq = hdr->dreq;spin_lock (&dreq->lock); -if (test_bit (NFS_IOHDR_ERROR , &hdr->flags)) - dreq->error = hdr->error; -if (test_bit (NFS_IOHDR_REDO , &hdr->flags)) {spin_unlock (&dreq->lock); goto out_put; } -if (hdr->good_bytes !=0 ) -nfs_direct_good_bytes (dreq, hdr); - -if (test_bit (NFS_IOHDR_EOF , &hdr->flags)) - dreq->error =0 ; - +nfs_direct_count_bytes (dreq, hdr);spin_unlock (&dreq->lock);while (!list_empty (&hdr->pages)) {
@@ -652,6 +661,9 @@ static void nfs_direct_write_reschedule(nfs_direct_write_scan_commit_list (dreq->inode, &reqs, &cinfo); dreq->count =0 ; + dreq->max_count =0 ; +list_for_each_entry (req, &reqs, wb_list) + dreq->max_count += req->wb_bytes; dreq->verf.committed =NFS_INVALID_STABLE_HOW ;nfs_clear_pnfs_ds_commit_verifiers (&dreq->ds_cinfo);for (i =0 ; i < dreq->mirror_count; i++)
@@ -791,17 +803,13 @@ static void nfs_direct_write_completion(nfs_init_cinfo_from_dreq (&cinfo, dreq);spin_lock (&dreq->lock); - -if (test_bit (NFS_IOHDR_ERROR , &hdr->flags)) - dreq->error = hdr->error; -if (test_bit (NFS_IOHDR_REDO , &hdr->flags)) {spin_unlock (&dreq->lock); goto out_put; } +nfs_direct_count_bytes (dreq, hdr);if (hdr->good_bytes !=0 ) { -nfs_direct_good_bytes (dreq, hdr);if (nfs_write_need_commit (hdr)) {if (dreq->flags ==NFS_ODIRECT_RESCHED_WRITES ) request_commit = true;
Greg Kroah-Hartman
maintainerPATCH 90/112 MIPS: Disable Loongson MMI instructions for kernel build
In reply to Greg Kroah-HartmanFrom: Paul Burton <[email protected]>
commit 2f2b4fd674cadd8c6b40eb629e140a14db4068fd upstream.
GCC 9.x automatically enables support for Loongson MMI instructions when using some -march= flags, and then errors out when -msoft-float is specified with:
cc1: error: ‘-mloongson-mmi’ must be used with ‘-mhard-float’
The kernel shouldn't be using these MMI instructions anyway, just as it doesn't use floating point instructions. Explicitly disable them in order to fix the build with GCC 9.x.
--- arch/mips/loongson64/Platform | 4 ++++ arch/mips/vdso/Makefile | 1 + 2 files changed, 5 insertions(+)
arch/mips/loongson64/Platform +4 -0
@@ -66,6 +66,10 @@ else $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) endif +# Some -march= flags enable MMI instructions, and GCC complains about that +# support being enabled alongside -msoft-float. Thus explicitly disable MMI. +cflags-y += $(call cc-option,-mno-loongson-mmi) + # # Loongson Machines' Support #
arch/mips/vdso/Makefile +1 -0
@@ -9,6 +9,7 @@ ccflags-vdso := \ $(filter -mmicromips,$(KBUILD_CFLAGS)) \ $(filter -march=%,$(KBUILD_CFLAGS)) \ $(filter -m%-float,$(KBUILD_CFLAGS)) \ + $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \ -D__VDSO__ ifdef CONFIG_CC_IS_CLANG
Greg Kroah-Hartman
maintainerPATCH 91/112 MIPS: elf_hwcap: Export userspace ASEs
In reply to Greg Kroah-HartmanFrom: Jiaxun Yang <[email protected]>
commit 38dffe1e4dde1d3174fdce09d67370412843ebb5 upstream.
A Golang developer reported MIPS hwcap isn't reflecting instructions that the processor actually supported so programs can't apply optimized code at runtime.
Thus we export the ASEs that can be used in userspace programs.
--- arch/mips/include/uapi/asm/hwcap.h | 11 +++++++++++ arch/mips/kernel/cpu-probe.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+)
arch/mips/include/uapi/asm/hwcap.h +11 -0
@@ -6,5 +6,16 @@#define HWCAP_MIPS_R6 (1 << 0)#define HWCAP_MIPS_MSA (1 << 1)#define HWCAP_MIPS_CRC32 (1 << 2) +#define HWCAP_MIPS_MIPS16 (1 << 3) +#define HWCAP_MIPS_MDMX (1 << 4) +#define HWCAP_MIPS_MIPS3D (1 << 5) +#define HWCAP_MIPS_SMARTMIPS (1 << 6) +#define HWCAP_MIPS_DSP (1 << 7) +#define HWCAP_MIPS_DSP2 (1 << 8) +#define HWCAP_MIPS_DSP3 (1 << 9) +#define HWCAP_MIPS_MIPS16E2 (1 << 10) +#define HWCAP_LOONGSON_MMI (1 << 11) +#define HWCAP_LOONGSON_EXT (1 << 12) +#define HWCAP_LOONGSON_EXT2 (1 << 13)#endif /* _UAPI_ASM_HWCAP_H */
arch/mips/kernel/cpu-probe.c +33 -0
@@ -2198,6 +2198,39 @@ void cpu_probe(void) elf_hwcap |=HWCAP_MIPS_MSA ; } +if (cpu_has_mips16) + elf_hwcap |=HWCAP_MIPS_MIPS16 ; + +if (cpu_has_mdmx) + elf_hwcap |=HWCAP_MIPS_MDMX ; + +if (cpu_has_mips3d) + elf_hwcap |=HWCAP_MIPS_MIPS3D ; + +if (cpu_has_smartmips) + elf_hwcap |=HWCAP_MIPS_SMARTMIPS ; + +if (cpu_has_dsp) + elf_hwcap |=HWCAP_MIPS_DSP ; + +if (cpu_has_dsp2) + elf_hwcap |=HWCAP_MIPS_DSP2 ; + +if (cpu_has_dsp3) + elf_hwcap |=HWCAP_MIPS_DSP3 ; + +if (cpu_has_mips16e2) + elf_hwcap |=HWCAP_MIPS_MIPS16E2 ; + +if (cpu_has_loongson_mmi) + elf_hwcap |=HWCAP_LOONGSON_MMI ; + +if (cpu_has_loongson_ext) + elf_hwcap |=HWCAP_LOONGSON_EXT ; + +if (cpu_has_loongson_ext2) + elf_hwcap |=HWCAP_LOONGSON_EXT2 ; +if (cpu_has_vz)cpu_probe_vz (c);
Greg Kroah-Hartman
maintainerPATCH 92/112 RDMA/vmw_pvrdma: Free SRQ only once
In reply to Greg Kroah-HartmanFrom: Adit Ranadive <[email protected]>
commit 18545e8b6871d21aa3386dc42867138da9948a33 upstream.
An extra kfree cleanup was missed since these are now deallocated by core.
--- drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | 2 -- 1 file changed, 2 deletions(-)
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c +0 -2
@@ -230,8 +230,6 @@ static void pvrdma_free_srq(struct pvrdmpvrdma_page_dir_cleanup (dev, &srq->pdir); -kfree (srq); -atomic_dec (&dev->num_srqs); }
Greg Kroah-Hartman
maintainerPATCH 93/112 ACPI/PPTT: Add support for ACPI 6.3 thread flag
In reply to Greg Kroah-HartmanFrom: Jeremy Linton <[email protected]>
Commit bbd1b70639f785a970d998f35155c713f975e3ac upstream.
ACPI 6.3 adds a flag to the CPU node to indicate whether the given PE is a thread. Add a function to return that information for a given linux logical CPU.
--- drivers/acpi/pptt.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 +++++ 2 files changed, 57 insertions(+)
drivers/acpi/pptt.c +52 -0
@@ -540,6 +540,44 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)return retval; } +/** +* check_acpi_cpu_flag() - Determine if CPU node has a flag set +* @cpu: Kernel logical CPU number +* @rev: The minimum PPTT revision defining the flag +* @flag: The flag itself +* +* Check the node representing a CPU for a given flag. +* +* Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or +* the table revision isn't new enough. +* 1, any passed flag set +* 0, flag unset +*/ +static int check_acpi_cpu_flag (unsigned int cpu,int rev,u32 flag) +{ +struct acpi_table_header *table; +acpi_status status; +u32 acpi_cpu_id =get_acpi_id_for_cpu (cpu); +struct acpi_pptt_processor *cpu_node =NULL ; +int ret = -ENOENT ; + + status =acpi_get_table (ACPI_SIG_PPTT ,0 , &table); +if (ACPI_FAILURE (status)) { +acpi_pptt_warn_missing (); +return ret; + } + +if (table->revision >= rev) + cpu_node =acpi_find_processor_node (table, acpi_cpu_id); + +if (cpu_node) + ret = (cpu_node->flags & flag) !=0 ; + +acpi_put_table (table); + +return ret; +} +/** * acpi_find_last_cache_level() - Determines the number of cache levels for a PE * @cpu: Kernel logical CPU number
@@ -604,6 +642,20 @@ int cache_setup_acpi(unsigned int cpu)return status; } +/** +* acpi_pptt_cpu_is_thread() - Determine if CPU is a thread +* @cpu: Kernel logical CPU number +* +* Return: 1, a thread +* 0, not a thread +* -ENOENT ,if the PPTT doesn't exist, the CPU cannot be found or +* the table revision isn't new enough. +*/ +int acpi_pptt_cpu_is_thread (unsigned int cpu) +{ +return check_acpi_cpu_flag (cpu,2 ,ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD ); +} +/** * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU * @cpu: Kernel logical CPU number
include/linux/acpi.h +5 -0
@@ -1302,11 +1302,16 @@ static inline int lpit_read_residency_count_address(u64 *address)#endif #ifdef CONFIG_ACPI_PPTT +int acpi_pptt_cpu_is_thread (unsigned int cpu);int find_acpi_cpu_topology (unsigned int cpu,int level);int find_acpi_cpu_topology_package (unsigned int cpu);int find_acpi_cpu_topology_hetero_id (unsigned int cpu);int find_acpi_cpu_cache_topology (unsigned int cpu,int level);#else +static inline int acpi_pptt_cpu_is_thread (unsigned int cpu) +{ +return -EINVAL ; +}static inline int find_acpi_cpu_topology (unsigned int cpu,int level) {return -EINVAL ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 94/112 arm64: topology: Use PPTT to determine if PE is a thread
In reply to Greg Kroah-HartmanFrom: Jeremy Linton <[email protected]>
Commit 98dc19902a0b2e5348e43d6a2c39a0a7d0fc639e upstream.
ACPI 6.3 adds a thread flag to represent if a CPU/PE is actually a thread. Given that the MPIDR_MT bit may not represent this information consistently on homogeneous machines we should prefer the PPTT flag if its available.
--- arch/arm64/kernel/topology.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
arch/arm64/kernel/topology.c +15 -4
@@ -340,17 +340,28 @@ void remove_cpu_topology(unsigned int cpu) }#ifdef CONFIG_ACPI +static bool __init acpi_cpu_is_threaded (int cpu) +{ +int is_threaded =acpi_pptt_cpu_is_thread (cpu); + +/* +* if the PPTT doesn't have thread information, assume a homogeneous +* machine and return the current CPU's thread state. +*/ +if (is_threaded <0 ) + is_threaded =read_cpuid_mpidr () &MPIDR_MT_BITMASK ; + +return !!is_threaded; +} +/* * Propagate the topology information of the processor_topology_node tree to the * cpu_topology array. */ static int __init parse_acpi_topology (void ) { -bool is_threaded;int cpu, topology_id; - is_threaded =read_cpuid_mpidr () &MPIDR_MT_BITMASK ; -for_each_possible_cpu (cpu) {int i, cache_id;
@@ -358,7 +369,7 @@ static int __init parse_acpi_topology(void)if (topology_id <0 )return topology_id; -if (is_threaded) { +if (acpi_cpu_is_threaded (cpu)) { cpu_topology[cpu].thread_id = topology_id; topology_id =find_acpi_cpu_topology (cpu,1 ); cpu_topology[cpu].core_id = topology_id;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 95/112 iio: light: fix vcnl4000 devicetree hooks
In reply to Greg Kroah-HartmanFrom: Marco Felsch <[email protected]>
[ Upstream commit 1436a78c63495dd94c8d4f84a76d78d5317d481b ]
Since commit ebd457d55911 ("iio: light: vcnl4000 add devicetree hooks") the of_match_table is supported but the data shouldn't be a string. Instead it shall be one of 'enum vcnl4000_device_ids'. Also the matching logic for the vcnl4020 was wrong. Since the data retrieve mechanism is still based on the i2c_device_id no failures did appeared till now.
--- drivers/iio/light/vcnl4000.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/iio/light/vcnl4000.c +5 -5
@@ -398,15 +398,15 @@ static int vcnl4000_probe(struct i2c_client *client,static const struct of_device_id vcnl_4000_of_match[] = { { .compatible ="vishay,vcnl4000" , - .data ="VCNL4000" , + .data = (void *)VCNL4000 , }, { .compatible ="vishay,vcnl4010" , - .data ="VCNL4010" , + .data = (void *)VCNL4010 , }, { - .compatible ="vishay,vcnl4010" , - .data ="VCNL4020" , + .compatible ="vishay,vcnl4020" , + .data = (void *)VCNL4010 , }, { .compatible ="vishay,vcnl4040" ,
@@ -414,7 +414,7 @@ static const struct of_device_id vcnl_4000_of_match[] = { }, { .compatible = "vishay,vcnl4200", - .data = "VCNL4200", + .data = (void *)VCNL4200, }, {}, };
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 96/112 Fix the locking in dcache_readdir() and friends
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit d4f4de5e5ef8efde85febb6876cd3c8ab1631999 upstream.
There are two problems in dcache_readdir() - one is that lockless traversal of the list needs non-trivial cooperation of d_alloc() (at least a switch to list_add_rcu(), and probably more than just that) and another is that it assumes that no removal will happen without the directory locked exclusive. Said assumption had always been there, never had been stated explicitly and is violated by several places in the kernel (devpts and selinuxfs).
* replacement of next_positive() with different calling conventions:
it returns struct list_head * instead of struct dentry *; the latter is passed in and out by reference, grabbing the result and dropping the original value.
* scan is under ->d_lock. If we run out of timeslice, cursor is moved
after the last position we'd reached and we reschedule; then the scan continues from that place. To avoid livelocks between multiple lseek() (with cursors getting moved past each other, never reaching the real entries) we always skip the cursors, need_resched() or not.
* returned list_head * is either ->d_child of dentry we'd found or
->d_subdirs of parent (if we got to the end of the list).
* dcache_readdir() and dcache_dir_lseek() switched to new helper.dcache_readdir() always holds a reference to dentry passed to dir_emit() now. Cursor is moved to just before the entry where dir_emit() has failed or into the very end of the list, if we'd run out.
* move_cursor() eliminated - it had sucky calling conventions and
after fixing that it became simply list_move() (in lseek and scan_positives) or list_move_tail() (in readdir).
All operations with the list are under ->d_lock now, and we do not
depend upon having all file removals done with parent locked exclusive anymore.
--- fs/libfs.c | 134 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 69 insertions(+), 65 deletions(-)
fs/libfs.c +69 -65
@@ -89,58 +89,47 @@ int dcache_dir_close(struct inode *inodeEXPORT_SYMBOL (dcache_dir_close);/* parent is locked at least shared */ -static struct dentry *next_positive (struct dentry *parent, -struct list_head *from, -int count) +/* +* Returns an element of siblings' list. +* We are looking for <count>th positive after <p>; if +* found, dentry is grabbed and passed to caller via *<res>. +* If no such element exists, the anchor of list is returned +* and *<res> is set to NULL. +*/ +static struct list_head *scan_positives (struct dentry *cursor, +struct list_head *p, +loff_t count, +struct dentry **res) { -unsigned *seq = &parent->d_inode->i_dir_seq, n; -struct dentry *res; -struct list_head *p; -bool skipped; -int i; +struct dentry *dentry = cursor->d_parent, *found =NULL ; -retry: - i = count; - skipped = false; - n =smp_load_acquire (seq) & ~1 ; - res =NULL ; -rcu_read_lock (); -for (p = from->next; p != &parent->d_subdirs; p = p->next) { +spin_lock (&dentry->d_lock); +while ((p = p->next) != &dentry->d_subdirs) { struct dentry *d = list_entry(p, struct dentry, d_child); -if (!simple_positive (d)) { - skipped = true; - }else if (!--i) { - res = d; -break ; +// we must at least skip cursors, to avoid livelocks +if (d->d_flags &DCACHE_DENTRY_CURSOR ) +continue ; +if (simple_positive (d) && !--count) { +spin_lock_nested (&d->d_lock,DENTRY_D_LOCK_NESTED ); +if (simple_positive (d)) + found =dget_dlock (d); +spin_unlock (&d->d_lock); +if (likely (found)) +break ; + count =1 ; + } +if (need_resched ()) { +list_move (&cursor->d_child, p); + p = &cursor->d_child; +spin_unlock (&dentry->d_lock); +cond_resched (); +spin_lock (&dentry->d_lock); } } -rcu_read_unlock (); -if (skipped) { -smp_rmb (); -if (unlikely (*seq != n)) - goto retry; - } -return res; -} - -static void move_cursor (struct dentry *cursor,struct list_head *after) -{ -struct dentry *parent = cursor->d_parent; -unsigned n, *seq = &parent->d_inode->i_dir_seq; -spin_lock (&parent->d_lock); -for (;;) { - n = *seq; -if (!(n &1 ) &&cmpxchg (seq, n, n +1 ) == n) -break ; -cpu_relax (); - } -__list_del (cursor->d_child.prev, cursor->d_child.next); -if (after) -list_add (&cursor->d_child, after); -else -list_add_tail (&cursor->d_child, &parent->d_subdirs); -smp_store_release (seq, n +2 ); -spin_unlock (&parent->d_lock); +spin_unlock (&dentry->d_lock); +dput (*res); + *res = found; +return p; }loff_t dcache_dir_lseek (struct file *file,loff_t offset,int whence)
@@ -158,17 +147,28 @@ loff_t dcache_dir_lseek(struct file *filreturn -EINVAL ; }if (offset != file->f_pos) { +struct dentry *cursor = file->private_data; +struct dentry *to =NULL ; +struct list_head *p; + file->f_pos = offset; -if (file->f_pos >=2 ) { -struct dentry *cursor = file->private_data; -struct dentry *to; -loff_t n = file->f_pos -2 ; - -inode_lock_shared (dentry->d_inode); - to =next_positive (dentry, &dentry->d_subdirs, n); -move_cursor (cursor, to ? &to->d_child :NULL ); -inode_unlock_shared (dentry->d_inode); +inode_lock_shared (dentry->d_inode); + +if (file->f_pos >2 ) { + p =scan_positives (cursor, &dentry->d_subdirs, + file->f_pos -2 , &to); +spin_lock (&dentry->d_lock); +list_move (&cursor->d_child, p); +spin_unlock (&dentry->d_lock); + }else { +spin_lock (&dentry->d_lock); +list_del_init (&cursor->d_child); +spin_unlock (&dentry->d_lock); } + +dput (to); + +inode_unlock_shared (dentry->d_inode); }return offset; }
@@ -190,25 +190,29 @@ int dcache_readdir(struct file *file, st {struct dentry *dentry = file->f_path.dentry;struct dentry *cursor = file->private_data; -struct list_head *p = &cursor->d_child; -struct dentry *next; -bool moved = false; +struct list_head *anchor = &dentry->d_subdirs; +struct dentry *next =NULL ; +struct list_head *p;if (!dir_emit_dots (file, ctx))return 0 ;if (ctx->pos ==2 ) - p = &dentry->d_subdirs; -while ((next =next_positive (dentry, p,1 )) !=NULL ) { + p = anchor; +else + p = &cursor->d_child; + +while ((p =scan_positives (cursor, p,1 , &next)) != anchor) {if (!dir_emit (ctx, next->d_name.name, next->d_name.len,d_inode (next)->i_ino,dt_type (d_inode (next))))break ; - moved = true; - p = &next->d_child; ctx->pos++; } -if (moved) -move_cursor (cursor, p); +spin_lock (&dentry->d_lock); +list_move_tail (&cursor->d_child, p); +spin_unlock (&dentry->d_lock); +dput (next); +return 0 ; }EXPORT_SYMBOL (dcache_readdir);
Greg Kroah-Hartman
maintainerPATCH 97/112 drm/i915: Bump skl+ max plane width to 5k for linear/x-tiled
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit dc7890995e04bacb45ab21e0daaeae1e7c803eb3 upstream.
The officially validated plane width limit is 4k on skl+, however we already had people using 5k displays before we started to enforce the limit. Also it seems Windows allows 5k resolutions as well (though not sure if they do it with one plane or two).
According to hw folks 5k should work with the possible exception of the following features:
- Ytile (already limited to 4k)
- FP16 (already limited to 4k)
- render compression (already limited to 4k)
- KVMR sprite and cursor (don't care)
- horizontal panning (need to verify this)
- pipe and plane scaling (need to verify this)
So apart from last two items on that list we are already fine. We should really verify what happens with those last two items but I don't have a 5k display on hand atm so it'll have to wait.
In the meantime let's just bump the limit back up to 5k since several users have already been using it without apparent issues. At least we'll be no worse off than we were prior to lowering the limits.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111501
--- drivers/gpu/drm/i915/display/intel_display.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_display.c +14 -1
@@ -3291,7 +3291,20 @@ static int skl_max_plane_width(const strswitch (fb->modifier) {case DRM_FORMAT_MOD_LINEAR :case I915_FORMAT_MOD_X_TILED : -return 4096 ; +/* +* Validated limit is 4k, but has 5k should +* work apart from the following features: +* - Ytile (already limited to 4k) +* - FP16 (already limited to 4k) +* - render compression (already limited to 4k) +* - KVMR sprite and cursor (don't care) +* - horizontal panning (TODO verify this) +* - pipe and plane scaling (TODO verify this) +*/ +if (cpp ==8 ) +return 4096 ; +else +return 5120 ;case I915_FORMAT_MOD_Y_TILED_CCS :case I915_FORMAT_MOD_Yf_TILED_CCS:/* FIXME AUX plane? */
Greg Kroah-Hartman
maintainerPATCH 98/112 drm/i915: Whitelist COMMON_SLICE_CHICKEN2
In reply to Greg Kroah-HartmanFrom: Kenneth Graunke <[email protected]>
commit 282b7fd5f5ab4eba499e1162c1e2802c6d0bb82e upstream.
This allows userspace to use "legacy" mode for push constants, where they are committed at 3DPRIMITIVE or flush time, rather than being committed at 3DSTATE_BINDING_TABLE_POINTERS_XS time. Gen6-8 and Gen11 both use the "legacy" behavior - only Gen9 works in the "new" way.
Conflating push constants with binding tables is painful for userspace, we would like to be able to avoid doing so.
--- drivers/gpu/drm/i915/gt/intel_workarounds.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/i915/gt/intel_workarounds.c +3 -0
@@ -1042,6 +1042,9 @@ static void gen9_whitelist_build(struct/* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */ whitelist_reg (w,GEN8_HDC_CHICKEN1 ); + +/* WaSendPushConstantsFromMMIO:skl,bxt */ +whitelist_reg (w,COMMON_SLICE_CHICKEN2 ); }static void skl_whitelist_build (struct intel_engine_cs *engine)
Greg Kroah-Hartman
maintainerPATCH 99/112 drm/i915: Mark contents as dirty on a write fault
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit b925708f28c2b7a3a362d709bd7f77bc75c1daac upstream.
Since dropping the set-to-gtt-domain in commit a679f58d0510 ("drm/i915:
Flush pages on acquisition"), we no longer mark the contents as dirty on a write fault. This has the issue of us then not marking the pages as dirty on releasing the buffer, which means the contents are not written out to the swap device (should we ever pick that buffer as a victim). Notably, this is visible in the dumb buffer interface used for cursors. Having updated the cursor contents via mmap, and swapped away, if the shrinker should evict the old cursor, upon next reuse, the cursor would be invisible.
E.g. echo 80 > /proc/sys/kernel/sysrq ; echo f > /proc/sysrq-trigger
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111541
--- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/gem/i915_gem_mman.c +5 -1
@@ -317,7 +317,11 @@ vm_fault_t i915_gem_fault(struct vm_faul msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));GEM_BUG_ON (!obj->userfault_count); -i915_vma_set_ggtt_write (vma); +if (write) { +GEM_BUG_ON (!i915_gem_object_has_pinned_pages (obj)); +i915_vma_set_ggtt_write (vma); + obj->mm.dirty = true; + } err_fence:i915_vma_unpin_fence (vma);
Greg Kroah-Hartman
maintainerPATCH 100/112 drm/msm: Use the correct dma_sync calls harder
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
commit 9f614197c744002f9968e82c649fdf7fe778e1e7 upstream.
Looks like the dma_sync calls don't do what we want on armv7 either. Fixes:
Unable to handle kernel paging request at virtual address 50001000 pgd = (ptrval) [50001000] *pgd=00000000 Internal error: Oops: 805 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc6-00271-g9f159ae07f07 #4 Hardware name: Freescale i.MX53 (Device Tree Support) PC is at v7_dma_clean_range+0x20/0x38 LR is at __dma_page_cpu_to_dev+0x28/0x90 pc : [<c011c76c>] lr : [<c01181c4>] psr: 20000013 sp : d80b5a88 ip : de96c000 fp : d840ce6c r10: 00000000 r9 : 00000001 r8 : d843e010 r7 : 00000000 r6 : 00008000 r5 : ddb6c000 r4 : 00000000 r3 : 0000003f r2 : 00000040 r1 : 50008000 r0 : 50001000 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 70004019 DAC: 00000051 Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
--- drivers/gpu/drm/msm/msm_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/msm_gem.c +2 -2
@@ -50,7 +50,7 @@ static void sync_for_device(struct msm_g {struct device *dev = msm_obj->base.dev->dev; -if (get_dma_ops (dev)) { +if (get_dma_ops (dev) &&IS_ENABLED (CONFIG_ARM64 )) {dma_sync_sg_for_device (dev, msm_obj->sgt->sgl, msm_obj->sgt->nents,DMA_BIDIRECTIONAL ); }else {
@@ -63,7 +63,7 @@ static void sync_for_cpu(struct msm_gem_ {struct device *dev = msm_obj->base.dev->dev; -if (get_dma_ops (dev)) { +if (get_dma_ops (dev) &&IS_ENABLED (CONFIG_ARM64 )) {dma_sync_sg_for_cpu (dev, msm_obj->sgt->sgl, msm_obj->sgt->nents,DMA_BIDIRECTIONAL ); }else {
Greg Kroah-Hartman
maintainerPATCH 101/112 media: stkwebcam: fix runtime PM after driver unbind
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 30045f2174aab7fb4db7a9cf902d0aa6c75856a7 upstream.
Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") USB drivers must always balance their runtime PM gets and puts, including when the driver has already been unbound from the interface.
Leaving the interface with a positive PM usage counter would prevent a later bound driver from suspending the device.
Note that runtime PM has never actually been enabled for this driver since the support_autosuspend flag in its usb_driver struct is not set.
--- drivers/media/usb/stkwebcam/stk-webcam.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/media/usb/stkwebcam/stk-webcam.c +1 -2
@@ -643,8 +643,7 @@ static int v4l_stk_release(struct file * dev->owner =NULL ; } -if (is_present (dev)) -usb_autopm_put_interface (dev->interface); +usb_autopm_put_interface (dev->interface);mutex_unlock (&dev->lock);return v4l2_fh_release (fp); }
Greg Kroah-Hartman
maintainerPATCH 102/112 arm64/sve: Fix wrong free for task->thread.sve_state
In reply to Greg Kroah-HartmanFrom: Masayoshi Mizuma <[email protected]>
commit 4585fc59c0e813188d6a4c5de1f6976fce461fc2 upstream.
The system which has SVE feature crashed because of the memory pointed by task->thread.sve_state was destroyed by someone.
That is because sve_state is freed while the forking the child process. The child process has the pointer of sve_state which is same as the parent's because the child's task_struct is copied from the parent's one. If the copy_process() fails as an error on somewhere, for example, copy_creds(), then the sve_state is freed even if the parent is alive. The flow is as follows.
copy_process
p = dup_task_struct
=> arch_dup_task_struct
*dst = *src; // copy the entire region.
:
retval = copy_creds
if (retval < 0)
goto bad_fork_free;
:
bad_fork_free:
...
delayed_free_task(p);
=> free_task
=> arch_release_task_struct
=> fpsimd_release_task
=> __sve_free
=> kfree(task->thread.sve_state);
// free the parent's sve_stateMove child's sve_state = NULL and clearing TIF_SVE flag to arch_dup_task_struct() so that the child doesn't free the parent's one.
There is no need to wait until copy_process() to clear TIF_SVE for dst, because the thread flags for dst are initialized already by copying the src task_struct.
This change simplifies the code, so get rid of comments that are no longer needed.
As a note, arm64 used to have thread_info on the stack. So it would not be possible to clear TIF_SVE until the stack is initialized.
Quoted 1 line
From commit
c02433dd6de3("arm64: splitthread_infofrom task stack"),
the thread_info is part of the task, so it should be valid to modify the flag from arch_dup_task_struct().
--- arch/arm64/kernel/process.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)
arch/arm64/kernel/process.c +15 -17
@@ -323,22 +323,27 @@ void arch_release_task_struct(struct tasfpsimd_release_task (tsk); } -/* -* src and dst may temporarily have aliased sve_state after task_struct -* is copied. We cannot fix this properly here, because src may have -* live SVE state and dst's thread_info may not exist yet, so tweaking -* either src's or dst's TIF_SVE is not safe. -* -* The unaliasing is done in copy_thread() instead. This works because -* dst is not schedulable or traceable until both of these functions -* have been called. -*/ int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) {if (current->mm)fpsimd_preserve_current_state (); *dst = *src; +/* We rely on the above assignment to initialize dst's thread_flags: */ +BUILD_BUG_ON (!IS_ENABLED (CONFIG_THREAD_INFO_IN_TASK )); + +/* +* Detach src's sve_state (if any) from dst so that it does not +* get erroneously used or freed prematurely. dst's sve_state +* will be allocated on demand later on if dst uses SVE. +* For consistency, also clear TIF_SVE here: this could be done +* later in copy_process(), but to avoid tripping up future +* maintainers it is best not to leave TIF_SVE and sve_state in +* an inconsistent state, even temporarily. +*/ + dst->thread.sve_state =NULL ; +clear_tsk_thread_flag (dst,TIF_SVE ); +return 0 ; }
@@ -352,13 +357,6 @@ int copy_thread(unsigned long clone_flagmemset (&p->thread.cpu_context,0 ,sizeof (struct cpu_context ));/* -* Unalias p->thread.sve_state (if any) from the parent task -* and disable discard SVE state for p: -*/ -clear_tsk_thread_flag (p,TIF_SVE ); - p->thread.sve_state =NULL ; - -/* * In case p was allocated the same task_struct pointer as some * other recently-exited task, make sure p is disassociated from * any cpu that may have run that now-exited task recently.
Greg Kroah-Hartman
maintainerPATCH 103/112 tracing/hwlat: Report total time spent in all NMIs during the sample
In reply to Greg Kroah-HartmanFrom: Srivatsa S. Bhat (VMware) <[email protected]>
commit 98dc19c11470ee6048aba723d77079ad2cda8a52 upstream.
nmi_total_ts is supposed to record the total time spent in *all* NMIs that occur on the given CPU during the (active portion of the) sampling window. However, the code seems to be overwriting this variable for each NMI, thereby only recording the time spent in the most recent NMI. Fix it by accumulating the duration instead.
--- kernel/trace/trace_hwlat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_hwlat.c +1 -1
@@ -150,7 +150,7 @@ void trace_hwlat_callback(bool enter)if (enter) nmi_ts_start =time_get ();else - nmi_total_ts =time_get () - nmi_ts_start; + nmi_total_ts +=time_get () - nmi_ts_start; }if (enter)
Greg Kroah-Hartman
maintainerPATCH 104/112 tracing/hwlat: Dont ignore outer-loop duration when calculating max_latency
In reply to Greg Kroah-HartmanFrom: Srivatsa S. Bhat (VMware) <[email protected]>
commit fc64e4ad80d4b72efce116f87b3174f0b7196f8e upstream.
max_latency is intended to record the maximum ever observed hardware latency, which may occur in either part of the loop (inner/outer). So we need to also consider the outer-loop sample when updating max_latency.
--- kernel/trace/trace_hwlat.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_hwlat.c +2 -0
@@ -256,6 +256,8 @@ static int get_sample(void)/* Keep a running maximum ever recorded hardware latency */ if (sample > tr->max_latency) tr->max_latency = sample; +if (outer_sample > tr->max_latency) + tr->max_latency = outer_sample; } out:
Greg Kroah-Hartman
maintainerPATCH 105/112 ftrace: Get a reference counter for the trace_array on filter files
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 9ef16693aff8137faa21d16ffe65bb9832d24d71 upstream.
The ftrace set_ftrace_filter and set_ftrace_notrace files are specific for an instance now. They need to take a reference to the instance otherwise there could be a race between accessing the files and deleting the instance.
It wasn't until the :mod: caching where these file operations started referencing the trace_array directly.
--- kernel/trace/ftrace.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
kernel/trace/ftrace.c +18 -9
@@ -3540,21 +3540,22 @@ ftrace_regex_open(struct ftrace_ops *opsstruct ftrace_hash *hash;struct list_head *mod_head;struct trace_array *tr = ops->private; -int ret =0 ; +int ret = -ENOMEM ;ftrace_ops_init (ops);if (unlikely (ftrace_disabled))return -ENODEV ; +if (tr &&trace_array_get (tr) <0 ) +return -ENODEV ; + iter =kzalloc (sizeof (*iter),GFP_KERNEL );if (!iter) -return -ENOMEM ; + goto out; -if (trace_parser_get_init (&iter->parser,FTRACE_BUFF_MAX )) { -kfree (iter); -return -ENOMEM ; - } +if (trace_parser_get_init (&iter->parser,FTRACE_BUFF_MAX )) + goto out; iter->ops = ops; iter->flags = flag;
@@ -3584,13 +3585,13 @@ ftrace_regex_open(struct ftrace_ops *opsif (!iter->hash) {trace_parser_put (&iter->parser); -kfree (iter); - ret = -ENOMEM ; goto out_unlock; } }else iter->hash = hash; + ret =0 ; +if (file->f_mode &FMODE_READ ) { iter->pg = ftrace_pages_start;
@@ -3602,7 +3603,6 @@ ftrace_regex_open(struct ftrace_ops *ops/* Failed */ free_ftrace_hash (iter->hash);trace_parser_put (&iter->parser); -kfree (iter); } }else file->private_data = iter;
@@ -3610,6 +3610,13 @@ ftrace_regex_open(struct ftrace_ops *ops out_unlock:mutex_unlock (&ops->func_hash->regex_lock); + out: +if (ret) { +kfree (iter); +if (tr) +trace_array_put (tr); + } +return ret; }
@@ -5037,6 +5044,8 @@ int ftrace_regex_release(struct inode *imutex_unlock (&iter->ops->func_hash->regex_lock);free_ftrace_hash (iter->hash); +if (iter->tr) +trace_array_put (iter->tr);kfree (iter);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 106/112 tracing: Get trace_array reference for available_tracers files
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 194c2c74f5532e62c218adeb8e2b683119503907 upstream.
As instances may have different tracers available, we need to look at the trace_array descriptor that shows the list of the available tracers for the instance. But there's a race between opening the file and an admin deleting the instance. The trace_array_get() needs to be called before accessing the trace_array.
--- kernel/trace/trace.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
kernel/trace/trace.c +15 -2
@@ -4355,9 +4355,14 @@ static int show_traces_open(struct inodeif (tracing_disabled)return -ENODEV ; +if (trace_array_get (tr) <0 ) +return -ENODEV ; + ret =seq_open (file, &show_traces_seq_ops); -if (ret) +if (ret) { +trace_array_put (tr);return ret; + } m = file->private_data; m->private = tr;
@@ -4365,6 +4370,14 @@ static int show_traces_open(struct inodereturn 0 ; } +static int show_traces_release (struct inode *inode,struct file *file) +{ +struct trace_array *tr = inode->i_private; + +trace_array_put (tr); +return seq_release (inode, file); +} +static ssize_t tracing_write_stub (struct file *filp,const char __user *ubuf,size_t count,loff_t *ppos)
@@ -4395,8 +4408,8 @@ static const struct file_operations tracstatic const struct file_operations show_traces_fops = { .open = show_traces_open, .read = seq_read, - .release = seq_release, .llseek = seq_lseek, + .release = show_traces_release, }; static ssize_t
Greg Kroah-Hartman
maintainerPATCH 107/112 hwmon: Fix HWMON_P_MIN_ALARM mask
In reply to Greg Kroah-HartmanFrom: Nuno Sá <[email protected]>
commit 30945d31e5761436d9eba6b8cff468a5f7c9c266 upstream.
Both HWMON_P_MIN_ALARM and HWMON_P_MAX_ALARM were using BIT(hwmon_power_max_alarm).
--- include/linux/hwmon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/hwmon.h +1 -1
@@ -235,7 +235,7 @@ enum hwmon_power_attributes {#define HWMON_P_LABEL BIT(hwmon_power_label)#define HWMON_P_ALARM BIT(hwmon_power_alarm)#define HWMON_P_CAP_ALARM BIT(hwmon_power_cap_alarm) -#define HWMON_P_MIN_ALARM BIT(hwmon_power_max_alarm) +#define HWMON_P_MIN_ALARM BIT(hwmon_power_min_alarm)#define HWMON_P_MAX_ALARM BIT(hwmon_power_max_alarm)#define HWMON_P_LCRIT_ALARM BIT(hwmon_power_lcrit_alarm)#define HWMON_P_CRIT_ALARM BIT(hwmon_power_crit_alarm)
Greg Kroah-Hartman
maintainerPATCH 108/112 mtd: rawnand: au1550nd: Fix au_read_buf16() prototype
In reply to Greg Kroah-HartmanFrom: Paul Burton <[email protected]>
commit df8fed831cbcdce7b283b2d9c1aadadcf8940d05 upstream.
Commit 7e534323c416 ("mtd: rawnand: Pass a nand_chip object to chip->read_xxx() hooks") modified the prototype of the struct nand_chip read_buf function pointer. In the au1550nd driver we have 2 implementations of read_buf. The previously mentioned commit modified the au_read_buf() implementation to match the function pointer, but not au_read_buf16(). This results in a compiler warning for MIPS db1xxx_defconfig builds:
drivers/mtd/nand/raw/au1550nd.c:443:57:
warning: pointer type mismatch in conditional expression
Fix this by updating the prototype of au_read_buf16() to take a struct nand_chip pointer as its first argument, as is expected after commit 7e534323c416 ("mtd: rawnand: Pass a nand_chip object to chip->read_xxx() hooks").
Note that this shouldn't have caused any functional issues at runtime, since the offset of the struct mtd_info within struct nand_chip is 0 making mtd_to_nand() effectively a type-cast.
--- drivers/mtd/nand/raw/au1550nd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mtd/nand/raw/au1550nd.c +2 -3
@@ -134,16 +134,15 @@ static void au_write_buf16(struct nand_c/** * au_read_buf16 - read chip data into buffer -* @mtd: MTD device structure +* @this: NAND chip object * @buf: buffer to store date * @len: number of bytes to read * * read function for 16bit buswidth */ -static void au_read_buf16 (struct mtd_info *mtd,u_char *buf,int len) +static void au_read_buf16 (struct nand_chip *this,u_char *buf,int len) {int i; -struct nand_chip *this =mtd_to_nand (mtd);u16 *p = (u16 *) buf; len >>=1 ;
Greg Kroah-Hartman
maintainerPATCH 109/112 x86/asm: Fix MWAITX C-state hint value
In reply to Greg Kroah-HartmanFrom: Janakarajan Natarajan <[email protected]>
commit 454de1e7d970d6bc567686052329e4814842867c upstream.
As per "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions", MWAITX EAX[7:4]+1 specifies the optional hint of the optimized C-state. For C0 state, EAX[7:4] should be set to 0xf.
Currently, a value of 0xf is set for EAX[3:0] instead of EAX[7:4]. Fix this by changing MWAITX_DISABLE_CSTATES from 0xf to 0xf0.
This hasn't had any implications so far because setting reserved bits in EAX is simply ignored by the CPU.
[ bp: Fixup comment in delay_mwaitx() and massage. ]
--- arch/x86/include/asm/mwait.h | 2 +- arch/x86/lib/delay.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/include/asm/mwait.h +1 -1
@@ -21,7 +21,7 @@#define MWAIT_ECX_INTERRUPT_BREAK 0x1#define MWAITX_ECX_TIMER_ENABLE BIT(1)#define MWAITX_MAX_LOOPS ((u32)-1) -#define MWAITX_DISABLE_CSTATES 0xf +#define MWAITX_DISABLE_CSTATES 0xf0static inline void __monitor (const void *eax,unsigned long ecx,unsigned long edx)
arch/x86/lib/delay.c +2 -2
@@ -113,8 +113,8 @@ static void delay_mwaitx(unsigned long ___monitorx (raw_cpu_ptr (&cpu_tss_rw),0 ,0 );/* -* AMD, like Intel, supports the EAX hint and EAX=0xf -* means, do not enter any deep C-state and we use it +* AMD, like Intel's MWAIT version, supports the EAX hint and +* EAX=0xf0 means, do not enter any deep C-state and we use it * here in delay() to minimize wakeup latency. */ __mwaitx (MWAITX_DISABLE_CSTATES , delay,MWAITX_ECX_TIMER_ENABLE );
Greg Kroah-Hartman
maintainerPATCH 110/112 io_uring: only flush workqueues on fileset removal
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 8a99734081775c012a4a6c442fdef0379fe52bdf upstream.
We should not remove the workqueue, we just need to ensure that the workqueues are synced. The workqueues are torn down on ctx removal.
--- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/io_uring.c +2 -1
@@ -2566,7 +2566,8 @@ static void io_destruct_skb(struct sk_bu {struct io_ring_ctx *ctx = skb->sk->sk_user_data; -io_finish_async (ctx); +if (ctx->sqo_wq) +flush_workqueue (ctx->sqo_wq);unix_destruct_scm (skb); }
Greg Kroah-Hartman
maintainerPATCH 111/112 efi/tpm: Fix sanity check of unsigned tbl_size being less than zero
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
commit be59d57f98065af0b8472f66a0a969207b168680 upstream.
Currently the check for tbl_size being less than zero is always false because tbl_size is unsigned. Fix this by making it a signed int.
Addresses-Coverity: ("Unsigned compared against 0")
--- drivers/firmware/efi/tpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/tpm.c +1 -1
@@ -40,7 +40,7 @@ int __init efi_tpm_eventlog_init(void) {struct linux_efi_tpm_eventlog *log_tbl;struct efi_tcg2_final_events_table *final_tbl; -unsigned int tbl_size; +int tbl_size;int ret =0 ;if (efi.tpm_log =EFI_INVALID_TABLE_ADDR ) {
Greg Kroah-Hartman
maintainerPATCH 112/112 ASoC: sgtl5000: add ADC mute control
In reply to Greg Kroah-HartmanFrom: Oleksandr Suvorov <[email protected]>
commit 694b14554d75f2a1ae111202e71860d58b434a21 upstream.
This control mute/unmute the ADC input of SGTL5000 using its CHIP_ANA_CTRL register.
--- sound/soc/codecs/sgtl5000.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/codecs/sgtl5000.c +1 -0
@@ -720,6 +720,7 @@ static const struct snd_kcontrol_new sgt SGTL5000_CHIP_ANA_ADC_CTRL, 8, 1, 0, capture_6db_attenuate),SOC_SINGLE ("Capture ZC Switch" ,SGTL5000_CHIP_ANA_CTRL ,1 ,1 ,0 ), +SOC_SINGLE ("Capture Switch" ,SGTL5000_CHIP_ANA_CTRL ,0 ,1 ,1 ), SOC_DOUBLE_TLV("Headphone Playback Volume", SGTL5000_CHIP_ANA_HP_CTRL,
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.
This seems like a new feature and not an obvious candidate for stable?
Greg Kroah-Hartman
maintainerRe: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 9 lines · Mark Brown
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit 631bc8f0134a ("ASoC: sgtl5000: Fix of unmute outputs on probe"), which is e9f621efaebd in v5.3 replaced snd_soc_component_write with snd_soc_component_update_bits and therefore no longer cleared the MUTE_ADC flag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control for MUTE_ADC.
That's why I took this. If this isn't true, I'll be glad to drop this.
thanks,
greg k-h
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 20 lines · Greg Kroah-Hartman
Quoted 9 lines · Mark Brown
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit631bc8f0134a("ASoC: sgtl5000: Fix of unmute outputs on probe"), which ise9f621efaebdin v5.3 replacedsnd_soc_component_writewithsnd_soc_component_update_bitsand therefore no longer cleared theMUTE_ADCflag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control forMUTE_ADC.
Quoted 1 line
That's why I took this. If this isn't true, I'll be glad to drop this.
That's probably not an appropriate fix for stable - it's going to add a new control which users will need to manually set (or hope their userspace automatically figures out that it should set for them, more advanced userspaces like PulseAudio should) which isn't a drop in fix. You could either drop the backport that was done for zero cross or take a new patch that clears the MUTE_ADC flag (rather than punting to userspace to do so), or just be OK with what you've got at the minute which might be fine given the lack of user reports.
Greg Kroah-Hartman
maintainerRe: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 23 lines · Mark Brown
Quoted 20 lines · Greg Kroah-Hartman
Quoted 9 lines · Mark Brown
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit631bc8f0134a("ASoC: sgtl5000: Fix of unmute outputs on probe"), which ise9f621efaebdin v5.3 replacedsnd_soc_component_writewithsnd_soc_component_update_bitsand therefore no longer cleared theMUTE_ADCflag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control forMUTE_ADC.Quoted 1 line
That's why I took this. If this isn't true, I'll be glad to drop this.
Quoted 8 lines
That's probably not an appropriate fix for stable - it's going to add a new control which users will need to manually set (or hope their userspace automatically figures out that it should set for them, more advanced userspaces like PulseAudio should) which isn't a drop in fix. You could either drop the backport that was done for zero cross or take a new patch that clears the
MUTE_ADCflag (rather than punting to userspace to do so), or just be OK with what you've got at the minute which might be fine given the lack of user reports.
Ok, I'll gladly go drop it, thanks!
greg k-h
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 33 lines · Greg Kroah-Hartman
Quoted 23 lines · Mark Brown
Quoted 20 lines · Greg Kroah-Hartman
Quoted 9 lines · Mark Brown
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit631bc8f0134a("ASoC: sgtl5000: Fix of unmute outputs on probe"), which ise9f621efaebdin v5.3 replacedsnd_soc_component_writewithsnd_soc_component_update_bitsand therefore no longer cleared theMUTE_ADCflag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control forMUTE_ADC.Quoted 1 line
That's why I took this. If this isn't true, I'll be glad to drop this.
Quoted 8 lines
That's probably not an appropriate fix for stable - it's going to add a new control which users will need to manually set (or hope their userspace automatically figures out that it should set for them, more advanced userspaces like PulseAudio should) which isn't a drop in fix. You could either drop the backport that was done for zero cross or take a new patch that clears the
MUTE_ADCflag (rather than punting to userspace to do so), or just be OK with what you've got at the minute which might be fine given the lack of user reports.
Quoted 1 line
Ok, I'll gladly go drop it, thanks!
Mark, thanks for the clarification! I haven't thought of breaking anything with the backport as it worked fine for our application.
Greg, just to be sure:
Are you going to drop this patch and revert e9f621efaebd for v5.3?
Or should I send a patch which clears the MUTE_ADC flag like Mark suggested?
thanks & regards;Richard.L
A message that is not in the archive (sent off-list or not yet received): AM6PR05MB653568E379699EE907E146BDF96D0@AM6PR05MB6535.eurprd05.prod.outlook.com
Re: Fw: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 25 lines · Greg Kroah-Hartman
Quoted 24 lines · Mark Brown
Quoted 23 lines · Greg Kroah-Hartman
Quoted 21 lines · Mark Brown
Quoted 9 lines · Greg Kroah-Hartman
Quoted 6 lines
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit631bc8f0134a("ASoC: sgtl5000: Fix of unmute outputs on probe"), which ise9f621efaebdin v5.3 replacedsnd_soc_component_writewithsnd_soc_component_update_bitsand therefore no longer cleared theMUTE_ADCflag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control forMUTE_ADC.That's why I took this. If this isn't true, I'll be glad to drop this.
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
That's probably not an appropriate fix for stable - it's going to add a new control which users will need to manually set (or hope their userspace automatically figures out that it should set for them, more advanced userspaces like PulseAudio should) which isn't a drop in fix. You could either drop the backport that was done for zero cross or take a new patch that clears the
MUTE_ADCflag (rather than punting to userspace to do so), or just be OK with what you've got at the minute which might be fine given the lack of user reports.
Mark, obviously this is not a NEW feature. This patch adds LOST standard control.
Please look into other codecs:
$ grep -R 'SOC_SINGLE("Capture Switch"' sound/soc/
sound/soc/codecs/sgtl5000.c.orig: SOC_SINGLE("Capture Switch",
SGTL5000_CHIP_ANA_CTRL, 0, 1, 1),
sound/soc/codecs/wm9705.c: SOC_SINGLE("Capture Switch", AC97_REC_GAIN,
15, 1, 1),
sound/soc/codecs/wm9713.c:SOC_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
sound/soc/codecs/wm9712.c:SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),And even:
$ grep -R 'SOC_SINGLE(".*Capture Switch"' sound/soc/
sound/soc/codecs/lm49453.c: SOC_SINGLE("Port1 Capture Switch",
LM49453_P0_AUDIO_PORT1_BASIC_REG,
sound/soc/codecs/lm49453.c: SOC_SINGLE("Port2 Capture Switch",
LM49453_P0_AUDIO_PORT2_BASIC_REG,
sound/soc/codecs/sgtl5000.c.orig: SOC_SINGLE("Capture Switch",
SGTL5000_CHIP_ANA_CTRL, 0, 1, 1),
sound/soc/codecs/mc13783.c: SOC_SINGLE("Line in Capture Switch",
MC13783_AUDIO_RX1, 10, 1, 0),
sound/soc/codecs/ak4642.c: SOC_SINGLE("ALC Capture Switch", ALC_CTL1, 5, 1, 0),
sound/soc/codecs/adau1701.c: SOC_SINGLE("Master Capture Switch",
ADAU1701_DSPCTRL, 4, 1, 0),
sound/soc/codecs/alc5632.c: SOC_SINGLE("DMIC En Capture Switch",
sound/soc/codecs/alc5632.c: SOC_SINGLE("DMIC PreFilter Capture Switch",
sound/soc/codecs/wm9705.c: SOC_SINGLE("Capture Switch", AC97_REC_GAIN,
15, 1, 1),
sound/soc/codecs/adau1977.c: SOC_SINGLE("ADC" #x " Highpass-Filter
Capture Switch", \
sound/soc/codecs/adau1977.c: SOC_SINGLE("ADC" #x " DC Subtraction
Capture Switch", \
sound/soc/codecs/isabelle.c: SOC_SINGLE("ULATX12 Capture Switch",
ISABELLE_ULATX12_INTF_CFG_REG,
sound/soc/codecs/ad1980.c:SOC_SINGLE("PCM Capture Switch",
AC97_REC_GAIN, 15, 1, 1),
sound/soc/codecs/ad1980.c:SOC_SINGLE("Phone Capture Switch",
AC97_PHONE, 15, 1, 1),
sound/soc/codecs/wm8731.c:SOC_SINGLE("Mic Capture Switch",
WM8731_APANA, 1, 1, 1),
sound/soc/codecs/uda1380.c:/**/ SOC_SINGLE("ADC Capture Switch",
UDA1380_PGA, 15, 1, 1), /* MT_ADC */
sound/soc/codecs/wm9713.c:SOC_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
sound/soc/codecs/es8316.c: SOC_SINGLE("ALC Capture Switch",
ES8316_ADC_ALC1, 6, 1, 0),
sound/soc/codecs/sgtl5000.c: SOC_SINGLE("Capture Switch",
SGTL5000_CHIP_ANA_CTRL, 0, 1, 1),
sound/soc/codecs/tlv320aic31xx.c: SOC_SINGLE("ADC Capture Switch",
AIC31XX_ADCFGA, 7, 1, 1),
sound/soc/codecs/da7210.c: SOC_SINGLE("Aux2 Capture Switch",
DA7210_AUX2, 2, 1, 0),
sound/soc/codecs/wm9712.c:SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),git blame sound/soc/codecs/wm9705.c
...927b0aea93bb3 (Ian Molton 2009-01-19 17:23:11 +0000 87)
SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
...
This control was added not later than 2009, so I doubt my patch could break something in current user-land.
Quoted 5 lines
Quoted 2 lines
Ok, I'll gladly go drop it, thanks!
Mark, thanks for the clarification! I haven't thought of breaking anything with the backport as it worked fine for our application.
Signature · 6 lines
Best regards Oleksandr Suvorov Toradex AG Altsagenstrasse 5 | 6048 Horw/Luzern | Switzerland | T: +41 41 500 4800 (main line)
Re: Fw: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 2 lines · Oleksandr Suvorov
Mark, obviously this is not a NEW feature. This patch adds LOST standard control.
It's a new feature for this CODEC to have control over the capture mute, other devices have of course had control over it for a long time but for this device it's a new feature.
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 10 lines · Mark Brown
Quoted 2 lines · Oleksandr Suvorov
Mark, obviously this is not a NEW feature. This patch adds LOST standard control.
It's a new feature for this CODEC to have control over the capture mute,
other devices have of course had control over it for a long time but for
this device it's a new feature.
All versions of driver sgtl5000 (since creating in 2011) has a bug in sgtl5000_probe():
...
snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
SGTL5000_HP_ZCD_EN |
SGTL5000_ADC_ZCD_EN);...
This command rewrites the whole register value instead of just enabling ZCD feature for headphone and adc.
This register has bits for HP/LineOut/ADC muting, thus sgtl5000_probe() always unmutes HP/LineOut/ADC.
Because of this bug, HP/LineOut/ADC somehow worked several years: these blocks unmuted upon the probing of device and never muted again.
And they could not be muted/unmuted - there were no controls for that.
[ IMHO unabling mute/unmute of main codec components is a bug too ].
On 2016, the commit 904a987345258 was introduced and added an ability to mute/unmute HP/LineOut, but not ADC unfortunately.
On the other hand, the bug in sgtl5000_probe() (HP/LineOut/ADC unmuting) leads to "pop" sound on driver loading (according to sgtl5000 manual, both HP/LineOut should be muted upon device initialization).
The bugfix 631bc8f0134ae should be applied only after 904a987345258 + 694b14554d75f.
So I see 3 ways:
1. drop this patch and revert 631bc8f0134ae in stable versions 4.19, 5.2, 5.3.
So the bug with unmuting all outputs and ADC on device probing will still present in all kernel versions that include sgtl500 codec driver.
2. keep 631bc8f0134ae and add 694b14554d75f to 4.19, 5.2 and 5.3.
3. add 631bc8f0134ae to 4.4, 4.9 and 4.14 add 694b14554d75f to 4.4-5.3
add 904a987345258 to 4.4
So this bug will be fixed in all supported versions.
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 6 lines · Oleksandr Suvorov
All versions of driver sgtl5000 (since creating in 2011) has a bug in
sgtl5000_probe():
...snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN);
Quoted 6 lines
...
This command rewrites the whole register value instead of just enabling ZCD feature for headphone and adc.This register has bits for HP/LineOut/ADC muting, thus
sgtl5000_probe()always unmutes HP/LineOut/ADC.
Yes, or at the very least this is a badly documented bit of intentional code. I suspect it may be the latter but at this point we can't tell.
Quoted 4 lines
1. drop this patch and revert
631bc8f0134aein stable versions 4.19, 5.2, 5.3.
So the bug with unmuting all outputs and ADC on device probing will still present in all kernel versions that include sgtl500 codec driver.
This patch here being adding the userspace control of the switch and 631bc8f0134ae being the patch that made the ZC change only update the specific bits rather than write an absolute value to the register. This means that we end up with the audio unmuted but no user control over this at runtime. From a user perspective I think this is fine, it's not ideal that there's no control but they can still record.
Please include human readable descriptions of things like commits and issues being discussed in e-mail in your mails, this makes them much easier for humans to read.
Quoted 1 line
2. keep
631bc8f0134aeand add694b14554d75fto 4.19, 5.2 and 5.3.
This means the patch that makes ZC only update the ZC bits and also the patch that makes the mutes user controllable, the default being muted. As I pointed out up thread this would mean that someone upgrading to a newer stable may need to change their userspace to do the unmute instead of having things unconditionally unmuted by the driver. This is not really what people expect from stable updates, we want them to be able to pull these in without thinking about it. i
To backport the addition of the controls to stable we'd need an additional change which sets the default for this control to unmuted, there's a case for having such a change upstream regardless but it's still not clear if any of these changes are really fixes in the sense that we mean for stable.
Quoted 3 lines
3. add
631bc8f0134aeto 4.4, 4.9 and 4.14
add694b14554d75fto 4.4-5.3
add904a987345258to 4.4
This is basically the same as 2 except it adds some more user controllable mute controls with 904a987345258 and does different things in different versions for reasons I'm not clear on. It has the same issue.
Quoted 1 line
So this bug will be fixed in all supported versions.
It is not clear that this is even a bug in the first place, it's not full functionality but that doesn't mean that it's a bug it just means that there's some missing functionality.
Re: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
Quoted 21 lines · Mark Brown
All versions of driver sgtl5000 (since creating in 2011) has a bug in
Quoted 5 lines
sgtl5000_probe():
...snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN);Quoted 7 lines
...
This command rewrites the whole register value instead of just enabling
ZCD feature for headphone and adc.
This register has bits for HP/LineOut/ADC muting, thussgtl5000_probe()
always unmutes HP/LineOut/ADC.Yes, or at the very least this is a badly documented bit of intentional
code. I suspect it may be the latter but at this point we can't tell.Quoted 1 line
2. keep
631bc8f0134aeand add694b14554d75fto 4.19, 5.2 and 5.3.
Quoted 12 lines
This means the patch that makes ZC only update the ZC bits and also the
patch that makes the mutes user controllable, the default being muted.
As I pointed out up thread this would mean that someone upgrading to a
newer stable may need to change their userspace to do the unmute instead
of having things unconditionally unmuted by the driver. This is not really what people expect from stable updates, we want them to be able
to pull these in without thinking about it. i
I think now I see, what you mean.
Of corse, we can change the original commit
[ 631bc8f0134ae ASoC: sgtl5000: Fix of unmute outputs on probe ] for stable branches, unmuting ADC/HP/Lineout at the end of probing. We keep an original behaviour for users and reduce the possible 'pop' on probe.
But, to take significant advantage, we should add ADC control too, and, as this is a feature, it is undesirable for stable branches.
So probably the best decision is to roll original 631bc8f0134ae back in all stable branches where it was added.
Thank you, Mark. Your explanation is extremely useful.
Quoted 5 lines
To backport the addition of the controls to stable we'd need an additional change which sets the default for this control to unmuted, there's a case for having such a change upstream regardless but it's still not clear if any of these changes are really fixes in the sense that we mean for stable.
Greg Kroah-Hartman
maintainerRe: [PATCH 5.3 112/112] ASoC: sgtl5000: add ADC mute control
In reply to Richard LeitnerQuoted 35 lines · Richard Leitner
Quoted 33 lines · Greg Kroah-Hartman
Quoted 31 lines · Mark Brown
Quoted 20 lines · Greg Kroah-Hartman
Quoted 9 lines · Mark Brown
Quoted 6 lines · Greg Kroah-Hartman
From: Oleksandr Suvorov <[email protected]>
commit
694b14554d75f2a1ae111202e71860d58b434a21upstream.This control mute/unmute the ADC input of SGTL5000 using its
CHIP_ANA_CTRLregister.This seems like a new feature and not an obvious candidate for stable?
there was a long email from Richard that said:
Upstream commit631bc8f0134a("ASoC: sgtl5000: Fix of unmute outputs on probe"), which ise9f621efaebdin v5.3 replacedsnd_soc_component_writewithsnd_soc_component_update_bitsand therefore no longer cleared theMUTE_ADCflag. This caused the ADC to stay muted and recording doesn't work any longer. This patch fixes this problem by adding a Switch control forMUTE_ADC.Quoted 1 line
That's why I took this. If this isn't true, I'll be glad to drop this.
That's probably not an appropriate fix for stable - it's going to add a new control which users will need to manually set (or hope their userspace automatically figures out that it should set for them, more advanced userspaces like PulseAudio should) which isn't a drop in fix. You could either drop the backport that was done for zero cross or take a new patch that clears the
MUTE_ADCflag (rather than punting to userspace to do so), or just be OK with what you've got at the minute which might be fine given the lack of user reports.
Quoted 8 lines
Quoted 1 line
Ok, I'll gladly go drop it, thanks!
Mark, thanks for the clarification! I haven't thought of breaking anything with the backport as it worked fine for our application.
Greg, just to be sure:
Are you going to drop this patch and revert
e9f621efaebdfor v5.3?
I dropped this patch.
If the revert is needed, please send that and I will be glad to queue it up for the next round of releases.
thanks,
greg k-h
stable-rc/linux-5.3.y boot: 118 boots: 1 failed, 109 passed with 7 offline, 1 untried/unknown (v5.3.6-112-gcbb18cd3e478)
stable-rc/linux-5.3.y boot: 118 boots: 1 failed, 109 passed with 7 offline, 1 untried/unknown (v5.3.6-112-gcbb18cd3e478)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-5.3.y/kernel/v5.3.6-112-gcbb18cd3e478/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-5.3.y/kernel/v5.3.6-112-gcbb18cd3e478/
Tree: stable-rc
Branch: linux-5.3.y
Git Describe: v5.3.6-112-gcbb18cd3e478
Git Commit: cbb18cd3e47885e336b42ce05d553b44e1e3a7a0
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 78 unique boards, 25 SoC families, 17 builds out of 208
Boot Failure Detected:
arm64:
defconfig:
gcc-8:
meson-gxm-khadas-vim2: 1 failed lab
Offline Platforms:
arm:
sunxi_defconfig:
gcc-8
sun5i-r8-chip: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
multi_v7_defconfig:
gcc-8
qcom-apq8064-cm-qs600: 1 offline lab
sun5i-r8-chip: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
davinci_all_defconfig:
gcc-8
dm365evm,legacy: 1 offline lab
qcom_defconfig:
gcc-8
qcom-apq8064-cm-qs600: 1 offline lab---
For more info write to <[email protected]>
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Greg Kroah-Hartman
maintainerQuoted 15 lines · shuah
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 4 lines
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 5.3.7-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-5.3.y
git commit: cbb18cd3e47885e336b42ce05d553b44e1e3a7a0
git describe: v5.3.6-112-gcbb18cd3e478
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.3-oe/build/v5.3.6-112-gcbb18cd3e478
No regressions (compared to build v5.3.6)
No fixes (compared to build v5.3.6)
Ran 24228 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15
- x86
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* libgpiod
* libhugetlbfs
* ltp-containers-tests
* kselftest
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-timers-tests
* network-basic-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* ltp-open-posix-tests
* kvm-unit-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 17 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm,x86_64, and i386.
Great, thanks for testing all of these and letting me know.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 391 pass: 391 fail: 0
Guenter
Greg Kroah-Hartman
maintainerQuoted 6 lines · Guenter Roeck
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Quoted 3 lines
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 391 pass: 391 fail: 0
Thanks for testing all of these and letting me know.
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.thanks,
greg k-h
Compiled, booted, and no regressions found on my x86_64 system.
Thanks,
Didik Setiawan
Greg Kroah-Hartman
maintainerQuoted 15 lines · Didik Setiawan
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.
Quoted 5 lines
Quoted 3 lines
thanks,
greg k-h
Compiled, booted, and no regressions found on my
x86_64system.
Wonderful, thanks for testing all of these and letting me know.
greg k-h
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.3:
12 builds: 12 pass, 0 fail
22 boots: 22 pass, 0 fail
38 tests: 38 pass, 0 failLinux version: 5.3.7-rc1-gcbb18cd3e478
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04Cheers
Jon
Signature · 1 line
nvpublic
Greg Kroah-Hartman
maintainerQuoted 23 lines · Jon Hunter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.3.7 release. There are 112 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri 18 Oct 2019 09:43:41 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.3.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.3.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.3:
Quoted 9 lines
12 builds: 12 pass, 0 fail 22 boots: 22 pass, 0 fail 38 tests: 38 pass, 0 failLinux version: 5.3.7-rc1-gcbb18cd3e478
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Wonderful, thanks for testing all of these and letting me know.
greg k-h