6.6.79-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 6.6.79-rc1 review
This is the start of the stable review cycle for the 6.6.79 release. There are 152 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, 21 Feb 2025 08:25:11 +0000. 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/v6.x/stable-review/patch-6.6.79-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-6.6.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.6.79-rc1
Greg Kroah-Hartman <[email protected]>
Revert "vfio/platform: check the bounds of read/write syscalls"
David Woodhouse <[email protected]>
x86/i8253: Disable PIT timer 0 when not in use
Michal Luczaj <[email protected]>
vsock: Orphan socket after transport release
Michal Luczaj <[email protected]>
vsock: Keep the binding until socket destruction
Pavel Begunkov <[email protected]>
io_uring/kbuf: reallocate buf lists on upgrade
Vicki Pfau <[email protected]>
HID: hid-steam: Don't use cancel_delayed_work_sync in IRQ context
Ivan Kokshaysky <[email protected]>
alpha: replace hardcoded stack offsets with autogenerated ones
Zhaoyang Huang <[email protected]>
mm: gup: fix infinite loop within __get_longterm_locked
Marc Zyngier <[email protected]>
arm64: Filter out SVE hwcaps when FEAT_SVE isn't implemented
Yu Kuai <[email protected]>
md/md-bitmap: move bitmap_{start, end}write to md upper layer
Yu Kuai <[email protected]>
md/raid5: implement pers->bitmap_sector()
Yu Kuai <[email protected]>
md: add a new callback pers->bitmap_sector()
Yu Kuai <[email protected]>
md/md-bitmap: remove the last parameter for bimtap_ops->endwrite()
Yu Kuai <[email protected]>
md/md-bitmap: factor behind write counters out from bitmap_{start/end}write()
Benjamin Marzinski <[email protected]>
md/raid5: recheck if reshape has finished with device_lock held
Hangbin Liu <[email protected]>
selftests: rtnetlink: update netdevsim ipsec output format
Hangbin Liu <[email protected]>
netdevsim: print human readable IP address
Alex Hung <[email protected]>
drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
Srinivasan Shanmugam <[email protected]>
drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer
Andrew Cooper <[email protected]>
x86/static-call: Remove early_boot_irqs_disabled check to fix Xen PVH dom0
Christian Gmeiner <[email protected]>
drm/v3d: Stop active perfmon if it is being destroyed
Tomi Valkeinen <[email protected]>
drm/rcar-du: dsi: Fix PHY lock bit check
Devarsh Thakkar <[email protected]>
drm/tidss: Clear the interrupt status for interrupts being disabled
Tomi Valkeinen <[email protected]>
drm/tidss: Fix issue in irq handling causing irq-flood issue
Eric Dumazet <[email protected]>
ipv6: mcast: add RCU protection to mld_newpack()
Eric Dumazet <[email protected]>
ipv6: mcast: extend RCU protection in igmp6_send()
Eric Dumazet <[email protected]>
ndisc: extend RCU protection in ndisc_send_skb()
Eric Dumazet <[email protected]>
openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
Eric Dumazet <[email protected]>
arp: use RCU protection in arp_xmit()
Eric Dumazet <[email protected]>
neighbour: use RCU protection in __neigh_notify()
Li Zetao <[email protected]>
neighbour: delete redundant judgment statements
Eric Dumazet <[email protected]>
ndisc: use RCU protection in ndisc_alloc_skb()
Vicki Pfau <[email protected]>
HID: hid-steam: Move hidraw input (un)registering to work
Vicki Pfau <[email protected]>
HID: hid-steam: Make sure rumble work is canceled on removal
Max Maisel <[email protected]>
HID: hid-steam: Add Deck IMU support
Dan Carpenter <[email protected]>
HID: hid-steam: Fix cleanup in probe()
Dan Carpenter <[email protected]>
HID: hid-steam: remove pointless error message
Vicki Pfau <[email protected]>
HID: hid-steam: Add gamepad-only mode switched to by holding options
Vicki Pfau <[email protected]>
HID: hid-steam: Update list of identifiers from SDL
Vicki Pfau <[email protected]>
HID: hid-steam: Clean up locking
Vicki Pfau <[email protected]>
HID: hid-steam: Disable watchdog instead of using a heartbeat
Vicki Pfau <[email protected]>
HID: hid-steam: Avoid overwriting smoothing parameter
Eric Dumazet <[email protected]>
ipv6: icmp: convert to dev_net_rcu()
Eric Dumazet <[email protected]>
ipv6: use RCU protection in ip6_default_advmss()
Eric Dumazet <[email protected]>
flow_dissector: use RCU protection to fetch dev_net()
Eric Dumazet <[email protected]>
ipv4: icmp: convert to dev_net_rcu()
Eric Dumazet <[email protected]>
ipv4: use RCU protection in __ip_rt_update_pmtu()
Vladimir Vdovin <[email protected]>
net: ipv4: Cache pmtu for all packet paths if multipath enabled
Eric Dumazet <[email protected]>
ipv4: use RCU protection in inet_select_addr()
Eric Dumazet <[email protected]>
ipv4: use RCU protection in rt_is_expired()
Eric Dumazet <[email protected]>
ipv4: use RCU protection in ipv4_default_advmss()
Eric Dumazet <[email protected]>
net: add dev_net_rcu() helper
Jiri Pirko <[email protected]>
net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu()
Eric Dumazet <[email protected]>
ipv4: add RCU protection to ip4_dst_hoplimit()
Waiman Long <[email protected]>
clocksource: Use migrate_disable() to avoid calling get_random_u32() in atomic context
Waiman Long <[email protected]>
clocksource: Use pr_info() for "Checking clocksource synchronization" message
Filipe Manana <[email protected]>
btrfs: fix hole expansion when writing at an offset beyond EOF
Wentao Liang <[email protected]>
mlxsw: Add return value check for mlxsw_sp_port_get_stats_raw()
Song Yoong Siang <[email protected]>
igc: Set buffer type for empty frames in igc_init_empty_frame
Andy-ld Lu <[email protected]>
mmc: mtk-sd: Fix register settings for hs400(es) mode
Nathan Chancellor <[email protected]>
arm64: Handle .ARM.attributes section in linker scripts
Jiasheng Jiang <[email protected]>
regmap-irq: Add missing kfree()
Varadarajan Narayanan <[email protected]>
regulator: qcom_smd: Add l2, l5 sub-node to mp5496 regulator
Jann Horn <[email protected]>
partitions: mac: fix handling of bogus partition table
Wentao Liang <[email protected]>
gpio: stmpe: Check return value of stmpe_reg_read in stmpe_gpio_irq_sync_unlock
Mario Limonciello <[email protected]>
gpiolib: acpi: Add a quirk for Acer Nitro ANV14
Ivan Kokshaysky <[email protected]>
alpha: align stack for page fault and user unaligned trap handlers
John Keeping <[email protected]>
serial: 8250: Fix fifo underflow on flush
Andy Shevchenko <[email protected]>
serial: port: Always update ->iotype in __uart_read_properties()
Andy Shevchenko <[email protected]>
serial: port: Assign ->iotype correctly when ->iobase is set
Shakeel Butt <[email protected]>
cgroup: fix race between fork and cgroup.kill
Ard Biesheuvel <[email protected]>
efi: Avoid cold plugged memory for placing the kernel
Thomas Weißschuh <[email protected]>
kbuild: userprogs: fix bitsize and target detection on clang
Aditya Kumar Singh <[email protected]>
wifi: ath12k: fix handling of 6 GHz rules
Ivan Kokshaysky <[email protected]>
alpha: make stack 16-byte aligned (most cases)
Vincent Mailhol <[email protected]>
can: etas_es58x: fix potential NULL pointer dereference on udev->serial
Alexander Hölzl <[email protected]>
can: j1939: j1939_sk_send_loop(): fix unable to send messages with data length zero
Krzysztof Kozlowski <[email protected]>
can: c_can: fix unbalanced runtime PM disable in error path
Fedor Pchelkin <[email protected]>
can: ctucanfd: handle skb allocation failure
Johan Hovold <[email protected]>
USB: serial: option: drop MeiG Smart defines
Fabio Porcedda <[email protected]>
USB: serial: option: fix Telit Cinterion FN990A name
Fabio Porcedda <[email protected]>
USB: serial: option: add Telit Cinterion FN990B compositions
Chester A. Unal <[email protected]>
USB: serial: option: add MeiG Smart SLM828
Jann Horn <[email protected]>
usb: cdc-acm: Fix handling of oversized fragments
Jann Horn <[email protected]>
usb: cdc-acm: Check control transfer buffer size before access
Marek Vasut <[email protected]>
USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk
Alan Stern <[email protected]>
USB: hub: Ignore non-compliant devices with too many configs or interfaces
John Keeping <[email protected]>
usb: gadget: f_midi: fix MIDI Streaming descriptor lengths
Mathias Nyman <[email protected]>
USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone
Lei Huang <[email protected]>
USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist
Stefan Eichenberger <[email protected]>
usb: core: fix pipe creation for get_bMaxPacketSize0
Huacai Chen <[email protected]>
USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI
Fabrice Gasnier <[email protected]>
usb: dwc2: gadget: remove of_node reference upon udc_stop
Guo Ren <[email protected]>
usb: gadget: udc: renesas_usb3: Fix compiler warning
Elson Roy Serrao <[email protected]>
usb: roles: set switch registered flag early on
Selvarasu Ganesan <[email protected]>
usb: dwc3: Fix timeout issue during controller enter/exit from halt state
Selvarasu Ganesan <[email protected]>
usb: gadget: f_midi: Fixing wMaxPacketSize exceeded issue during MIDI bind retries
Sean Christopherson <[email protected]>
perf/x86/intel: Ensure LBRs are disabled when a CPU is starting
Sean Christopherson <[email protected]>
KVM: nSVM: Enter guest mode before initializing nested NPT MMU
Sean Christopherson <[email protected]>
KVM: x86: Reject Hyper-V's SEND_IPI hypercalls if local APIC isn't in-kernel
Jiang Liu <[email protected]>
drm/amdgpu: avoid buffer overflow attach in smu_sys_set_pp_table()
Sven Eckelmann <[email protected]>
batman-adv: Drop unmanaged ELP metric worker
Sven Eckelmann <[email protected]>
batman-adv: Ignore neighbor throughput metrics in error case
Andy Strohman <[email protected]>
batman-adv: fix panic during interface removal
Hans de Goede <[email protected]>
ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V
Mike Marshall <[email protected]>
orangefs: fix a oob in orangefs_debug_write
Rik van Riel <[email protected]>
x86/mm/tlb: Only trim the mm_cpumask once a second
Hans de Goede <[email protected]>
ACPI: x86: Add skip i2c clients quirk for Vexia EDU ATLA 10 tablet 5V
Koichiro Den <[email protected]>
selftests: gpio: gpio-sim: Fix missing chip disablements
Maksym Planeta <[email protected]>
Grab mm lock before grabbing pt lock
Zichen Xie <[email protected]>
NFS: Fix potential buffer overflowin nfs_sysfs_link_rpc_client()
Ramesh Thomas <[email protected]>
vfio/pci: Enable iowrite64 and ioread64 for vfio pci
Tomas Glozar <[email protected]>
rtla/timerlat_top: Abort event processing on second signal
Tomas Glozar <[email protected]>
rtla/timerlat_hist: Abort event processing on second signal
Guixin Liu <[email protected]>
scsi: ufs: bsg: Set bsg_queue to NULL after removal
Rakesh Babu Saladi <[email protected]>
PCI: switchtec: Add Microchip PCI100X device IDs
Takashi Iwai <[email protected]>
PCI/DPC: Quirk PIO log size for Intel Raptor Lake-P
Edward Adam Davis <[email protected]>
media: vidtv: Fix a null-ptr-deref in vidtv_mux_stop_thread
Isaac Scott <[email protected]>
media: uvcvideo: Add Kurokesu C1 PRO camera
Isaac Scott <[email protected]>
media: uvcvideo: Add new quirk definition for the Sonix Technology Co. 292a camera
Isaac Scott <[email protected]>
media: uvcvideo: Implement dual stream quirk to fix loss of usb packets
Tomi Valkeinen <[email protected]>
media: i2c: ds90ub953: Add error handling for i2c reads/writes
Tomi Valkeinen <[email protected]>
media: i2c: ds90ub913: Add error handling to ub913_hw_init()
Arnd Bergmann <[email protected]>
media: cxd2841er: fix 64-bit division on gcc-9
Kartik Rajput <[email protected]>
soc/tegra: fuse: Update Tegra234 nvmem keepout list
Aaro Koskinen <[email protected]>
fbdev: omap: use threaded IRQ for LCD DMA
Michael Margolin <[email protected]>
RDMA/efa: Reset device on probe failure
Masahiro Yamada <[email protected]>
tools: fix annoying "mkdir -p ..." logs when building tools in parallel
Andy Shevchenko <[email protected]>
gpiolib: Fix crash on error in gpiochip_get_ngpios()
Jens Axboe <[email protected]>
block: cleanup and fix batch completion adding conditions
Juergen Gross <[email protected]>
x86/xen: allow larger contiguous memory regions in PV guests
Juergen Gross <[email protected]>
xen/swiotlb: relax alignment requirements
Jiang Liu <[email protected]>
drm/amdgpu: bail out when failed to load fw in psp_init_cap_microcode()
Artur Weber <[email protected]>
gpio: bcm-kona: Add missing newline to dev_err format string
Artur Weber <[email protected]>
gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ
Artur Weber <[email protected]>
gpio: bcm-kona: Fix GPIO lock/unlock for banks above bank 0
Krzysztof Karas <[email protected]>
drm/i915/selftests: avoid using uninitialized context
Muhammad Adeel <[email protected]>
cgroup: Remove steal time from usage_usec
Radu Rendec <[email protected]>
arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array
Eric Dumazet <[email protected]>
team: better TEAM_OPTION_TYPE_STRING validation
Yuli Wang <[email protected]>
LoongArch: csum: Fix OoB access in IP checksum code for negative lengths
Marco Crivellari <[email protected]>
LoongArch: Fix idle VS timer enqueue
Eric Dumazet <[email protected]>
vxlan: check vxlan_vnigroup_init() return value
Eric Dumazet <[email protected]>
vrf: use RCU protection in l3mdev_l3_out()
Eric Dumazet <[email protected]>
ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu()
Murad Masimov <[email protected]>
ax25: Fix refcount leak caused by setting SO_BINDTODEVICE sockopt
Kunihiko Hayashi <[email protected]>
spi: sn-f-ospi: Fix division by zero
Tulio Fernandes <[email protected]>
HID: hid-thrustmaster: fix stack-out-of-bounds read in usb_check_int_endpoints()
Charles Han <[email protected]>
HID: multitouch: Add NULL check in mt_input_configured
Andy Shevchenko <[email protected]>
pinctrl: cy8c95x0: Respect IRQ trigger settings from firmware
Dai Ngo <[email protected]>
NFSD: fix hang in nfsd4_shutdown_callback
Li Lingfeng <[email protected]>
nfsd: clear acl_access/acl_default after releasing them
-------------
Diffstat:
Documentation/arch/arm64/elf_hwcaps.rst | 36 +- .../bindings/regulator/qcom,smd-rpm-regulator.yaml | 2 +- Makefile | 17 +- arch/alpha/include/uapi/asm/ptrace.h | 2 + arch/alpha/kernel/asm-offsets.c | 2 + arch/alpha/kernel/entry.S | 24 +- arch/alpha/kernel/traps.c | 2 +- arch/alpha/mm/fault.c | 4 +- arch/arm64/kernel/cacheinfo.c | 12 +- arch/arm64/kernel/cpufeature.c | 38 +- arch/arm64/kernel/vdso/vdso.lds.S | 1 + arch/arm64/kernel/vmlinux.lds.S | 1 + arch/loongarch/kernel/genex.S | 28 +- arch/loongarch/kernel/idle.c | 3 +- arch/loongarch/kernel/reset.c | 6 +- arch/loongarch/lib/csum.c | 2 +- arch/x86/events/intel/core.c | 5 +- arch/x86/include/asm/mmu.h | 2 + arch/x86/include/asm/mmu_context.h | 1 + arch/x86/include/asm/msr-index.h | 3 +- arch/x86/include/asm/tlbflush.h | 1 + arch/x86/kernel/i8253.c | 11 +- arch/x86/kernel/static_call.c | 1 - arch/x86/kvm/hyperv.c | 6 +- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/svm/nested.c | 10 +- arch/x86/mm/tlb.c | 35 +- arch/x86/xen/mmu_pv.c | 75 ++- block/partitions/mac.c | 18 +- drivers/acpi/x86/utils.c | 13 + drivers/base/regmap/regmap-irq.c | 2 + drivers/clocksource/i8253.c | 13 +- drivers/firmware/efi/efi.c | 6 +- drivers/firmware/efi/libstub/randomalloc.c | 3 + drivers/firmware/efi/libstub/relocate.c | 3 + drivers/gpio/gpio-bcm-kona.c | 71 +- drivers/gpio/gpio-stmpe.c | 15 +- drivers/gpio/gpiolib-acpi.c | 14 + drivers/gpio/gpiolib.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 5 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 3 +- .../drm/amd/display/dc/dcn201/dcn201_resource.c | 4 +- .../gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 3 +- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +- drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 2 +- .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 1 - drivers/gpu/drm/tidss/tidss_dispc.c | 22 +- drivers/gpu/drm/v3d/v3d_perfmon.c | 5 + drivers/hid/hid-multitouch.c | 5 +- drivers/hid/hid-steam.c | 738 ++++++++++++++++----- drivers/hid/hid-thrustmaster.c | 2 +- drivers/infiniband/hw/efa/efa_main.c | 9 +- drivers/md/md-bitmap.c | 75 ++- drivers/md/md-bitmap.h | 6 +- drivers/md/md.c | 26 + drivers/md/md.h | 5 + drivers/md/raid1.c | 35 +- drivers/md/raid1.h | 1 - drivers/md/raid10.c | 26 +- drivers/md/raid10.h | 1 - drivers/md/raid5-cache.c | 4 - drivers/md/raid5.c | 174 ++--- drivers/md/raid5.h | 4 - drivers/media/dvb-frontends/cxd2841er.c | 8 +- drivers/media/i2c/ds90ub913.c | 25 +- drivers/media/i2c/ds90ub953.c | 46 +- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 8 +- drivers/media/usb/uvc/uvc_driver.c | 18 + drivers/media/usb/uvc/uvc_video.c | 27 +- drivers/media/usb/uvc/uvcvideo.h | 1 + drivers/mmc/host/mtk-sd.c | 31 +- drivers/net/can/c_can/c_can_platform.c | 5 +- drivers/net/can/ctucanfd/ctucanfd_base.c | 10 +- drivers/net/can/usb/etas_es58x/es58x_devlink.c | 6 +- drivers/net/ethernet/intel/igc/igc_main.c | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 4 +- drivers/net/netdevsim/ipsec.c | 12 +- drivers/net/team/team.c | 4 +- drivers/net/vxlan/vxlan_core.c | 7 +- drivers/net/wireless/ath/ath12k/wmi.c | 61 +- drivers/net/wireless/ath/ath12k/wmi.h | 1 - drivers/pci/quirks.c | 12 + drivers/pci/switch/switchtec.c | 26 + drivers/pinctrl/pinctrl-cy8c95x0.c | 2 +- drivers/soc/tegra/fuse/fuse-tegra30.c | 17 +- drivers/spi/spi-sn-f-ospi.c | 3 + drivers/tty/serial/8250/8250.h | 2 + drivers/tty/serial/8250/8250_dma.c | 16 + drivers/tty/serial/8250/8250_port.c | 9 + drivers/tty/serial/serial_port.c | 5 +- drivers/ufs/core/ufs_bsg.c | 1 + drivers/usb/class/cdc-acm.c | 28 +- drivers/usb/core/hub.c | 14 +- drivers/usb/core/quirks.c | 6 + drivers/usb/dwc2/gadget.c | 1 + drivers/usb/dwc3/gadget.c | 34 + drivers/usb/gadget/function/f_midi.c | 17 +- drivers/usb/gadget/udc/renesas_usb3.c | 2 +- drivers/usb/host/pci-quirks.c | 9 + drivers/usb/roles/class.c | 5 +- drivers/usb/serial/option.c | 49 +- drivers/vfio/pci/vfio_pci_rdwr.c | 1 + drivers/vfio/platform/vfio_platform_common.c | 10 - drivers/video/fbdev/omap/lcd_dma.c | 4 +- drivers/xen/swiotlb-xen.c | 20 +- fs/btrfs/file.c | 4 +- fs/nfs/sysfs.c | 6 +- fs/nfsd/nfs2acl.c | 2 + fs/nfsd/nfs3acl.c | 2 + fs/nfsd/nfs4callback.c | 7 +- fs/orangefs/orangefs-debugfs.c | 4 +- include/linux/blk-mq.h | 18 +- include/linux/cgroup-defs.h | 6 +- include/linux/efi.h | 1 + include/linux/i8253.h | 1 + include/linux/netdevice.h | 6 + include/linux/sched/task.h | 1 + include/net/l3mdev.h | 2 + include/net/net_namespace.h | 15 +- include/net/route.h | 9 +- io_uring/kbuf.c | 15 +- kernel/cgroup/cgroup.c | 20 +- kernel/cgroup/rstat.c | 1 - kernel/time/clocksource.c | 9 +- mm/gup.c | 14 +- net/ax25/af_ax25.c | 11 + net/batman-adv/bat_v.c | 2 - net/batman-adv/bat_v_elp.c | 122 +++- net/batman-adv/bat_v_elp.h | 2 - net/batman-adv/types.h | 3 - net/can/j1939/socket.c | 4 +- net/can/j1939/transport.c | 5 +- net/core/flow_dissector.c | 21 +- net/core/neighbour.c | 11 +- net/ipv4/arp.c | 4 +- net/ipv4/devinet.c | 3 +- net/ipv4/icmp.c | 31 +- net/ipv4/route.c | 39 +- net/ipv6/icmp.c | 42 +- net/ipv6/mcast.c | 45 +- net/ipv6/ndisc.c | 28 +- net/ipv6/route.c | 7 +- net/openvswitch/datapath.c | 12 +- net/vmw_vsock/af_vsock.c | 12 +- sound/soc/intel/boards/bytcr_rt5640.c | 17 +- tools/testing/selftests/gpio/gpio-sim.sh | 31 +- tools/testing/selftests/net/pmtu.sh | 112 +++- tools/testing/selftests/net/rtnetlink.sh | 4 +- tools/tracing/rtla/src/timerlat_hist.c | 8 + tools/tracing/rtla/src/timerlat_top.c | 8 + 151 files changed, 2108 insertions(+), 846 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/152 nfsd: clear acl_access/acl_default after releasing them
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
commit 7faf14a7b0366f153284db0ad3347c457ea70136 upstream.
If getting acl_default fails, acl_access and acl_default will be released simultaneously. However, acl_access will still retain a pointer pointing to the released posix_acl, which will trigger a WARNING in nfs3svc_release_getacl like this:
------------[ cut here ]------------ refcount_t: underflow; use-after-free. WARNING: CPU: 26 PID: 3199 at lib/refcount.c:28 refcount_warn_saturate+0xb5/0x170 Modules linked in: CPU: 26 UID: 0 PID: 3199 Comm: nfsd Not tainted 6.12.0-rc6-00079-g04ae226af01f-dirty #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcount_warn_saturate+0xb5/0x170 Code: cc cc 0f b6 1d b3 20 a5 03 80 fb 01 0f 87 65 48 d8 00 83 e3 01 75 e4 48 c7 c7 c0 3b 9b 85 c6 05 97 20 a5 03 01 e8 fb 3e 30 ff <0f> 0b eb cd 0f b6 1d 8a3 RSP: 0018:ffffc90008637cd8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff83904fde RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88871ed36380 RBP: ffff888158beeb40 R08: 0000000000000001 R09: fffff520010c6f56 R10: ffffc90008637ab7 R11: 0000000000000001 R12: 0000000000000001 R13: ffff888140e77400 R14: ffff888140e77408 R15: ffffffff858b42c0 FS: 0000000000000000(0000) GS:ffff88871ed00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000562384d32158 CR3: 000000055cc6a000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? refcount_warn_saturate+0xb5/0x170 ? __warn+0xa5/0x140 ? refcount_warn_saturate+0xb5/0x170 ? report_bug+0x1b1/0x1e0 ? handle_bug+0x53/0xa0 ? exc_invalid_op+0x17/0x40 ? asm_exc_invalid_op+0x1a/0x20 ? tick_nohz_tick_stopped+0x1e/0x40 ? refcount_warn_saturate+0xb5/0x170 ? refcount_warn_saturate+0xb5/0x170 nfs3svc_release_getacl+0xc9/0xe0 svc_process_common+0x5db/0xb60 ? __pfx_svc_process_common+0x10/0x10 ? __rcu_read_unlock+0x69/0xa0 ? __pfx_nfsd_dispatch+0x10/0x10 ? svc_xprt_received+0xa1/0x120 ? xdr_init_decode+0x11d/0x190 svc_process+0x2a7/0x330 svc_handle_xprt+0x69d/0x940 svc_recv+0x180/0x2d0 nfsd+0x168/0x200 ? __pfx_nfsd+0x10/0x10 kthread+0x1a2/0x1e0 ? kthread+0xf4/0x1e0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x34/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Kernel panic - not syncing: kernel: panic_on_warn set ...
Clear acl_access/acl_default after posix_acl_release is called to prevent UAF from being triggered.
--- fs/nfsd/nfs2acl.c | 2 ++ fs/nfsd/nfs3acl.c | 2 ++ 2 files changed, 4 insertions(+)
fs/nfsd/nfs2acl.c +2 -0
@@ -84,6 +84,8 @@ out: fail:posix_acl_release (resp->acl_access);posix_acl_release (resp->acl_default); + resp->acl_access =NULL ; + resp->acl_default =NULL ; goto out; }
fs/nfsd/nfs3acl.c +2 -0
@@ -76,6 +76,8 @@ out: fail:posix_acl_release (resp->acl_access);posix_acl_release (resp->acl_default); + resp->acl_access =NULL ; + resp->acl_default =NULL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 2/152 NFSD: fix hang in nfsd4_shutdown_callback
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dai Ngo <[email protected]>
commit 036ac2778f7b28885814c6fbc07e156ad1624d03 upstream.
If nfs4_client is in courtesy state then there is no point to send the callback. This causes nfsd4_shutdown_callback to hang since cl_cb_inflight is not 0. This hang lasts about 15 minutes until TCP notifies NFSD that the connection was dropped.
This patch modifies nfsd4_run_cb_work to skip the RPC call if nfs4_client is in courtesy state.
--- fs/nfsd/nfs4callback.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4callback.c +5 -2
@@ -1410,8 +1410,11 @@ nfsd4_run_cb_work(struct work_struct *wonfsd4_process_cb_update (cb); clnt = clp->cl_cb_client; -if (!clnt) { -/* Callback channel broken, or client killed; give up: */ +if (!clnt || clp->cl_state ==NFSD4_COURTESY ) { +/* +* Callback channel broken, client killed or +* nfs4_client in courtesy state; give up. +*/ nfsd41_destroy_cb (cb);return ; }
Greg Kroah-Hartman
maintainerPATCH 3/152 pinctrl: cy8c95x0: Respect IRQ trigger settings from firmware
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 1ddee69108d305bbc059cbf31c0b47626796be77 ]
Some of the platforms may connect the INT pin via inversion logic effectively make the triggering to be active-low.
Remove explicit trigger flag to respect the settings from firmware.
Without this change even idling chip produces spurious interrupts and kernel disables the line in the result:
irq 33: nobody cared (try booting with the "irqpoll" option)
CPU: 0 UID: 0 PID: 125 Comm: irq/33-i2c-INT3 Not tainted 6.12.0-00236-g8b874ed11dae #64 Hardware name: Intel Corp. QUARK/Galileo, BIOS 0x01000900 01/01/2014 ... handlers: [<86e86bea>] irq_default_primary_handler threaded [<d153e44a>] cy8c95x0_irq_handler [pinctrl_cy8c95x0] Disabling IRQ #33
--- drivers/pinctrl/pinctrl-cy8c95x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/pinctrl-cy8c95x0.c +1 -1
@@ -1281,7 +1281,7 @@ static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) ret =devm_request_threaded_irq (chip->dev, irq,NULL , cy8c95x0_irq_handler, -IRQF_ONESHOT |IRQF_SHARED |IRQF_TRIGGER_HIGH , +IRQF_ONESHOT |IRQF_SHARED ,dev_name (chip->dev), chip);if (ret) {dev_err (chip->dev,"failed to request irq %d\n" , irq);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 4/152 HID: multitouch: Add NULL check in mt_input_configured
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 9b8e2220d3a052a690b1d1b23019673e612494c5 ]
devm_kasprintf() can return a NULL pointer on failure,but this returned value in mt_input_configured() is not checked. Add NULL check in mt_input_configured(), to handle kernel NULL pointer dereference error.
--- drivers/hid/hid-multitouch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/hid/hid-multitouch.c +4 -1
@@ -1668,9 +1668,12 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)break ; } -if (suffix) +if (suffix) { hi->input->name =devm_kasprintf (&hdev->dev,GFP_KERNEL ,"%s %s" , hdev->name, suffix); +if (!hi->input->name) +return -ENOMEM ; + }return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 5/152 HID: hid-thrustmaster: fix stack-out-of-bounds read in usb_check_int_endpoints()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tulio Fernandes <[email protected]>
[ Upstream commit 0b43d98ff29be3144e86294486b1373b5df74c0e ]
Syzbot[1] has detected a stack-out-of-bounds read of the ep_addr array from hid-thrustmaster driver. This array is passed to usb_check_int_endpoints function from usb.c core driver, which executes a for loop that iterates over the elements of the passed array. Not finding a null element at the end of the array, it tries to read the next, non-existent element, crashing the kernel.
To fix this, a 0 element was added at the end of the array to break the for loop.
[1] https://syzkaller.appspot.com/bug?extid=9c9179ac46169c56c1ad
--- drivers/hid/hid-thrustmaster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/hid-thrustmaster.c +1 -1
@@ -171,7 +171,7 @@ static void thrustmaster_interrupts(struct hid_device *hdev) b_ep = ep->desc.bEndpointAddress;/* Are the expected endpoints present? */ -u8 ep_addr[1 ] = {b_ep}; +u8 ep_addr[2 ] = {b_ep,0 };if (!usb_check_int_endpoints (usbif, ep_addr)) {hid_err (hdev,"Unexpected non-int endpoint\n" );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 6/152 spi: sn-f-ospi: Fix division by zero
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kunihiko Hayashi <[email protected]>
[ Upstream commit 3588b1c0fde2f58d166e3f94a5a58d64b893526c ]
When there is no dummy cycle in the spi-nor commands, both dummy bus cycle bytes and width are zero. Because of the cpu's warning when divided by zero, the warning should be avoided. Return just zero to avoid such calculations.
--- drivers/spi/spi-sn-f-ospi.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/spi/spi-sn-f-ospi.c +3 -0
@@ -116,6 +116,9 @@ struct f_ospi {static u32 f_ospi_get_dummy_cycle (const struct spi_mem_op *op) { +if (!op->dummy.nbytes) +return 0 ; +return (op->dummy.nbytes *8 ) / op->dummy.buswidth; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 7/152 ax25: Fix refcount leak caused by setting SO_BINDTODEVICE sockopt
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Murad Masimov <[email protected]>
[ Upstream commit bca0902e61731a75fc4860c8720168d9f1bae3b6 ]
If an AX25 device is bound to a socket by setting the SO_BINDTODEVICE socket option, a refcount leak will occur in ax25_release().
Commit 9fd75b66b8f6 ("ax25: Fix refcount leaks caused by ax25_cb_del()") added decrement of device refcounts in ax25_release(). In order for that to work correctly the refcounts must already be incremented when the device is bound to the socket. An AX25 device can be bound to a socket by either calling ax25_bind() or setting SO_BINDTODEVICE socket option. In both cases the refcounts should be incremented, but in fact it is done only in ax25_bind().
This bug leads to the following issue reported by Syzkaller:
================================================================refcount_t: decrement hit 0; leaking memory.
WARNING: CPU: 1 PID: 5932 at lib/refcount.c:31 refcount_warn_saturate+0x1ed/0x210 lib/refcount.c:31 Modules linked in: CPU: 1 UID: 0 PID: 5932 Comm: syz-executor424 Not tainted 6.13.0-rc4-syzkaller-00110-g4099a71718b0 #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:refcount_warn_saturate+0x1ed/0x210 lib/refcount.c:31 Call Trace: <TASK> __refcount_dec include/linux/refcount.h:336 [inline] refcount_dec include/linux/refcount.h:351 [inline] ref_tracker_free+0x710/0x820 lib/ref_tracker.c:236 netdev_tracker_free include/linux/netdevice.h:4156 [inline] netdev_put include/linux/netdevice.h:4173 [inline] netdev_put include/linux/netdevice.h:4169 [inline] ax25_release+0x33f/0xa10 net/ax25/af_ax25.c:1069 __sock_release+0xb0/0x270 net/socket.c:640 sock_close+0x1c/0x30 net/socket.c:1408 ... do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... </TASK> ================================================================
Fix the implementation of ax25_setsockopt() by adding increment of refcounts for the new device bound, and decrement of refcounts for the old unbound device.
--- net/ax25/af_ax25.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
net/ax25/af_ax25.c +11 -0
@@ -685,6 +685,15 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ; } +if (ax25->ax25_dev) { +if (dev == ax25->ax25_dev->dev) { +rcu_read_unlock (); +break ; + } +netdev_put (ax25->ax25_dev->dev, &ax25->dev_tracker); +ax25_dev_put (ax25->ax25_dev); + } + ax25->ax25_dev =ax25_dev_ax25dev (dev);if (!ax25->ax25_dev) {rcu_read_unlock ();
@@ -692,6 +701,8 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ; }ax25_fillin_cb (ax25, ax25->ax25_dev); +netdev_hold (dev, &ax25->dev_tracker,GFP_ATOMIC ); +ax25_dev_hold (ax25->ax25_dev);rcu_read_unlock ();break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 8/152 ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 48145a57d4bbe3496e8e4880b23ea6b511e6e519 ]
ndisc_send_redirect() is called under RCU protection, not RTNL.
It must use dev_get_by_index_rcu() instead of __dev_get_by_index()
--- net/ipv6/ndisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/ndisc.c +1 -1
@@ -1680,7 +1680,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)bool ret;if (netif_is_l3_master (skb->dev)) { - dev =__dev_get_by_index (dev_net (skb->dev),IPCB (skb)->iif); + dev =dev_get_by_index_rcu (dev_net (skb->dev),IPCB (skb)->iif);if (!dev)return ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 9/152 vrf: use RCU protection in l3mdev_l3_out()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 6d0ce46a93135d96b7fa075a94a88fe0da8e8773 ]
l3mdev_l3_out() can be called without RCU being held:
raw_sendmsg()
ip_push_pending_frames()
ip_send_skb()
ip_local_out()
__ip_local_out()
l3mdev_ip_out()Add rcu_read_lock() / rcu_read_unlock() pair to avoid a potential UAF.
--- include/net/l3mdev.h | 2 ++ 1 file changed, 2 insertions(+)
include/net/l3mdev.h +2 -0
@@ -198,10 +198,12 @@ struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto)if (netif_is_l3_slave (dev)) {struct net_device *master; +rcu_read_lock (); master =netdev_master_upper_dev_get_rcu (dev);if (master && master->l3mdev_ops->l3mdev_l3_out) skb = master->l3mdev_ops->l3mdev_l3_out (master, sk, skb, proto); +rcu_read_unlock (); }return skb;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 10/152 vxlan: check vxlan_vnigroup_init() return value
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 5805402dcc56241987bca674a1b4da79a249bab7 ]
vxlan_init() must check vxlan_vnigroup_init() success otherwise a crash happens later, spotted by syzbot.
Oops: general protection fault, probably for non-canonical address 0xdffffc000000002c: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000160-0x0000000000000167] CPU: 0 UID: 0 PID: 7313 Comm: syz-executor147 Not tainted 6.14.0-rc1-syzkaller-00276-g69b54314c975 #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:vxlan_vnigroup_uninit+0x89/0x500 drivers/net/vxlan/vxlan_vnifilter.c:912 Code: 00 48 8b 44 24 08 4c 8b b0 98 41 00 00 49 8d 86 60 01 00 00 48 89 c2 48 89 44 24 10 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 4d 04 00 00 49 8b 86 60 01 00 00 48 ba 00 00 00 RSP: 0018:ffffc9000cc1eea8 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: 0000000000000001 RCX: ffffffff8672effb RDX: 000000000000002c RSI: ffffffff8672ecb9 RDI: ffff8880461b4f18 RBP: ffff8880461b4ef4 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000020000 R13: ffff8880461b0d80 R14: 0000000000000000 R15: dffffc0000000000 FS: 00007fecfa95d6c0(0000) GS:ffff88806a600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fecfa95cfb8 CR3: 000000004472c000 CR4: 0000000000352ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> vxlan_uninit+0x1ab/0x200 drivers/net/vxlan/vxlan_core.c:2942 unregister_netdevice_many_notify+0x12d6/0x1f30 net/core/dev.c:11824 unregister_netdevice_many net/core/dev.c:11866 [inline] unregister_netdevice_queue+0x307/0x3f0 net/core/dev.c:11736 register_netdevice+0x1829/0x1eb0 net/core/dev.c:10901 __vxlan_dev_create+0x7c6/0xa30 drivers/net/vxlan/vxlan_core.c:3981 vxlan_newlink+0xd1/0x130 drivers/net/vxlan/vxlan_core.c:4407 rtnl_newlink_create net/core/rtnetlink.c:3795 [inline] __rtnl_newlink net/core/rtnetlink.c:3906 [inline]
--- drivers/net/vxlan/vxlan_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/vxlan/vxlan_core.c +5 -2
@@ -2966,8 +2966,11 @@ static int vxlan_init(struct net_device *dev)struct vxlan_dev *vxlan =netdev_priv (dev);int err; -if (vxlan->cfg.flags &VXLAN_F_VNIFILTER ) -vxlan_vnigroup_init (vxlan); +if (vxlan->cfg.flags &VXLAN_F_VNIFILTER ) { + err =vxlan_vnigroup_init (vxlan); +if (err) +return err; + } dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);if (!dev->tstats) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 11/152 LoongArch: Fix idle VS timer enqueue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marco Crivellari <[email protected]>
[ Upstream commit edb1942542bc538707cea221e9c7923a6270465f ]
LoongArch re-enables interrupts on its idle routine and performs a TIF_NEED_RESCHED check afterwards before putting the CPU to sleep.
The IRQs firing between the check and the idle instruction may set the TIF_NEED_RESCHED flag. In order to deal with such a race, IRQs interrupting __arch_cpu_idle() rollback their return address to the beginning of __arch_cpu_idle() so that TIF_NEED_RESCHED is checked again before going back to sleep.
However idle IRQs can also queue timers that may require a tick reprogramming through a new generic idle loop iteration but those timers would go unnoticed here because __arch_cpu_idle() only checks TIF_NEED_RESCHED. It doesn't check for pending timers.
Fix this with fast-forwarding idle IRQs return address to the end of the idle routine instead of the beginning, so that the generic idle loop can handle both TIF_NEED_RESCHED and pending timers.
--- arch/loongarch/kernel/genex.S | 28 +++++++++++++++------------- arch/loongarch/kernel/idle.c | 3 +-- arch/loongarch/kernel/reset.c | 6 +++--- 3 files changed, 19 insertions(+), 18 deletions(-)
arch/loongarch/kernel/genex.S +15 -13
@@ -18,27 +18,29 @@ .align 5 SYM_FUNC_START(__arch_cpu_idle) - /* start of rollback region */ - LONG_L t0, tp, TI_FLAGS - nop - andi t0, t0, _TIF_NEED_RESCHED - bnez t0, 1f - nop - nop - nop + /* start of idle interrupt region */ + ori t0, zero, CSR_CRMD_IE + /* idle instruction needs irq enabled */ + csrxchg t0, t0, LOONGARCH_CSR_CRMD + /* + * If an interrupt lands here; between enabling interrupts above and + * going idle on the next instruction, we must *NOT* go idle since the + * interrupt could have set TIF_NEED_RESCHED or caused an timer to need + * reprogramming. Fall through -- see handle_vint() below -- and have + * the idle loop take care of things. + */ idle 0 - /* end of rollback region */ + /* end of idle interrupt region */ 1: jr ra SYM_FUNC_END(__arch_cpu_idle) SYM_CODE_START(handle_vint) BACKUP_T0T1 SAVE_ALL - la_abs t1, __arch_cpu_idle + la_abs t1, 1b LONG_L t0, sp, PT_ERA - /* 32 byte rollback region */ - ori t0, t0, 0x1f - xori t0, t0, 0x1f + /* 3 instructions idle interrupt region */ + ori t0, t0, 0b1100 bne t0, t1, 1f LONG_S t0, sp, PT_ERA 1: move a0, sp
arch/loongarch/kernel/idle.c +1 -2
@@ -11,7 +11,6 @@ void __cpuidle arch_cpu_idle(void) { -raw_local_irq_enable (); -__arch_cpu_idle ();/* idle instruction needs irq enabled */ +__arch_cpu_idle ();raw_local_irq_disable (); }
arch/loongarch/kernel/reset.c +3 -3
@@ -33,7 +33,7 @@ void machine_halt(void)console_flush_on_panic (CONSOLE_FLUSH_PENDING );while (true) { -__arch_cpu_idle (); + __asm__ __volatile__("idle 0" : : :"memory" ); } }
@@ -53,7 +53,7 @@ void machine_power_off(void)#endif while (true) { -__arch_cpu_idle (); + __asm__ __volatile__("idle 0" : : :"memory" ); } }
@@ -74,6 +74,6 @@ void machine_restart(char *command)acpi_reboot ();while (true) { -__arch_cpu_idle (); + __asm__ __volatile__("idle 0" : : :"memory" ); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 12/152 LoongArch: csum: Fix OoB access in IP checksum code for negative lengths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuli Wang <[email protected]>
[ Upstream commit 6287f1a8c16138c2ec750953e35039634018c84a ]
Commit 69e3a6aa6be2 ("LoongArch: Add checksum optimization for 64-bit system") would cause an undefined shift and an out-of-bounds read.
Commit 8bd795fedb84 ("arm64: csum: Fix OoB access in IP checksum code for negative lengths") fixes the same issue on ARM64.
--- arch/loongarch/lib/csum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/lib/csum.c +1 -1
@@ -25,7 +25,7 @@ unsigned int __no_sanitize_address do_csum(const unsigned char *buff, int len)const u64 *ptr;u64 data, sum64 =0 ; -if (unlikely (len ==0 )) +if (unlikely (len <=0 ))return 0 ; offset = (unsigned long )buff &7 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 13/152 team: better TEAM_OPTION_TYPE_STRING validation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 5bef3ac184b5626ea62385d6b82a1992b89d7940 ]
syzbot reported following splat [1]
Make sure user-provided data contains one nul byte.
[1]
BUG: KMSAN: uninit-value in string_nocheck lib/vsprintf.c:633 [inline] BUG: KMSAN: uninit-value in string+0x3ec/0x5f0 lib/vsprintf.c:714 string_nocheck lib/vsprintf.c:633 [inline] string+0x3ec/0x5f0 lib/vsprintf.c:714 vsnprintf+0xa5d/0x1960 lib/vsprintf.c:2843 __request_module+0x252/0x9f0 kernel/module/kmod.c:149 team_mode_get drivers/net/team/team_core.c:480 [inline] team_change_mode drivers/net/team/team_core.c:607 [inline] team_mode_option_set+0x437/0x970 drivers/net/team/team_core.c:1401 team_option_set drivers/net/team/team_core.c:375 [inline] team_nl_options_set_doit+0x1339/0x1f90 drivers/net/team/team_core.c:2662 genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0x1214/0x12c0 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x375/0x650 net/netlink/af_netlink.c:2543 genl_rcv+0x40/0x60 net/netlink/genetlink.c:1219 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0xf52/0x1260 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x10da/0x11e0 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:718 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:733 ____sys_sendmsg+0x877/0xb60 net/socket.c:2573 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2627 __sys_sendmsg net/socket.c:2659 [inline] __do_sys_sendmsg net/socket.c:2664 [inline] __se_sys_sendmsg net/socket.c:2662 [inline] __x64_sys_sendmsg+0x212/0x3c0 net/socket.c:2662 x64_sys_call+0x2ed6/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- drivers/net/team/team.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/team/team.c +3 -1
@@ -2657,7 +2657,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) ctx.data.u32_val =nla_get_u32 (attr_data);break ;case TEAM_OPTION_TYPE_STRING : -if (nla_len (attr_data) >TEAM_STRING_MAX_LEN ) { +if (nla_len (attr_data) >TEAM_STRING_MAX_LEN || + !memchr (nla_data (attr_data),'\0' , +nla_len (attr_data))) { err = -EINVAL ; goto team_put; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 14/152 arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radu Rendec <[email protected]>
[ Upstream commit 875d742cf5327c93cba1f11e12b08d3cce7a88d2 ]
The loop that detects/populates cache information already has a bounds check on the array size but does not account for cache levels with separate data/instructions cache. Fix this by incrementing the index for any populated leaf (instead of any populated level).
--- arch/arm64/kernel/cacheinfo.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
arch/arm64/kernel/cacheinfo.c +7 -5
@@ -101,16 +101,18 @@ int populate_cache_leaves(unsigned int cpu)unsigned int level, idx;enum cache_type type;struct cpu_cacheinfo *this_cpu_ci =get_cpu_cacheinfo (cpu); -struct cacheinfo *this_leaf = this_cpu_ci->info_list; +struct cacheinfo *infos = this_cpu_ci->info_list;for (idx =0 , level =1 ; level <= this_cpu_ci->num_levels && - idx < this_cpu_ci->num_leaves; idx++, level++) { + idx < this_cpu_ci->num_leaves; level++) { type =get_cache_type (level);if (type ==CACHE_TYPE_SEPARATE ) { -ci_leaf_init (this_leaf++,CACHE_TYPE_DATA , level); -ci_leaf_init (this_leaf++,CACHE_TYPE_INST , level); +if (idx +1 >= this_cpu_ci->num_leaves) +break ; +ci_leaf_init (&infos[idx++],CACHE_TYPE_DATA , level); +ci_leaf_init (&infos[idx++],CACHE_TYPE_INST , level); }else { -ci_leaf_init (this_leaf++, type, level); +ci_leaf_init (&infos[idx++], type, level); } }return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 15/152 cgroup: Remove steal time from usage_usec
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Adeel <[email protected]>
[ Upstream commit db5fd3cf8bf41b84b577b8ad5234ea95f327c9be ]
The CPU usage time is the time when user, system or both are using the CPU. Steal time is the time when CPU is waiting to be run by the Hypervisor. It should not be added to the CPU usage time, hence removing it from the usage_usec entry.
--- kernel/cgroup/rstat.c | 1 - 1 file changed, 1 deletion(-)
kernel/cgroup/rstat.c +0 -1
@@ -469,7 +469,6 @@ static void root_cgroup_cputime(struct cgroup_base_stat *bstat) cputime->sum_exec_runtime += user; cputime->sum_exec_runtime += sys; - cputime->sum_exec_runtime += cpustat[CPUTIME_STEAL ];#ifdef CONFIG_SCHED_CORE bstat->forceidle_sum += cpustat[CPUTIME_FORCEIDLE ];
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 16/152 drm/i915/selftests: avoid using uninitialized context
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <[email protected]>
[ Upstream commit 53139b3f9998ea07289e7b70b909fea2264a0de9 ]
There is an error path in igt_ppgtt_alloc(), which leads to ww object being passed down to i915_gem_ww_ctx_fini() without initialization. Correct that by only putting ppgtt->vm and returning early.
--- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +2 -2
@@ -168,7 +168,7 @@ static int igt_ppgtt_alloc(void *arg)return PTR_ERR (ppgtt);if (!ppgtt->vm.allocate_va_range) - goto err_ppgtt_cleanup; + goto ppgtt_vm_put;/* * While we only allocate the page tables here and so we could
@@ -236,7 +236,7 @@ static int igt_ppgtt_alloc(void *arg) goto retry; }i915_gem_ww_ctx_fini (&ww); - +ppgtt_vm_put:i915_vm_put (&ppgtt->vm);return err; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 17/152 gpio: bcm-kona: Fix GPIO lock/unlock for banks above bank 0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artur Weber <[email protected]>
[ Upstream commit de1d0d160f64ee76df1d364d521b2faf465a091c ]
The GPIO lock/unlock functions clear/write a bit to the relevant register for each bank. However, due to an oversight the bit that was being written was based on the total GPIO number, not the index of the GPIO within the relevant bank, causing it to fail for any GPIO above 32 (thus any GPIO for banks above bank 0).
Fix lock/unlock for these banks by using the correct bit.
--- drivers/gpio/gpio-bcm-kona.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpio/gpio-bcm-kona.c +4 -2
@@ -86,11 +86,12 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,u32 val;unsigned long flags;int bank_id =GPIO_BANK (gpio); +int bit =GPIO_BIT (gpio);raw_spin_lock_irqsave (&kona_gpio->lock, flags); val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); - val |=BIT (gpio); + val |=BIT (bit);bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val);raw_spin_unlock_irqrestore (&kona_gpio->lock, flags);
@@ -102,11 +103,12 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,u32 val;unsigned long flags;int bank_id =GPIO_BANK (gpio); +int bit =GPIO_BIT (gpio);raw_spin_lock_irqsave (&kona_gpio->lock, flags); val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); - val &= ~BIT (gpio); + val &= ~BIT (bit);bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val);raw_spin_unlock_irqrestore (&kona_gpio->lock, flags);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 18/152 gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artur Weber <[email protected]>
[ Upstream commit 57f5db77a915cc29461a679a6bcae7097967be1a ]
The settings for all GPIOs are locked by default in bcm_kona_gpio_reset. The settings for a GPIO are unlocked when requesting it as a GPIO, but not when requesting it as an interrupt, causing the IRQ settings to not get applied.
Fix this by making sure to unlock the right bits when an IRQ is requested. To avoid a situation where an IRQ being released causes a lock despite the same GPIO being used by a GPIO request or vice versa, add an unlock counter and only lock if it reaches 0.
--- drivers/gpio/gpio-bcm-kona.c | 67 +++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 12 deletions(-)
drivers/gpio/gpio-bcm-kona.c +55 -12
@@ -69,6 +69,22 @@ struct bcm_kona_gpio {struct bcm_kona_gpio_bank {int id;int irq; +/* +* Used to keep track of lock/unlock operations for each GPIO in the +* bank. +* +* All GPIOs are locked by default (see bcm_kona_gpio_reset), and the +* unlock count for all GPIOs is 0 by default. Each unlock increments +* the counter, and each lock decrements the counter. +* +* The lock function only locks the GPIO once its unlock counter is +* down to 0. This is necessary because the GPIO is unlocked in two +* places in this driver: once for requested GPIOs, and once for +* requested IRQs. Since it is possible for a GPIO to be requested +* as both a GPIO and an IRQ, we need to ensure that we don't lock it +* too early. +*/ +u8 gpio_unlock_count[GPIO_PER_BANK ];/* Used in the interrupt handler */ struct bcm_kona_gpio *kona_gpio; };
@@ -87,14 +103,23 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,unsigned long flags;int bank_id =GPIO_BANK (gpio);int bit =GPIO_BIT (gpio); +struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; -raw_spin_lock_irqsave (&kona_gpio->lock, flags); +if (bank->gpio_unlock_count[bit] ==0 ) { +dev_err (kona_gpio->gpio_chip.parent, +"Unbalanced locks for GPIO %u\n" , gpio); +return ; + } - val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); - val |=BIT (bit); -bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val); +if (--bank->gpio_unlock_count[bit] ==0 ) { +raw_spin_lock_irqsave (&kona_gpio->lock, flags); -raw_spin_unlock_irqrestore (&kona_gpio->lock, flags); + val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); + val |=BIT (bit); +bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val); + +raw_spin_unlock_irqrestore (&kona_gpio->lock, flags); + } } static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
@@ -104,14 +129,19 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,unsigned long flags;int bank_id =GPIO_BANK (gpio);int bit =GPIO_BIT (gpio); +struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; -raw_spin_lock_irqsave (&kona_gpio->lock, flags); +if (bank->gpio_unlock_count[bit] ==0 ) { +raw_spin_lock_irqsave (&kona_gpio->lock, flags); - val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); - val &= ~BIT (bit); -bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val); + val =readl (kona_gpio->reg_base +GPIO_PWD_STATUS (bank_id)); + val &= ~BIT (bit); +bcm_kona_gpio_write_lock_regs (kona_gpio->reg_base, bank_id, val); -raw_spin_unlock_irqrestore (&kona_gpio->lock, flags); +raw_spin_unlock_irqrestore (&kona_gpio->lock, flags); + } + + ++bank->gpio_unlock_count[bit]; }static int bcm_kona_gpio_get_dir (struct gpio_chip *chip,unsigned gpio)
@@ -362,6 +392,7 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d) kona_gpio =irq_data_get_irq_chip_data (d); reg_base = kona_gpio->reg_base; +raw_spin_lock_irqsave (&kona_gpio->lock, flags); val =readl (reg_base +GPIO_INT_MASK (bank_id));
@@ -384,6 +415,7 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d) kona_gpio =irq_data_get_irq_chip_data (d); reg_base = kona_gpio->reg_base; +raw_spin_lock_irqsave (&kona_gpio->lock, flags); val =readl (reg_base +GPIO_INT_MSKCLR (bank_id));
@@ -479,15 +511,26 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc)static int bcm_kona_gpio_irq_reqres (struct irq_data *d) {struct bcm_kona_gpio *kona_gpio =irq_data_get_irq_chip_data (d); +unsigned int gpio = d->hwirq; + +/* +* We need to unlock the GPIO before any other operations are performed +* on the relevant GPIO configuration registers +*/ +bcm_kona_gpio_unlock_gpio (kona_gpio, gpio); -return gpiochip_reqres_irq (&kona_gpio->gpio_chip, d->hwirq); +return gpiochip_reqres_irq (&kona_gpio->gpio_chip, gpio); }static void bcm_kona_gpio_irq_relres (struct irq_data *d) {struct bcm_kona_gpio *kona_gpio =irq_data_get_irq_chip_data (d); +unsigned int gpio = d->hwirq; + +/* Once we no longer use it, lock the GPIO again */ +bcm_kona_gpio_lock_gpio (kona_gpio, gpio); -gpiochip_relres_irq (&kona_gpio->gpio_chip, d->hwirq); +gpiochip_relres_irq (&kona_gpio->gpio_chip, gpio); }static struct irq_chip bcm_gpio_irq_chip = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 19/152 gpio: bcm-kona: Add missing newline to dev_err format string
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artur Weber <[email protected]>
[ Upstream commit 615279db222c3ac56d5c93716efd72b843295c1f ]
Add a missing newline to the format string of the "Couldn't get IRQ for bank..." error message.
--- drivers/gpio/gpio-bcm-kona.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-bcm-kona.c +1 -1
@@ -659,7 +659,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) bank->irq =platform_get_irq (pdev, i); bank->kona_gpio = kona_gpio;if (bank->irq <0 ) { -dev_err (dev,"Couldn't get IRQ for bank %d" , i); +dev_err (dev,"Couldn't get IRQ for bank %d\n" , i); ret = -ENOENT ; goto err_irq_domain; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 20/152 drm/amdgpu: bail out when failed to load fw in psp_init_cap_microcode()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiang Liu <[email protected]>
[ Upstream commit a0a455b4bc7483ad60e8b8a50330c1e05bb7bfcf ]
In function psp_init_cap_microcode(), it should bail out when failed to load firmware, otherwise it may cause invalid memory access.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +3 -2
@@ -3450,9 +3450,10 @@ int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)if (err == -ENODEV ) {dev_warn (adev->dev,"cap microcode does not exist, skip\n" ); err =0 ; - goto out; + }else { +dev_err (adev->dev,"fail to initialize cap microcode\n" ); } -dev_err (adev->dev,"fail to initialize cap microcode\n" ); + goto out; } info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CAP ];
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 21/152 xen/swiotlb: relax alignment requirements
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <[email protected]>
[ Upstream commit 85fcb57c983f423180ba6ec5d0034242da05cc54 ]
When mapping a buffer for DMA via .map_page or .map_sg DMA operations, there is no need to check the machine frames to be aligned according to the mapped areas size. All what is needed in these cases is that the buffer is contiguous at machine level.
So carve out the alignment check from range_straddles_page_boundary() and move it to a helper called by xen_swiotlb_alloc_coherent() and xen_swiotlb_free_coherent() directly.
--- drivers/xen/swiotlb-xen.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/xen/swiotlb-xen.c +12 -8
@@ -74,19 +74,21 @@ static inline phys_addr_t xen_dma_to_phys(struct device *dev,return xen_bus_to_phys (dev,dma_to_phys (dev, dma_addr)); } +static inline bool range_requires_alignment (phys_addr_t p,size_t size) +{ +phys_addr_t algn =1ULL << (get_order (size) +PAGE_SHIFT ); +phys_addr_t bus_addr =pfn_to_bfn (XEN_PFN_DOWN (p)) <<XEN_PAGE_SHIFT ; + +return IS_ALIGNED (p, algn) && !IS_ALIGNED (bus_addr, algn); +} +static inline int range_straddles_page_boundary (phys_addr_t p,size_t size) {unsigned long next_bfn, xen_pfn =XEN_PFN_DOWN (p);unsigned int i, nr_pages =XEN_PFN_UP (xen_offset_in_page (p) + size); -phys_addr_t algn =1ULL << (get_order (size) +PAGE_SHIFT ); next_bfn =pfn_to_bfn (xen_pfn); -/* If buffer is physically aligned, ensure DMA alignment. */ -if (IS_ALIGNED (p, algn) && - !IS_ALIGNED ((phys_addr_t )next_bfn <<XEN_PAGE_SHIFT , algn)) -return 1 ; -for (i =1 ; i < nr_pages; i++)if (pfn_to_bfn (++xen_pfn) != ++next_bfn)return 1 ;
@@ -155,7 +157,8 @@ xen_swiotlb_alloc_coherent(struct device *dev, size_t size, *dma_handle =xen_phys_to_dma (dev, phys);if (*dma_handle + size -1 > dma_mask || -range_straddles_page_boundary (phys, size)) { +range_straddles_page_boundary (phys, size) || +range_requires_alignment (phys, size)) {if (xen_create_contiguous_region (phys, order,fls64 (dma_mask), dma_handle) !=0 ) goto out_free_pages;
@@ -181,7 +184,8 @@ xen_swiotlb_free_coherent(struct device *dev, size_t size, void *vaddr, size =ALIGN (size,XEN_PAGE_SIZE );if (WARN_ON_ONCE (dma_handle + size -1 > dev->coherent_dma_mask) || -WARN_ON_ONCE (range_straddles_page_boundary (phys, size))) +WARN_ON_ONCE (range_straddles_page_boundary (phys, size) || +range_requires_alignment (phys, size)))return ;if (TestClearPageXenRemapped (virt_to_page (vaddr)))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 22/152 x86/xen: allow larger contiguous memory regions in PV guests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <[email protected]>
[ Upstream commit e93ec87286bd1fd30b7389e7a387cfb259f297e3 ]
Today a PV guest (including dom0) can create 2MB contiguous memory regions for DMA buffers at max. This has led to problems at least with the megaraid_sas driver, which wants to allocate a 2.3MB DMA buffer.
The limiting factor is the frame array used to do the hypercall for making the memory contiguous, which has 512 entries and is just a static array in mmu_pv.c.
In order to not waste memory for non-PV guests, put the initial frame array into .init.data section and dynamically allocate an array from the .init_after_bootmem hook of PV guests.
In case a contiguous memory area larger than the initially supported 2MB is requested, allocate a larger buffer for the frame list. Note that such an allocation is tried only after memory management has been initialized properly, which is tested via a flag being set in the .init_after_bootmem hook.
--- arch/x86/xen/mmu_pv.c | 71 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 9 deletions(-)
arch/x86/xen/mmu_pv.c +62 -9
@@ -113,6 +113,51 @@ static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;*/ static DEFINE_SPINLOCK (xen_reservation_lock); +/* Protected by xen_reservation_lock. */ +#define MIN_CONTIG_ORDER 9/* 2MB */ +static unsigned int discontig_frames_order =MIN_CONTIG_ORDER ; +static unsigned long discontig_frames_early[1UL <<MIN_CONTIG_ORDER ]__initdata ; +static unsigned long *discontig_frames__refdata = discontig_frames_early; +static bool discontig_frames_dyn; + +static int alloc_discontig_frames (unsigned int order) +{ +unsigned long *new_array, *old_array; +unsigned int old_order; +unsigned long flags; + +BUG_ON (order <MIN_CONTIG_ORDER ); +BUILD_BUG_ON (sizeof (discontig_frames_early) !=PAGE_SIZE ); + + new_array = (unsigned long *)__get_free_pages (GFP_KERNEL , + order -MIN_CONTIG_ORDER ); +if (!new_array) +return -ENOMEM ; + +spin_lock_irqsave (&xen_reservation_lock, flags); + + old_order = discontig_frames_order; + +if (order > discontig_frames_order || !discontig_frames_dyn) { +if (!discontig_frames_dyn) + old_array =NULL ; +else + old_array = discontig_frames; + + discontig_frames = new_array; + discontig_frames_order = order; + discontig_frames_dyn = true; + }else { + old_array = new_array; + } + +spin_unlock_irqrestore (&xen_reservation_lock, flags); + +free_pages ((unsigned long )old_array, old_order -MIN_CONTIG_ORDER ); + +return 0 ; +} +/* * Note about cr3 (pagetable base) values: *
@@ -813,6 +858,9 @@ static void __init xen_after_bootmem(void)SetPagePinned (virt_to_page (level3_user_vsyscall));#endif xen_pgd_walk (&init_mm, xen_mark_pinned,FIXADDR_TOP ); + +if (alloc_discontig_frames (MIN_CONTIG_ORDER )) +BUG (); } static void xen_unpin_page(struct mm_struct *mm, struct page *page,
@@ -2199,10 +2247,6 @@ void __init xen_init_mmu_ops(void)memset (dummy_mapping,0xff ,PAGE_SIZE ); } -/* Protected by xen_reservation_lock. */ -#define MAX_CONTIG_ORDER 9/* 2MB */ -static unsigned long discontig_frames[1 <<MAX_CONTIG_ORDER ]; -#define VOID_PTE (mfn_pte(0, __pgprot(0))) static void xen_zap_pfn_range(unsigned long vaddr, unsigned int order, unsigned long *in_frames,
@@ -2319,18 +2363,25 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,unsigned int address_bits, dma_addr_t *dma_handle) { - unsigned long *in_frames = discontig_frames, out_frame; + unsigned long *in_frames, out_frame;unsigned long flags;int success;unsigned long vstart = (unsigned long )phys_to_virt (pstart); -if (unlikely (order >MAX_CONTIG_ORDER )) -return -ENOMEM ; +if (unlikely (order > discontig_frames_order)) { +if (!discontig_frames_dyn) +return -ENOMEM ; + +if (alloc_discontig_frames (order)) +return -ENOMEM ; + }memset ((void *) vstart,0 ,PAGE_SIZE << order);spin_lock_irqsave (&xen_reservation_lock, flags); + in_frames = discontig_frames; +/* 1. Zap current PTEs, remembering MFNs. */ xen_zap_pfn_range (vstart, order, in_frames,NULL );
@@ -2354,12 +2405,12 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,void xen_destroy_contiguous_region (phys_addr_t pstart,unsigned int order) { -unsigned long *out_frames = discontig_frames, in_frame; +unsigned long *out_frames, in_frame;unsigned long flags;int success;unsigned long vstart; -if (unlikely (order >MAX_CONTIG_ORDER )) +if (unlikely (order > discontig_frames_order))return ; vstart = (unsigned long )phys_to_virt (pstart);
@@ -2367,6 +2418,8 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)spin_lock_irqsave (&xen_reservation_lock, flags); + out_frames = discontig_frames; +/* 1. Find start MFN of contiguous extent. */ in_frame =virt_to_mfn ((void *)vstart);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 23/152 block: cleanup and fix batch completion adding conditions
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit 1f47ed294a2bd577d5ae43e6e28e1c9a3be4a833 ]
The conditions for whether or not a request is allowed adding to a completion batch are a bit hard to read, and they also have a few issues. One is that ioerror may indeed be a random value on passthrough, and it's being checked unconditionally of whether or not the given request is a passthrough request or not.
Rewrite the conditions to be separate for easier reading, and only check ioerror for non-passthrough requests. This fixes an issue with bio unmapping on passthrough, where it fails getting added to a batch. This both leads to suboptimal performance, and may trigger a potential schedule-under-atomic condition for polled passthrough IO.
--- include/linux/blk-mq.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
include/linux/blk-mq.h +14 -4
@@ -849,12 +849,22 @@ static inline bool blk_mq_add_to_batch(struct request *req, void (*complete)(struct io_comp_batch *)) {/* -* blk_mq_end_request_batch() can't end request allocated from -* sched tags +* Check various conditions that exclude batch processing: +* 1) No batch container +* 2) Has scheduler data attached +* 3) Not a passthrough request and end_io set +* 4) Not a passthrough request and an ioerror */ -if (!iob || (req->rq_flags &RQF_SCHED_TAGS ) || ioerror || - (req->end_io && !blk_rq_is_passthrough (req))) +if (!iob)return false; +if (req->rq_flags &RQF_SCHED_TAGS ) +return false; +if (!blk_rq_is_passthrough (req)) { +if (req->end_io) +return false; +if (ioerror <0 ) +return false; + }if (!iob->complete) iob->complete = complete;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 24/152 gpiolib: Fix crash on error in gpiochip_get_ngpios()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 7b4aebeecbbd5b5fe73e35fad3f62ed21aa7ef44 ]
The gpiochip_get_ngpios() uses chip_*() macros to print messages. However these macros rely on gpiodev to be initialised and set, which is not the case when called via bgpio_init(). In such a case the printing messages will crash on NULL pointer dereference. Replace chip_*() macros by the respective dev_*() ones to avoid such crash.
--- drivers/gpio/gpiolib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpio/gpiolib.c +3 -3
@@ -723,13 +723,13 @@ int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev) }if (gc->ngpio ==0 ) { -chip_err (gc,"tried to insert a GPIO chip with zero lines\n" ); +dev_err (dev,"tried to insert a GPIO chip with zero lines\n" );return -EINVAL ; }if (gc->ngpio >FASTPATH_NGPIO ) -chip_warn (gc,"line cnt %u is greater than fast path cnt %u\n" , - gc->ngpio,FASTPATH_NGPIO ); +dev_warn (dev,"line cnt %u is greater than fast path cnt %u\n" , + gc->ngpio,FASTPATH_NGPIO );return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 25/152 tools: fix annoying "mkdir -p ..." logs when building tools in parallel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit d1d0963121769d8d16150b913fe886e48efefa51 ]
When CONFIG_OBJTOOL=y or CONFIG_DEBUG_INFO_BTF=y, parallel builds show awkward "mkdir -p ..." logs.
$ make -j16
[ snip ]
mkdir -p /home/masahiro/ref/linux/tools/objtool && make O=/home/masahiro/ref/linux subdir=tools/objtool --no-print-directory -C objtool
mkdir -p /home/masahiro/ref/linux/tools/bpf/resolve_btfids && make O=/home/masahiro/ref/linux subdir=tools/bpf/resolve_btfids --no-print-directory -C bpf/resolve_btfidsDefining MAKEFLAGS=<value> on the command line wipes out command line switches from the resultant MAKEFLAGS definition, even though the command line switches are active. [1]
MAKEFLAGS puts all single-letter options into the first word, and that word will be empty if no single-letter options were given. [2] However, this breaks if MAKEFLAGS=<value> is given on the command line.
The tools/ and tools/% targets set MAKEFLAGS=<value> on the command line, which breaks the following code in tools/scripts/Makefile.include:
short-opts := $(firstword -$(MAKEFLAGS))
If MAKEFLAGS really needs modification, it should be done through the environment variable, as follows:
MAKEFLAGS=<value> $(MAKE) ...
That said, I question whether modifying MAKEFLAGS is necessary here. The only flag we might want to exclude is --no-print-directory, as the tools build system changes the working directory. However, people might find the "Entering/Leaving directory" logs annoying.
I simply removed the offending MAKEFLAGS=<value>.
[1]: https://savannah.gnu.org/bugs/?62469
[2]: https://www.gnu.org/software/make/manual/make.html#Testing-Flags
--- Makefile | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
Makefile +2 -7
@@ -1348,18 +1348,13 @@ ifneq ($(wildcard $(resolve_btfids_O)),) $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean endif -# Clear a bunch of variables before executing the submake -ifeq ($(quiet),silent_) -tools_silent=s -endif - tools/: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ + $(Q)$(MAKE) LDFLAGS= O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ tools/%: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* + $(Q)$(MAKE) LDFLAGS= O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* # --------------------------------------------------------------------------- # Kernel selftest
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 26/152 RDMA/efa: Reset device on probe failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Margolin <[email protected]>
[ Upstream commit 123c13f10ed3627ba112172d8bd122a72cae226d ]
Make sure the device is being reset on driver exit whatever the reason is, to keep the device aligned and allow it to close shared resources (e.g. admin queue).
--- drivers/infiniband/hw/efa/efa_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/infiniband/hw/efa/efa_main.c +5 -4
@@ -452,7 +452,6 @@ static void efa_ib_device_remove(struct efa_dev *dev)ibdev_info (&dev->ibdev,"Unregister ib device\n" );ib_unregister_device (&dev->ibdev);efa_destroy_eqs (dev); -efa_com_dev_reset (&dev->edev,EFA_REGS_RESET_NORMAL );efa_release_doorbell_bar (dev); }
@@ -623,12 +622,14 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev)return ERR_PTR (err); } -static void efa_remove_device (struct pci_dev *pdev) +static void efa_remove_device (struct pci_dev *pdev, +enum efa_regs_reset_reason_types reset_reason) {struct efa_dev *dev =pci_get_drvdata (pdev);struct efa_com_dev *edev; edev = &dev->edev; +efa_com_dev_reset (edev, reset_reason);efa_com_admin_destroy (edev);efa_free_irq (dev, &dev->admin_irq);efa_disable_msix (dev);
@@ -656,7 +657,7 @@ static int efa_probe(struct pci_dev *pdev, const struct pci_device_id *ent)return 0 ; err_remove_device: -efa_remove_device (pdev); +efa_remove_device (pdev,EFA_REGS_RESET_INIT_ERR );return err; }
@@ -665,7 +666,7 @@ static void efa_remove(struct pci_dev *pdev)struct efa_dev *dev =pci_get_drvdata (pdev);efa_ib_device_remove (dev); -efa_remove_device (pdev); +efa_remove_device (pdev,EFA_REGS_RESET_NORMAL ); }static struct pci_driver efa_pci_driver = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 27/152 fbdev: omap: use threaded IRQ for LCD DMA
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaro Koskinen <[email protected]>
[ Upstream commit e4b6b665df815b4841e71b72f06446884e8aad40 ]
When using touchscreen and framebuffer, Nokia 770 crashes easily with:
BUG: scheduling while atomic: irq/144-ads7846/82/0x00010000
Modules linked in: usb_f_ecm g_ether usb_f_rndis u_ether libcomposite configfs omap_udc ohci_omap ohci_hcd
CPU: 0 UID: 0 PID: 82 Comm: irq/144-ads7846 Not tainted 6.12.7-770 #2
Hardware name: Nokia 770
Call trace:
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x54/0x5c
dump_stack_lvl from __schedule_bug+0x50/0x70
__schedule_bug from __schedule+0x4d4/0x5bc
__schedule from schedule+0x34/0xa0
schedule from schedule_preempt_disabled+0xc/0x10
schedule_preempt_disabled from __mutex_lock.constprop.0+0x218/0x3b4
__mutex_lock.constprop.0 from clk_prepare_lock+0x38/0xe4
clk_prepare_lock from clk_set_rate+0x18/0x154
clk_set_rate from sossi_read_data+0x4c/0x168
sossi_read_data from hwa742_read_reg+0x5c/0x8c
hwa742_read_reg from send_frame_handler+0xfc/0x300
send_frame_handler from process_pending_requests+0x74/0xd0
process_pending_requests from lcd_dma_irq_handler+0x50/0x74
lcd_dma_irq_handler from __handle_irq_event_percpu+0x44/0x130
__handle_irq_event_percpu from handle_irq_event+0x28/0x68
handle_irq_event from handle_level_irq+0x9c/0x170
handle_level_irq from generic_handle_domain_irq+0x2c/0x3c
generic_handle_domain_irq from omap1_handle_irq+0x40/0x8c
omap1_handle_irq from generic_handle_arch_irq+0x28/0x3c
generic_handle_arch_irq from call_with_stack+0x1c/0x24
call_with_stack from __irq_svc+0x94/0xa8
Exception stack(0xc5255da0 to 0xc5255de8)
5da0: 00000001 c22fc620 00000000 00000000 c08384a8 c106fc00 00000000 c240c248
5dc0: c113a600 c3f6ec30 00000001 00000000 c22fc620 c5255df0 c22fc620 c0279a94
5de0: 60000013 ffffffff
__irq_svc from clk_prepare_lock+0x4c/0xe4
clk_prepare_lock from clk_get_rate+0x10/0x74
clk_get_rate from uwire_setup_transfer+0x40/0x180
uwire_setup_transfer from spi_bitbang_transfer_one+0x2c/0x9c
spi_bitbang_transfer_one from spi_transfer_one_message+0x2d0/0x664
spi_transfer_one_message from __spi_pump_transfer_message+0x29c/0x498
__spi_pump_transfer_message from __spi_sync+0x1f8/0x2e8
__spi_sync from spi_sync+0x24/0x40
spi_sync from ads7846_halfd_read_state+0x5c/0x1c0
ads7846_halfd_read_state from ads7846_irq+0x58/0x348
ads7846_irq from irq_thread_fn+0x1c/0x78
irq_thread_fn from irq_thread+0x120/0x228
irq_thread from kthread+0xc8/0xe8
kthread from ret_from_fork+0x14/0x28As a quick fix, switch to a threaded IRQ which provides a stable system.
--- drivers/video/fbdev/omap/lcd_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/fbdev/omap/lcd_dma.c +2 -2
@@ -432,8 +432,8 @@ static int __init omap_init_lcd_dma(void)spin_lock_init (&lcd_dma.lock); - r =request_irq (INT_DMA_LCD , lcd_dma_irq_handler,0 , -"LCD DMA" ,NULL ); + r =request_threaded_irq (INT_DMA_LCD ,NULL , lcd_dma_irq_handler, +IRQF_ONESHOT ,"LCD DMA" ,NULL );if (r !=0 )pr_err ("unable to request IRQ for LCD DMA (error %d)\n" , r);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 28/152 soc/tegra: fuse: Update Tegra234 nvmem keepout list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kartik Rajput <[email protected]>
[ Upstream commit 836b341cc8dab680acc06a7883bfeea89680b689 ]
Various Nvidia userspace applications and tests access following fuse via Fuse nvmem interface:
* odmid
* odminfo
* boot_security_info
* public_key_hash
* reserved_odm0
* reserved_odm1
* reserved_odm2
* reserved_odm3
* reserved_odm4
* reserved_odm5
* reserved_odm6
* reserved_odm7
* odm_lock
* pk_h1
* pk_h2
* revoke_pk_h0
* revoke_pk_h1
* security_mode
* system_fw_field_ratchet0
* system_fw_field_ratchet1
* system_fw_field_ratchet2
* system_fw_field_ratchet3
* optin_enable
Update tegra234_fuse_keepouts list to allow reading these fuse from nvmem sysfs interface.
--- drivers/soc/tegra/fuse/fuse-tegra30.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/soc/tegra/fuse/fuse-tegra30.c +11 -6
@@ -646,15 +646,20 @@ static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = { };static const struct nvmem_keepout tegra234_fuse_keepouts[] = { - { .start =0x01c , .end =0x0c8 }, - { .start =0x12c , .end =0x184 }, + { .start =0x01c , .end =0x064 }, + { .start =0x084 , .end =0x0a0 }, + { .start =0x0a4 , .end =0x0c8 }, + { .start =0x12c , .end =0x164 }, + { .start =0x16c , .end =0x184 }, { .start =0x190 , .end =0x198 }, { .start =0x1a0 , .end =0x204 }, - { .start =0x21c , .end =0x250 }, - { .start =0x25c , .end =0x2f0 }, + { .start =0x21c , .end =0x2f0 }, { .start =0x310 , .end =0x3d8 }, - { .start =0x400 , .end =0x4f0 }, - { .start =0x4f8 , .end =0x7e8 }, + { .start =0x400 , .end =0x420 }, + { .start =0x444 , .end =0x490 }, + { .start =0x4bc , .end =0x4f0 }, + { .start =0x4f8 , .end =0x54c }, + { .start =0x57c , .end =0x7e8 }, { .start =0x8d0 , .end =0x8d8 }, { .start =0xacc , .end =0xf00 } };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 29/152 media: cxd2841er: fix 64-bit division on gcc-9
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit 8d46603eeeb4c6abff1d2e49f2a6ae289dac765e ]
It appears that do_div() once more gets confused by a complex expression that ends up not quite being constant despite __builtin_constant_p() thinking it is:
ERROR: modpost: "__aeabi_uldivmod" [drivers/media/dvb-frontends/cxd2841er.ko] undefined!
Use div_u64() instead, forcing the expression to be evaluated first, and making it a bit more readable.
--- drivers/media/dvb-frontends/cxd2841er.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +2 -6
@@ -311,12 +311,8 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,static u32 cxd2841er_calc_iffreq_xtal (enum cxd2841er_xtal xtal,u32 ifhz) { -u64 tmp; - - tmp = (u64 ) ifhz *16777216 ; -do_div (tmp, ((xtal ==SONY_XTAL_24000 ) ?48000000 :41000000 )); - -return (u32 ) tmp; +return div_u64 (ifhz *16777216ull , + (xtal ==SONY_XTAL_24000 ) ?48000000 :41000000 ); }static u32 cxd2841er_calc_iffreq (u32 ifhz)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 30/152 media: i2c: ds90ub913: Add error handling to ub913_hw_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit acd8f58d7a3bce0fbd3263961cd09555c00464ba ]
Add error handling to ub913_hw_init() using a new helper function, ub913_update_bits().
--- drivers/media/i2c/ds90ub913.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
drivers/media/i2c/ds90ub913.c +21 -4
@@ -8,6 +8,7 @@* Copyright (c) 2023 Tomi Valkeinen <[email protected]> */ +#include <linux/bitfield.h> #include <linux/clk-provider.h> #include <linux/clk.h> #include <linux/delay.h>
@@ -146,6 +147,19 @@ static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val)return ret; } +static int ub913_update_bits (const struct ub913_data *priv,u8 reg,u8 mask, +u8 val) +{ +int ret; + + ret =regmap_update_bits (priv->regmap, reg, mask, val); +if (ret <0 ) +dev_err (&priv->client->dev, +"Cannot update register 0x%02x %d!\n" , reg, ret); + +return ret; +} +/* * GPIO chip */
@@ -733,10 +747,13 @@ static int ub913_hw_init(struct ub913_data *priv)if (ret)return dev_err_probe (dev, ret,"i2c master init failed\n" ); -ub913_read (priv,UB913_REG_GENERAL_CFG , &v); - v &= ~UB913_REG_GENERAL_CFG_PCLK_RISING ; - v |= priv->pclk_polarity_rising ?UB913_REG_GENERAL_CFG_PCLK_RISING :0 ; -ub913_write (priv,UB913_REG_GENERAL_CFG , v); + ret =ub913_update_bits (priv,UB913_REG_GENERAL_CFG , +UB913_REG_GENERAL_CFG_PCLK_RISING , +FIELD_PREP (UB913_REG_GENERAL_CFG_PCLK_RISING , + priv->pclk_polarity_rising)); + +if (ret) +return ret;return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 31/152 media: i2c: ds90ub953: Add error handling for i2c reads/writes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 0794c43ea1e451007e80246e1288ebbf44139397 ]
Add error handling for i2c reads/writes in various places.
--- drivers/media/i2c/ds90ub953.c | 46 ++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-)
drivers/media/i2c/ds90ub953.c +32 -14
@@ -398,8 +398,13 @@ static int ub953_gpiochip_probe(struct ub953_data *priv)int ret;/* Set all GPIOs to local input mode */ -ub953_write (priv,UB953_REG_LOCAL_GPIO_DATA ,0 ); -ub953_write (priv,UB953_REG_GPIO_INPUT_CTRL ,0xf ); + ret =ub953_write (priv,UB953_REG_LOCAL_GPIO_DATA ,0 ); +if (ret) +return ret; + + ret =ub953_write (priv,UB953_REG_GPIO_INPUT_CTRL ,0xf ); +if (ret) +return ret; gc->label =dev_name (dev); gc->parent = dev;
@@ -961,10 +966,11 @@ static void ub953_calc_clkout_params(struct ub953_data *priv, clkout_data->rate = clkout_rate; } -static void ub953_write_clkout_regs (struct ub953_data *priv, -const struct ub953_clkout_data *clkout_data) +static int ub953_write_clkout_regs (struct ub953_data *priv, +const struct ub953_clkout_data *clkout_data) {u8 clkout_ctrl0, clkout_ctrl1; +int ret;if (priv->hw_data->is_ub971) clkout_ctrl0 = clkout_data->m;
@@ -974,8 +980,15 @@ static void ub953_write_clkout_regs(struct ub953_data *priv, clkout_ctrl1 = clkout_data->n; -ub953_write (priv,UB953_REG_CLKOUT_CTRL0 , clkout_ctrl0); -ub953_write (priv,UB953_REG_CLKOUT_CTRL1 , clkout_ctrl1); + ret =ub953_write (priv,UB953_REG_CLKOUT_CTRL0 , clkout_ctrl0); +if (ret) +return ret; + + ret =ub953_write (priv,UB953_REG_CLKOUT_CTRL1 , clkout_ctrl1); +if (ret) +return ret; + +return 0 ; } static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw,
@@ -1055,9 +1068,7 @@ static int ub953_clkout_set_rate(struct clk_hw *hw, unsigned long rate,dev_dbg (&priv->client->dev,"%s %lu (requested %lu)\n" , __func__, clkout_data.rate, rate); -ub953_write_clkout_regs (priv, &clkout_data); - -return 0 ; +return ub953_write_clkout_regs (priv, &clkout_data); }static const struct clk_ops ub953_clkout_ops = {
@@ -1082,7 +1093,9 @@ static int ub953_register_clkout(struct ub953_data *priv)/* Initialize clkout to 25MHz by default */ ub953_calc_clkout_params (priv,UB953_DEFAULT_CLKOUT_RATE , &clkout_data); -ub953_write_clkout_regs (priv, &clkout_data); + ret =ub953_write_clkout_regs (priv, &clkout_data); +if (ret) +return ret; priv->clkout_clk_hw.init = &init;
@@ -1229,10 +1242,15 @@ static int ub953_hw_init(struct ub953_data *priv)if (ret)return dev_err_probe (dev, ret,"i2c init failed\n" ); -ub953_write (priv,UB953_REG_GENERAL_CFG , - (priv->non_continous_clk ?0 :UB953_REG_GENERAL_CFG_CONT_CLK ) | - ((priv->num_data_lanes -1 ) <<UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT ) | -UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE ); + v =0 ; + v |= priv->non_continous_clk ?0 :UB953_REG_GENERAL_CFG_CONT_CLK ; + v |= (priv->num_data_lanes -1 ) << +UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT ; + v |=UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE ; + + ret =ub953_write (priv,UB953_REG_GENERAL_CFG , v); +if (ret) +return ret;return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 32/152 media: uvcvideo: Implement dual stream quirk to fix loss of usb packets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Isaac Scott <[email protected]>
[ Upstream commit c2eda35e675b6ea4a0a21a4b1167b121571a9036 ]
Some cameras, such as the Sonix Technology Co. 292A, exhibit issues when running two parallel streams, causing USB packets to be dropped when an H.264 stream posts a keyframe while an MJPEG stream is running simultaneously. This occasionally causes the driver to erroneously output two consecutive JPEG images as a single frame.
To fix this, we inspect the buffer, and trigger a new frame when we find an SOI.
--- drivers/media/usb/uvc/uvc_video.c | 27 ++++++++++++++++++++++++++- drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_video.c +26 -1
@@ -20,6 +20,7 @@#include <linux/atomic.h> #include <asm/unaligned.h> +#include <media/jpeg.h> #include <media/v4l2-common.h> #include "uvcvideo.h"
@@ -1114,6 +1115,7 @@ static void uvc_video_stats_stop(struct uvc_streaming *stream)static int uvc_video_decode_start (struct uvc_streaming *stream,struct uvc_buffer *buf,const u8 *data,int len) { +u8 header_len;u8 fid;/*
@@ -1127,6 +1129,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,return -EINVAL ; } + header_len = data[0 ]; fid = data[1 ] &UVC_STREAM_FID ;/*
@@ -1208,9 +1211,31 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,return -EAGAIN ; } +/* +* Some cameras, when running two parallel streams (one MJPEG alongside +* another non-MJPEG stream), are known to lose the EOF packet for a frame. +* We can detect the end of a frame by checking for a new SOI marker, as +* the SOI always lies on the packet boundary between two frames for +* these devices. +*/ +if (stream->dev->quirks &UVC_QUIRK_MJPEG_NO_EOF && + (stream->cur_format->fcc ==V4L2_PIX_FMT_MJPEG || + stream->cur_format->fcc ==V4L2_PIX_FMT_JPEG )) { +const u8 *packet = data + header_len; + +if (len >= header_len +2 && + packet[0 ] ==0xff && packet[1 ] ==JPEG_MARKER_SOI && + buf->bytesused !=0 ) { + buf->state =UVC_BUF_STATE_READY ; + buf->error =1 ; + stream->last_fid ^=UVC_STREAM_FID ; +return -EAGAIN ; + } + } + stream->last_fid = fid; -return data[0 ]; +return header_len; } static inline enum dma_data_direction uvc_stream_dir(
drivers/media/usb/uvc/uvcvideo.h +1 -0
@@ -76,6 +76,7 @@#define UVC_QUIRK_NO_RESET_RESUME 0x00004000#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000 +#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000/* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 33/152 media: uvcvideo: Add new quirk definition for the Sonix Technology Co. 292a camera
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Isaac Scott <[email protected]>
[ Upstream commit 81f8c0e138c43610cf09b8d2a533068aa58e538e ]
The Sonix Technology Co. 292A camera (which uses an AR0330 sensor), can produce MJPEG and H.264 streams concurrently. When doing so, it drops the last packets of MJPEG frames every time the H.264 stream generates a key frame. Set the UVC_QUIRK_MJPEG_NO_EOF quirk to work around the issue.
--- drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/usb/uvc/uvc_driver.c +9 -0
@@ -2886,6 +2886,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, +/* Sonix Technology Co. Ltd. - 292A IPC AR0330 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0c45, + .idProduct = 0x6366, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, /* MT6227 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 34/152 media: uvcvideo: Add Kurokesu C1 PRO camera
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Isaac Scott <[email protected]>
[ Upstream commit 2762eab6d4140781840f253f9a04b8627017248b ]
Add support for the Kurokesu C1 PRO camera. This camera experiences the same issues faced by the Sonix Technology Co. 292A IPC AR0330. As such, enable the UVC_QUIRK_MJPEG_NO_EOF quirk for this device to prevent frames from being erroneously dropped.
--- drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/usb/uvc/uvc_driver.c +9 -0
@@ -2923,6 +2923,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, +/* Kurokesu C1 PRO */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x16d0, + .idProduct = 0x0ed1, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, /* Syntek (HP Spartan) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 35/152 media: vidtv: Fix a null-ptr-deref in vidtv_mux_stop_thread
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit 1221989555db711578a327a9367f1be46500cb48 ]
syzbot report a null-ptr-deref in vidtv_mux_stop_thread. [1]
If dvb->mux is not initialized successfully by vidtv_mux_init() in the vidtv_start_streaming(), it will trigger null pointer dereference about mux in vidtv_mux_stop_thread().
Adjust the timing of streaming initialization and check it before stopping it.
[1]
KASAN: null-ptr-deref in range [0x0000000000000128-0x000000000000012f] CPU: 0 UID: 0 PID: 5842 Comm: syz-executor248 Not tainted 6.13.0-rc4-syzkaller-00012-g9b2ffa6148b1 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 RIP: 0010:vidtv_mux_stop_thread+0x26/0x80 drivers/media/test-drivers/vidtv/vidtv_mux.c:471 Code: 90 90 90 90 66 0f 1f 00 55 53 48 89 fb e8 82 2e c8 f9 48 8d bb 28 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 02 7e 3b 0f b6 ab 28 01 00 00 31 ff 89 ee e8 RSP: 0018:ffffc90003f2faa8 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff87cfb125 RDX: 0000000000000025 RSI: ffffffff87d120ce RDI: 0000000000000128 RBP: ffff888029b8d220 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000003 R12: ffff888029b8d188 R13: ffffffff8f590aa0 R14: ffffc9000581c5c8 R15: ffff888029a17710 FS: 00007f7eef5156c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7eef5e635c CR3: 0000000076ca6000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> vidtv_stop_streaming drivers/media/test-drivers/vidtv/vidtv_bridge.c:209 [inline] vidtv_stop_feed+0x151/0x250 drivers/media/test-drivers/vidtv/vidtv_bridge.c:252 dmx_section_feed_stop_filtering+0x90/0x160 drivers/media/dvb-core/dvb_demux.c:1000 dvb_dmxdev_feed_stop.isra.0+0x1ee/0x270 drivers/media/dvb-core/dmxdev.c:486 dvb_dmxdev_filter_stop+0x22a/0x3a0 drivers/media/dvb-core/dmxdev.c:559 dvb_dmxdev_filter_free drivers/media/dvb-core/dmxdev.c:840 [inline] dvb_demux_release+0x92/0x550 drivers/media/dvb-core/dmxdev.c:1246 __fput+0x3f8/0xb60 fs/file_table.c:450 task_work_run+0x14e/0x250 kernel/task_work.c:239 get_signal+0x1d3/0x2610 kernel/signal.c:2790 arch_do_signal_or_restart+0x90/0x7e0 arch/x86/kernel/signal.c:337 exit_to_user_mode_loop kernel/entry/common.c:111 [inline] exit_to_user_mode_prepare include/linux/entry-common.h:329 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline] syscall_exit_to_user_mode+0x150/0x2a0 kernel/entry/common.c:218 do_syscall_64+0xda/0x250 arch/x86/entry/common.c:89 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/media/test-drivers/vidtv/vidtv_bridge.c +7 -1
@@ -191,10 +191,11 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) mux_args.mux_buf_sz = mux_buf_sz; - dvb->streaming = true; dvb->mux =vidtv_mux_init (dvb->fe[0 ], dev, &mux_args);if (!dvb->mux)return -ENOMEM ; + + dvb->streaming = true;vidtv_mux_start_thread (dvb->mux);dev_dbg_ratelimited (dev,"Started streaming\n" );
@@ -205,6 +206,11 @@ static int vidtv_stop_streaming(struct vidtv_dvb *dvb) {struct device *dev = &dvb->pdev->dev; +if (!dvb->streaming) { +dev_warn_ratelimited (dev,"No streaming. Skipping.\n" ); +return 0 ; + } + dvb->streaming = false;vidtv_mux_stop_thread (dvb->mux);vidtv_mux_destroy (dvb->mux);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 36/152 PCI/DPC: Quirk PIO log size for Intel Raptor Lake-P
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit b198499c7d2508a76243b98e7cca992f6fd2b7f7 ]
Apparently the Raptor Lake-P reference firmware configures the PIO log size correctly, but some vendor BIOSes, including at least ASUSTeK COMPUTER INC. Zenbook UX3402VA_UX3402VA, do not.
Apply the quirk for Raptor Lake-P. This prevents kernel complaints like:
DPC: RP PIO log size 0 is invalid
and also enables the DPC driver to dump the RP PIO Log registers when DPC is triggered.
Note that the bug report also mentions 8086:a76e, which has been already added by 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports").
--- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/quirks.c +1 -0
@@ -6247,6 +6247,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x9a2d , dpc_log_size);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x9a2f , dpc_log_size);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x9a31 , dpc_log_size); +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0xa72f , dpc_log_size);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0xa73f , dpc_log_size);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0xa76e , dpc_log_size);#endif
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 37/152 PCI: switchtec: Add Microchip PCI100X device IDs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rakesh Babu Saladi <[email protected]>
[ Upstream commit a3282f84b2151d254dc4abf24d1255c6382be774 ]
Add Microchip parts to the Device ID table so the driver supports PCI100x devices.
Add a new macro to quirk the Microchip Switchtec PCI100x parts to allow DMA access via NTB to work when the IOMMU is turned on.
PCI100x family has 6 variants; each variant is designed for different application usages, different port counts and lane counts:
PCI1001 has 1 x4 upstream port and 3 x4 downstream ports PCI1002 has 1 x4 upstream port and 4 x2 downstream ports PCI1003 has 2 x4 upstream ports, 2 x2 upstream ports, and 2 x2
downstream ports
PCI1004 has 4 x4 upstream ports
PCI1005 has 1 x4 upstream port and 6 x2 downstream ports PCI1006 has 6 x2 upstream ports and 2 x2 downstream ports
[Historical note: these parts use PCI_VENDOR_ID_EFAR (0x1055), from EFAR Microsystems, which was acquired in 1996 by Standard Microsystems Corp, which was acquired by Microchip Technology in 2012. The PCI-SIG confirms that Vendor ID 0x1055 is assigned to Microchip even though it's not visible via https://pcisig.com/membership/member-companies]
--- drivers/pci/quirks.c | 11 +++++++++++ drivers/pci/switch/switchtec.c | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+)
drivers/pci/quirks.c +11 -0
@@ -5978,6 +5978,17 @@ SWITCHTEC_QUIRK(0x5552); /* PAXA 52XG5 */SWITCHTEC_QUIRK (0x5536 );/* PAXA 36XG5 */ SWITCHTEC_QUIRK (0x5528 );/* PAXA 28XG5 */ +#define SWITCHTEC_PCI100X_QUIRK (vid) \ + DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_EFAR, vid, \ + PCI_CLASS_BRIDGE_OTHER, 8, quirk_switchtec_ntb_dma_alias) +SWITCHTEC_PCI100X_QUIRK (0x1001 );/* PCI1001XG4 */ +SWITCHTEC_PCI100X_QUIRK (0x1002 );/* PCI1002XG4 */ +SWITCHTEC_PCI100X_QUIRK (0x1003 );/* PCI1003XG4 */ +SWITCHTEC_PCI100X_QUIRK (0x1004 );/* PCI1004XG4 */ +SWITCHTEC_PCI100X_QUIRK (0x1005 );/* PCI1005XG4 */ +SWITCHTEC_PCI100X_QUIRK (0x1006 );/* PCI1006XG4 */ + +/* * The PLX NTB uses devfn proxy IDs to move TLPs between NT endpoints. * These IDs are used to forward responses to the originator on the other
drivers/pci/switch/switchtec.c +26 -0
@@ -1737,6 +1737,26 @@ static void switchtec_pci_remove(struct pci_dev *pdev) .driver_data = gen, \ } +#define SWITCHTEC_PCI100X_DEVICE (device_id, gen) \ + { \ + .vendor = PCI_VENDOR_ID_EFAR, \ + .device = device_id, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + .class = (PCI_CLASS_MEMORY_OTHER << 8), \ + .class_mask = 0xFFFFFFFF, \ + .driver_data = gen, \ + }, \ + { \ + .vendor = PCI_VENDOR_ID_EFAR, \ + .device = device_id, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + .class = (PCI_CLASS_BRIDGE_OTHER << 8), \ + .class_mask = 0xFFFFFFFF, \ + .driver_data = gen, \ + } +static const struct pci_device_id switchtec_pci_tbl[] = {SWITCHTEC_PCI_DEVICE (0x8531 ,SWITCHTEC_GEN3 ),/* PFX 24xG3 */ SWITCHTEC_PCI_DEVICE (0x8532 ,SWITCHTEC_GEN3 ),/* PFX 32xG3 */
@@ -1831,6 +1851,12 @@ static const struct pci_device_id switchtec_pci_tbl[] = {SWITCHTEC_PCI_DEVICE (0x5552 ,SWITCHTEC_GEN5 ),/* PAXA 52XG5 */ SWITCHTEC_PCI_DEVICE (0x5536 ,SWITCHTEC_GEN5 ),/* PAXA 36XG5 */ SWITCHTEC_PCI_DEVICE (0x5528 ,SWITCHTEC_GEN5 ),/* PAXA 28XG5 */ +SWITCHTEC_PCI100X_DEVICE (0x1001 ,SWITCHTEC_GEN4 ),/* PCI1001 16XG4 */ +SWITCHTEC_PCI100X_DEVICE (0x1002 ,SWITCHTEC_GEN4 ),/* PCI1002 12XG4 */ +SWITCHTEC_PCI100X_DEVICE (0x1003 ,SWITCHTEC_GEN4 ),/* PCI1003 16XG4 */ +SWITCHTEC_PCI100X_DEVICE (0x1004 ,SWITCHTEC_GEN4 ),/* PCI1004 16XG4 */ +SWITCHTEC_PCI100X_DEVICE (0x1005 ,SWITCHTEC_GEN4 ),/* PCI1005 16XG4 */ +SWITCHTEC_PCI100X_DEVICE (0x1006 ,SWITCHTEC_GEN4 ),/* PCI1006 16XG4 */ {0} };MODULE_DEVICE_TABLE (pci, switchtec_pci_tbl);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 38/152 scsi: ufs: bsg: Set bsg_queue to NULL after removal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixin Liu <[email protected]>
[ Upstream commit 1e95c798d8a7f70965f0f88d4657b682ff0ec75f ]
Currently, this does not cause any issues, but I believe it is necessary to set bsg_queue to NULL after removing it to prevent potential use-after-free (UAF) access.
--- drivers/ufs/core/ufs_bsg.c | 1 + 1 file changed, 1 insertion(+)
drivers/ufs/core/ufs_bsg.c +1 -0
@@ -216,6 +216,7 @@ void ufs_bsg_remove(struct ufs_hba *hba)return ;bsg_remove_queue (hba->bsg_queue); + hba->bsg_queue =NULL ;device_del (bsg_dev);put_device (bsg_dev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 39/152 rtla/timerlat_hist: Abort event processing on second signal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Glozar <[email protected]>
[ Upstream commit d6899e560366e10141189697502bc5521940c588 ]
If either SIGINT is received twice, or after a SIGALRM (that is, after timerlat was supposed to stop), abort processing events currently left in the tracefs buffer and exit immediately.
This allows the user to exit rtla without waiting for processing all events, should that take longer than wanted, at the cost of not processing all samples.
--- tools/tracing/rtla/src/timerlat_hist.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/tracing/rtla/src/timerlat_hist.c +8 -0
@@ -952,6 +952,14 @@ static int stop_tracing;static struct trace_instance *hist_inst =NULL ;static void stop_hist (int sig) { +if (stop_tracing) { +/* +* Stop requested twice in a row; abort event processing and +* exit immediately +*/ +tracefs_iterate_stop (hist_inst->inst); +return ; + } stop_tracing =1 ;if (hist_inst)trace_instance_stop (hist_inst);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 40/152 rtla/timerlat_top: Abort event processing on second signal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Glozar <[email protected]>
[ Upstream commit 80967b354a76b360943af384c10d807d98bea5c4 ]
If either SIGINT is received twice, or after a SIGALRM (that is, after timerlat was supposed to stop), abort processing events currently left in the tracefs buffer and exit immediately.
This allows the user to exit rtla without waiting for processing all events, should that take longer than wanted, at the cost of not processing all samples.
--- tools/tracing/rtla/src/timerlat_top.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/tracing/rtla/src/timerlat_top.c +8 -0
@@ -731,6 +731,14 @@ static int stop_tracing;static struct trace_instance *top_inst =NULL ;static void stop_top (int sig) { +if (stop_tracing) { +/* +* Stop requested twice in a row; abort event processing and +* exit immediately +*/ +tracefs_iterate_stop (top_inst->inst); +return ; + } stop_tracing =1 ;if (top_inst)trace_instance_stop (top_inst);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 41/152 vfio/pci: Enable iowrite64 and ioread64 for vfio pci
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ramesh Thomas <[email protected]>
[ Upstream commit 2b938e3db335e3670475e31a722c2bee34748c5a ]
Definitions of ioread64 and iowrite64 macros in asm/io.h called by vfio pci implementations are enclosed inside check for CONFIG_GENERIC_IOMAP. They don't get defined if CONFIG_GENERIC_IOMAP is defined. Include linux/io-64-nonatomic-lo-hi.h to define iowrite64 and ioread64 macros when they are not defined. io-64-nonatomic-lo-hi.h maps the macros to generic implementation in lib/iomap.c. The generic implementation does 64 bit rw if readq/writeq is defined for the architecture, otherwise it would do 32 bit back to back rw.
Note that there are two versions of the generic implementation that differs in the order the 32 bit words are written if 64 bit support is not present. This is not the little/big endian ordering, which is handled separately. This patch uses the lo followed by hi word ordering which is consistent with current back to back implementation in the vfio/pci code.
--- drivers/vfio/pci/vfio_pci_rdwr.c | 1 + 1 file changed, 1 insertion(+)
drivers/vfio/pci/vfio_pci_rdwr.c +1 -0
@@ -16,6 +16,7 @@#include <linux/io.h> #include <linux/vfio.h> #include <linux/vgaarb.h> +#include <linux/io-64-nonatomic-lo-hi.h> #include "vfio_pci_priv.h"
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 42/152 NFS: Fix potential buffer overflowin nfs_sysfs_link_rpc_client()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zichen Xie <[email protected]>
[ Upstream commit 49fd4e34751e90e6df009b70cd0659dc839e7ca8 ]
name is char[64] where the size of clnt->cl_program->name remains unknown. Invoking strcat() directly will also lead to potential buffer overflow. Change them to strscpy() and strncat() to fix potential issues.
--- fs/nfs/sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/nfs/sysfs.c +3 -3
@@ -280,9 +280,9 @@ void nfs_sysfs_link_rpc_client(struct nfs_server *server,char name[RPC_CLIENT_NAME_SIZE ];int ret; -strcpy (name, clnt->cl_program->name); -strcat (name, uniq ? uniq :"" ); -strcat (name,"_client" ); +strscpy (name, clnt->cl_program->name,sizeof (name)); +strncat (name, uniq ? uniq :"" ,sizeof (name) -strlen (name) -1 ); +strncat (name,"_client" ,sizeof (name) -strlen (name) -1 ); ret =sysfs_create_link_nowarn (&server->kobj, &clnt->cl_sysfs->kobject, name);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 43/152 Grab mm lock before grabbing pt lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maksym Planeta <[email protected]>
[ Upstream commit 6d002348789bc16e9203e9818b7a3688787e3b29 ]
Function xen_pin_page calls xen_pte_lock, which in turn grab page table lock (ptlock). When locking, xen_pte_lock expect mm->page_table_lock to be held before grabbing ptlock, but this does not happen when pinning is caused by xen_mm_pin_all.
This commit addresses lockdep warning below, which shows up when suspending a Xen VM.
[ 3680.658422] Freezing user space processes
[ 3680.660156] Freezing user space processes completed (elapsed 0.001 seconds)
[ 3680.660182] OOM killer disabled.
[ 3680.660192] Freezing remaining freezable tasks
[ 3680.661485] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[ 3680.685254]
[ 3680.685265] ==================================
[ 3680.685269] WARNING: Nested lock was not taken
[ 3680.685274] 6.12.0+ #16 Tainted: G W
[ 3680.685279] ----------------------------------
[ 3680.685283] migration/0/19 is trying to lock:
[ 3680.685288] ffff88800bac33c0 (ptlock_ptr(ptdesc)#2){+.+.}-{3:3}, at: xen_pin_page+0x175/0x1d0
[ 3680.685303]
[ 3680.685303] but this task is not holding:
[ 3680.685308] init_mm.page_table_lock
[ 3680.685311]
[ 3680.685311] stack backtrace:
[ 3680.685316] CPU: 0 UID: 0 PID: 19 Comm: migration/0 Tainted: G W 6.12.0+ #16
[ 3680.685324] Tainted: [W]=WARN
[ 3680.685328] Stopper: multi_cpu_stop+0x0/0x120 <- __stop_cpus.constprop.0+0x8c/0xd0
[ 3680.685339] Call Trace:
[ 3680.685344] <TASK>
[ 3680.685347] dump_stack_lvl+0x77/0xb0
[ 3680.685356] __lock_acquire+0x917/0x2310
[ 3680.685364] lock_acquire+0xce/0x2c0
[ 3680.685369] ? xen_pin_page+0x175/0x1d0
[ 3680.685373] _raw_spin_lock_nest_lock+0x2f/0x70
[ 3680.685381] ? xen_pin_page+0x175/0x1d0
[ 3680.685386] xen_pin_page+0x175/0x1d0
[ 3680.685390] ? __pfx_xen_pin_page+0x10/0x10
[ 3680.685394] __xen_pgd_walk+0x233/0x2c0
[ 3680.685401] ? stop_one_cpu+0x91/0x100
[ 3680.685405] __xen_pgd_pin+0x5d/0x250
[ 3680.685410] xen_mm_pin_all+0x70/0xa0
[ 3680.685415] xen_pv_pre_suspend+0xf/0x280
[ 3680.685420] xen_suspend+0x57/0x1a0
[ 3680.685428] multi_cpu_stop+0x6b/0x120
[ 3680.685432] ? update_cpumasks_hier+0x7c/0xa60
[ 3680.685439] ? __pfx_multi_cpu_stop+0x10/0x10
[ 3680.685443] cpu_stopper_thread+0x8c/0x140
[ 3680.685448] ? smpboot_thread_fn+0x20/0x1f0
[ 3680.685454] ? __pfx_smpboot_thread_fn+0x10/0x10
[ 3680.685458] smpboot_thread_fn+0xed/0x1f0
[ 3680.685462] kthread+0xde/0x110
[ 3680.685467] ? __pfx_kthread+0x10/0x10
[ 3680.685471] ret_from_fork+0x2f/0x50
[ 3680.685478] ? __pfx_kthread+0x10/0x10
[ 3680.685482] ret_from_fork_asm+0x1a/0x30
[ 3680.685489] </TASK>
[ 3680.685491]
[ 3680.685491] other info that might help us debug this:
[ 3680.685497] 1 lock held by migration/0/19:
[ 3680.685500] #0: ffffffff8284df38 (pgd_lock){+.+.}-{3:3}, at: xen_mm_pin_all+0x14/0xa0
[ 3680.685512]
[ 3680.685512] stack backtrace:
[ 3680.685518] CPU: 0 UID: 0 PID: 19 Comm: migration/0 Tainted: G W 6.12.0+ #16
[ 3680.685528] Tainted: [W]=WARN
[ 3680.685531] Stopper: multi_cpu_stop+0x0/0x120 <- __stop_cpus.constprop.0+0x8c/0xd0
[ 3680.685538] Call Trace:
[ 3680.685541] <TASK>
[ 3680.685544] dump_stack_lvl+0x77/0xb0
[ 3680.685549] __lock_acquire+0x93c/0x2310
[ 3680.685554] lock_acquire+0xce/0x2c0
[ 3680.685558] ? xen_pin_page+0x175/0x1d0
[ 3680.685562] _raw_spin_lock_nest_lock+0x2f/0x70
[ 3680.685568] ? xen_pin_page+0x175/0x1d0
[ 3680.685572] xen_pin_page+0x175/0x1d0
[ 3680.685578] ? __pfx_xen_pin_page+0x10/0x10
[ 3680.685582] __xen_pgd_walk+0x233/0x2c0
[ 3680.685588] ? stop_one_cpu+0x91/0x100
[ 3680.685592] __xen_pgd_pin+0x5d/0x250
[ 3680.685596] xen_mm_pin_all+0x70/0xa0
[ 3680.685600] xen_pv_pre_suspend+0xf/0x280
[ 3680.685607] xen_suspend+0x57/0x1a0
[ 3680.685611] multi_cpu_stop+0x6b/0x120
[ 3680.685615] ? update_cpumasks_hier+0x7c/0xa60
[ 3680.685620] ? __pfx_multi_cpu_stop+0x10/0x10
[ 3680.685625] cpu_stopper_thread+0x8c/0x140
[ 3680.685629] ? smpboot_thread_fn+0x20/0x1f0
[ 3680.685634] ? __pfx_smpboot_thread_fn+0x10/0x10
[ 3680.685638] smpboot_thread_fn+0xed/0x1f0
[ 3680.685642] kthread+0xde/0x110
[ 3680.685645] ? __pfx_kthread+0x10/0x10
[ 3680.685649] ret_from_fork+0x2f/0x50
[ 3680.685654] ? __pfx_kthread+0x10/0x10
[ 3680.685657] ret_from_fork_asm+0x1a/0x30
[ 3680.685662] </TASK>
[ 3680.685267] xen:grant_table: Grant tables using version 1 layout
[ 3680.685921] OOM killer enabled.
[ 3680.685934] Restarting tasks ... done.Message-ID: <[email protected]>
--- arch/x86/xen/mmu_pv.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/x86/xen/mmu_pv.c +4 -0
@@ -827,6 +827,7 @@ void xen_mm_pin_all(void) {struct page *page; +spin_lock (&init_mm.page_table_lock);spin_lock (&pgd_lock);list_for_each_entry (page, &pgd_list, lru) {
@@ -837,6 +838,7 @@ void xen_mm_pin_all(void) }spin_unlock (&pgd_lock); +spin_unlock (&init_mm.page_table_lock); } static void __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
@@ -936,6 +938,7 @@ void xen_mm_unpin_all(void) {struct page *page; +spin_lock (&init_mm.page_table_lock);spin_lock (&pgd_lock);list_for_each_entry (page, &pgd_list, lru) {
@@ -947,6 +950,7 @@ void xen_mm_unpin_all(void) }spin_unlock (&pgd_lock); +spin_unlock (&init_mm.page_table_lock); }static void xen_enter_mmap (struct mm_struct *mm)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 44/152 selftests: gpio: gpio-sim: Fix missing chip disablements
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <[email protected]>
[ Upstream commit f8524ac33cd452aef5384504b3264db6039a455e ]
Since upstream commit 8bd76b3d3f3a ("gpio: sim: lock up configfs that an instantiated device depends on"), rmdir for an active virtual devices been prohibited.
Update gpio-sim selftest to align with the change.
--- tools/testing/selftests/gpio/gpio-sim.sh | 31 +++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-)
tools/testing/selftests/gpio/gpio-sim.sh +25 -6
@@ -46,12 +46,6 @@ remove_chip() { rmdir $CONFIGFS_DIR/$CHIP || fail "Unable to remove the chip" } -configfs_cleanup() { - for CHIP in `ls $CONFIGFS_DIR/`; do - remove_chip $CHIP - done -} - create_chip() { local CHIP=$1
@@ -105,6 +99,13 @@ disable_chip() { echo 0 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to disable the chip" } +configfs_cleanup() { + for CHIP in `ls $CONFIGFS_DIR/`; do + disable_chip $CHIP + remove_chip $CHIP + done +} + configfs_chip_name() { local CHIP=$1 local BANK=$2
@@ -181,6 +182,7 @@ create_chip chip create_bank chip bank enable_chip chip test -n `cat $CONFIGFS_DIR/chip/bank/chip_name` || fail "chip_name doesn't work" +disable_chip chip remove_chip chip echo "1.2. chip_name returns 'none' if the chip is still pending"
@@ -195,6 +197,7 @@ create_chip chip create_bank chip bank enable_chip chip test -n `cat $CONFIGFS_DIR/chip/dev_name` || fail "dev_name doesn't work" +disable_chip chip remove_chip chip echo "2. Creating and configuring simulated chips"
@@ -204,6 +207,7 @@ create_chip chip create_bank chip bank enable_chip chip test "`get_chip_num_lines chip bank`" = "1" || fail "default number of lines is not 1" +disable_chip chip remove_chip chip echo "2.2. Number of lines can be specified"
@@ -212,6 +216,7 @@ create_bank chip bank set_num_lines chip bank 16 enable_chip chip test "`get_chip_num_lines chip bank`" = "16" || fail "number of lines is not 16" +disable_chip chip remove_chip chip echo "2.3. Label can be set"
@@ -220,6 +225,7 @@ create_bank chip bank set_label chip bank foobar enable_chip chip test "`get_chip_label chip bank`" = "foobar" || fail "label is incorrect" +disable_chip chip remove_chip chip echo "2.4. Label can be left empty"
@@ -227,6 +233,7 @@ create_chip chip create_bank chip bank enable_chip chip test -z "`cat $CONFIGFS_DIR/chip/bank/label`" || fail "label is not empty" +disable_chip chip remove_chip chip echo "2.5. Line names can be configured"
@@ -238,6 +245,7 @@ set_line_name chip bank 2 bar enable_chip chip test "`get_line_name chip bank 0`" = "foo" || fail "line name is incorrect" test "`get_line_name chip bank 2`" = "bar" || fail "line name is incorrect" +disable_chip chip remove_chip chip echo "2.6. Line config can remain unused if offset is greater than number of lines"
@@ -248,6 +256,7 @@ set_line_name chip bank 5 foobar enable_chip chip test "`get_line_name chip bank 0`" = "" || fail "line name is incorrect" test "`get_line_name chip bank 1`" = "" || fail "line name is incorrect" +disable_chip chip remove_chip chip echo "2.7. Line configfs directory names are sanitized"
@@ -267,6 +276,7 @@ for CHIP in $CHIPS; do enable_chip $CHIP done for CHIP in $CHIPS; do + disable_chip $CHIP remove_chip $CHIP done
@@ -278,6 +288,7 @@ echo foobar > $CONFIGFS_DIR/chip/bank/label 2> /dev/null && \ fail "Setting label of a live chip should fail" echo 8 > $CONFIGFS_DIR/chip/bank/num_lines 2> /dev/null && \ fail "Setting number of lines of a live chip should fail" +disable_chip chip remove_chip chip echo "2.10. Can't create line items when chip is live"
@@ -285,6 +296,7 @@ create_chip chip create_bank chip bank enable_chip chip mkdir $CONFIGFS_DIR/chip/bank/line0 2> /dev/null && fail "Creating line item should fail" +disable_chip chip remove_chip chip echo "2.11. Probe errors are propagated to user-space"
@@ -316,6 +328,7 @@ mkdir -p $CONFIGFS_DIR/chip/bank/line4/hog enable_chip chip $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 4 2> /dev/null && \ fail "Setting the value of a hogged line shouldn't succeed" +disable_chip chip remove_chip chip echo "3. Controlling simulated chips"
@@ -331,6 +344,7 @@ test "$?" = "1" || fail "pull set incorrectly" sysfs_set_pull chip bank 0 pull-down $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 1 test "$?" = "0" || fail "pull set incorrectly" +disable_chip chip remove_chip chip echo "3.2. Pull can be read from sysfs"
@@ -344,6 +358,7 @@ SYSFS_PATH=/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull test `cat $SYSFS_PATH` = "pull-down" || fail "reading the pull failed" sysfs_set_pull chip bank 0 pull-up test `cat $SYSFS_PATH` = "pull-up" || fail "reading the pull failed" +disable_chip chip remove_chip chip echo "3.3. Incorrect input in sysfs is rejected"
@@ -355,6 +370,7 @@ DEVNAME=`configfs_dev_name chip` CHIPNAME=`configfs_chip_name chip bank` SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull" echo foobar > $SYSFS_PATH 2> /dev/null && fail "invalid input not detected" +disable_chip chip remove_chip chip echo "3.4. Can't write to value"
@@ -365,6 +381,7 @@ DEVNAME=`configfs_dev_name chip` CHIPNAME=`configfs_chip_name chip bank` SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" echo 1 > $SYSFS_PATH 2> /dev/null && fail "writing to 'value' succeeded unexpectedly" +disable_chip chip remove_chip chip echo "4. Simulated GPIO chips are functional"
@@ -382,6 +399,7 @@ $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 0 & sleep 0.1 # FIXME Any better way? test `cat $SYSFS_PATH` = "1" || fail "incorrect value read from sysfs" kill $! +disable_chip chip remove_chip chip echo "4.2. Bias settings work correctly"
@@ -394,6 +412,7 @@ CHIPNAME=`configfs_chip_name chip bank` SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" $BASE_DIR/gpio-mockup-cdev -b pull-up /dev/`configfs_chip_name chip bank` 0 test `cat $SYSFS_PATH` = "1" || fail "bias setting does not work" +disable_chip chip remove_chip chip echo "GPIO $MODULE test PASS"
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 45/152 ACPI: x86: Add skip i2c clients quirk for Vexia EDU ATLA 10 tablet 5V
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit 8f62ca9c338aae4f73e9ce0221c3d4668359ddd8 ]
The Vexia EDU ATLA 10 tablet comes in 2 different versions with significantly different mainboards. The only outward difference is that the charging barrel on one is marked 5V and the other is marked 9V.
Both ship with Android 4.4 as factory OS and have the usual broken DSDT issues for x86 Android tablets.
Add a quirk to skip ACPI I2C client enumeration for the 5V version to complement the existing quirk for the 9V version.
--- drivers/acpi/x86/utils.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/acpi/x86/utils.c +13 -0
@@ -400,6 +400,19 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), }, + { +/* Vexia Edu Atla 10 tablet 5V version */ + .matches = { +/* Having all 3 of these not set is somewhat unique */ +DMI_MATCH (DMI_SYS_VENDOR ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_NAME ,"To be filled by O.E.M." ), +/* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), + }, + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, {/* Vexia Edu Atla 10 tablet 9V version */ .matches = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 46/152 x86/mm/tlb: Only trim the mm_cpumask once a second
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rik van Riel <[email protected]>
[ Upstream commit 6db2526c1d694c91c6e05e2f186c085e9460f202 ]
Setting and clearing CPU bits in the mm_cpumask is only ever done by the CPU itself, from the context switch code or the TLB flush code.
Synchronization is handled by switch_mm_irqs_off() blocking interrupts.
Sending TLB flush IPIs to CPUs that are in the mm_cpumask, but no longer running the program causes a regression in the will-it-scale tlbflush2 test. This test is contrived, but a large regression here might cause a small regression in some real world workload.
Instead of always sending IPIs to CPUs that are in the mm_cpumask, but no longer running the program, send these IPIs only once a second.
The rest of the time we can skip over CPUs where the loaded_mm is different from the target mm.
--- arch/x86/include/asm/mmu.h | 2 ++ arch/x86/include/asm/mmu_context.h | 1 + arch/x86/include/asm/tlbflush.h | 1 + arch/x86/mm/tlb.c | 35 +++++++++++++++++++++++++++--- 4 files changed, 36 insertions(+), 3 deletions(-)
arch/x86/include/asm/mmu.h +2 -0
@@ -37,6 +37,8 @@ typedef struct {*/ atomic64_t tlb_gen; +unsigned long next_trim_cpumask; +#ifdef CONFIG_MODIFY_LDT_SYSCALL struct rw_semaphore ldt_usr_sem;struct ldt_struct *ldt;
arch/x86/include/asm/mmu_context.h +1 -0
@@ -145,6 +145,7 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.ctx_id =atomic64_inc_return (&last_mm_ctx_id);atomic64_set (&mm->context.tlb_gen,0 ); + mm->context.next_trim_cpumask = jiffies +HZ ;#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS if (cpu_feature_enabled (X86_FEATURE_OSPKE )) {
arch/x86/include/asm/tlbflush.h +1 -0
@@ -222,6 +222,7 @@ struct flush_tlb_info {unsigned int initiating_cpu;u8 stride_shift;u8 freed_tables; +u8 trim_cpumask; };void flush_tlb_local (void );
arch/x86/mm/tlb.c +32 -3
@@ -898,9 +898,36 @@ static void flush_tlb_func(void *info) nr_invalidate); } -static bool tlb_is_not_lazy (int cpu,void *data) +static bool should_flush_tlb (int cpu,void *data) { -return !per_cpu (cpu_tlbstate_shared.is_lazy, cpu); +struct flush_tlb_info *info = data; + +/* Lazy TLB will get flushed at the next context switch. */ +if (per_cpu (cpu_tlbstate_shared.is_lazy, cpu)) +return false; + +/* No mm means kernel memory flush. */ +if (!info->mm) +return true; + +/* The target mm is loaded, and the CPU is not lazy. */ +if (per_cpu (cpu_tlbstate.loaded_mm, cpu) == info->mm) +return true; + +/* In cpumask, but not the loaded mm? Periodically remove by flushing. */ +if (info->trim_cpumask) +return true; + +return false; +} + +static bool should_trim_cpumask (struct mm_struct *mm) +{ +if (time_after (jiffies,READ_ONCE (mm->context.next_trim_cpumask))) { +WRITE_ONCE (mm->context.next_trim_cpumask, jiffies +HZ ); +return true; + } +return false; } DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
@@ -934,7 +961,7 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask,if (info->freed_tables)on_each_cpu_mask (cpumask, flush_tlb_func, (void *)info, true);else -on_each_cpu_cond_mask (tlb_is_not_lazy, flush_tlb_func, +on_each_cpu_cond_mask (should_flush_tlb, flush_tlb_func, (void *)info,1 , cpumask); }
@@ -985,6 +1012,7 @@ static struct flush_tlb_info *get_flush_tlb_info(struct mm_struct *mm, info->freed_tables = freed_tables; info->new_tlb_gen = new_tlb_gen; info->initiating_cpu =smp_processor_id (); + info->trim_cpumask =0 ;return info; }
@@ -1027,6 +1055,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,* flush_tlb_func_local() directly in this case. */ if (cpumask_any_but (mm_cpumask (mm), cpu) < nr_cpu_ids) { + info->trim_cpumask =should_trim_cpumask (mm);flush_tlb_multi (mm_cpumask (mm), info); }else if (mm ==this_cpu_read (cpu_tlbstate.loaded_mm)) {lockdep_assert_irqs_enabled ();
Signature · 1 line
2.39.5
Re: [PATCH 6.6 046/152] x86/mm/tlb: Only trim the mm_cpumask once a second
Hi,
I noticed commit 6db2526c1d69 ("x86/mm/tlb: Only trim the mm_cpumask once a second") is aimed to fix performance regression introduced by commit 209954cbc7d0 ("x86/mm/tlb: Update mm_cpumask lazily")
But commit 209954cbc7d0 isn't merged into stable 6.6, it seems merely merging commit 6db2526c1d69 into stable 6.6 is meaningless.
Thanks.
Greg KH
maintainerRe: [PATCH 6.6 046/152] x86/mm/tlb: Only trim the mm_cpumask once a second
Quoted 8 lines · Jinjiang Tu
Hi,
I noticed commit
6db2526c1d69("x86/mm/tlb: Only trim themm_cpumaskonce a second") is aimed to fix performance regression introduced by commit209954cbc7d0("x86/mm/tlb: Updatemm_cpumasklazily")But commit
209954cbc7d0isn't merged into stable 6.6, it seems merely merging commit6db2526c1d69into stable 6.6 is meaningless.
If you revert it, does everything still work properly? If so, can you submit a patch to revert it if you think it should be removed, from all affected branches?
thanks,
greg k-h
Re: [PATCH 6.6 046/152] x86/mm/tlb: Only trim the mm_cpumask once a second
Quoted 7 lines · Greg KH
Quoted 6 lines · Jinjiang Tu
Hi,
I noticed commit
6db2526c1d69("x86/mm/tlb: Only trim themm_cpumaskonce a second") is aimed to fix performance regression introduced by commit209954cbc7d0("x86/mm/tlb: Updatemm_cpumasklazily")
Quoted 5 lines
Quoted 2 lines
But commit
209954cbc7d0isn't merged into stable 6.6, it seems merely merging commit6db2526c1d69into stable 6.6 is meaningless.If you revert it, does everything still work properly? If so, can you submit a patch to revert it if you think it should be removed, from all affected branches?
From theoretical analysis, I think reverting it won't introduce any regression.
Rik, could you please confirm it?
Thanks.
Quoted 5 lines
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 47/152 orangefs: fix a oob in orangefs_debug_write
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Marshall <[email protected]>
[ Upstream commit f7c848431632598ff9bce57a659db6af60d75b39 ]
I got a syzbot report: slab-out-of-bounds Read in orangefs_debug_write... several people suggested fixes, I tested Al Viro's suggestion and made this patch.
--- fs/orangefs/orangefs-debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/orangefs/orangefs-debugfs.c +2 -2
@@ -393,9 +393,9 @@ static ssize_t orangefs_debug_write(struct file *file,* Thwart users who try to jamb a ridiculous number * of bytes into the debug file... */ -if (count >ORANGEFS_MAX_DEBUG_STRING_LEN +1 ) { +if (count >ORANGEFS_MAX_DEBUG_STRING_LEN ) { silly = count; - count =ORANGEFS_MAX_DEBUG_STRING_LEN +1 ; + count =ORANGEFS_MAX_DEBUG_STRING_LEN ; } buf =kzalloc (ORANGEFS_MAX_DEBUG_STRING_LEN ,GFP_KERNEL );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 48/152 ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit 6917192378c1ce17ba31df51c4e0d8b1c97a453b ]
The Vexia EDU ATLA 10 tablet comes in 2 different versions with significantly different mainboards. The only outward difference is that the charging barrel on one is marked 5V and the other is marked 9V.
The 5V version mostly works with the BYTCR defaults, except that it is missing a CHAN package in its ACPI tables and the default of using SSP0-AIF2 is wrong, instead SSP0-AIF1 must be used. That and its jack detect signal is not inverted as it usually is.
Add a DMI quirk for the 5V version to fix sound not working.
--- sound/soc/intel/boards/bytcr_rt5640.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
sound/soc/intel/boards/bytcr_rt5640.c +16 -1
@@ -1132,7 +1132,22 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, - { /* Vexia Edu Atla 10 tablet */ + { +/* Vexia Edu Atla 10 tablet 5V version */ + .matches = { +/* Having all 3 of these not set is somewhat unique */ +DMI_MATCH (DMI_SYS_VENDOR ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_NAME ,"To be filled by O.E.M." ), +/* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | +BYT_RT5640_JD_NOT_INV | +BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, + { /* Vexia Edu Atla 10 tablet 9V version */ .matches = {DMI_MATCH (DMI_BOARD_VENDOR ,"AMI Corporation" ), DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 49/152 batman-adv: fix panic during interface removal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Strohman <[email protected]>
commit ccb7276a6d26d6f8416e315b43b45e15ee7f29e2 upstream.
Reference counting is used to ensure that batadv_hardif_neigh_node and batadv_hard_iface are not freed before/during batadv_v_elp_throughput_metric_update work is finished.
But there isn't a guarantee that the hard if will remain associated with a soft interface up until the work is finished.
This fixes a crash triggered by reboot that looks like this:
Call trace: batadv_v_mesh_free+0xd0/0x4dc [batman_adv] batadv_v_elp_throughput_metric_update+0x1c/0xa4 process_one_work+0x178/0x398 worker_thread+0x2e8/0x4d0 kthread+0xd8/0xdc ret_from_fork+0x10/0x20
(the batadv_v_mesh_free call is misleading,
and does not actually happen)
I was able to make the issue happen more reliably by changing hardif_neigh->bat_v.metric_work work to be delayed work. This allowed me to track down and confirm the fix.
[[email protected]: prevent entering batadv_v_elp_get_throughput without
soft_iface]
--- net/batman-adv/bat_v_elp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/batman-adv/bat_v_elp.c +8 -1
@@ -66,12 +66,19 @@ static void batadv_v_elp_start_timer(strstatic u32 batadv_v_elp_get_throughput (struct batadv_hardif_neigh_node *neigh) {struct batadv_hard_iface *hard_iface = neigh->if_incoming; +struct net_device *soft_iface = hard_iface->soft_iface;struct ethtool_link_ksettings link_settings;struct net_device *real_netdev;struct station_info sinfo;u32 throughput;int ret; +/* don't query throughput when no longer associated with any +* batman-adv interface +*/ +if (!soft_iface) +return BATADV_THROUGHPUT_DEFAULT_VALUE ; +/* if the user specified a customised value for this interface, then * return it directly */
@@ -141,7 +148,7 @@ static u32 batadv_v_elp_get_throughput(s default_throughput:if (!(hard_iface->bat_v.flags &BATADV_WARNING_DEFAULT )) { - batadv_info(hard_iface->soft_iface, + batadv_info(soft_iface, "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", hard_iface->net_dev->name, BATADV_THROUGHPUT_DEFAULT_VALUE / 10,
Greg Kroah-Hartman
maintainerPATCH 50/152 batman-adv: Ignore neighbor throughput metrics in error case
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit e7e34ffc976aaae4f465b7898303241b81ceefc3 upstream.
If a temporary error happened in the evaluation of the neighbor throughput information, then the invalid throughput result should not be stored in the throughtput EWMA.
--- net/batman-adv/bat_v_elp.c | 50 ++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 16 deletions(-)
net/batman-adv/bat_v_elp.c +34 -16
@@ -59,11 +59,13 @@ static void batadv_v_elp_start_timer(str/** * batadv_v_elp_get_throughput() - get the throughput towards a neighbour * @neigh: the neighbour for which the throughput has to be obtained +* @pthroughput: calculated throughput towards the given neighbour in multiples +* of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). * -* Return: The throughput towards the given neighbour in multiples of 100kpbs -* (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). +* Return: true when value behind @pthroughput was set */ -static u32 batadv_v_elp_get_throughput (struct batadv_hardif_neigh_node *neigh) +static bool batadv_v_elp_get_throughput (struct batadv_hardif_neigh_node *neigh, +u32 *pthroughput) {struct batadv_hard_iface *hard_iface = neigh->if_incoming;struct net_device *soft_iface = hard_iface->soft_iface;
@@ -77,14 +79,16 @@ static u32 batadv_v_elp_get_throughput(s* batman-adv interface */ if (!soft_iface) -return BATADV_THROUGHPUT_DEFAULT_VALUE ; +return false;/* if the user specified a customised value for this interface, then * return it directly */ throughput =atomic_read (&hard_iface->bat_v.throughput_override); -if (throughput !=0 ) -return throughput; +if (throughput !=0 ) { + *pthroughput = throughput; +return true; + }/* if this is a wireless device, then ask its throughput through * cfg80211 API
@@ -111,19 +115,24 @@ static u32 batadv_v_elp_get_throughput(s* possible to delete this neighbor. For now set * the throughput metric to 0. */ -return 0 ; + *pthroughput =0 ; +return true; }if (ret) goto default_throughput; -if (sinfo.filled &BIT (NL80211_STA_INFO_EXPECTED_THROUGHPUT )) -return sinfo.expected_throughput /100 ; +if (sinfo.filled &BIT (NL80211_STA_INFO_EXPECTED_THROUGHPUT )) { + *pthroughput = sinfo.expected_throughput /100 ; +return true; + }/* try to estimate the expected throughput based on reported tx * rates */ -if (sinfo.filled &BIT (NL80211_STA_INFO_TX_BITRATE )) -return cfg80211_calculate_bitrate (&sinfo.txrate) /3 ; +if (sinfo.filled &BIT (NL80211_STA_INFO_TX_BITRATE )) { + *pthroughput =cfg80211_calculate_bitrate (&sinfo.txrate) /3 ; +return true; + } goto default_throughput; }
@@ -142,8 +151,10 @@ static u32 batadv_v_elp_get_throughput(s hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX ; throughput = link_settings.base.speed; -if (throughput && throughput !=SPEED_UNKNOWN ) -return throughput *10 ; +if (throughput && throughput !=SPEED_UNKNOWN ) { + *pthroughput = throughput *10 ; +return true; + } } default_throughput:
@@ -157,7 +168,8 @@ default_throughput: }/* if none of the above cases apply, return the base_throughput */ -return BATADV_THROUGHPUT_DEFAULT_VALUE ; + *pthroughput =BATADV_THROUGHPUT_DEFAULT_VALUE ; +return true; }/**
@@ -169,15 +181,21 @@ void batadv_v_elp_throughput_metric_upda {struct batadv_hardif_neigh_node_bat_v *neigh_bat_v;struct batadv_hardif_neigh_node *neigh; +u32 throughput; +bool valid; neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, metric_work); neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, bat_v); -ewma_throughput_add (&neigh->bat_v.throughput, -batadv_v_elp_get_throughput (neigh)); + valid =batadv_v_elp_get_throughput (neigh, &throughput); +if (!valid) + goto put_neigh; + +ewma_throughput_add (&neigh->bat_v.throughput, throughput); +put_neigh:/* decrement refcounter to balance increment performed before scheduling * this task */
Greg Kroah-Hartman
maintainerPATCH 51/152 batman-adv: Drop unmanaged ELP metric worker
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 8c8ecc98f5c65947b0070a24bac11e12e47cc65d upstream.
The ELP worker needs to calculate new metric values for all neighbors "reachable" over an interface. Some of the used metric sources require locks which might need to sleep. This sleep is incompatible with the RCU list iterator used for the recorded neighbors. The initial approach to work around of this problem was to queue another work item per neighbor and then run this in a new context.
Even when this solved the RCU vs might_sleep() conflict, it has a major
problems: Nothing was stopping the work item in case it is not needed anymore - for example because one of the related interfaces was removed or the batman-adv module was unloaded - resulting in potential invalid memory accesses.
Directly canceling the metric worker also has various problems:
* cancel_work_sync for a to-be-deactivated interface is called with rtnl_lock held. But the code in the ELP metric worker also tries to use rtnl_lock() - which will never return in this case. This also means that cancel_work_sync would never return because it is waiting for the worker to finish.
* iterating over the neighbor list for the to-be-deactivated interface is currently done using the RCU specific methods. Which means that it is possible to miss items when iterating over it without the associated spinlock - a behaviour which is acceptable for a periodic metric check but not for a cleanup routine (which must "stop" all still running workers)
The better approch is to get rid of the per interface neighbor metric worker and handle everything in the interface worker. The original problems are solved by:
* creating a list of neighbors which require new metric information inside the RCU protected context, gathering the metric according to the new list outside the RCU protected context
* only use rcu_trylock inside metric gathering code to avoid a deadlock when the cancel_delayed_work_sync is called in the interface removal code (which is called with the rtnl_lock held)
--- net/batman-adv/bat_v.c | 2 - net/batman-adv/bat_v_elp.c | 71 ++++++++++++++++++++++++++++++--------------- net/batman-adv/bat_v_elp.h | 2 - net/batman-adv/types.h | 3 - 4 files changed, 48 insertions(+), 30 deletions(-)
net/batman-adv/bat_v.c +0 -2
@@ -113,8 +113,6 @@ static void batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) {ewma_throughput_init (&hardif_neigh->bat_v.throughput); -INIT_WORK (&hardif_neigh->bat_v.metric_work, - batadv_v_elp_throughput_metric_update); }/**
net/batman-adv/bat_v_elp.c +48 -23
143 lines not on this page · raw message
net/batman-adv/bat_v_elp.h +0 -2
@@ -10,7 +10,6 @@#include "main.h" #include <linux/skbuff.h> -#include <linux/workqueue.h> int batadv_v_elp_iface_enable (struct batadv_hard_iface *hard_iface);void batadv_v_elp_iface_disable (struct batadv_hard_iface *hard_iface);
@@ -19,6 +18,5 @@ void batadv_v_elp_iface_activate(structvoid batadv_v_elp_primary_iface_set (struct batadv_hard_iface *primary_iface);int batadv_v_elp_packet_recv (struct sk_buff *skb,struct batadv_hard_iface *if_incoming); -void batadv_v_elp_throughput_metric_update (struct work_struct *work);#endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */
net/batman-adv/types.h +0 -3
@@ -596,9 +596,6 @@ struct batadv_hardif_neigh_node_bat_v {* neighbor */ unsigned long last_unicast_tx; - -/** @metric_work: work queue callback item for metric update */ -struct work_struct metric_work; };/**
Greg Kroah-Hartman
maintainerPATCH 52/152 drm/amdgpu: avoid buffer overflow attach in smu_sys_set_pp_table()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiang Liu <[email protected]>
commit 1abb2648698bf10783d2236a6b4a7ca5e8021699 upstream.
It malicious user provides a small pptable through sysfs and then a bigger pptable, it may cause buffer overflow attack in function smu_sys_set_pp_table().
--- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +2 -1
@@ -517,7 +517,8 @@ static int smu_sys_set_pp_table(void *hareturn -EIO ; } -if (!smu_table->hardcode_pptable) { +if (!smu_table->hardcode_pptable || smu_table->power_play_table_size < size) { +kfree (smu_table->hardcode_pptable); smu_table->hardcode_pptable =kzalloc (size,GFP_KERNEL );if (!smu_table->hardcode_pptable)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 53/152 KVM: x86: Reject Hyper-Vs SEND_IPI hypercalls if local APIC isnt in-kernel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit a8de7f100bb5989d9c3627d3a223ee1c863f3b69 upstream.
Advertise support for Hyper-V's SEND_IPI and SEND_IPI_EX hypercalls if and only if the local API is emulated/virtualized by KVM, and explicitly reject said hypercalls if the local APIC is emulated in userspace, i.e. don't rely on userspace to opt-in to KVM_CAP_HYPERV_ENFORCE_CPUID.
Rejecting SEND_IPI and SEND_IPI_EX fixes a NULL-pointer dereference if Hyper-V enlightenments are exposed to the guest without an in-kernel local APIC:
dump_stack+0xbe/0xfd __kasan_report.cold+0x34/0x84 kasan_report+0x3a/0x50 __apic_accept_irq+0x3a/0x5c0 kvm_hv_send_ipi.isra.0+0x34e/0x820 kvm_hv_hypercall+0x8d9/0x9d0 kvm_emulate_hypercall+0x506/0x7e0 __vmx_handle_exit+0x283/0xb60 vmx_handle_exit+0x1d/0xd0 vcpu_enter_guest+0x16b0/0x24c0 vcpu_run+0xc0/0x550 kvm_arch_vcpu_ioctl_run+0x170/0x6d0 kvm_vcpu_ioctl+0x413/0xb20 __se_sys_ioctl+0x111/0x160 do_syscal1_64+0x30/0x40 entry_SYSCALL_64_after_hwframe+0x67/0xd1
Note, checking the sending vCPU is sufficient, as the per-VM irqchip_mode can't be modified after vCPUs are created, i.e. if one vCPU has an in-kernel local APIC, then all vCPUs have an in-kernel local APIC.
--- arch/x86/kvm/hyperv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/kvm/hyperv.c +5 -1
@@ -2175,6 +2175,9 @@ static u64 kvm_hv_send_ipi(struct kvm_vcu32 vector;bool all_cpus; +if (!lapic_in_kernel (vcpu)) +return HV_STATUS_INVALID_HYPERCALL_INPUT ; +if (hc->code ==HVCALL_SEND_IPI ) {if (!hc->fast) { if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi,
@@ -2801,7 +2804,8 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vc ent->eax |=HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED ; ent->eax |=HV_X64_APIC_ACCESS_RECOMMENDED ; ent->eax |=HV_X64_RELAXED_TIMING_RECOMMENDED ; - ent->eax |=HV_X64_CLUSTER_IPI_RECOMMENDED ; +if (!vcpu ||lapic_in_kernel (vcpu)) + ent->eax |=HV_X64_CLUSTER_IPI_RECOMMENDED ; ent->eax |=HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED ;if (evmcs_ver) ent->eax |=HV_X64_ENLIGHTENED_VMCS_RECOMMENDED ;
Greg Kroah-Hartman
maintainerPATCH 54/152 KVM: nSVM: Enter guest mode before initializing nested NPT MMU
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 46d6c6f3ef0eaff71c2db6d77d4e2ebb7adac34f upstream.
When preparing vmcb02 for nested VMRUN (or state restore), "enter" guest mode prior to initializing the MMU for nested NPT so that guest_mode is set in the MMU's role. KVM's model is that all L2 MMUs are tagged with guest_mode, as the behavior of hypervisor MMUs tends to be significantly different than kernel MMUs.
Practically speaking, the bug is relatively benign, as KVM only directly queries role.guest_mode in kvm_mmu_free_guest_mode_roots() and kvm_mmu_page_ad_need_write_protect(), which SVM doesn't use, and in paths that are optimizations (mmu_page_zap_pte() and shadow_mmu_try_split_huge_pages()).
And while the role is incorprated into shadow page usage, because nested NPT requires KVM to be using NPT for L1, reusing shadow pages across L1 and L2 is impossible as L1 MMUs will always have direct=1, while L2 MMUs will have direct=0.
Hoist the TLB processing and setting of HF_GUEST_MASK to the beginning of the flow instead of forcing guest_mode in the MMU, as nothing in nested_vmcb02_prepare_control() between the old and new locations touches TLB flush requests or HF_GUEST_MASK, i.e. there's no reason to present inconsistent vCPU state to the MMU.
--- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/svm/nested.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-)
arch/x86/kvm/mmu/mmu.c +1 -1
@@ -5289,7 +5289,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_union kvm_mmu_page_role root_role;/* NPT requires CR0.PG=1. */ -WARN_ON_ONCE (cpu_role.base.direct); +WARN_ON_ONCE (cpu_role.base.direct || !cpu_role.base.guest_mode); root_role = cpu_role.base; root_role.level =kvm_mmu_get_tdp_level (vcpu);
arch/x86/kvm/svm/nested.c +5 -5
@@ -644,6 +644,11 @@ static void nested_vmcb02_prepare_controu32 pause_count12;u32 pause_thresh12; +nested_svm_transition_tlb_flush (vcpu); + +/* Enter Guest-Mode */ +enter_guest_mode (vcpu); +/* * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2, * exit_int_info, exit_int_info_err, next_rip, insn_len, insn_bytes.
@@ -760,11 +765,6 @@ static void nested_vmcb02_prepare_contro } } -nested_svm_transition_tlb_flush (vcpu); - -/* Enter Guest-Mode */ -enter_guest_mode (vcpu); -/* * Merge guest and host intercepts - must be called with vcpu in * guest-mode to take effect.
Greg Kroah-Hartman
maintainerPATCH 55/152 perf/x86/intel: Ensure LBRs are disabled when a CPU is starting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit c631a2de7ae48d50434bdc205d901423f8577c65 upstream.
Explicitly clear DEBUGCTL.LBR when a CPU is starting, prior to purging the LBR MSRs themselves, as at least one system has been found to transfer control to the kernel with LBRs enabled (it's unclear whether it's a BIOS flaw or a CPU goof). Because the kernel preserves the original DEBUGCTL, even when toggling LBRs, leaving DEBUGCTL.LBR as is results in running with LBRs enabled at all times.
--- arch/x86/events/intel/core.c | 5 ++++- arch/x86/include/asm/msr-index.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-)
arch/x86/events/intel/core.c +4 -1
@@ -4715,8 +4715,11 @@ static void intel_pmu_cpu_starting(int cinit_debug_store_on_cpu (cpu);/* -* Deal with CPUs that don't clear their LBRs on power-up. +* Deal with CPUs that don't clear their LBRs on power-up, and that may +* even boot with LBRs enabled. */ +if (!static_cpu_has (X86_FEATURE_ARCH_LBR ) && x86_pmu.lbr_nr) +msr_clear_bit (MSR_IA32_DEBUGCTLMSR ,DEBUGCTLMSR_LBR_BIT );intel_pmu_lbr_reset (); cpuc->lbr_sel =NULL ;
arch/x86/include/asm/msr-index.h +2 -1
@@ -358,7 +358,8 @@#define MSR_IA32_PASID_VALID BIT_ULL(31)/* DEBUGCTLMSR bits (others vary by model): */ -#define DEBUGCTLMSR_LBR (1UL << 0)/* last branch recording */ +#define DEBUGCTLMSR_LBR_BIT 0/* last branch recording */ +#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT)#define DEBUGCTLMSR_BTF_SHIFT 1#define DEBUGCTLMSR_BTF (1UL << 1)/* single-step on branches */ #define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2)
Greg Kroah-Hartman
maintainerPATCH 56/152 usb: gadget: f_midi: Fixing wMaxPacketSize exceeded issue during MIDI bind retries
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvarasu Ganesan <[email protected]>
commit 9e8b21410f310c50733f6e1730bae5a8e30d3570 upstream.
The current implementation sets the wMaxPacketSize of bulk in/out endpoints to 1024 bytes at the end of the f_midi_bind function. However, in cases where there is a failure in the first midi bind attempt, consider rebinding. This scenario may encounter an f_midi_bind issue due to the previous bind setting the bulk endpoint's wMaxPacketSize to 1024 bytes, which exceeds the ep->maxpacket_limit where configured dwc3 TX/RX FIFO's maxpacket size of 512 bytes for IN/OUT endpoints in support HS speed only.
Here the term "rebind" in this context refers to attempting to bind the MIDI function a second time in certain scenarios. The situations where rebinding is considered include:
* When there is a failure in the first UDC write attempt, which may be caused by other functions bind along with MIDI.
* Runtime composition change : Example : MIDI,ADB to MIDI. Or MIDI to MIDI,ADB.
This commit addresses this issue by resetting the wMaxPacketSize before endpoint claim. And here there is no need to reset all values in the usb endpoint descriptor structure, as all members except wMaxPacketSize and bEndpointAddress have predefined values.
This ensures that restores the endpoint to its expected configuration, and preventing conflicts with value of ep->maxpacket_limit. It also aligns with the approach used in other function drivers, which treat endpoint descriptors as if they were full speed before endpoint claim.
--- drivers/usb/gadget/function/f_midi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/gadget/function/f_midi.c +9 -0
@@ -906,6 +906,15 @@ static int f_midi_bind(struct usb_config status = -ENODEV ; +/* +* Reset wMaxPacketSize with maximum packet size of FS bulk transfer before +* endpoint claim. This ensures that the wMaxPacketSize does not exceed the +* limit during bind retries where configured dwc3 TX/RX FIFO's maxpacket +* size of 512 bytes for IN/OUT endpoints in support HS speed only. +*/ + bulk_in_desc.wMaxPacketSize =cpu_to_le16 (64 ); + bulk_out_desc.wMaxPacketSize =cpu_to_le16 (64 ); +/* allocate instance-specific endpoints */ midi->in_ep =usb_ep_autoconfig (cdev->gadget, &bulk_in_desc);if (!midi->in_ep)
Greg Kroah-Hartman
maintainerPATCH 57/152 usb: dwc3: Fix timeout issue during controller enter/exit from halt state
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvarasu Ganesan <[email protected]>
commit d3a8c28426fc1fb3252753a9f1db0d691ffc21b0 upstream.
There is a frequent timeout during controller enter/exit from halt state after toggling the run_stop bit by SW. This timeout occurs when performing frequent role switches between host and device, causing device enumeration issues due to the timeout. This issue was not present when USB2 suspend PHY was disabled by passing the SNPS quirks (snps,dis_u2_susphy_quirk and snps,dis_enblslpm_quirk) from the DTS. However, there is a requirement to enable USB2 suspend PHY by setting of GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY bits when controller starts in gadget or host mode results in the timeout issue.
This commit addresses this timeout issue by ensuring that the bits GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting the dwc3_gadget_run_stop sequence and restoring them after the dwc3_gadget_run_stop sequence is completed.
--- drivers/usb/dwc3/gadget.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
drivers/usb/dwc3/gadget.c +34 -0
@@ -2618,10 +2618,38 @@ static int dwc3_gadget_run_stop(struct d {u32 reg;u32 timeout =2000 ; +u32 saved_config =0 ;if (pm_runtime_suspended (dwc->dev))return 0 ; +/* +* When operating in USB 2.0 speeds (HS/FS), ensure that +* GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting +* or stopping the controller. This resolves timeout issues that occur +* during frequent role switches between host and device modes. +* +* Save and clear these settings, then restore them after completing the +* controller start or stop sequence. +* +* This solution was discovered through experimentation as it is not +* mentioned in the dwc3 programming guide. It has been tested on an +* Exynos platforms. +*/ + reg =dwc3_readl (dwc->regs,DWC3_GUSB2PHYCFG (0 )); +if (reg &DWC3_GUSB2PHYCFG_SUSPHY ) { + saved_config |=DWC3_GUSB2PHYCFG_SUSPHY ; + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY ; + } + +if (reg &DWC3_GUSB2PHYCFG_ENBLSLPM ) { + saved_config |=DWC3_GUSB2PHYCFG_ENBLSLPM ; + reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM ; + } + +if (saved_config) +dwc3_writel (dwc->regs,DWC3_GUSB2PHYCFG (0 ), reg); + reg =dwc3_readl (dwc->regs,DWC3_DCTL );if (is_on) { if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
@@ -2649,6 +2677,12 @@ static int dwc3_gadget_run_stop(struct d reg &=DWC3_DSTS_DEVCTRLHLT ; }while (--timeout && !(!is_on ^ !reg)); +if (saved_config) { + reg =dwc3_readl (dwc->regs,DWC3_GUSB2PHYCFG (0 )); + reg |= saved_config; +dwc3_writel (dwc->regs,DWC3_GUSB2PHYCFG (0 ), reg); + } +if (!timeout)return -ETIMEDOUT ;
Greg Kroah-Hartman
maintainerPATCH 58/152 usb: roles: set switch registered flag early on
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Elson Roy Serrao <[email protected]>
commit 634775a752a86784511018a108f3b530cc3399a7 upstream.
The role switch registration and set_role() can happen in parallel as they are invoked independent of each other. There is a possibility that a driver might spend significant amount of time in usb_role_switch_register() API due to the presence of time intensive operations like component_add() which operate under common mutex. This leads to a time window after allocating the switch and before setting the registered flag where the set role notifications are dropped. Below timeline summarizes this behavior
Thread1 | Thread2usb_role_switch_register() |
| | ---> allocate switch | | | ---> component_add() | usb_role_switch_set_role() | | | | | --> Drop role notifications | | since sw->registered | | flag is not set. | | --->Set registered flag.|
To avoid this, set the registered flag early on in the switch register API.
--- drivers/usb/roles/class.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/roles/class.c +3 -2
@@ -355,14 +355,15 @@ usb_role_switch_register(struct device *dev_set_name (&sw->dev,"%s-role-switch" , desc->name ? desc->name :dev_name (parent)); + sw->registered = true; + ret =device_register (&sw->dev);if (ret) { + sw->registered = false;put_device (&sw->dev);return ERR_PTR (ret); } - sw->registered = true; -/* TODO: Symlinks for the host port and the device controller. */ return sw;
Greg Kroah-Hartman
maintainerPATCH 59/152 usb: gadget: udc: renesas_usb3: Fix compiler warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guo Ren <[email protected]>
commit 335a1fc1193481f8027f176649c72868172f6f8b upstream.
drivers/usb/gadget/udc/renesas_usb3.c: In function 'renesas_usb3_probe':drivers/usb/gadget/udc/renesas_usb3.c:2638:73: warning: '%d' directive output may be truncated writing between 1 and 11 bytes into a region of size 6 [-Wformat-truncation=]
2638 | snprintf(usb3_ep->ep_name, sizeof(usb3_ep->ep_name), "ep%d", i);
^~~~~~~~~~~~~~~~~~~~~~~~ ^~ ^--- drivers/usb/gadget/udc/renesas_usb3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/renesas_usb3.c +1 -1
@@ -310,7 +310,7 @@ struct renesas_usb3_request {struct list_head queue; }; -#define USB3_EP_NAME_SIZE 8 +#define USB3_EP_NAME_SIZE 16struct renesas_usb3_ep {struct usb_ep ep;struct renesas_usb3 *usb3;
Greg Kroah-Hartman
maintainerPATCH 60/152 usb: dwc2: gadget: remove of_node reference upon udc_stop
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabrice Gasnier <[email protected]>
commit 58cd423820d5b5610977e55e4acdd06628829ede upstream.
In dwc2_hsotg_udc_start(), e.g. when binding composite driver, "of_node" is set to hsotg->dev->of_node.
It causes errors when binding the gadget driver several times, on stm32mp157c-ev1 board. Below error is seen:
"pin PA10 already requested by 49000000.usb-otg; cannot claim for gadget.0"
The first time, no issue is seen as when registering the driver, of_node isn't NULL:
-> gadget_dev_desc_UDC_store
-> usb_gadget_register_driver_owner
-> driver_register
...
-> really_probe -> pinctrl_bind_pins (no effect)Then dwc2_hsotg_udc_start() sets of_node.
The second time (stop the gadget, reconfigure it, then start it again), of_node has been set, so the probing code tries to acquire pins for the gadget. These pins are hold by the controller, hence the error.
So clear gadget.dev.of_node in udc_stop() routine to avoid the issue.
--- drivers/usb/dwc2/gadget.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/dwc2/gadget.c +1 -0
@@ -4612,6 +4612,7 @@ static int dwc2_hsotg_udc_stop(struct usspin_lock_irqsave (&hsotg->lock, flags); hsotg->driver =NULL ; + hsotg->gadget.dev.of_node =NULL ; hsotg->gadget.speed =USB_SPEED_UNKNOWN ; hsotg->enabled =0 ;
Greg Kroah-Hartman
maintainerPATCH 61/152 USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit e71f7f42e3c874ac3314b8f250e8416a706165af upstream.
LS7A EHCI controller doesn't have extended capabilities, so the EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS register should be 0x0, but it reads as 0xa0 now. This is a hardware flaw and will be fixed in future, now just clear the EECP field to avoid error messages on boot:
......
[ 0.581675] pci 0000:00:04.1: EHCI: unrecognized capability ff [ 0.581699] pci 0000:00:04.1: EHCI: unrecognized capability ff [ 0.581716] pci 0000:00:04.1: EHCI: unrecognized capability ff [ 0.581851] pci 0000:00:04.1: EHCI: unrecognized capability ff ...... [ 0.581916] pci 0000:00:05.1: EHCI: unrecognized capability ff [ 0.581951] pci 0000:00:05.1: EHCI: unrecognized capability ff [ 0.582704] pci 0000:00:05.1: EHCI: unrecognized capability ff [ 0.582799] pci 0000:00:05.1: EHCI: unrecognized capability ff
......
--- drivers/usb/host/pci-quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/host/pci-quirks.c +9 -0
@@ -946,6 +946,15 @@ static void quirk_usb_disable_ehci(struc* booting from USB disk or using a usb keyboard */ hcc_params =readl (base +EHCI_HCC_PARAMS ); + +/* LS7A EHCI controller doesn't have extended capabilities, the +* EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS +* register should be 0x0 but it reads as 0xa0. So clear it to +* avoid error messages on boot. +*/ +if (pdev->vendor ==PCI_VENDOR_ID_LOONGSON && pdev->device ==0x7a14 ) + hcc_params &= ~(0xffL <<8 ); + offset = (hcc_params >>8 ) &0xff ;while (offset && --count) {pci_read_config_dword (pdev, offset, &cap);
Greg Kroah-Hartman
maintainerPATCH 62/152 usb: core: fix pipe creation for get_bMaxPacketSize0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Eichenberger <[email protected]>
commit 4aac0db5a0ebc599d4ad9bf5ebab78afa1f33e10 upstream.
When usb_control_msg is used in the get_bMaxPacketSize0 function, the USB pipe does not include the endpoint device number. This can cause failures when a usb hub port is reinitialized after encountering a bad cable connection. As a result, the system logs the following error messages:
usb usb2-port1: cannot reset (err = -32)
usb usb2-port1: Cannot enable. Maybe the USB cable is bad? usb usb2-port1: attempt power cycle
usb 2-1: new high-speed USB device number 5 using ci_hdrc usb 2-1: device descriptor read/8, error -71
The problem began after commit 85d07c556216 ("USB: core: Unite old scheme and new scheme descriptor reads"). There usb_get_device_descriptor was replaced with get_bMaxPacketSize0. Unlike usb_get_device_descriptor, the get_bMaxPacketSize0 function uses the macro usb_rcvaddr0pipe, which does not include the endpoint device number. usb_get_device_descriptor, on the other hand, used the macro usb_rcvctrlpipe, which includes the endpoint device number.
By modifying the get_bMaxPacketSize0 function to use usb_rcvctrlpipe instead of usb_rcvaddr0pipe, the issue can be resolved. This change will ensure that the endpoint device number is included in the USB pipe, preventing reinitialization failures. If the endpoint has not set the device number yet, it will still work because the device number is 0 in udev.
--- drivers/usb/core/hub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/core/hub.c +1 -2
@@ -4666,7 +4666,6 @@ void usb_ep0_reinit(struct usb_device *uEXPORT_SYMBOL_GPL (usb_ep0_reinit);#define usb_sndaddr0pipe () (PIPE_CONTROL << 30) -#define usb_rcvaddr0pipe () ((PIPE_CONTROL << 30) | USB_DIR_IN)static int hub_set_address (struct usb_device *udev,int devnum) {
@@ -4772,7 +4771,7 @@ static int get_bMaxPacketSize0(struct usfor (i =0 ; i <GET_MAXPACKET0_TRIES ; ++i) {/* Start with invalid values in case the transfer fails */ buf->bDescriptorType = buf->bMaxPacketSize0 =0 ; - rc = usb_control_msg(udev, usb_rcvaddr0pipe(), + rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, size,
Greg Kroah-Hartman
maintainerPATCH 63/152 USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lei Huang <[email protected]>
commit e169d96eecd447ff7fd7542ca5fa0911f5622054 upstream.
Teclast disk used on Huawei hisi platforms doesn't work well, losing connectivity intermittently if LPM is enabled. Add quirk disable LPM to resolve the issue.
--- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -522,6 +522,9 @@ static const struct usb_device_id usb_qu/* Blackmagic Design UltraStudio SDI */ { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM }, + /* Teclast disk */ + { USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM }, + /* Hauppauge HVR-950q */ { USB_DEVICE(0x2040, 0x7200), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
Greg Kroah-Hartman
maintainerPATCH 64/152 USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit 159daf1258227f44b26b5d38f4aa8f37b8cca663 upstream.
The fastboot tool for communicating with Android bootloaders does not work reliably with this device if USB 2 Link Power Management (LPM) is enabled.
Various fastboot commands are affected, including the following, which usually reproduces the problem within two tries:
fastboot getvar kernel
getvar:kernel FAILED (remote: 'GetVar Variable Not found')
This issue was hidden on many systems up until commit 63a1f8454962 ("xhci: stored cached port capability values in one place") as the xhci driver failed to detect USB 2 LPM support if USB 3 ports were listed before USB 2 ports in the "supported protocol capabilities".
Adding the quirk resolves the issue. No drawbacks are expected since the device uses different USB product IDs outside of fastboot mode, and since fastboot commands worked before, until LPM was enabled on the tested system by the aforementioned commit.
Based on a patch from Forest <[email protected]> from which most of the code and commit message is taken.
--- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -432,6 +432,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0c45, 0x7056), .driver_info = USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */ + { USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM }, + /* Action Semiconductor flash disk */ { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255 },
Greg Kroah-Hartman
maintainerPATCH 65/152 usb: gadget: f_midi: fix MIDI Streaming descriptor lengths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
commit da1668997052ed1cb00322e1f3b63702615c9429 upstream.
While the MIDI jacks are configured correctly, and the MIDIStreaming endpoint descriptors are filled with the correct information, bNumEmbMIDIJack and bLength are set incorrectly in these descriptors.
This does not matter when the numbers of in and out ports are equal, but when they differ the host will receive broken descriptors with uninitialized stack memory leaking into the descriptor for whichever value is smaller.
The precise meaning of "in" and "out" in the port counts is not clearly defined and can be confusing. But elsewhere the driver consistently uses this to match the USB meaning of IN and OUT viewed from the host, so that "in" ports send data to the host and "out" ports receive data from it.
--- drivers/usb/gadget/function/f_midi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_midi.c +4 -4
@@ -1008,11 +1008,11 @@ static int f_midi_bind(struct usb_config }/* configure the endpoint descriptors ... */ - ms_out_desc.bLength =USB_DT_MS_ENDPOINT_SIZE (midi->in_ports); - ms_out_desc.bNumEmbMIDIJack = midi->in_ports; + ms_out_desc.bLength =USB_DT_MS_ENDPOINT_SIZE (midi->out_ports); + ms_out_desc.bNumEmbMIDIJack = midi->out_ports; - ms_in_desc.bLength =USB_DT_MS_ENDPOINT_SIZE (midi->out_ports); - ms_in_desc.bNumEmbMIDIJack = midi->out_ports; + ms_in_desc.bLength =USB_DT_MS_ENDPOINT_SIZE (midi->in_ports); + ms_in_desc.bNumEmbMIDIJack = midi->in_ports;/* ... and add them to the list */ endpoint_descriptor_index = i;
Greg Kroah-Hartman
maintainerPATCH 66/152 USB: hub: Ignore non-compliant devices with too many configs or interfaces
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <[email protected]>
commit 2240fed37afbcdb5e8b627bc7ad986891100e05d upstream.
Robert Morris created a test program which can cause usb_hub_to_struct_hub() to dereference a NULL or inappropriate pointer:
Oops: general protection fault, probably for non-canonical address 0xcccccccccccccccc: 0000 [#1] SMP DEBUG_PAGEALLOC PTI CPU: 7 UID: 0 PID: 117 Comm: kworker/7:1 Not tainted 6.13.0-rc3-00017-gf44d154d6e3d #14 Hardware name: FreeBSD BHYVE/BHYVE, BIOS 14.0 10/17/2021 Workqueue: usb_hub_wq hub_event RIP: 0010:usb_hub_adjust_deviceremovable+0x78/0x110 ... Call Trace: <TASK> ? die_addr+0x31/0x80 ? exc_general_protection+0x1b4/0x3c0 ? asm_exc_general_protection+0x26/0x30 ? usb_hub_adjust_deviceremovable+0x78/0x110 hub_probe+0x7c7/0xab0 usb_probe_interface+0x14b/0x350 really_probe+0xd0/0x2d0 ? __pfx___device_attach_driver+0x10/0x10 __driver_probe_device+0x6e/0x110 driver_probe_device+0x1a/0x90 __device_attach_driver+0x7e/0xc0 bus_for_each_drv+0x7f/0xd0 __device_attach+0xaa/0x1a0 bus_probe_device+0x8b/0xa0 device_add+0x62e/0x810 usb_set_configuration+0x65d/0x990 usb_generic_driver_probe+0x4b/0x70 usb_probe_device+0x36/0xd0
The cause of this error is that the device has two interfaces, and the hub driver binds to interface 1 instead of interface 0, which is where usb_hub_to_struct_hub() looks.
We can prevent the problem from occurring by refusing to accept hub devices that violate the USB spec by having more than one configuration or interface.
--- drivers/usb/core/hub.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/core/hub.c +11 -0
@@ -1819,6 +1819,17 @@ static int hub_probe(struct usb_interfac hdev =interface_to_usbdev (intf);/* +* The USB 2.0 spec prohibits hubs from having more than one +* configuration or interface, and we rely on this prohibition. +* Refuse to accept a device that violates it. +*/ +if (hdev->descriptor.bNumConfigurations >1 || + hdev->actconfig->desc.bNumInterfaces >1 ) { +dev_err (&intf->dev,"Invalid hub with more than one config or interface\n" ); +return -EINVAL ; + } + +/* * Set default autosuspend delay as 0 to speedup bus suspend, * based on the below considerations: *
Greg Kroah-Hartman
maintainerPATCH 67/152 USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit 7284922f3e4fa285dff1b8bb593aa9a0b8458f30 upstream.
Add Renesas R-Car D3 USB Download mode quirk and update comments on all the other Renesas R-Car USB Download mode quirks to discern them from each other. This follows R-Car Series, 3rd Generation reference manual Rev.2.00 chapter 19.2.8 USB download mode .
--- drivers/usb/class/cdc-acm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/class/cdc-acm.c +6 -3
@@ -1727,13 +1727,16 @@ static const struct usb_device_id acm_id { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ .driver_info =NO_UNION_NORMAL ,/* has no union descriptor */ }, - { USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */ + { USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */ .driver_info = DISABLE_ECHO, /* Don't echo banner */ }, - { USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */ + { USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */ .driver_info = DISABLE_ECHO, /* Don't echo banner */ }, - { USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */ + { USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */ .driver_info = DISABLE_ECHO, /* Don't echo banner */ }, { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; [email protected] */
Greg Kroah-Hartman
maintainerPATCH 68/152 usb: cdc-acm: Check control transfer buffer size before access
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit e563b01208f4d1f609bcab13333b6c0e24ce6a01 upstream.
If the first fragment is shorter than struct usb_cdc_notification, we can't calculate an expected_size. Log an error and discard the notification instead of reading lengths from memory outside the received data, which can lead to memory corruption when the expected_size decreases between fragments, causing expected_size - acm->nb_index to wrap.
This issue has been present since the beginning of git history; however, it only leads to memory corruption since commit ea2583529cd1 ("cdc-acm: reassemble fragmented notifications").
A mitigating factor is that acm_ctrl_irq() can only execute after userspace has opened /dev/ttyACM*; but if ModemManager is running, ModemManager will do that automatically depending on the USB device's vendor/product IDs and its other interfaces.
--- drivers/usb/class/cdc-acm.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/usb/class/cdc-acm.c +14 -3
@@ -371,7 +371,7 @@ static void acm_process_notification(strstatic void acm_ctrl_irq (struct urb *urb) {struct acm *acm = urb->context; -struct usb_cdc_notification *dr = urb->transfer_buffer; +struct usb_cdc_notification *dr;unsigned int current_size = urb->actual_length;unsigned int expected_size, copy_size, alloc_size;int retval;
@@ -398,9 +398,20 @@ static void acm_ctrl_irq(struct urb *urbusb_mark_last_busy (acm->dev); -if (acm->nb_index) +if (acm->nb_index ==0 ) { +/* +* The first chunk of a message must contain at least the +* notification header with the length field, otherwise we +* can't get an expected_size. +*/ +if (current_size <sizeof (struct usb_cdc_notification )) { +dev_dbg (&acm->control->dev,"urb too short\n" ); + goto exit; + } + dr = urb->transfer_buffer; + }else { dr = (struct usb_cdc_notification *)acm->notification_buffer; - + }/* size = notification-header + (optional) data */ expected_size =sizeof (struct usb_cdc_notification ) +le16_to_cpu (dr->wLength);
Greg Kroah-Hartman
maintainerPATCH 69/152 usb: cdc-acm: Fix handling of oversized fragments
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 12e712964f41d05ae034989892de445781c46730 upstream.
If we receive an initial fragment of size 8 bytes which specifies a wLength of 1 byte (so the reassembled message is supposed to be 9 bytes long), and we then receive a second fragment of size 9 bytes (which is not supposed to happen), we currently wrongly bypass the fragment reassembly code but still pass the pointer to the acm->notification_buffer to acm_process_notification().
Make this less wrong by always going through fragment reassembly when we expect more fragments.
Before this patch, receiving an overlong fragment could lead to newctrl in acm_process_notification() being uninitialized data (instead of data coming from the device).
--- drivers/usb/class/cdc-acm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/class/cdc-acm.c +1 -1
@@ -416,7 +416,7 @@ static void acm_ctrl_irq(struct urb *urb expected_size =sizeof (struct usb_cdc_notification ) +le16_to_cpu (dr->wLength); -if (current_size < expected_size) { +if (acm->nb_index !=0 || current_size < expected_size) {/* notification is transmitted fragmented, reassemble */ if (acm->nb_size < expected_size) {u8 *new_buffer;
Greg Kroah-Hartman
maintainerPATCH 70/152 USB: serial: option: add MeiG Smart SLM828
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chester A. Unal <[email protected]>
commit db79e75460fc59b19f9c89d4b068e61cee59f37d upstream.
MeiG Smart SLM828 is an LTE-A CAT6 modem with the mPCIe form factor. The "Cls=ff(vend.) Sub=10 Prot=02" and "Cls=ff(vend.) Sub=10 Prot=03" interfaces respond to AT commands. Add these interfaces.
The product ID the modem uses is shared across multiple modems. Therefore, add comments to describe which interface is used for which modem.
T: Bus=01 Lev=01 Prnt=05 Port=01 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2dee ProdID=4d22 Rev=05.04 S: Manufacturer=MEIG S: Product=LTE-A Module S: SerialNumber=4da7ec42 C: #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=10 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=10 Prot=02 Driver=(none) E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=03 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=04 Driver=(none) E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=05 Driver=qmi_wwan E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/usb/serial/option.c +10 -5
@@ -621,7 +621,10 @@ static void option_instat_callback(struc/* MeiG Smart Technology products */ #define MEIGSMART_VENDOR_ID 0x2dee -/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ +/* +* MeiG Smart SLM828, SRM815, and SRM825L use the same product ID. SLM828 is +* based on Qualcomm SDX12. SRM815 and SRM825L are based on Qualcomm 315. +*/ #define MEIGSMART_PRODUCT_SRM825L 0x4d22/* MeiG Smart SLM320 based on UNISOC UIS8910 */ #define MEIGSMART_PRODUCT_SLM320 0x4d41
@@ -2405,10 +2408,12 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ .driver_info = NCTRL(1) }, { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
Greg Kroah-Hartman
maintainerPATCH 71/152 USB: serial: option: add Telit Cinterion FN990B compositions
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Porcedda <[email protected]>
commit c979fb5ece2dc11cc9cc3d5c66f750e210bfdee2 upstream.
Add the following Telit Cinterion FN990B40 compositions:
0x10d0: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 17 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10d0 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN990 S: SerialNumber=43b38f19 C: #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x10d1: MBIM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10d1 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN990 S: SerialNumber=43b38f19 C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x10d2: RNDIS + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 18 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10d2 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN990 S: SerialNumber=43b38f19 C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x10d3: ECM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + DPL + QDSS (Qualcomm Debug SubSystem) + adb
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 20 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10d3 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN990 S: SerialNumber=43b38f19 C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/usb/serial/option.c +16 -0
@@ -1406,6 +1406,22 @@ static const struct usb_device_id option .driver_info = RSVD(0) | NCTRL(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */ + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30), + .driver_info = NCTRL(5) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */ + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30), + .driver_info = NCTRL(6) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */ + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30), + .driver_info = NCTRL(6) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */ + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) }, + { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30), + .driver_info = NCTRL(6) }, { 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 72/152 USB: serial: option: fix Telit Cinterion FN990A name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Porcedda <[email protected]>
commit 12606fe73f33647c5e79bf666833bf0b225e649d upstream.
The correct name for FN990 is FN990A so use it in order to avoid confusion with FN990B.
--- drivers/usb/serial/option.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/usb/serial/option.c +5 -5
@@ -1370,15 +1370,15 @@ static const struct usb_device_id option .driver_info = NCTRL(2) | RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ .driver_info = NCTRL(0) | RSVD(1) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */ .driver_info = NCTRL(0) | RSVD(1) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */ .driver_info = NCTRL(2) | RSVD(3) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */ .driver_info = NCTRL(0) | RSVD(1) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */ .driver_info = RSVD(0) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
Greg Kroah-Hartman
maintainerPATCH 73/152 USB: serial: option: drop MeiG Smart defines
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 6aa8a63c471eb6756aabd03f880feffe6a7af6c9 upstream.
Several MeiG Smart modems apparently use the same product id, making the defines even less useful.
Drop them in favour of using comments consistently to make the id table slightly less unwieldy.
--- drivers/usb/serial/option.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-)
drivers/usb/serial/option.c +8 -20
@@ -619,18 +619,6 @@ static void option_instat_callback(struc/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ #define LUAT_PRODUCT_AIR720U 0x4e00 -/* MeiG Smart Technology products */ -#define MEIGSMART_VENDOR_ID 0x2dee -/* -* MeiG Smart SLM828, SRM815, and SRM825L use the same product ID. SLM828 is -* based on Qualcomm SDX12. SRM815 and SRM825L are based on Qualcomm 315. -*/ -#define MEIGSMART_PRODUCT_SRM825L 0x4d22 -/* MeiG Smart SLM320 based on UNISOC UIS8910 */ -#define MEIGSMART_PRODUCT_SLM320 0x4d41 -/* MeiG Smart SLM770A based on ASR1803 */ -#define MEIGSMART_PRODUCT_SLM770A 0x4d57 -/* Device flags */ /* Highest interface number which can be used with NCTRL() and RSVD() */
@@ -2366,6 +2354,14 @@ static const struct usb_device_id option { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
@@ -2422,14 +2418,6 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ - { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ .driver_info = NCTRL(1) }, { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
Greg Kroah-Hartman
maintainerPATCH 74/152 can: ctucanfd: handle skb allocation failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin <[email protected]>
commit 9bd24927e3eeb85642c7baa3b28be8bea6c2a078 upstream.
If skb allocation fails, the pointer to struct can_frame is NULL. This is actually handled everywhere inside ctucan_err_interrupt() except for the only place.
Add the missed NULL check.
Found by Linux Verification Center (linuxtesting.org) with SVACE static analysis tool.
--- drivers/net/can/ctucanfd/ctucanfd_base.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/can/ctucanfd/ctucanfd_base.c +6 -4
@@ -867,10 +867,12 @@ static void ctucan_err_interrupt(struct }break ;case CAN_STATE_ERROR_ACTIVE : - cf->can_id |=CAN_ERR_CNT ; - cf->data[1 ] =CAN_ERR_CRTL_ACTIVE ; - cf->data[6 ] = bec.txerr; - cf->data[7 ] = bec.rxerr; +if (skb) { + cf->can_id |=CAN_ERR_CNT ; + cf->data[1 ] =CAN_ERR_CRTL_ACTIVE ; + cf->data[6 ] = bec.txerr; + cf->data[7 ] = bec.rxerr; + }break ;default : netdev_warn(ndev, "unhandled error state (%d:%s)!\n",
Greg Kroah-Hartman
maintainerPATCH 75/152 can: c_can: fix unbalanced runtime PM disable in error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 257a2cd3eb578ee63d6bf90475dc4f4b16984139 upstream.
Runtime PM is enabled as one of the last steps of probe(), so all earlier gotos to "exit_free_device" label were not correct and were leading to unbalanced runtime PM disable depth.
--- drivers/net/can/c_can/c_can_platform.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/can/c_can/c_can_platform.c +3 -2
@@ -394,15 +394,16 @@ static int c_can_plat_probe(struct platfif (ret) {dev_err (&pdev->dev,"registering %s failed (err=%d)\n" ,KBUILD_MODNAME , ret); - goto exit_free_device; + goto exit_pm_runtime; }dev_info (&pdev->dev,"%s device registered (regs=%p, irq=%d)\n" ,KBUILD_MODNAME , priv->base, dev->irq);return 0 ; -exit_free_device: +exit_pm_runtime:pm_runtime_disable (priv->device); +exit_free_device:free_c_can_dev (dev); exit:dev_err (&pdev->dev,"probe failed\n" );
Greg Kroah-Hartman
maintainerPATCH 76/152 can: j1939: j1939_sk_send_loop(): fix unable to send messages with data length zero
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Hölzl <[email protected]>
commit 44de577e61ed239db09f0da9d436866bef9b77dd upstream.
The J1939 standard requires the transmission of messages of length 0.
For example proprietary messages are specified with a data length of 0 to 1785. The transmission of such messages is not possible. Sending results in no error being returned but no corresponding can frame being generated.
Enable the transmission of zero length J1939 messages. In order to facilitate this two changes are necessary:
1) If the transmission of a new message is requested from user space the message is segmented in j1939_sk_send_loop(). Let the segmentation take into account zero length messages, do not terminate immediately, queue the corresponding skb.
2) j1939_session_skb_get_by_offset() selects the next skb to transmit for a session. Take into account that there might be zero length skbs in the queue.
--- net/can/j1939/socket.c | 4 ++-- net/can/j1939/transport.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-)
net/can/j1939/socket.c +2 -2
@@ -1132,7 +1132,7 @@ static int j1939_sk_send_loop(struct j19 todo_size = size; -while (todo_size) { + do { struct j1939_sk_buff_cb *skcb; segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE,
@@ -1177,7 +1177,7 @@ static int j1939_sk_send_loop(struct j19 todo_size -= segment_size; session->total_queued_size += segment_size; - } + }while (todo_size);switch (ret) {case 0 :/* OK */
net/can/j1939/transport.c +3 -2
@@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset skb_queue_walk(&session->skb_queue, do_skb) { do_skcb =j1939_skb_to_cb (do_skb); -if (offset_start >= do_skcb->offset && - offset_start < (do_skcb->offset + do_skb->len)) { +if ((offset_start >= do_skcb->offset && + offset_start < (do_skcb->offset + do_skb->len)) || + (offset_start ==0 && do_skcb->offset ==0 && do_skb->len ==0 )) { skb = do_skb; } }
Greg Kroah-Hartman
maintainerPATCH 77/152 can: etas_es58x: fix potential NULL pointer dereference on udev->serial
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Mailhol <[email protected]>
commit a1ad2109ce41c9e3912dadd07ad8a9c640064ffb upstream.
The driver assumed that es58x_dev->udev->serial could never be NULL. While this is true on commercially available devices, an attacker could spoof the device identity providing a NULL USB serial number. That would trigger a NULL pointer dereference.
Add a check on es58x_dev->udev->serial before accessing it.
--- drivers/net/can/usb/etas_es58x/es58x_devlink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/can/usb/etas_es58x/es58x_devlink.c +5 -1
@@ -248,7 +248,11 @@ static int es58x_devlink_info_get(structreturn ret; } -return devlink_info_serial_number_put (req, es58x_dev->udev->serial); +if (es58x_dev->udev->serial) + ret =devlink_info_serial_number_put (req, + es58x_dev->udev->serial); + +return ret; }const struct devlink_ops es58x_dl_ops = {
Greg Kroah-Hartman
maintainerPATCH 78/152 alpha: make stack 16-byte aligned (most cases)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Kokshaysky <[email protected]>
commit 0a0f7362b0367634a2d5cb7c96226afc116f19c9 upstream.
The problem is that GCC expects 16-byte alignment of the incoming stack since early 2004, as Maciej found out [1]:
Having actually dug speculatively I can see that the psABI was changed in
GCC 3.5 with commit e5e10fb4a350 ("re PR target/14539 (128-bit long double improperly aligned)") back in Mar 2004, when the stack pointer alignment was increased from 8 bytes to 16 bytes, and arch/alpha/kernel/entry.S has various suspicious stack pointer adjustments, starting with SP_OFF which is not a whole multiple of 16.
Also, as Magnus noted, "ALPHA Calling Standard" [2] required the same:
D.3.1 Stack Alignment
This standard requires that stacks be octaword aligned at the time a new procedure is invoked.
However:
- the "normal" kernel stack is always misaligned by 8 bytes, thanks to the odd number of 64-bit words in 'struct pt_regs', which is the very first thing pushed onto the kernel thread stack;
- syscall, fault, interrupt etc. handlers may, or may not, receive aligned stack depending on numerous factors.
Somehow we got away with it until recently, when we ended up with a stack corruption in kernel/smp.c:smp_call_function_single() due to its use of 32-byte aligned local data and the compiler doing clever things allocating it on the stack.
This adds padding between the PAL-saved and kernel-saved registers so that 'struct pt_regs' have an even number of 64-bit words. This makes the stack properly aligned for most of the kernel code, except two handlers which need special threatment.
Note: struct pt_regs doesn't belong in uapi/asm; this should be fixed, but let's put this off until later.
--- arch/alpha/include/uapi/asm/ptrace.h | 2 ++ 1 file changed, 2 insertions(+)
arch/alpha/include/uapi/asm/ptrace.h +2 -0
@@ -42,6 +42,8 @@ struct pt_regs {unsigned long trap_a0;unsigned long trap_a1;unsigned long trap_a2; +/* This makes the stack 16-byte aligned as GCC expects */ +unsigned long __pad0;/* These are saved by PAL-code: */ unsigned long ps;unsigned long pc;
Greg Kroah-Hartman
maintainerPATCH 79/152 wifi: ath12k: fix handling of 6 GHz rules
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Kumar Singh <[email protected]>
commit 64a1ba4072b34af1b76bf15fca5c2075b8cc4d64 upstream.
In the US country code, to avoid including 6 GHz rules in the 5 GHz rules list, the number of 5 GHz rules is set to a default constant value of 4 (REG_US_5G_NUM_REG_RULES). However, if there are more than 4 valid 5 GHz rules, the current logic will bypass the legitimate 6 GHz rules.
For example, if there are 5 valid 5 GHz rules and 1 valid 6 GHz rule, the current logic will only consider 4 of the 5 GHz rules, treating the last valid rule as a 6 GHz rule. Consequently, the actual 6 GHz rule is never processed, leading to the eventual disabling of 6 GHz channels.
To fix this issue, instead of hardcoding the value to 4, use a helper function to determine the number of 6 GHz rules present in the 5 GHz rules list and ignore only those rules.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath12k/wmi.c | 61 +++++++++++++++++++++++++--------- drivers/net/wireless/ath/ath12k/wmi.h | 1 2 files changed, 45 insertions(+), 17 deletions(-)
drivers/net/wireless/ath/ath12k/wmi.c +45 -16
@@ -4418,6 +4418,22 @@ static struct ath12k_reg_rulereturn reg_rule_ptr; } +static u8 ath12k_wmi_ignore_num_extra_rules (struct ath12k_wmi_reg_rule_ext_params *rule, +u32 num_reg_rules) +{ +u8 num_invalid_5ghz_rules =0 ; +u32 count, start_freq; + +for (count =0 ; count < num_reg_rules; count++) { + start_freq =le32_get_bits (rule[count].freq_info,REG_RULE_START_FREQ ); + +if (start_freq >=ATH12K_MIN_6G_FREQ ) + num_invalid_5ghz_rules++; + } + +return num_invalid_5ghz_rules; +} +static int ath12k_pull_reg_chan_list_ext_update_ev (struct ath12k_base *ab,struct sk_buff *skb,struct ath12k_reg_info *reg_info)
@@ -4428,6 +4444,7 @@ static int ath12k_pull_reg_chan_list_extu32 num_2g_reg_rules, num_5g_reg_rules;u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE ];u32 num_6g_reg_rules_cl[WMI_REG_CURRENT_MAX_AP_TYPE ][WMI_REG_MAX_CLIENT_TYPE ]; +u8 num_invalid_5ghz_ext_rules;u32 total_reg_rules =0 ;int ret, i, j;
@@ -4521,20 +4538,6 @@ static int ath12k_pull_reg_chan_list_extmemcpy (reg_info->alpha2, &ev->alpha2,REG_ALPHA2_LEN ); -/* FIXME: Currently FW includes 6G reg rule also in 5G rule -* list for country US. -* Having same 6G reg rule in 5G and 6G rules list causes -* intersect check to be true, and same rules will be shown -* multiple times in iw cmd. So added hack below to avoid -* parsing 6G rule from 5G reg rule list, and this can be -* removed later, after FW updates to remove 6G reg rule -* from 5G rules list. -*/ -if (memcmp (reg_info->alpha2,"US" ,2 ) ==0 ) { - reg_info->num_5g_reg_rules =REG_US_5G_NUM_REG_RULES ; - num_5g_reg_rules = reg_info->num_5g_reg_rules; - } - reg_info->dfs_region =le32_to_cpu (ev->dfs_region); reg_info->phybitmap =le32_to_cpu (ev->phybitmap); reg_info->num_phy =le32_to_cpu (ev->num_phy);
@@ -4636,8 +4639,29 @@ static int ath12k_pull_reg_chan_list_ext } } + ext_wmi_reg_rule += num_2g_reg_rules; + +/* Firmware might include 6 GHz reg rule in 5 GHz rule list +* for few countries along with separate 6 GHz rule. +* Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list +* causes intersect check to be true, and same rules will be +* shown multiple times in iw cmd. +* Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list +*/ + num_invalid_5ghz_ext_rules =ath12k_wmi_ignore_num_extra_rules (ext_wmi_reg_rule, + num_5g_reg_rules); + +if (num_invalid_5ghz_ext_rules) { +ath12k_dbg (ab,ATH12K_DBG_WMI , +"CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules" , + reg_info->alpha2, reg_info->num_5g_reg_rules, + num_invalid_5ghz_ext_rules); + + num_5g_reg_rules = num_5g_reg_rules - num_invalid_5ghz_ext_rules; + reg_info->num_5g_reg_rules = num_5g_reg_rules; + } +if (num_5g_reg_rules) { - ext_wmi_reg_rule += num_2g_reg_rules; reg_info->reg_rules_5g_ptr =create_ext_reg_rules_from_wmi (num_5g_reg_rules, ext_wmi_reg_rule);
@@ -4649,7 +4673,12 @@ static int ath12k_pull_reg_chan_list_ext } } - ext_wmi_reg_rule += num_5g_reg_rules; +/* We have adjusted the number of 5 GHz reg rules above. But still those +* many rules needs to be adjusted in ext_wmi_reg_rule. +* +* NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. +*/ + ext_wmi_reg_rule += (num_5g_reg_rules + num_invalid_5ghz_ext_rules);for (i =0 ; i <WMI_REG_CURRENT_MAX_AP_TYPE ; i++) { reg_info->reg_rules_6g_ap_ptr[i] =
drivers/net/wireless/ath/ath12k/wmi.h +0 -1
@@ -3891,7 +3891,6 @@ struct ath12k_wmi_eht_rate_set_params {#define MAX_REG_RULES 10#define REG_ALPHA2_LEN 2#define MAX_6G_REG_RULES 5 -#define REG_US_5G_NUM_REG_RULES 4enum wmi_start_event_param {WMI_VDEV_START_RESP_EVENT =0 ,
Greg Kroah-Hartman
maintainerPATCH 80/152 kbuild: userprogs: fix bitsize and target detection on clang
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 1b71c2fb04e7a713abc6edde4a412416ff3158f2 upstream.
scripts/Makefile.clang was changed in the linked commit to move --target from KBUILD_CFLAGS to KBUILD_CPPFLAGS, as that generally has a broader scope. However that variable is not inspected by the userprogs logic, breaking cross compilation on clang.
Use both variables to detect bitsize and target arguments for userprogs.
--- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Makefile +2 -2
@@ -1054,8 +1054,8 @@ LDFLAGS_vmlinux += --orphan-handling=$(C endif # Align the bit size of userspace programs with the kernel -KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) -KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) +KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) +KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) # make the checker run with the right architecture CHECKFLAGS += --arch=$(ARCH)
Greg Kroah-Hartman
maintainerPATCH 81/152 efi: Avoid cold plugged memory for placing the kernel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit ba69e0750b0362870294adab09339a0c39c3beaf upstream.
UEFI 2.11 introduced EFI_MEMORY_HOT_PLUGGABLE to annotate system memory regions that are 'cold plugged' at boot, i.e., hot pluggable memory that is available from early boot, and described as system RAM by the firmware.
Existing loaders and EFI applications running in the boot context will happily use this memory for allocating data structures that cannot be freed or moved at runtime, and this prevents the memory from being unplugged. Going forward, the new EFI_MEMORY_HOT_PLUGGABLE attribute should be tested, and memory annotated as such should be avoided for such allocations.
In the EFI stub, there are a couple of occurrences where, instead of the high-level AllocatePages() UEFI boot service, a low-level code sequence is used that traverses the EFI memory map and carves out the requested number of pages from a free region. This is needed, e.g., for allocating as low as possible, or for allocating pages at random.
While AllocatePages() should presumably avoid special purpose memory and cold plugged regions, this manual approach needs to incorporate this logic itself, in order to prevent the kernel itself from ending up in a hot unpluggable region, preventing it from being unplugged.
So add the EFI_MEMORY_HOTPLUGGABLE macro definition, and check for it where appropriate.
--- drivers/firmware/efi/efi.c | 6 ++++-- drivers/firmware/efi/libstub/randomalloc.c | 3 +++ drivers/firmware/efi/libstub/relocate.c | 3 +++ include/linux/efi.h | 1 + 4 files changed, 11 insertions(+), 2 deletions(-)
drivers/firmware/efi/efi.c +4 -2
@@ -908,13 +908,15 @@ char * __init efi_md_typeattr_format(chaEFI_MEMORY_WB |EFI_MEMORY_UCE |EFI_MEMORY_RO |EFI_MEMORY_WP |EFI_MEMORY_RP |EFI_MEMORY_XP |EFI_MEMORY_NV |EFI_MEMORY_SP |EFI_MEMORY_CPU_CRYPTO | - EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) +EFI_MEMORY_MORE_RELIABLE |EFI_MEMORY_HOT_PLUGGABLE | + EFI_MEMORY_RUNTIME)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else snprintf(pos, size, -"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]" , +"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]" , attr &EFI_MEMORY_RUNTIME ?"RUN" :"" , + attr &EFI_MEMORY_HOT_PLUGGABLE ?"HP" :"" , attr &EFI_MEMORY_MORE_RELIABLE ?"MR" :"" , attr &EFI_MEMORY_CPU_CRYPTO ?"CC" :"" , attr & EFI_MEMORY_SP ? "SP" : "",
drivers/firmware/efi/libstub/randomalloc.c +3 -0
@@ -25,6 +25,9 @@ static unsigned long get_entry_num_slotsif (md->type !=EFI_CONVENTIONAL_MEMORY )return 0 ; +if (md->attribute &EFI_MEMORY_HOT_PLUGGABLE ) +return 0 ; +if (efi_soft_reserve_enabled () && (md->attribute &EFI_MEMORY_SP ))return 0 ;
drivers/firmware/efi/libstub/relocate.c +3 -0
@@ -53,6 +53,9 @@ efi_status_t efi_low_alloc_above(unsigneif (desc->type !=EFI_CONVENTIONAL_MEMORY )continue ; +if (desc->attribute &EFI_MEMORY_HOT_PLUGGABLE ) +continue ; +if (efi_soft_reserve_enabled () && (desc->attribute &EFI_MEMORY_SP ))continue ;
include/linux/efi.h +1 -0
@@ -127,6 +127,7 @@ typedef struct {#define EFI_MEMORY_RO ((u64)0x0000000000020000ULL)/* read-only */ #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL)/* soft reserved */ #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL)/* supports encryption */ +#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20)/* supports unplugging at runtime */ #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL)/* range requires runtime mapping */ #define EFI_MEMORY_DESCRIPTOR_VERSION 1
Greg Kroah-Hartman
maintainerPATCH 82/152 cgroup: fix race between fork and cgroup.kill
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shakeel Butt <[email protected]>
commit b69bb476dee99d564d65d418e9a20acca6f32c3f upstream.
Tejun reported the following race between fork() and cgroup.kill at [1].
Tejun:
I was looking at cgroup.kill implementation and wondering whether there could be a race window. So, __cgroup_kill() does the following:
k1. Set CGRP_KILL.
k2. Iterate tasks and deliver SIGKILL.
k3. Clear CGRP_KILL.
The copy_process() does the following:
c1. Copy a bunch of stuff.
c2. Grab siglock.
c3. Check fatal_signal_pending().
c4. Commit to forking.
c5. Release siglock.
c6. Call cgroup_post_fork() which puts the task on the css_set and tests
CGRP_KILL.
The intention seems to be that either a forking task gets SIGKILL and terminates on c3 or it sees CGRP_KILL on c6 and kills the child. However, I don't see what guarantees that k3 can't happen before c6. ie. After a forking task passes c5, k2 can take place and then before the forking task reaches c6, k3 can happen. Then, nobody would send SIGKILL to the child. What am I missing?
This is indeed a race. One way to fix this race is by taking cgroup_threadgroup_rwsem in write mode in __cgroup_kill() as the fork() side takes cgroup_threadgroup_rwsem in read mode from cgroup_can_fork() to cgroup_post_fork(). However that would be heavy handed as this adds one more potential stall scenario for cgroup.kill which is usually called under extreme situation like memory pressure.
To fix this race, let's maintain a sequence number per cgroup which gets incremented on __cgroup_kill() call. On the fork() side, the cgroup_can_fork() will cache the sequence number locally and recheck it against the cgroup's sequence number at cgroup_post_fork() site. If the sequence numbers mismatch, it means __cgroup_kill() can been called and we should send SIGKILL to the newly created task.
--- include/linux/cgroup-defs.h | 6 +++--- include/linux/sched/task.h | 1 + kernel/cgroup/cgroup.c | 20 ++++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-)
include/linux/cgroup-defs.h +3 -3
@@ -71,9 +71,6 @@ enum {/* Cgroup is frozen. */ CGRP_FROZEN, - -/* Control group has to be killed. */ - CGRP_KILL, };/* cgroup_root->flags */
@@ -438,6 +435,9 @@ struct cgroup {int nr_threaded_children;/* # of live threaded child cgroups */ +/* sequence number for cgroup.kill, serialized by css_set_lock. */ +unsigned int kill_seq; +struct kernfs_node *kn;/* cgroup kernfs entry */ struct cgroup_file procs_file;/* handle for "cgroup.procs" */ struct cgroup_file events_file;/* handle for "cgroup.events" */
include/linux/sched/task.h +1 -0
@@ -41,6 +41,7 @@ struct kernel_clone_args {void *fn_arg;struct cgroup *cgrp;struct css_set *cset; +unsigned int kill_seq; };/*
kernel/cgroup/cgroup.c +12 -8
@@ -3941,7 +3941,7 @@ static void __cgroup_kill(struct cgrouplockdep_assert_held (&cgroup_mutex);spin_lock_irq (&css_set_lock); -set_bit (CGRP_KILL , &cgrp->flags); + cgrp->kill_seq++;spin_unlock_irq (&css_set_lock);css_task_iter_start (&cgrp->self,CSS_TASK_ITER_PROCS |CSS_TASK_ITER_THREADED , &it);
@@ -3957,10 +3957,6 @@ static void __cgroup_kill(struct cgroupsend_sig (SIGKILL , task,0 ); }css_task_iter_end (&it); - -spin_lock_irq (&css_set_lock); -clear_bit (CGRP_KILL , &cgrp->flags); -spin_unlock_irq (&css_set_lock); }static void cgroup_kill (struct cgroup *cgrp)
@@ -6399,6 +6395,10 @@ static int cgroup_css_set_fork(struct kespin_lock_irq (&css_set_lock); cset =task_css_set (current);get_css_set (cset); +if (kargs->cgrp) + kargs->kill_seq = kargs->cgrp->kill_seq; +else + kargs->kill_seq = cset->dfl_cgrp->kill_seq;spin_unlock_irq (&css_set_lock);if (!(kargs->flags &CLONE_INTO_CGROUP )) {
@@ -6582,6 +6582,7 @@ void cgroup_post_fork(struct task_struct struct kernel_clone_args *kargs) __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex) { + unsigned int cgrp_kill_seq = 0; unsigned long cgrp_flags = 0; bool kill = false; struct cgroup_subsys *ss;
@@ -6595,10 +6596,13 @@ void cgroup_post_fork(struct task_struct/* init tasks are special, only link regular threads */ if (likely (child->pid)) { -if (kargs->cgrp) +if (kargs->cgrp) { cgrp_flags = kargs->cgrp->flags; -else + cgrp_kill_seq = kargs->cgrp->kill_seq; + }else { cgrp_flags = cset->dfl_cgrp->flags; + cgrp_kill_seq = cset->dfl_cgrp->kill_seq; + }WARN_ON_ONCE (!list_empty (&child->cg_list)); cset->nr_tasks++;
@@ -6633,7 +6637,7 @@ void cgroup_post_fork(struct task_struct* child down right after we finished preparing it for * userspace. */ - kill =test_bit (CGRP_KILL , &cgrp_flags); + kill = kargs->kill_seq != cgrp_kill_seq; }spin_unlock_irq (&css_set_lock);
Greg Kroah-Hartman
maintainerPATCH 83/152 serial: port: Assign ->iotype correctly when ->iobase is set
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 166ac2bba167d575e7146beaa66093bc7c072f43 upstream.
Currently the ->iotype is always assigned to the UPIO_MEM when the respective property is not found. However, this will not support the cases when user wants to have UPIO_PORT to be set or preserved. Support this scenario by checking ->iobase value and default the ->iotype respectively.
--- drivers/tty/serial/serial_port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/serial_port.c +2 -1
@@ -172,6 +172,7 @@ EXPORT_SYMBOL(uart_remove_one_port);* The caller is responsible to initialize the following fields of the @port * ->dev (must be valid) * ->flags +* ->iobase * ->mapbase * ->mapsize * ->regshift (if @use_defaults is false)
@@ -213,7 +214,7 @@ static int __uart_read_properties(struct/* Read the registers I/O access type (default: MMIO 8-bit) */ ret =device_property_read_u32 (dev,"reg-io-width" , &value);if (ret) { - port->iotype =UPIO_MEM ; + port->iotype = port->iobase ?UPIO_PORT :UPIO_MEM ; }else {switch (value) {case 1 :
Greg Kroah-Hartman
maintainerPATCH 84/152 serial: port: Always update ->iotype in __uart_read_properties()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit e8486bd50ecf63c9a1e25271f258a8d959f2672f upstream.
The documentation of the __uart_read_properties() states that ->iotype member is always altered after the function call, but the code doesn't do that in the case when use_defaults == false and the value of reg-io-width is unsupported. Make sure the code follows the documentation.
Note, the current users of the uart_read_and_validate_port_properties() will fail and the change doesn't affect their behaviour, neither users of uart_read_port_properties() will be affected since the alteration happens there even in the current code flow.
--- drivers/tty/serial/serial_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/serial_port.c +1 -1
@@ -227,11 +227,11 @@ static int __uart_read_properties(struct port->iotype =device_is_big_endian (dev) ?UPIO_MEM32BE :UPIO_MEM32 ;break ;default : + port->iotype =UPIO_UNKNOWN ;if (!use_defaults) {dev_err (dev,"Unsupported reg-io-width (%u)\n" , value);return -EINVAL ; } - port->iotype =UPIO_UNKNOWN ;break ; } }
Greg Kroah-Hartman
maintainerPATCH 85/152 serial: 8250: Fix fifo underflow on flush
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
commit 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 upstream.
When flushing the serial port's buffer, uart_flush_buffer() calls kfifo_reset() but if there is an outstanding DMA transfer then the completion function will consume data from the kfifo via uart_xmit_advance(), underflowing and leading to ongoing DMA as the driver tries to transmit another 2^32 bytes.
This is readily reproduced with serial-generic and amidi sending even short messages as closing the device on exit will wait for the fifo to drain and in the underflow case amidi hangs for 30 seconds on exit in tty_wait_until_sent(). A trace of that gives:
kworker/1:1-84 [001] 51.769423: bprint: serial8250_tx_dma: tx_size=3 fifo_len=3
amidi-763 [001] 51.769460: bprint: uart_flush_buffer: resetting fifo
irq/21-fe530000-76 [000] 51.769474: bprint: __dma_tx_complete: tx_size=3
irq/21-fe530000-76 [000] 51.769479: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294967293
irq/21-fe530000-76 [000] 51.781295: bprint: __dma_tx_complete: tx_size=4096
irq/21-fe530000-76 [000] 51.781301: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294963197
irq/21-fe530000-76 [000] 51.793131: bprint: __dma_tx_complete: tx_size=4096
irq/21-fe530000-76 [000] 51.793135: bprint: serial8250_tx_dma: tx_size=4096 fifo_len=4294959101
irq/21-fe530000-76 [000] 51.804949: bprint: __dma_tx_complete: tx_size=4096Since the port lock is held in when the kfifo is reset in uart_flush_buffer() and in __dma_tx_complete(), adding a flush_buffer hook to adjust the outstanding DMA byte count is sufficient to avoid the kfifo underflow.
--- drivers/tty/serial/8250/8250.h | 2 ++ drivers/tty/serial/8250/8250_dma.c | 16 ++++++++++++++++ drivers/tty/serial/8250/8250_port.c | 9 +++++++++ 3 files changed, 27 insertions(+)
drivers/tty/serial/8250/8250.h +2 -0
@@ -350,6 +350,7 @@ static inline int is_omap1510_8250(struc#ifdef CONFIG_SERIAL_8250_DMA extern int serial8250_tx_dma (struct uart_8250_port *); +extern void serial8250_tx_dma_flush (struct uart_8250_port *);extern int serial8250_rx_dma (struct uart_8250_port *);extern void serial8250_rx_dma_flush (struct uart_8250_port *);extern int serial8250_request_dma (struct uart_8250_port *);
@@ -382,6 +383,7 @@ static inline int serial8250_tx_dma(stru {return -1 ; } +static inline void serial8250_tx_dma_flush (struct uart_8250_port *p) { }static inline int serial8250_rx_dma (struct uart_8250_port *p) {return -1 ;
drivers/tty/serial/8250/8250_dma.c +16 -0
@@ -139,6 +139,22 @@ err:return ret; } +void serial8250_tx_dma_flush (struct uart_8250_port *p) +{ +struct uart_8250_dma *dma = p->dma; + +if (!dma->tx_running) +return ; + +/* +* kfifo_reset() has been called by the serial core, avoid +* advancing and underflowing in __dma_tx_complete(). +*/ + dma->tx_size =0 ; + +dmaengine_terminate_async (dma->rxchan); +} +int serial8250_rx_dma (struct uart_8250_port *p) {struct uart_8250_dma *dma = p->dma;
drivers/tty/serial/8250/8250_port.c +9 -0
@@ -2557,6 +2557,14 @@ static unsigned int npcm_get_divisor(strreturn DIV_ROUND_CLOSEST (port->uartclk,16 * baud +2 ) -2 ; } +static void serial8250_flush_buffer (struct uart_port *port) +{ +struct uart_8250_port *up =up_to_u8250p (port); + +if (up->dma) +serial8250_tx_dma_flush (up); +} +static unsigned int serial8250_do_get_divisor (struct uart_port *port,unsigned int baud,unsigned int *frac)
@@ -3260,6 +3268,7 @@ static const struct uart_ops serial8250_ .break_ctl = serial8250_break_ctl, .startup = serial8250_startup, .shutdown = serial8250_shutdown, + .flush_buffer = serial8250_flush_buffer, .set_termios = serial8250_set_termios, .set_ldisc = serial8250_set_ldisc, .pm = serial8250_pm,
Greg Kroah-Hartman
maintainerPATCH 86/152 alpha: align stack for page fault and user unaligned trap handlers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Kokshaysky <[email protected]>
commit 3b35a171060f846b08b48646b38c30b5d57d17ff upstream.
do_page_fault() and do_entUna() are special because they use non-standard stack frame layout. Fix them manually.
--- arch/alpha/kernel/entry.S | 20 ++++++++++---------- arch/alpha/kernel/traps.c | 2 +- arch/alpha/mm/fault.c | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-)
arch/alpha/kernel/entry.S +10 -10
@@ -198,8 +198,8 @@ CFI_END_OSF_FRAME entArith CFI_START_OSF_FRAME entMM SAVE_ALL /* save $9 - $15 so the inline exception code can manipulate them. */ - subq $sp, 56, $sp - .cfi_adjust_cfa_offset 56 + subq $sp, 64, $sp + .cfi_adjust_cfa_offset 64 stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp)
@@ -214,7 +214,7 @@ CFI_START_OSF_FRAME entMM .cfi_rel_offset $13, 32 .cfi_rel_offset $14, 40 .cfi_rel_offset $15, 48 - addq $sp, 56, $19 + addq $sp, 64, $19 /* handle the fault */ lda $8, 0x3fff bic $sp, $8, $8
@@ -227,7 +227,7 @@ CFI_START_OSF_FRAME entMM ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) - addq $sp, 56, $sp + addq $sp, 64, $sp .cfi_restore $9 .cfi_restore $10 .cfi_restore $11
@@ -235,7 +235,7 @@ CFI_START_OSF_FRAME entMM .cfi_restore $13 .cfi_restore $14 .cfi_restore $15 - .cfi_adjust_cfa_offset -56 + .cfi_adjust_cfa_offset -64 /* finish up the syscall as normal. */ br ret_from_sys_call CFI_END_OSF_FRAME entMM
@@ -382,8 +382,8 @@ entUnaUser: .cfi_restore $0 .cfi_adjust_cfa_offset -256 SAVE_ALL /* setup normal kernel stack */ - lda $sp, -56($sp) - .cfi_adjust_cfa_offset 56 + lda $sp, -64($sp) + .cfi_adjust_cfa_offset 64 stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp)
@@ -399,7 +399,7 @@ entUnaUser: .cfi_rel_offset $14, 40 .cfi_rel_offset $15, 48 lda $8, 0x3fff - addq $sp, 56, $19 + addq $sp, 64, $19 bic $sp, $8, $8 jsr $26, do_entUnaUser ldq $9, 0($sp)
@@ -409,7 +409,7 @@ entUnaUser: ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) - lda $sp, 56($sp) + lda $sp, 64($sp) .cfi_restore $9 .cfi_restore $10 .cfi_restore $11
@@ -417,7 +417,7 @@ entUnaUser: .cfi_restore $13 .cfi_restore $14 .cfi_restore $15 - .cfi_adjust_cfa_offset -56 + .cfi_adjust_cfa_offset -64 br ret_from_sys_call CFI_END_OSF_FRAME entUna
arch/alpha/kernel/traps.c +1 -1
@@ -707,7 +707,7 @@ s_reg_to_mem (unsigned long s_reg)static int unauser_reg_offsets[32 ] = {R (r0),R (r1),R (r2),R (r3),R (r4),R (r5),R (r6),R (r7),R (r8),/* r9 ... r15 are stored in front of regs. */ --56 ,-48 ,-40 ,-32 ,-24 ,-16 ,-8 , +-64 ,-56 ,-48 ,-40 ,-32 ,-24 ,-16 ,/* padding at -8 */ R (r16),R (r17),R (r18),R (r19),R (r20),R (r21),R (r22),R (r23),R (r24),R (r25),R (r26),R (r27),R (r28),R (gp),
arch/alpha/mm/fault.c +2 -2
@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct */* Macro for exception fixup code to access integer registers. */ #define dpf_reg (r) \ - (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ - (r) <= 18 ? (r)+10 : (r)-10]) + (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \ + (r) <= 18 ? (r)+11 : (r)-10]) asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
Greg Kroah-Hartman
maintainerPATCH 87/152 gpiolib: acpi: Add a quirk for Acer Nitro ANV14
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 8743d66979e494c5378563e6b5a32e913380abd8 upstream.
Spurious immediate wake up events are reported on Acer Nitro ANV14. GPIO 11 is specified as an edge triggered input and also a wake source but this pin is supposed to be an output pin for an LED, so it's effectively floating.
Block the interrupt from getting set up for this GPIO on this device.
--- drivers/gpio/gpiolib-acpi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/gpio/gpiolib-acpi.c +14 -0
@@ -1706,6 +1706,20 @@ static const struct dmi_system_id gpioli .ignore_wake = "PNP0C50:00@8", }, }, + { + /* + * Spurious wakeups from GPIO 11 + * Found in BIOS 1.04 + * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_interrupt = "AMDI0030:00@11", + }, + }, {} /* Terminating entry */ };
Greg Kroah-Hartman
maintainerPATCH 88/152 gpio: stmpe: Check return value of stmpe_reg_read in stmpe_gpio_irq_sync_unlock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit b9644fbfbcab13da7f8b37bef7c51e5b8407d031 upstream.
The stmpe_reg_read function can fail, but its return value is not checked in stmpe_gpio_irq_sync_unlock. This can lead to silent failures and incorrect behavior if the hardware access fails.
This patch adds checks for the return value of stmpe_reg_read. If the function fails, an error message is logged and the function returns early to avoid further issues.
--- drivers/gpio/gpio-stmpe.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/gpio/gpio-stmpe.c +12 -3
@@ -191,7 +191,7 @@ static void stmpe_gpio_irq_sync_unlock(s [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, }; -int i, j; +int ret, i, j;/* * STMPE1600: to be able to get IRQ from pins,
@@ -199,8 +199,16 @@ static void stmpe_gpio_irq_sync_unlock(s* GPSR or GPCR registers */ if (stmpe->partnum ==STMPE1600 ) { -stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB ]); -stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB ]); + ret =stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB ]); +if (ret <0 ) { +dev_err (stmpe->dev,"Failed to read GPMR_LSB: %d\n" , ret); + goto err; + } + ret =stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB ]); +if (ret <0 ) { +dev_err (stmpe->dev,"Failed to read GPMR_CSB: %d\n" , ret); + goto err; + } }for (i =0 ; i <CACHE_NR_REGS ; i++) {
@@ -222,6 +230,7 @@ static void stmpe_gpio_irq_sync_unlock(s } } +err:mutex_unlock (&stmpe_gpio->irq_lock); }
Greg Kroah-Hartman
maintainerPATCH 89/152 partitions: mac: fix handling of bogus partition table
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 80e648042e512d5a767da251d44132553fe04ae0 upstream.
Fix several issues in partition probing:
- The bailout for a bad partoffset must use put_dev_sector(), since the preceding read_part_sector() succeeded.
- If the partition table claims a silly sector size like 0xfff bytes (which results in partition table entries straddling sector boundaries), bail out instead of accessing out-of-bounds memory.
- We must not assume that the partition table contains proper NUL termination - use strnlen() and strncmp() instead of strlen() and strcmp().
--- block/partitions/mac.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
block/partitions/mac.c +15 -3
@@ -51,13 +51,25 @@ int mac_partition(struct parsed_partitio } secsize =be16_to_cpu (md->block_size);put_dev_sector (sect); + +/* +* If the "block size" is not a power of 2, things get weird - we might +* end up with a partition straddling a sector boundary, so we wouldn't +* be able to read a partition entry with read_part_sector(). +* Real block sizes are probably (?) powers of two, so just require +* that. +*/ +if (!is_power_of_2 (secsize)) +return -1 ; datasize =round_down (secsize,512 ); data =read_part_sector (state, datasize /512 , §);if (!data)return -1 ; partoffset = secsize %512 ; -if (partoffset +sizeof (*part) > datasize) +if (partoffset +sizeof (*part) > datasize) { +put_dev_sector (sect);return -1 ; + } part = (struct mac_partition *) (data + partoffset);if (be16_to_cpu (part->signature) !=MAC_PARTITION_MAGIC ) {put_dev_sector (sect);
@@ -110,8 +122,8 @@ int mac_partition(struct parsed_partitioint i, l; goodness++; - l =strlen (part->name); -if (strcmp (part->name,"/" ) ==0 ) + l =strnlen (part->name,sizeof (part->name)); +if (strncmp (part->name,"/" ,sizeof (part->name)) ==0 ) goodness++;for (i =0 ; i <= l -4 ; ++i) { if (strncasecmp(part->name + i, "root",
Greg Kroah-Hartman
maintainerPATCH 90/152 regulator: qcom_smd: Add l2, l5 sub-node to mp5496 regulator
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
commit b0eddc21900fb44f8c5db95710479865e3700fbd upstream.
Adding l2, l5 sub-node entry to mp5496 regulator node.
--- Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +1 -1
@@ -22,7 +22,7 @@ description: Each sub-node is identified using the node's name, with valid values listed for each of the pmics below. - For mp5496, s1, s2 + For mp5496, s1, s2, l2, l5 For pm2250, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22
Greg Kroah-Hartman
maintainerPATCH 91/152 regmap-irq: Add missing kfree()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
commit 32ffed055dcee17f6705f545b069e44a66067808 upstream.
Add kfree() for "d->main_status_buf" to the error-handling path to prevent a memory leak.
--- drivers/base/regmap/regmap-irq.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/base/regmap/regmap-irq.c +2 -0
@@ -894,6 +894,7 @@ err_alloc:kfree (d->wake_buf);kfree (d->mask_buf_def);kfree (d->mask_buf); +kfree (d->main_status_buf);kfree (d->status_buf);kfree (d->status_reg_buf);if (d->config_buf) {
@@ -969,6 +970,7 @@ void regmap_del_irq_chip(int irq, structkfree (d->wake_buf);kfree (d->mask_buf_def);kfree (d->mask_buf); +kfree (d->main_status_buf);kfree (d->status_reg_buf);kfree (d->status_buf);if (d->config_buf) {
Greg Kroah-Hartman
maintainerPATCH 92/152 arm64: Handle .ARM.attributes section in linker scripts
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit ca0f4fe7cf7183bfbdc67ca2de56ae1fc3a8db2b upstream.
A recent LLVM commit [1] started generating an .ARM.attributes section similar to the one that exists for 32-bit, which results in orphan section warnings (or errors if CONFIG_WERROR is enabled) from the linker because it is not handled in the arm64 linker scripts.
ld.lld: error: arch/arm64/kernel/vdso/vgettimeofday.o:(.ARM.attributes) is being placed in '.ARM.attributes' ld.lld: error: arch/arm64/kernel/vdso/vgetrandom.o:(.ARM.attributes) is being placed in '.ARM.attributes'
ld.lld: error: vmlinux.a(lib/vsprintf.o):(.ARM.attributes) is being placed in '.ARM.attributes' ld.lld: error: vmlinux.a(lib/win_minmax.o):(.ARM.attributes) is being placed in '.ARM.attributes' ld.lld: error: vmlinux.a(lib/xarray.o):(.ARM.attributes) is being placed in '.ARM.attributes'
Discard the new sections in the necessary linker scripts to resolve the warnings, as the kernel and vDSO do not need to retain it, similar to the .note.gnu.property section.
--- arch/arm64/kernel/vdso/vdso.lds.S | 1 + arch/arm64/kernel/vmlinux.lds.S | 1 + 2 files changed, 2 insertions(+)
arch/arm64/kernel/vdso/vdso.lds.S +1 -0
@@ -38,6 +38,7 @@ SECTIONS */ /DISCARD/ : { *(.note.GNU-stack .note.gnu.property) + *(.ARM.attributes) } .note : { *(.note.*) } :text :note
arch/arm64/kernel/vmlinux.lds.S +1 -0
@@ -162,6 +162,7 @@ SECTIONS /DISCARD/ : { *(.interp .dynamic) *(.dynsym .dynstr .hash .gnu.hash) + *(.ARM.attributes) } . = KIMAGE_VADDR;
Greg Kroah-Hartman
maintainerPATCH 93/152 mmc: mtk-sd: Fix register settings for hs400(es) mode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy-ld Lu <[email protected]>
commit 3e68abf2b9cebe76c6cd4b1aca8e95cd671035a3 upstream.
For hs400(es) mode, the 'hs400-ds-delay' is typically configured in the dts. However, some projects may only define 'mediatek,hs400-ds-dly3', which can lead to initialization failures in hs400es mode. CMD13 reported response crc error in the mmc_switch_status() just after switching to hs400es mode.
[ 1.914038][ T82] mmc0: mmc_select_hs400es failed, error -84 [ 1.914954][ T82] mmc0: error -84 whilst initialising MMC card
Currently, the hs400_ds_dly3 value is set within the tuning function. This means that the PAD_DS_DLY3 field is not configured before tuning process, which is the reason for the above-mentioned CMD13 response crc error.
Move the PAD_DS_DLY3 field configuration into msdc_prepare_hs400_tuning(), and add a value check of hs400_ds_delay to prevent overwriting by zero when the 'hs400-ds-delay' is not set in the dts. In addition, since hs400(es) only tune the PAD_DS_DLY1, the PAD_DS_DLY2_SEL bit should be cleared to bypass it.
--- drivers/mmc/host/mtk-sd.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
drivers/mmc/host/mtk-sd.c +20 -11
@@ -260,6 +260,7 @@#define MSDC_PAD_TUNE_CMD_SEL BIT(21)/* RW */ #define PAD_DS_TUNE_DLY_SEL BIT(0)/* RW */ +#define PAD_DS_TUNE_DLY2_SEL BIT(1)/* RW */ #define PAD_DS_TUNE_DLY1 GENMASK(6, 2)/* RW */ #define PAD_DS_TUNE_DLY2 GENMASK(11, 7)/* RW */ #define PAD_DS_TUNE_DLY3 GENMASK(16, 12)/* RW */
@@ -305,6 +306,7 @@/* EMMC50_PAD_DS_TUNE mask */ #define PAD_DS_DLY_SEL BIT(16)/* RW */ +#define PAD_DS_DLY2_SEL BIT(15)/* RW */ #define PAD_DS_DLY1 GENMASK(14, 10)/* RW */ #define PAD_DS_DLY3 GENMASK(4, 0)/* RW */
@@ -2309,13 +2311,23 @@ tune_done:static int msdc_prepare_hs400_tuning (struct mmc_host *mmc,struct mmc_ios *ios) {struct msdc_host *host =mmc_priv (mmc); + host->hs400_mode = true; -if (host->top_base) -writel (host->hs400_ds_delay, - host->top_base +EMMC50_PAD_DS_TUNE ); -else -writel (host->hs400_ds_delay, host->base +PAD_DS_TUNE ); +if (host->top_base) { +if (host->hs400_ds_dly3) +sdr_set_field (host->top_base +EMMC50_PAD_DS_TUNE , +PAD_DS_DLY3 , host->hs400_ds_dly3); +if (host->hs400_ds_delay) +writel (host->hs400_ds_delay, + host->top_base +EMMC50_PAD_DS_TUNE ); + }else { +if (host->hs400_ds_dly3) +sdr_set_field (host->base +PAD_DS_TUNE , +PAD_DS_TUNE_DLY3 , host->hs400_ds_dly3); +if (host->hs400_ds_delay) +writel (host->hs400_ds_delay, host->base +PAD_DS_TUNE ); + }/* hs400 mode must set it to 0 */ sdr_clr_bits (host->base +MSDC_PATCH_BIT2 ,MSDC_PATCH_BIT2_CFGCRCSTS );/* to improve read performance, set outstanding to 2 */
@@ -2335,14 +2347,11 @@ static int msdc_execute_hs400_tuning(strif (host->top_base) {sdr_set_bits (host->top_base +EMMC50_PAD_DS_TUNE ,PAD_DS_DLY_SEL ); -if (host->hs400_ds_dly3) -sdr_set_field (host->top_base +EMMC50_PAD_DS_TUNE , -PAD_DS_DLY3 , host->hs400_ds_dly3); +sdr_clr_bits (host->top_base +EMMC50_PAD_DS_TUNE , +PAD_DS_DLY2_SEL ); }else {sdr_set_bits (host->base +PAD_DS_TUNE ,PAD_DS_TUNE_DLY_SEL ); -if (host->hs400_ds_dly3) -sdr_set_field (host->base +PAD_DS_TUNE , -PAD_DS_TUNE_DLY3 , host->hs400_ds_dly3); +sdr_clr_bits (host->base +PAD_DS_TUNE ,PAD_DS_TUNE_DLY2_SEL ); } host->hs400_tuning = true;
Greg Kroah-Hartman
maintainerPATCH 94/152 igc: Set buffer type for empty frames in igc_init_empty_frame
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Yoong Siang <[email protected]>
commit 63f20f00d23d569e4e67859b4e8dcc9de79221cb upstream.
Set the buffer type to IGC_TX_BUFFER_TYPE_SKB for empty frame in the igc_init_empty_frame function. This ensures that the buffer type is correctly identified and handled during Tx ring cleanup.
--- drivers/net/ethernet/intel/igc/igc_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/igc/igc_main.c +1 -0
@@ -1096,6 +1096,7 @@ static int igc_init_empty_frame(struct ireturn -ENOMEM ; } + buffer->type =IGC_TX_BUFFER_TYPE_SKB ; buffer->skb = skb; buffer->protocol =0 ; buffer->bytecount = skb->len;
Greg Kroah-Hartman
maintainerPATCH 95/152 mlxsw: Add return value check for mlxsw_sp_port_get_stats_raw()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit fee5d688940690cc845937459e340e4e02598e90 upstream.
Add a check for the return value of mlxsw_sp_port_get_stats_raw() in __mlxsw_sp_port_get_stats(). If mlxsw_sp_port_get_stats_raw() returns an error, exit the function to prevent further processing with potentially invalid data.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +3 -1
@@ -768,7 +768,9 @@ static void __mlxsw_sp_port_get_stats(st err =mlxsw_sp_get_hw_stats_by_group (&hw_stats, &len, grp);if (err)return ; -mlxsw_sp_port_get_stats_raw (dev, grp, prio, ppcnt_pl); + err =mlxsw_sp_port_get_stats_raw (dev, grp, prio, ppcnt_pl); +if (err) +return ;for (i =0 ; i < len; i++) { data[data_index + i] = hw_stats[i].getter (ppcnt_pl);if (!hw_stats[i].cells_bytes)
Greg Kroah-Hartman
maintainerPATCH 96/152 btrfs: fix hole expansion when writing at an offset beyond EOF
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit da2dccd7451de62b175fb8f0808d644959e964c7 upstream.
At btrfs_write_check() if our file's i_size is not sector size aligned and we have a write that starts at an offset larger than the i_size that falls within the same page of the i_size, then we end up not zeroing the file range [i_size, write_offset).
The code is this:
start_pos = round_down(pos, fs_info->sectorsize);
oldsize = i_size_read(inode);
if (start_pos > oldsize) {
/* Expand hole size to cover write data, preventing empty gap */
loff_t end_pos = round_up(pos + count, fs_info->sectorsize);
ret = btrfs_cont_expand(BTRFS_I(inode), oldsize, end_pos);
if (ret)
return ret;
}So if our file's i_size is 90269 bytes and a write at offset 90365 bytes comes in, we get 'start_pos' set to 90112 bytes, which is less than the i_size and therefore we don't zero out the range [90269, 90365) by calling btrfs_cont_expand().
This is an old bug introduced in commit 9036c10208e1 ("Btrfs: update hole handling v2"), from 2008, and the buggy code got moved around over the years.
Fix this by discarding 'start_pos' and comparing against the write offset ('pos') without any alignment.
This bug was recently exposed by test case generic/363 which tests this scenario by polluting ranges beyond EOF with an mmap write and than verify that after a file increases we get zeroes for the range which is supposed to be a hole and not what we wrote with the previous mmaped write.
We're only seeing this exposed now because generic/363 used to run only on xfs until last Sunday's fstests update.
The test was failing like this:
$ ./check generic/363 FSTYP -- btrfs PLATFORM -- Linux/x86_64 debian0 6.13.0-rc7-btrfs-next-185+ #17 SMP PREEMPT_DYNAMIC Mon Feb 3 12:28:46 WET 2025 MKFS_OPTIONS -- /dev/sdc MOUNT_OPTIONS -- /dev/sdc /home/fdmanana/btrfs-tests/scratch_1
generic/363 0s ... [failed, exit status 1]- output mismatch (see /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad)
# --- tests/generic/363.out 2025-02-05 15:31:14.013646509 +0000
# +++ /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad 2025-02-05 17:25:33.112630781 +0000
@@ -1 +1,46 @@
QA output created by 363
+READ BAD DATA: offset = 0xdcad, size = 0xd921, fname = /home/fdmanana/btrfs-tests/dev/junk
+OFFSET GOOD BAD RANGE
+0x1609d 0x0000 0x3104 0x0
+operation# (mod 256) for the bad data may be 4
+0x1609e 0x0000 0x0472 0x1
+operation# (mod 256) for the bad data may be 4
...
(Run 'diff -u /home/fdmanana/git/hub/xfstests/tests/generic/363.out /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad' to see the entire diff)
Ran: generic/363
Failures: generic/363
Failed 1 of 1 tests
--- fs/btrfs/file.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/btrfs/file.c +1 -3
@@ -1134,7 +1134,6 @@ static int btrfs_write_check(struct kiocloff_t pos = iocb->ki_pos;int ret;loff_t oldsize; -loff_t start_pos;/* * Quickly bail out on NOWAIT writes if we don't have the nodatacow or
@@ -1158,9 +1157,8 @@ static int btrfs_write_check(struct kioc*/ update_time_for_write (inode); - start_pos =round_down (pos, fs_info->sectorsize); oldsize =i_size_read (inode); -if (start_pos > oldsize) { +if (pos > oldsize) {/* Expand hole size to cover write data, preventing empty gap */ loff_t end_pos =round_up (pos + count, fs_info->sectorsize);
Greg Kroah-Hartman
maintainerPATCH 97/152 clocksource: Use pr_info() for "Checking clocksource synchronization" message
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 1f566840a82982141f94086061927a90e79440e5 ]
The "Checking clocksource synchronization" message is normally printed when clocksource_verify_percpu() is called for a given clocksource if both the CLOCK_SOURCE_UNSTABLE and CLOCK_SOURCE_VERIFY_PERCPU flags are set.
It is an informational message and so pr_info() is the correct choice.
Stable-dep-of: 6bb05a33337b ("clocksource: Use migrate_disable() to avoid calling get_random_u32() in atomic context")
--- kernel/time/clocksource.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/time/clocksource.c +2 -1
@@ -360,7 +360,8 @@ void clocksource_verify_percpu(struct clocksource *cs)return ; } testcpu =smp_processor_id (); -pr_warn ("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n" , cs->name, testcpu,cpumask_pr_args (&cpus_chosen)); +pr_info ("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n" , + cs->name, testcpu,cpumask_pr_args (&cpus_chosen));for_each_cpu (cpu, &cpus_chosen) {if (cpu == testcpu)continue ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 98/152 clocksource: Use migrate_disable() to avoid calling get_random_u32() in atomic context
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 6bb05a33337b2c842373857b63de5c9bf1ae2a09 ]
The following bug report happened with a PREEMPT_RT kernel:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2012, name: kwatchdog preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 get_random_u32+0x4f/0x110 clocksource_verify_choose_cpus+0xab/0x1a0 clocksource_verify_percpu.part.0+0x6b/0x330 clocksource_watchdog_kthread+0x193/0x1a0
It is due to the fact that clocksource_verify_choose_cpus() is invoked with preemption disabled. This function invokes get_random_u32() to obtain random numbers for choosing CPUs. The batched_entropy_32 local lock and/or the base_crng.lock spinlock in driver/char/random.c will be acquired during the call. In PREEMPT_RT kernel, they are both sleeping locks and so cannot be acquired in atomic context.
Fix this problem by using migrate_disable() to allow smp_processor_id() to be reliably used without introducing atomic context. preempt_disable() is then called after clocksource_verify_choose_cpus() but before the clocksource measurement is being run to avoid introducing unexpected latency.
--- kernel/time/clocksource.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/time/clocksource.c +4 -2
@@ -351,10 +351,10 @@ void clocksource_verify_percpu(struct clocksource *cs)cpumask_clear (&cpus_ahead);cpumask_clear (&cpus_behind);cpus_read_lock (); -preempt_disable (); +migrate_disable ();clocksource_verify_choose_cpus ();if (cpumask_empty (&cpus_chosen)) { -preempt_enable (); +migrate_enable ();cpus_read_unlock ();pr_warn ("Not enough CPUs to check clocksource '%s'.\n" , cs->name);return ;
@@ -362,6 +362,7 @@ void clocksource_verify_percpu(struct clocksource *cs) testcpu =smp_processor_id ();pr_info ("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n" , cs->name, testcpu,cpumask_pr_args (&cpus_chosen)); +preempt_disable ();for_each_cpu (cpu, &cpus_chosen) {if (cpu == testcpu)continue ;
@@ -381,6 +382,7 @@ void clocksource_verify_percpu(struct clocksource *cs) cs_nsec_min = cs_nsec; }preempt_enable (); +migrate_enable ();cpus_read_unlock ();if (!cpumask_empty (&cpus_ahead)) pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n",
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 99/152 ipv4: add RCU protection to ip4_dst_hoplimit()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 469308552ca4560176cfc100e7ca84add1bebd7c ]
ip4_dst_hoplimit() must use RCU protection to make sure the net structure it reads does not disappear.
--- include/net/route.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
include/net/route.h +7 -2
@@ -357,10 +357,15 @@ static inline int inet_iif(const struct sk_buff *skb)static inline int ip4_dst_hoplimit (const struct dst_entry *dst) {int hoplimit =dst_metric_raw (dst,RTAX_HOPLIMIT ); -struct net *net =dev_net (dst->dev); -if (hoplimit ==0 ) +if (hoplimit ==0 ) { +const struct net *net; + +rcu_read_lock (); + net =dev_net_rcu (dst->dev); hoplimit =READ_ONCE (net->ipv4.sysctl_ip_default_ttl); +rcu_read_unlock (); + }return hoplimit; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 100/152 net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit 2034d90ae41ae93e30d492ebcf1f06f97a9cfba6 ]
Make the net pointer stored in possible_net_t structure annotated as an RCU pointer. Change the access helpers to treat it as such. Introduce read_pnet_rcu() helper to allow caller to dereference the net pointer under RCU read lock.
Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()")
--- include/net/net_namespace.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
include/net/net_namespace.h +12 -3
@@ -369,21 +369,30 @@ static inline void put_net_track(struct net *net, netns_tracker *tracker)typedef struct {#ifdef CONFIG_NET_NS -struct net *net; +struct net __rcu *net;#endif }possible_net_t ;static inline void write_pnet (possible_net_t *pnet,struct net *net) {#ifdef CONFIG_NET_NS - pnet->net = net; +rcu_assign_pointer (pnet->net, net);#endif }static inline struct net *read_pnet (const possible_net_t *pnet) {#ifdef CONFIG_NET_NS -return pnet->net; +return rcu_dereference_protected (pnet->net, true); +#else +return &init_net; +#endif +} + +static inline struct net *read_pnet_rcu (possible_net_t *pnet) +{ +#ifdef CONFIG_NET_NS +return rcu_dereference (pnet->net);#else return &init_net;#endif
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 101/152 net: add dev_net_rcu() helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 482ad2a4ace2740ca0ff1cbc8f3c7f862f3ab507 ]
dev->nd_net can change, readers should either
use rcu_read_lock() or RTNL.
We currently use a generic helper, dev_net() with no debugging support. We probably have many hidden bugs.
Add dev_net_rcu() helper for callers using rcu_read_lock() protection.
Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()")
--- include/linux/netdevice.h | 6 ++++++ include/net/net_namespace.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
include/linux/netdevice.h +6 -0
@@ -2593,6 +2593,12 @@ struct net *dev_net(const struct net_device *dev)return read_pnet (&dev->nd_net); } +static inline +struct net *dev_net_rcu (const struct net_device *dev) +{ +return read_pnet_rcu (&dev->nd_net); +} +static inline void dev_net_set (struct net_device *dev,struct net *net) {
include/net/net_namespace.h +1 -1
@@ -389,7 +389,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet)#endif } -static inline struct net *read_pnet_rcu (possible_net_t *pnet) +static inline struct net *read_pnet_rcu (const possible_net_t *pnet) {#ifdef CONFIG_NET_NS return rcu_dereference (pnet->net);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 102/152 ipv4: use RCU protection in ipv4_default_advmss()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 71b8471c93fa0bcab911fcb65da1eb6c4f5f735f ]
ipv4_default_advmss() must use RCU protection to make sure the net structure it reads does not disappear.
--- net/ipv4/route.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
net/ipv4/route.c +8 -3
@@ -1306,10 +1306,15 @@ static void set_class_tag(struct rtable *rt, u32 tag)static unsigned int ipv4_default_advmss (const struct dst_entry *dst) { -struct net *net =dev_net (dst->dev);unsigned int header_size =sizeof (struct tcphdr ) +sizeof (struct iphdr ); - unsigned int advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, - net->ipv4.ip_rt_min_advmss); +unsigned int advmss; +struct net *net; + +rcu_read_lock (); + net =dev_net_rcu (dst->dev); + advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, + net->ipv4.ip_rt_min_advmss); +rcu_read_unlock ();return min (advmss,IPV4_MAX_PMTU - header_size); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 103/152 ipv4: use RCU protection in rt_is_expired()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit dd205fcc33d92d54eee4d7f21bb073af9bd5ce2b ]
rt_is_expired() must use RCU protection to make sure the net structure it reads does not disappear.
--- net/ipv4/route.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/ipv4/route.c +7 -1
@@ -393,7 +393,13 @@ static inline int ip_rt_proc_init(void)static inline bool rt_is_expired (const struct rtable *rth) { -return rth->rt_genid !=rt_genid_ipv4 (dev_net (rth->dst.dev)); +bool res; + +rcu_read_lock (); + res = rth->rt_genid !=rt_genid_ipv4 (dev_net_rcu (rth->dst.dev)); +rcu_read_unlock (); + +return res; }void rt_cache_flush (struct net *net)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 104/152 ipv4: use RCU protection in inet_select_addr()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 719817cd293e4fa389e1f69c396f3f816ed5aa41 ]
inet_select_addr() must use RCU protection to make sure the net structure it reads does not disappear.
--- net/ipv4/devinet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/devinet.c +2 -1
@@ -1341,10 +1341,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)__be32 addr =0 ;unsigned char localnet_scope =RT_SCOPE_HOST ;struct in_device *in_dev; -struct net *net =dev_net (dev); +struct net *net;int master_idx;rcu_read_lock (); + net =dev_net_rcu (dev); in_dev =__in_dev_get_rcu (dev);if (!in_dev) goto no_in_dev;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 105/152 net: ipv4: Cache pmtu for all packet paths if multipath enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Vdovin <[email protected]>
[ Upstream commit 7d3f3b4367f315a61fc615e3138f3d320da8c466 ]
Check number of paths by fib_info_num_path(), and update_or_create_fnhe() for every path. Problem is that pmtu is cached only for the oif that has received icmp message "need to frag", other oifs will still try to use "default" iface mtu.
An example topology showing the problem:
| host1
+---------+
| dummy0 | 10.179.20.18/32 mtu9000
+---------+
+-----------+----------------+
+---------+ +---------+
| ens17f0 | 10.179.2.141/31 | ens17f1 | 10.179.2.13/31
+---------+ +---------+
| (all here have mtu 9000) |
+------+ +------+
| ro1 | 10.179.2.140/31 | ro2 | 10.179.2.12/31
+------+ +------+
| |
---------+------------+-------------------+------
|
+-----+
| ro3 | 10.10.10.10 mtu1500
+-----+
|
========================================
some networks
========================================
|
+-----+
| eth0| 10.10.30.30 mtu9000
+-----+
| host2host1 have enabled multipath and
sysctl net.ipv4.fib_multipath_hash_policy = 1:
default proto static src 10.179.20.18
nexthop via 10.179.2.12 dev ens17f1 weight 1
nexthop via 10.179.2.140 dev ens17f0 weight 1When host1 tries to do pmtud from 10.179.20.18/32 to host2, host1 receives at ens17f1 iface an icmp packet from ro3 that ro3 mtu=1500. And host1 caches it in nexthop exceptions cache.
Problem is that it is cached only for the iface that has received icmp, and there is no way that ro3 will send icmp msg to host1 via another path.
Host1 now have this routes to host2:
ip r g 10.10.30.30 sport 30000 dport 443
10.10.30.30 via 10.179.2.12 dev ens17f1 src 10.179.20.18 uid 0
cache expires 521sec mtu 1500
ip r g 10.10.30.30 sport 30033 dport 443
10.10.30.30 via 10.179.2.140 dev ens17f0 src 10.179.20.18 uid 0
cache
So when host1 tries again to reach host2 with mtu>1500,
if packet flow is lucky enough to be hashed with oif=ens17f1 its ok, if oif=ens17f0 it blackholes and still gets icmp msgs from ro3 to ens17f1, until lucky day when ro3 will send it through another flow to ens17f0.
Stable-dep-of: 139512191bd0 ("ipv4: use RCU protection in __ip_rt_update_pmtu()")
--- net/ipv4/route.c | 13 ++++ tools/testing/selftests/net/pmtu.sh | 112 +++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 17 deletions(-)
net/ipv4/route.c +13 -0
@@ -1046,6 +1046,19 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)struct fib_nh_common *nhc;fib_select_path (net, &res, fl4,NULL ); +#ifdef CONFIG_IP_ROUTE_MULTIPATH +if (fib_info_num_path (res.fi) >1 ) { +int nhsel; + +for (nhsel =0 ; nhsel <fib_info_num_path (res.fi); nhsel++) { + nhc =fib_info_nhc (res.fi, nhsel); +update_or_create_fnhe (nhc, fl4->daddr,0 , mtu, lock, + jiffies + net->ipv4.ip_rt_mtu_expires); + } +rcu_read_unlock (); +return ; + } +#endif /* CONFIG_IP_ROUTE_MULTIPATH */ nhc =FIB_RES_NHC (res);update_or_create_fnhe (nhc, fl4->daddr,0 , mtu, lock, jiffies + net->ipv4.ip_rt_mtu_expires);
tools/testing/selftests/net/pmtu.sh +95 -17
168 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 106/152 ipv4: use RCU protection in __ip_rt_update_pmtu()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 139512191bd06f1b496117c76372b2ce372c9a41 ]
__ip_rt_update_pmtu() must use RCU protection to make sure the net structure it reads does not disappear.
--- net/ipv4/route.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/ipv4/route.c +6 -5
@@ -1020,9 +1020,9 @@ out: kfree_skb_reason(skb, reason);static void __ip_rt_update_pmtu (struct rtable *rt,struct flowi4 *fl4,u32 mtu) {struct dst_entry *dst = &rt->dst; -struct net *net =dev_net (dst->dev);struct fib_result res;bool lock = false; +struct net *net;u32 old_mtu;if (ip_mtu_locked (dst))
@@ -1032,6 +1032,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)if (old_mtu < mtu)return ; +rcu_read_lock (); + net =dev_net_rcu (dst->dev);if (mtu < net->ipv4.ip_rt_min_pmtu) { lock = true; mtu =min (old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1039,9 +1041,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)if (rt->rt_pmtu == mtu && !lock &&time_before (jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires /2 )) -return ; + goto out; -rcu_read_lock ();if (fib_lookup (net, fl4, &res,0 ) ==0 ) {struct fib_nh_common *nhc;
@@ -1055,14 +1056,14 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)update_or_create_fnhe (nhc, fl4->daddr,0 , mtu, lock, jiffies + net->ipv4.ip_rt_mtu_expires); } -rcu_read_unlock (); -return ; + goto out; }#endif /* CONFIG_IP_ROUTE_MULTIPATH */ nhc =FIB_RES_NHC (res);update_or_create_fnhe (nhc, fl4->daddr,0 , mtu, lock, jiffies + net->ipv4.ip_rt_mtu_expires); } +out:rcu_read_unlock (); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 107/152 ipv4: icmp: convert to dev_net_rcu()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 4b8474a0951e605d2a27a2c483da4eb4b8c63760 ]
__icmp_send() must ensure rcu_read_lock() is held, as spotted by Jakub.
Other ICMP uses of dev_net() seem safe, change them to dev_net_rcu() to get LOCKDEP support.
--- net/ipv4/icmp.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
net/ipv4/icmp.c +17 -14
@@ -403,10 +403,10 @@ static void icmp_push_reply(struct sock *sk,static void icmp_reply (struct icmp_bxm *icmp_param,struct sk_buff *skb) { -struct ipcm_cookie ipc;struct rtable *rt =skb_rtable (skb); -struct net *net =dev_net (rt->dst.dev); +struct net *net =dev_net_rcu (rt->dst.dev);bool apply_ratelimit = false; +struct ipcm_cookie ipc;struct flowi4 fl4;struct sock *sk;struct inet_sock *inet;
@@ -609,12 +609,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,struct sock *sk;if (!rt) - goto out; +return ; + +rcu_read_lock ();if (rt->dst.dev) - net =dev_net (rt->dst.dev); + net =dev_net_rcu (rt->dst.dev);else if (skb_in->dev) - net =dev_net (skb_in->dev); + net =dev_net_rcu (skb_in->dev);else goto out;
@@ -783,7 +785,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,icmp_xmit_unlock (sk); out_bh_enable:local_bh_enable (); -out:; +out: +rcu_read_unlock (); }EXPORT_SYMBOL (__icmp_send);
@@ -832,7 +835,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)* avoid additional coding at protocol handlers. */ if (!pskb_may_pull (skb, iph->ihl *4 +8 )) { -__ICMP_INC_STATS (dev_net (skb->dev),ICMP_MIB_INERRORS ); +__ICMP_INC_STATS (dev_net_rcu (skb->dev),ICMP_MIB_INERRORS );return ; }
@@ -866,7 +869,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb)struct net *net;u32 info =0 ; - net =dev_net (skb_dst (skb)->dev); + net =dev_net_rcu (skb_dst (skb)->dev);/* * Incomplete header ?
@@ -977,7 +980,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb)static enum skb_drop_reason icmp_redirect (struct sk_buff *skb) {if (skb->len <sizeof (struct iphdr )) { -__ICMP_INC_STATS (dev_net (skb->dev),ICMP_MIB_INERRORS ); +__ICMP_INC_STATS (dev_net_rcu (skb->dev),ICMP_MIB_INERRORS );return SKB_DROP_REASON_PKT_TOO_SMALL ; }
@@ -1009,7 +1012,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)struct icmp_bxm icmp_param;struct net *net; - net =dev_net (skb_dst (skb)->dev); + net =dev_net_rcu (skb_dst (skb)->dev);/* should there be an ICMP stat for ignored echos? */ if (READ_ONCE (net->ipv4.sysctl_icmp_echo_ignore_all))return SKB_NOT_DROPPED_YET ;
@@ -1038,9 +1041,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)bool icmp_build_probe (struct sk_buff *skb,struct icmphdr *icmphdr) { +struct net *net =dev_net_rcu (skb->dev);struct icmp_ext_hdr *ext_hdr, _ext_hdr;struct icmp_ext_echo_iio *iio, _iio; -struct net *net =dev_net (skb->dev);struct inet6_dev *in6_dev;struct in_device *in_dev;struct net_device *dev;
@@ -1179,7 +1182,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)return SKB_NOT_DROPPED_YET ; out_err: -__ICMP_INC_STATS (dev_net (skb_dst (skb)->dev),ICMP_MIB_INERRORS ); +__ICMP_INC_STATS (dev_net_rcu (skb_dst (skb)->dev),ICMP_MIB_INERRORS );return SKB_DROP_REASON_PKT_TOO_SMALL ; }
@@ -1196,7 +1199,7 @@ int icmp_rcv(struct sk_buff *skb) {enum skb_drop_reason reason =SKB_DROP_REASON_NOT_SPECIFIED ;struct rtable *rt =skb_rtable (skb); -struct net *net =dev_net (rt->dst.dev); +struct net *net =dev_net_rcu (rt->dst.dev);struct icmphdr *icmph;if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) {
@@ -1369,9 +1372,9 @@ int icmp_err(struct sk_buff *skb, u32 info)struct iphdr *iph = (struct iphdr *)skb->data;int offset = iph->ihl<<2 ;struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); +struct net *net =dev_net_rcu (skb->dev);int type =icmp_hdr (skb)->type;int code =icmp_hdr (skb)->code; -struct net *net =dev_net (skb->dev);/* * Use ping_err to handle all icmp errors except those
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 108/152 flow_dissector: use RCU protection to fetch dev_net()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit afec62cd0a4191cde6dd3a75382be4d51a38ce9b ]
__skb_flow_dissect() can be called from arbitrary contexts.
It must extend its RCU protection section to include the call to dev_net(), which can become dev_net_rcu().
This makes sure the net structure can not disappear under us.
--- net/core/flow_dissector.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
net/core/flow_dissector.c +11 -10
@@ -1084,10 +1084,12 @@ bool __skb_flow_dissect(const struct net *net,FLOW_DISSECTOR_KEY_BASIC , target_container); +rcu_read_lock (); +if (skb) {if (!net) {if (skb->dev) - net =dev_net (skb->dev); + net =dev_net_rcu (skb->dev);else if (skb->sk) net =sock_net (skb->sk); }
@@ -1098,7 +1100,6 @@ bool __skb_flow_dissect(const struct net *net,enum netns_bpf_attach_type type =NETNS_BPF_FLOW_DISSECTOR ;struct bpf_prog_array *run_array; -rcu_read_lock (); run_array =rcu_dereference (init_net.bpf.run_array[type]);if (!run_array) run_array =rcu_dereference (net->bpf.run_array[type]);
@@ -1126,17 +1127,17 @@ bool __skb_flow_dissect(const struct net *net, prog =READ_ONCE (run_array->items[0 ].prog); result =bpf_flow_dissect (prog, &ctx, n_proto, nhoff, hlen, flags); -if (result ==BPF_FLOW_DISSECTOR_CONTINUE ) - goto dissect_continue; -__skb_flow_bpf_to_target (&flow_keys, flow_dissector, - target_container); -rcu_read_unlock (); -return result ==BPF_OK ; +if (result !=BPF_FLOW_DISSECTOR_CONTINUE ) { +__skb_flow_bpf_to_target (&flow_keys, flow_dissector, + target_container); +rcu_read_unlock (); +return result ==BPF_OK ; + } } -dissect_continue: -rcu_read_unlock (); } +rcu_read_unlock (); +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_ETH_ADDRS )) {struct ethhdr *eth =eth_hdr (skb);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 109/152 ipv6: use RCU protection in ip6_default_advmss()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 3c8ffcd248da34fc41e52a46e51505900115fc2a ]
ip6_default_advmss() needs rcu protection to make sure the net structure it reads does not disappear.
--- net/ipv6/route.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/ipv6/route.c +6 -1
@@ -3188,13 +3188,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) {struct net_device *dev = dst->dev;unsigned int mtu =dst_mtu (dst); -struct net *net =dev_net (dev); +struct net *net; mtu -=sizeof (struct ipv6hdr ) +sizeof (struct tcphdr ); +rcu_read_lock (); + + net =dev_net_rcu (dev);if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) mtu = net->ipv6.sysctl.ip6_rt_min_advmss; +rcu_read_unlock (); +/* * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and * corresponding MSS is IPV6_MAXPLEN - tcp_header_size.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 110/152 ipv6: icmp: convert to dev_net_rcu()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 34aef2b0ce3aa4eb4ef2e1f5cad3738d527032f5 ]
icmp6_send() must acquire rcu_read_lock() sooner to ensure the dev_net() call done from a safe context.
Other ICMPv6 uses of dev_net() seem safe, change them to dev_net_rcu() to get LOCKDEP support to catch bugs.
--- net/ipv6/icmp.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
net/ipv6/icmp.c +23 -19
@@ -76,7 +76,7 @@ static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, {/* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset); -struct net *net =dev_net (skb->dev); +struct net *net =dev_net_rcu (skb->dev);if (type ==ICMPV6_PKT_TOOBIG )ip6_update_pmtu (skb, net, info, skb->dev->ifindex,0 ,sock_net_uid (net,NULL ));
@@ -473,7 +473,10 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,if (!skb->dev)return ; - net =dev_net (skb->dev); + +rcu_read_lock (); + + net =dev_net_rcu (skb->dev); mark =IP6_REPLY_MARK (net, skb->mark);/* * Make sure we respect the rules
@@ -496,7 +499,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, !(type ==ICMPV6_PARAMPROB && code ==ICMPV6_UNK_OPTION && (opt_unrec(skb, info)))) - return; + goto out; saddr =NULL ; }
@@ -526,7 +529,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,if ((addr_type ==IPV6_ADDR_ANY ) || (addr_type &IPV6_ADDR_MULTICAST )) {net_dbg_ratelimited ("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n" , &hdr->saddr, &hdr->daddr); -return ; + goto out; }/*
@@ -535,7 +538,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,if (is_ineligible (skb)) {net_dbg_ratelimited ("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n" , &hdr->saddr, &hdr->daddr); -return ; + goto out; }/* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */
@@ -582,7 +585,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, np =inet6_sk (sk);if (!icmpv6_xrlim_allow (sk, type, &fl6, apply_ratelimit)) - goto out; + goto out_unlock; tmp_hdr.icmp6_type = type; tmp_hdr.icmp6_code = code;
@@ -600,7 +603,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, dst =icmpv6_route_lookup (net, skb, sk, &fl6);if (IS_ERR (dst)) - goto out; + goto out_unlock; ipc6.hlimit =ip6_sk_dst_hoplimit (np, &fl6, dst);
@@ -616,7 +619,6 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, goto out_dst_release; } -rcu_read_lock (); idev =__in6_dev_get (skb->dev); if (ip6_append_data(sk, icmpv6_getfrag, &msg,
@@ -630,13 +632,15 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,icmpv6_push_pending_frames (sk, &fl6, &tmp_hdr, len +sizeof (struct icmp6hdr )); } -rcu_read_unlock (); + out_dst_release:dst_release (dst); -out: +out_unlock:icmpv6_xmit_unlock (sk); out_bh_enable:local_bh_enable (); +out: +rcu_read_unlock (); }EXPORT_SYMBOL (icmp6_send);
@@ -679,8 +683,8 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,skb_pull (skb2, nhs);skb_reset_network_header (skb2); - rt =rt6_lookup (dev_net (skb->dev), &ipv6_hdr (skb2)->saddr,NULL ,0 , - skb,0 ); + rt =rt6_lookup (dev_net_rcu (skb->dev), &ipv6_hdr (skb2)->saddr, +NULL ,0 , skb,0 );if (rt && rt->dst.dev) skb2->dev = rt->dst.dev;
@@ -717,7 +721,7 @@ EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);static enum skb_drop_reason icmpv6_echo_reply (struct sk_buff *skb) { -struct net *net =dev_net (skb->dev); +struct net *net =dev_net_rcu (skb->dev);struct sock *sk;struct inet6_dev *idev;struct ipv6_pinfo *np;
@@ -832,7 +836,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) {struct inet6_skb_parm *opt =IP6CB (skb); -struct net *net =dev_net (skb->dev); +struct net *net =dev_net_rcu (skb->dev);const struct inet6_protocol *ipprot;enum skb_drop_reason reason;int inner_offset;
@@ -889,7 +893,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,static int icmpv6_rcv (struct sk_buff *skb) {enum skb_drop_reason reason =SKB_DROP_REASON_NOT_SPECIFIED ; -struct net *net =dev_net (skb->dev); +struct net *net =dev_net_rcu (skb->dev);struct net_device *dev =icmp6_dev (skb);struct inet6_dev *idev =__in6_dev_get (dev);const struct in6_addr *saddr, *daddr;
@@ -921,7 +925,7 @@ static int icmpv6_rcv(struct sk_buff *skb)skb_set_network_header (skb, nh); } -__ICMP6_INC_STATS (dev_net (dev), idev,ICMP6_MIB_INMSGS ); +__ICMP6_INC_STATS (dev_net_rcu (dev), idev,ICMP6_MIB_INMSGS ); saddr = &ipv6_hdr (skb)->saddr; daddr = &ipv6_hdr (skb)->daddr;
@@ -939,7 +943,7 @@ static int icmpv6_rcv(struct sk_buff *skb) type = hdr->icmp6_type; -ICMP6MSGIN_INC_STATS (dev_net (dev), idev, type); +ICMP6MSGIN_INC_STATS (dev_net_rcu (dev), idev, type);switch (type) {case ICMPV6_ECHO_REQUEST :
@@ -1034,9 +1038,9 @@ static int icmpv6_rcv(struct sk_buff *skb) csum_error: reason =SKB_DROP_REASON_ICMP_CSUM ; -__ICMP6_INC_STATS (dev_net (dev), idev,ICMP6_MIB_CSUMERRORS ); +__ICMP6_INC_STATS (dev_net_rcu (dev), idev,ICMP6_MIB_CSUMERRORS ); discard_it: -__ICMP6_INC_STATS (dev_net (dev), idev,ICMP6_MIB_INERRORS ); +__ICMP6_INC_STATS (dev_net_rcu (dev), idev,ICMP6_MIB_INERRORS ); drop_no_count:kfree_skb_reason (skb, reason);return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 111/152 HID: hid-steam: Avoid overwriting smoothing parameter
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit 34281b4d916f167a6f77975380e1df07f06248b7 ]
The original implementation of this driver incorrectly guessed the function of this register. It's not only unnecessary to write to this register for lizard mode but actually counter-productive since it overwrites whatever previous value was intentionally set, for example by Steam.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/hid/hid-steam.c +0 -5
@@ -340,9 +340,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MAPPINGS );/* enable mouse */ steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MOUSE ); -steam_write_registers (steam, -STEAM_REG_RPAD_MARGIN ,0x01 ,/* enable margin */ -0 );cancel_delayed_work_sync (&steam->heartbeat); }else {
@@ -351,7 +348,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)if (steam->quirks &STEAM_QUIRK_DECK ) { steam_write_registers(steam, - STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */ STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */ STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */ STEAM_REG_LPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */
@@ -365,7 +361,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)schedule_delayed_work (&steam->heartbeat,5 *HZ ); }else {steam_write_registers (steam, -STEAM_REG_RPAD_MARGIN ,0x00 ,/* disable margin */ STEAM_REG_LPAD_MODE ,0x07 ,/* disable mouse */ STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ 0 );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 112/152 HID: hid-steam: Disable watchdog instead of using a heartbeat
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit 917972636e8271c5691710ce5dcd66c2d3bd04f2 ]
The Steam Deck has a setting that controls whether or not the watchdog is enabled, so instead of using a heartbeat to keep the watchdog from triggering, this commit changes the behavior to simply disable the watchdog instead.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-)
drivers/hid/hid-steam.c +2 -28
@@ -101,6 +101,7 @@ static LIST_HEAD(steam_devices);#define STEAM_REG_GYRO_MODE 0x30#define STEAM_REG_LPAD_CLICK_PRESSURE 0x34#define STEAM_REG_RPAD_CLICK_PRESSURE 0x35 +#define STEAM_REG_WATCHDOG_ENABLE 0x47/* Raw event identifiers */ #define STEAM_EV_INPUT_DATA 0x01
@@ -134,7 +135,6 @@ struct steam_device {struct power_supply __rcu *battery;u8 battery_charge;u16 voltage; -struct delayed_work heartbeat;struct work_struct rumble_work;u16 rumble_left;u16 rumble_right;
@@ -340,8 +340,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MAPPINGS );/* enable mouse */ steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MOUSE ); - -cancel_delayed_work_sync (&steam->heartbeat); }else {/* disable esc, enter, cursor */ steam_send_report_byte (steam,STEAM_CMD_CLEAR_MAPPINGS );
@@ -352,13 +350,8 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ STEAM_REG_LPAD_CLICK_PRESSURE ,0xFFFF ,/* disable clicky pad */ STEAM_REG_RPAD_CLICK_PRESSURE ,0xFFFF ,/* disable clicky pad */ +STEAM_REG_WATCHDOG_ENABLE ,0 ,/* disable watchdog that tests if Steam is active */ 0); -/* -* The Steam Deck has a watchdog that automatically enables -* lizard mode if it doesn't see any traffic for too long -*/ -if (!work_busy (&steam->heartbeat.work)) -schedule_delayed_work (&steam->heartbeat,5 *HZ ); }else { steam_write_registers(steam, STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */
@@ -733,22 +726,6 @@ static bool steam_is_valve_interface(struct hid_device *hdev)return !list_empty (&rep_enum->report_list); } -static void steam_lizard_mode_heartbeat (struct work_struct *work) -{ - struct steam_device *steam = container_of(work, struct steam_device, - heartbeat.work); - -mutex_lock (&steam->mutex); -if (!steam->client_opened && steam->client_hdev) { -steam_send_report_byte (steam,STEAM_CMD_CLEAR_MAPPINGS ); -steam_write_registers (steam, -STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ -0 ); -schedule_delayed_work (&steam->heartbeat,5 *HZ ); - } -mutex_unlock (&steam->mutex); -} -static int steam_client_ll_parse (struct hid_device *hdev) {struct steam_device *steam = hdev->driver_data;
@@ -887,7 +864,6 @@ static int steam_probe(struct hid_device *hdev, steam->quirks = id->driver_data;INIT_WORK (&steam->work_connect, steam_work_connect_cb);INIT_LIST_HEAD (&steam->list); -INIT_DEFERRABLE_WORK (&steam->heartbeat, steam_lizard_mode_heartbeat);INIT_WORK (&steam->rumble_work, steam_haptic_rumble_cb); steam->client_hdev =steam_create_client_hid (hdev);
@@ -944,7 +920,6 @@ static int steam_probe(struct hid_device *hdev,hid_destroy_device (steam->client_hdev); client_hdev_fail:cancel_work_sync (&steam->work_connect); -cancel_delayed_work_sync (&steam->heartbeat);cancel_work_sync (&steam->rumble_work); steam_alloc_fail: hid_err(hdev, "%s: failed with error %d\n",
@@ -965,7 +940,6 @@ static void steam_remove(struct hid_device *hdev)mutex_lock (&steam->mutex); steam->client_hdev =NULL ; steam->client_opened = false; -cancel_delayed_work_sync (&steam->heartbeat);mutex_unlock (&steam->mutex);cancel_work_sync (&steam->work_connect);if (steam->quirks &STEAM_QUIRK_WIRELESS ) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 113/152 HID: hid-steam: Clean up locking
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit 691ead124a0c35e56633dbb73e43711ff3db23ef ]
This cleans up the locking logic so that the spinlock is consistently used for access to a small handful of struct variables, and the mutex is exclusively and consistently used for ensuring that mutliple threads aren't trying to send/receive reports at the same time. Previously, only some report transactions were guarded by this mutex, potentially breaking atomicity. The mutex has been renamed to reflect this usage.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 122 +++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 53 deletions(-)
drivers/hid/hid-steam.c +69 -53
@@ -124,7 +124,7 @@ struct steam_device {struct list_head list;spinlock_t lock;struct hid_device *hdev, *client_hdev; -struct mutex mutex; +struct mutex report_mutex;bool client_opened;struct input_dev __rcu *input;unsigned long quirks;
@@ -267,21 +267,26 @@ static int steam_get_serial(struct steam_device *steam)* Send: 0xae 0x15 0x01 * Recv: 0xae 0x15 0x01 serialnumber (10 chars) */ -int ret; +int ret =0 ;u8 cmd[] = {STEAM_CMD_GET_SERIAL ,0x15 ,0x01 };u8 reply[3 +STEAM_SERIAL_LEN +1 ]; +mutex_lock (&steam->report_mutex); ret =steam_send_report (steam, cmd,sizeof (cmd));if (ret <0 ) -return ret; + goto out; ret =steam_recv_report (steam, reply,sizeof (reply));if (ret <0 ) -return ret; -if (reply[0 ] !=0xae || reply[1 ] !=0x15 || reply[2 ] !=0x01 ) -return -EIO ; + goto out; +if (reply[0 ] !=0xae || reply[1 ] !=0x15 || reply[2 ] !=0x01 ) { + ret = -EIO ; + goto out; + } reply[3 +STEAM_SERIAL_LEN ] =0 ;strscpy (steam->serial_no, reply +3 ,sizeof (steam->serial_no)); -return 0 ; +out: +mutex_unlock (&steam->report_mutex); +return ret; }/*
@@ -291,13 +296,18 @@ static int steam_get_serial(struct steam_device *steam)*/ static inline int steam_request_conn_status (struct steam_device *steam) { -return steam_send_report_byte (steam,STEAM_CMD_REQUEST_COMM_STATUS ); +int ret; +mutex_lock (&steam->report_mutex); + ret =steam_send_report_byte (steam,STEAM_CMD_REQUEST_COMM_STATUS ); +mutex_unlock (&steam->report_mutex); +return ret; }static inline int steam_haptic_rumble (struct steam_device *steam,u16 intensity,u16 left_speed,u16 right_speed,u8 left_gain,u8 right_gain) { +int ret;u8 report[11 ] = {STEAM_CMD_HAPTIC_RUMBLE ,9 }; report[3 ] = intensity &0xFF ;
@@ -309,7 +319,10 @@ static inline int steam_haptic_rumble(struct steam_device *steam, report[9 ] = left_gain; report[10 ] = right_gain; -return steam_send_report (steam, report,sizeof (report)); +mutex_lock (&steam->report_mutex); + ret =steam_send_report (steam, report,sizeof (report)); +mutex_unlock (&steam->report_mutex); +return ret; }static void steam_haptic_rumble_cb (struct work_struct *work)
@@ -336,11 +349,14 @@ static int steam_play_effect(struct input_dev *dev, void *data,static void steam_set_lizard_mode (struct steam_device *steam,bool enable) {if (enable) { +mutex_lock (&steam->report_mutex);/* enable esc, enter, cursors */ steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MAPPINGS );/* enable mouse */ steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MOUSE ); +mutex_unlock (&steam->report_mutex); }else { +mutex_lock (&steam->report_mutex);/* disable esc, enter, cursor */ steam_send_report_byte (steam,STEAM_CMD_CLEAR_MAPPINGS );
@@ -352,11 +368,13 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)STEAM_REG_RPAD_CLICK_PRESSURE ,0xFFFF ,/* disable clicky pad */ STEAM_REG_WATCHDOG_ENABLE ,0 ,/* disable watchdog that tests if Steam is active */ 0); +mutex_unlock (&steam->report_mutex); }else {steam_write_registers (steam,STEAM_REG_LPAD_MODE ,0x07 ,/* disable mouse */ STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ 0 ); +mutex_unlock (&steam->report_mutex); } } }
@@ -364,22 +382,29 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)static int steam_input_open (struct input_dev *dev) {struct steam_device *steam =input_get_drvdata (dev); +unsigned long flags; +bool set_lizard_mode; -mutex_lock (&steam->mutex); -if (!steam->client_opened && lizard_mode) +spin_lock_irqsave (&steam->lock, flags); + set_lizard_mode = !steam->client_opened && lizard_mode; +spin_unlock_irqrestore (&steam->lock, flags); +if (set_lizard_mode)steam_set_lizard_mode (steam, false); -mutex_unlock (&steam->mutex); +return 0 ; }static void steam_input_close (struct input_dev *dev) {struct steam_device *steam =input_get_drvdata (dev); +unsigned long flags; +bool set_lizard_mode; -mutex_lock (&steam->mutex); -if (!steam->client_opened && lizard_mode) +spin_lock_irqsave (&steam->lock, flags); + set_lizard_mode = !steam->client_opened && lizard_mode; +spin_unlock_irqrestore (&steam->lock, flags); +if (set_lizard_mode)steam_set_lizard_mode (steam, true); -mutex_unlock (&steam->mutex); }static enum power_supply_property steam_battery_props[] = {
@@ -624,6 +649,7 @@ static int steam_register(struct steam_device *steam) {int ret;bool client_opened; +unsigned long flags;/* * This function can be called several times in a row with the
@@ -636,11 +662,9 @@ static int steam_register(struct steam_device *steam)* Unlikely, but getting the serial could fail, and it is not so * important, so make up a serial number and go on. */ -mutex_lock (&steam->mutex);if (steam_get_serial (steam) <0 )strscpy (steam->serial_no,"XXXXXXXXXX" ,sizeof (steam->serial_no)); -mutex_unlock (&steam->mutex);hid_info (steam->hdev,"Steam Controller '%s' connected" , steam->serial_no);
@@ -655,15 +679,13 @@ static int steam_register(struct steam_device *steam)mutex_unlock (&steam_devices_lock); } -mutex_lock (&steam->mutex); +spin_lock_irqsave (&steam->lock, flags); client_opened = steam->client_opened; -if (!client_opened) +spin_unlock_irqrestore (&steam->lock, flags); +if (!client_opened) {steam_set_lizard_mode (steam, lizard_mode); -mutex_unlock (&steam->mutex); - -if (!client_opened) ret =steam_input_register (steam); -else + }else ret =0 ;return ret;
@@ -746,10 +768,11 @@ static void steam_client_ll_stop(struct hid_device *hdev)static int steam_client_ll_open (struct hid_device *hdev) {struct steam_device *steam = hdev->driver_data; +unsigned long flags; -mutex_lock (&steam->mutex); +spin_lock_irqsave (&steam->lock, flags); steam->client_opened = true; -mutex_unlock (&steam->mutex); +spin_unlock_irqrestore (&steam->lock, flags);steam_input_unregister (steam);
@@ -764,17 +787,14 @@ static void steam_client_ll_close(struct hid_device *hdev)bool connected;spin_lock_irqsave (&steam->lock, flags); - connected = steam->connected; + steam->client_opened = false; + connected = steam->connected && !steam->client_opened;spin_unlock_irqrestore (&steam->lock, flags); -mutex_lock (&steam->mutex); - steam->client_opened = false; -if (connected) +if (connected) {steam_set_lizard_mode (steam, lizard_mode); -mutex_unlock (&steam->mutex); - -if (connected)steam_input_register (steam); + } } static int steam_client_ll_raw_request(struct hid_device *hdev,
@@ -860,19 +880,12 @@ static int steam_probe(struct hid_device *hdev, steam->hdev = hdev;hid_set_drvdata (hdev, steam);spin_lock_init (&steam->lock); -mutex_init (&steam->mutex); +mutex_init (&steam->report_mutex); steam->quirks = id->driver_data;INIT_WORK (&steam->work_connect, steam_work_connect_cb);INIT_LIST_HEAD (&steam->list);INIT_WORK (&steam->rumble_work, steam_haptic_rumble_cb); - steam->client_hdev =steam_create_client_hid (hdev); -if (IS_ERR (steam->client_hdev)) { - ret =PTR_ERR (steam->client_hdev); - goto client_hdev_fail; - } - steam->client_hdev->driver_data = steam; -/* * With the real steam controller interface, do not connect hidraw. * Instead, create the client_hid and connect that.
@@ -881,10 +894,6 @@ static int steam_probe(struct hid_device *hdev,if (ret) goto hid_hw_start_fail; - ret =hid_add_device (steam->client_hdev); -if (ret) - goto client_hdev_add_fail; - ret =hid_hw_open (hdev);if (ret) { hid_err(hdev,
@@ -910,15 +919,26 @@ static int steam_probe(struct hid_device *hdev, } } + steam->client_hdev =steam_create_client_hid (hdev); +if (IS_ERR (steam->client_hdev)) { + ret =PTR_ERR (steam->client_hdev); + goto client_hdev_fail; + } + steam->client_hdev->driver_data = steam; + + ret =hid_add_device (steam->client_hdev); +if (ret) + goto client_hdev_add_fail; +return 0 ; -input_register_fail: -hid_hw_open_fail: client_hdev_add_fail:hid_hw_stop (hdev); -hid_hw_start_fail: -hid_destroy_device (steam->client_hdev); client_hdev_fail: +hid_destroy_device (steam->client_hdev); +input_register_fail: +hid_hw_open_fail: +hid_hw_start_fail:cancel_work_sync (&steam->work_connect);cancel_work_sync (&steam->rumble_work); steam_alloc_fail:
@@ -936,12 +956,10 @@ static void steam_remove(struct hid_device *hdev)return ; } +cancel_work_sync (&steam->work_connect);hid_destroy_device (steam->client_hdev); -mutex_lock (&steam->mutex); steam->client_hdev =NULL ; steam->client_opened = false; -mutex_unlock (&steam->mutex); -cancel_work_sync (&steam->work_connect);if (steam->quirks &STEAM_QUIRK_WIRELESS ) {hid_info (hdev,"Steam wireless receiver disconnected" ); }
@@ -1408,10 +1426,8 @@ static int steam_param_set_lizard_mode(const char *val,mutex_lock (&steam_devices_lock);list_for_each_entry (steam, &steam_devices, list) { -mutex_lock (&steam->mutex);if (!steam->client_opened)steam_set_lizard_mode (steam, lizard_mode); -mutex_unlock (&steam->mutex); }mutex_unlock (&steam_devices_lock);return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 114/152 HID: hid-steam: Update list of identifiers from SDL
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit 4f9a5a9769cc77075e606537e15747e8b8e9c7c9 ]
SDL includes a list of settings (formerly called registers in this driver), reports (formerly cmds), and various other identifiers that were provided by Valve. This commit imports a significant chunk of that list as well as replacing most of the guessed names and a handful of magic constants. It also replaces bitmask definitions that used hex with the BIT macro.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 286 +++++++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 65 deletions(-)
drivers/hid/hid-steam.c +221 -65
@@ -71,51 +71,207 @@ static LIST_HEAD(steam_devices);/* * Commands that can be sent in a feature report. -* Thanks to Valve for some valuable hints. +* Thanks to Valve and SDL for the names. */ -#define STEAM_CMD_SET_MAPPINGS 0x80 -#define STEAM_CMD_CLEAR_MAPPINGS 0x81 -#define STEAM_CMD_GET_MAPPINGS 0x82 -#define STEAM_CMD_GET_ATTRIB 0x83 -#define STEAM_CMD_GET_ATTRIB_LABEL 0x84 -#define STEAM_CMD_DEFAULT_MAPPINGS 0x85 -#define STEAM_CMD_FACTORY_RESET 0x86 -#define STEAM_CMD_WRITE_REGISTER 0x87 -#define STEAM_CMD_CLEAR_REGISTER 0x88 -#define STEAM_CMD_READ_REGISTER 0x89 -#define STEAM_CMD_GET_REGISTER_LABEL 0x8a -#define STEAM_CMD_GET_REGISTER_MAX 0x8b -#define STEAM_CMD_GET_REGISTER_DEFAULT 0x8c -#define STEAM_CMD_SET_MODE 0x8d -#define STEAM_CMD_DEFAULT_MOUSE 0x8e -#define STEAM_CMD_FORCEFEEDBAK 0x8f -#define STEAM_CMD_REQUEST_COMM_STATUS 0xb4 -#define STEAM_CMD_GET_SERIAL 0xae -#define STEAM_CMD_HAPTIC_RUMBLE 0xeb - -/* Some useful register ids */ -#define STEAM_REG_LPAD_MODE 0x07 -#define STEAM_REG_RPAD_MODE 0x08 -#define STEAM_REG_RPAD_MARGIN 0x18 -#define STEAM_REG_LED 0x2d -#define STEAM_REG_GYRO_MODE 0x30 -#define STEAM_REG_LPAD_CLICK_PRESSURE 0x34 -#define STEAM_REG_RPAD_CLICK_PRESSURE 0x35 -#define STEAM_REG_WATCHDOG_ENABLE 0x47 - -/* Raw event identifiers */ -#define STEAM_EV_INPUT_DATA 0x01 -#define STEAM_EV_CONNECT 0x03 -#define STEAM_EV_BATTERY 0x04 -#define STEAM_EV_DECK_INPUT_DATA 0x09 +enum { +ID_SET_DIGITAL_MAPPINGS =0x80 , +ID_CLEAR_DIGITAL_MAPPINGS =0x81 , +ID_GET_DIGITAL_MAPPINGS =0x82 , +ID_GET_ATTRIBUTES_VALUES =0x83 , +ID_GET_ATTRIBUTE_LABEL =0x84 , +ID_SET_DEFAULT_DIGITAL_MAPPINGS =0x85 , +ID_FACTORY_RESET =0x86 , +ID_SET_SETTINGS_VALUES =0x87 , +ID_CLEAR_SETTINGS_VALUES =0x88 , +ID_GET_SETTINGS_VALUES =0x89 , +ID_GET_SETTING_LABEL =0x8A , +ID_GET_SETTINGS_MAXS =0x8B , +ID_GET_SETTINGS_DEFAULTS =0x8C , +ID_SET_CONTROLLER_MODE =0x8D , +ID_LOAD_DEFAULT_SETTINGS =0x8E , +ID_TRIGGER_HAPTIC_PULSE =0x8F , +ID_TURN_OFF_CONTROLLER =0x9F , + +ID_GET_DEVICE_INFO =0xA1 , + +ID_CALIBRATE_TRACKPADS =0xA7 , +ID_RESERVED_0 =0xA8 , +ID_SET_SERIAL_NUMBER =0xA9 , +ID_GET_TRACKPAD_CALIBRATION =0xAA , +ID_GET_TRACKPAD_FACTORY_CALIBRATION =0xAB , +ID_GET_TRACKPAD_RAW_DATA =0xAC , +ID_ENABLE_PAIRING =0xAD , +ID_GET_STRING_ATTRIBUTE =0xAE , +ID_RADIO_ERASE_RECORDS =0xAF , +ID_RADIO_WRITE_RECORD =0xB0 , +ID_SET_DONGLE_SETTING =0xB1 , +ID_DONGLE_DISCONNECT_DEVICE =0xB2 , +ID_DONGLE_COMMIT_DEVICE =0xB3 , +ID_DONGLE_GET_WIRELESS_STATE =0xB4 , +ID_CALIBRATE_GYRO =0xB5 , +ID_PLAY_AUDIO =0xB6 , +ID_AUDIO_UPDATE_START =0xB7 , +ID_AUDIO_UPDATE_DATA =0xB8 , +ID_AUDIO_UPDATE_COMPLETE =0xB9 , +ID_GET_CHIPID =0xBA , + +ID_CALIBRATE_JOYSTICK =0xBF , +ID_CALIBRATE_ANALOG_TRIGGERS =0xC0 , +ID_SET_AUDIO_MAPPING =0xC1 , +ID_CHECK_GYRO_FW_LOAD =0xC2 , +ID_CALIBRATE_ANALOG =0xC3 , +ID_DONGLE_GET_CONNECTED_SLOTS =0xC4 , + +ID_RESET_IMU =0xCE , + +ID_TRIGGER_HAPTIC_CMD =0xEA , +ID_TRIGGER_RUMBLE_CMD =0xEB , +}; + +/* Settings IDs */ +enum { +/* 0 */ +SETTING_MOUSE_SENSITIVITY , +SETTING_MOUSE_ACCELERATION , +SETTING_TRACKBALL_ROTATION_ANGLE , +SETTING_HAPTIC_INTENSITY_UNUSED , +SETTING_LEFT_GAMEPAD_STICK_ENABLED , +SETTING_RIGHT_GAMEPAD_STICK_ENABLED , +SETTING_USB_DEBUG_MODE , +SETTING_LEFT_TRACKPAD_MODE , +SETTING_RIGHT_TRACKPAD_MODE , +SETTING_MOUSE_POINTER_ENABLED , + +/* 10 */ +SETTING_DPAD_DEADZONE , +SETTING_MINIMUM_MOMENTUM_VEL , +SETTING_MOMENTUM_DECAY_AMMOUNT , +SETTING_TRACKPAD_RELATIVE_MODE_TICKS_PER_PIXEL , +SETTING_HAPTIC_INCREMENT , +SETTING_DPAD_ANGLE_SIN , +SETTING_DPAD_ANGLE_COS , +SETTING_MOMENTUM_VERTICAL_DIVISOR , +SETTING_MOMENTUM_MAXIMUM_VELOCITY , +SETTING_TRACKPAD_Z_ON , + +/* 20 */ +SETTING_TRACKPAD_Z_OFF , +SETTING_SENSITIVY_SCALE_AMMOUNT , +SETTING_LEFT_TRACKPAD_SECONDARY_MODE , +SETTING_RIGHT_TRACKPAD_SECONDARY_MODE , +SETTING_SMOOTH_ABSOLUTE_MOUSE , +SETTING_STEAMBUTTON_POWEROFF_TIME , +SETTING_UNUSED_1 , +SETTING_TRACKPAD_OUTER_RADIUS , +SETTING_TRACKPAD_Z_ON_LEFT , +SETTING_TRACKPAD_Z_OFF_LEFT , + +/* 30 */ +SETTING_TRACKPAD_OUTER_SPIN_VEL , +SETTING_TRACKPAD_OUTER_SPIN_RADIUS , +SETTING_TRACKPAD_OUTER_SPIN_HORIZONTAL_ONLY , +SETTING_TRACKPAD_RELATIVE_MODE_DEADZONE , +SETTING_TRACKPAD_RELATIVE_MODE_MAX_VEL , +SETTING_TRACKPAD_RELATIVE_MODE_INVERT_Y , +SETTING_TRACKPAD_DOUBLE_TAP_BEEP_ENABLED , +SETTING_TRACKPAD_DOUBLE_TAP_BEEP_PERIOD , +SETTING_TRACKPAD_DOUBLE_TAP_BEEP_COUNT , +SETTING_TRACKPAD_OUTER_RADIUS_RELEASE_ON_TRANSITION , + +/* 40 */ +SETTING_RADIAL_MODE_ANGLE , +SETTING_HAPTIC_INTENSITY_MOUSE_MODE , +SETTING_LEFT_DPAD_REQUIRES_CLICK , +SETTING_RIGHT_DPAD_REQUIRES_CLICK , +SETTING_LED_BASELINE_BRIGHTNESS , +SETTING_LED_USER_BRIGHTNESS , +SETTING_ENABLE_RAW_JOYSTICK , +SETTING_ENABLE_FAST_SCAN , +SETTING_IMU_MODE , +SETTING_WIRELESS_PACKET_VERSION , + +/* 50 */ +SETTING_SLEEP_INACTIVITY_TIMEOUT , +SETTING_TRACKPAD_NOISE_THRESHOLD , +SETTING_LEFT_TRACKPAD_CLICK_PRESSURE , +SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE , +SETTING_LEFT_BUMPER_CLICK_PRESSURE , +SETTING_RIGHT_BUMPER_CLICK_PRESSURE , +SETTING_LEFT_GRIP_CLICK_PRESSURE , +SETTING_RIGHT_GRIP_CLICK_PRESSURE , +SETTING_LEFT_GRIP2_CLICK_PRESSURE , +SETTING_RIGHT_GRIP2_CLICK_PRESSURE , + +/* 60 */ +SETTING_PRESSURE_MODE , +SETTING_CONTROLLER_TEST_MODE , +SETTING_TRIGGER_MODE , +SETTING_TRACKPAD_Z_THRESHOLD , +SETTING_FRAME_RATE , +SETTING_TRACKPAD_FILT_CTRL , +SETTING_TRACKPAD_CLIP , +SETTING_DEBUG_OUTPUT_SELECT , +SETTING_TRIGGER_THRESHOLD_PERCENT , +SETTING_TRACKPAD_FREQUENCY_HOPPING , + +/* 70 */ +SETTING_HAPTICS_ENABLED , +SETTING_STEAM_WATCHDOG_ENABLE , +SETTING_TIMP_TOUCH_THRESHOLD_ON , +SETTING_TIMP_TOUCH_THRESHOLD_OFF , +SETTING_FREQ_HOPPING , +SETTING_TEST_CONTROL , +SETTING_HAPTIC_MASTER_GAIN_DB , +SETTING_THUMB_TOUCH_THRESH , +SETTING_DEVICE_POWER_STATUS , +SETTING_HAPTIC_INTENSITY , + +/* 80 */ +SETTING_STABILIZER_ENABLED , +SETTING_TIMP_MODE_MTE , +}; + +/* Input report identifiers */ +enum +{ +ID_CONTROLLER_STATE =1 , +ID_CONTROLLER_DEBUG =2 , +ID_CONTROLLER_WIRELESS =3 , +ID_CONTROLLER_STATUS =4 , +ID_CONTROLLER_DEBUG2 =5 , +ID_CONTROLLER_SECONDARY_STATE =6 , +ID_CONTROLLER_BLE_STATE =7 , +ID_CONTROLLER_DECK_STATE =9 +}; + +/* String attribute idenitifiers */ +enum { +ATTRIB_STR_BOARD_SERIAL , +ATTRIB_STR_UNIT_SERIAL , +};/* Values for GYRO_MODE (bitmask) */ -#define STEAM_GYRO_MODE_OFF 0x0000 -#define STEAM_GYRO_MODE_STEERING 0x0001 -#define STEAM_GYRO_MODE_TILT 0x0002 -#define STEAM_GYRO_MODE_SEND_ORIENTATION 0x0004 -#define STEAM_GYRO_MODE_SEND_RAW_ACCEL 0x0008 -#define STEAM_GYRO_MODE_SEND_RAW_GYRO 0x0010 +enum { +SETTING_GYRO_MODE_OFF =0 , +SETTING_GYRO_MODE_STEERING =BIT (0 ), +SETTING_GYRO_MODE_TILT =BIT (1 ), +SETTING_GYRO_MODE_SEND_ORIENTATION =BIT (2 ), +SETTING_GYRO_MODE_SEND_RAW_ACCEL =BIT (3 ), +SETTING_GYRO_MODE_SEND_RAW_GYRO =BIT (4 ), +}; + +/* Trackpad modes */ +enum { +TRACKPAD_ABSOLUTE_MOUSE , +TRACKPAD_RELATIVE_MOUSE , +TRACKPAD_DPAD_FOUR_WAY_DISCRETE , +TRACKPAD_DPAD_FOUR_WAY_OVERLAP , +TRACKPAD_DPAD_EIGHT_WAY , +TRACKPAD_RADIAL_MODE , +TRACKPAD_ABSOLUTE_DPAD , +TRACKPAD_NONE , +TRACKPAD_GESTURE_KEYBOARD , +};/* Other random constants */ #define STEAM_SERIAL_LEN 10
@@ -226,13 +382,13 @@ static inline int steam_send_report_byte(struct steam_device *steam, u8 cmd)return steam_send_report (steam, &cmd,1 ); } -static int steam_write_registers (struct steam_device *steam, +static int steam_write_settings (struct steam_device *steam,/* u8 reg, u16 val */ ...) {/* Send: 0x87 len (reg valLo valHi)* */ u8 reg;u16 val; -u8 cmd[64 ] = {STEAM_CMD_WRITE_REGISTER ,0x00 }; +u8 cmd[64 ] = {ID_SET_SETTINGS_VALUES ,0x00 };int ret;va_list args;
@@ -268,7 +424,7 @@ static int steam_get_serial(struct steam_device *steam)* Recv: 0xae 0x15 0x01 serialnumber (10 chars) */ int ret =0 ; -u8 cmd[] = {STEAM_CMD_GET_SERIAL ,0x15 ,0x01 }; +u8 cmd[] = {ID_GET_STRING_ATTRIBUTE ,0x15 ,ATTRIB_STR_UNIT_SERIAL };u8 reply[3 +STEAM_SERIAL_LEN +1 ];mutex_lock (&steam->report_mutex);
@@ -278,7 +434,7 @@ static int steam_get_serial(struct steam_device *steam) ret =steam_recv_report (steam, reply,sizeof (reply));if (ret <0 ) goto out; -if (reply[0 ] !=0xae || reply[1 ] !=0x15 || reply[2 ] !=0x01 ) { +if (reply[0 ] !=ID_GET_STRING_ATTRIBUTE || reply[1 ] !=0x15 || reply[2 ] !=ATTRIB_STR_UNIT_SERIAL ) { ret = -EIO ; goto out; }
@@ -298,7 +454,7 @@ static inline int steam_request_conn_status(struct steam_device *steam) {int ret;mutex_lock (&steam->report_mutex); - ret =steam_send_report_byte (steam,STEAM_CMD_REQUEST_COMM_STATUS ); + ret =steam_send_report_byte (steam,ID_DONGLE_GET_WIRELESS_STATE );mutex_unlock (&steam->report_mutex);return ret; }
@@ -308,7 +464,7 @@ static inline int steam_haptic_rumble(struct steam_device *steam, u8 left_gain, u8 right_gain) { int ret; -u8 report[11 ] = {STEAM_CMD_HAPTIC_RUMBLE ,9 }; +u8 report[11 ] = {ID_TRIGGER_RUMBLE_CMD ,9 }; report[3 ] = intensity &0xFF ; report[4 ] = intensity >>8 ;
@@ -351,28 +507,28 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)if (enable) {mutex_lock (&steam->report_mutex);/* enable esc, enter, cursors */ -steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MAPPINGS ); -/* enable mouse */ -steam_send_report_byte (steam,STEAM_CMD_DEFAULT_MOUSE ); +steam_send_report_byte (steam,ID_SET_DEFAULT_DIGITAL_MAPPINGS ); +/* reset settings */ +steam_send_report_byte (steam,ID_LOAD_DEFAULT_SETTINGS );mutex_unlock (&steam->report_mutex); }else {mutex_lock (&steam->report_mutex);/* disable esc, enter, cursor */ -steam_send_report_byte (steam,STEAM_CMD_CLEAR_MAPPINGS ); +steam_send_report_byte (steam,ID_CLEAR_DIGITAL_MAPPINGS );if (steam->quirks &STEAM_QUIRK_DECK ) { -steam_write_registers (steam, -STEAM_REG_LPAD_MODE ,0x07 ,/* disable mouse */ -STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ -STEAM_REG_LPAD_CLICK_PRESSURE ,0xFFFF ,/* disable clicky pad */ -STEAM_REG_RPAD_CLICK_PRESSURE ,0xFFFF ,/* disable clicky pad */ -STEAM_REG_WATCHDOG_ENABLE ,0 ,/* disable watchdog that tests if Steam is active */ +steam_write_settings (steam, +SETTING_LEFT_TRACKPAD_MODE ,TRACKPAD_NONE ,/* disable mouse */ +SETTING_RIGHT_TRACKPAD_MODE ,TRACKPAD_NONE ,/* disable mouse */ +SETTING_LEFT_TRACKPAD_CLICK_PRESSURE ,0xFFFF ,/* disable haptic click */ +SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE ,0xFFFF ,/* disable haptic click */ +SETTING_STEAM_WATCHDOG_ENABLE ,0 ,/* disable watchdog that tests if Steam is active */ 0 );mutex_unlock (&steam->report_mutex); }else { -steam_write_registers (steam, -STEAM_REG_LPAD_MODE ,0x07 ,/* disable mouse */ -STEAM_REG_RPAD_MODE ,0x07 ,/* disable mouse */ +steam_write_settings (steam, +SETTING_LEFT_TRACKPAD_MODE ,TRACKPAD_NONE ,/* disable mouse */ +SETTING_RIGHT_TRACKPAD_MODE ,TRACKPAD_NONE ,/* disable mouse */ 0 );mutex_unlock (&steam->report_mutex); }
@@ -1362,7 +1518,7 @@ static int steam_raw_event(struct hid_device *hdev,return 0 ;switch (data[2 ]) { -case STEAM_EV_INPUT_DATA : +case ID_CONTROLLER_STATE :if (steam->client_opened)return 0 ;rcu_read_lock ();
@@ -1371,7 +1527,7 @@ static int steam_raw_event(struct hid_device *hdev,steam_do_input_event (steam, input, data);rcu_read_unlock ();break ; -case STEAM_EV_DECK_INPUT_DATA : +case ID_CONTROLLER_DECK_STATE :if (steam->client_opened)return 0 ;rcu_read_lock ();
@@ -1380,7 +1536,7 @@ static int steam_raw_event(struct hid_device *hdev,steam_do_deck_input_event (steam, input, data);rcu_read_unlock ();break ; -case STEAM_EV_CONNECT : +case ID_CONTROLLER_WIRELESS :/* * The payload of this event is a single byte: * 0x01: disconnected.
@@ -1395,7 +1551,7 @@ static int steam_raw_event(struct hid_device *hdev,break ; }break ; -case STEAM_EV_BATTERY : +case ID_CONTROLLER_STATUS :if (steam->quirks &STEAM_QUIRK_WIRELESS ) {rcu_read_lock (); battery =rcu_dereference (steam->battery);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 115/152 HID: hid-steam: Add gamepad-only mode switched to by holding options
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit cd438e57dd05b077f4e87c1567beafb2377b6d6b ]
This commit adds a hotkey to switch between "gamepad" mode (mouse and keyboard disabled) and "desktop" mode (gamepad disabled) by holding down the options button (mapped here as the start button). This mirrors the behavior of the official Steam client.
This also adds and uses a function for generating haptic pulses, as Steam also does when engaging this hotkey.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 113 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 10 deletions(-)
drivers/hid/hid-steam.c +103 -10
@@ -273,6 +273,11 @@ enum { TRACKPAD_GESTURE_KEYBOARD, }; +/* Pad identifiers for the deck */ +#define STEAM_PAD_LEFT 0 +#define STEAM_PAD_RIGHT 1 +#define STEAM_PAD_BOTH 2 +/* Other random constants */ #define STEAM_SERIAL_LEN 10
@@ -291,6 +296,9 @@ struct steam_device {struct power_supply __rcu *battery;u8 battery_charge;u16 voltage; +struct delayed_work mode_switch; +bool did_mode_switch; +bool gamepad_mode;struct work_struct rumble_work;u16 rumble_left;u16 rumble_right;
@@ -459,6 +467,37 @@ static inline int steam_request_conn_status(struct steam_device *steam)return ret; } +/* +* Send a haptic pulse to the trackpads +* Duration and interval are measured in microseconds, count is the number +* of pulses to send for duration time with interval microseconds between them +* and gain is measured in decibels, ranging from -24 to +6 +*/ +static inline int steam_haptic_pulse (struct steam_device *steam,u8 pad, +u16 duration,u16 interval,u16 count,u8 gain) +{ +int ret; +u8 report[10 ] = {ID_TRIGGER_HAPTIC_PULSE ,8 }; + +/* Left and right are swapped on this report for legacy reasons */ +if (pad <STEAM_PAD_BOTH ) + pad ^=1 ; + + report[2 ] = pad; + report[3 ] = duration &0xFF ; + report[4 ] = duration >>8 ; + report[5 ] = interval &0xFF ; + report[6 ] = interval >>8 ; + report[7 ] = count &0xFF ; + report[8 ] = count >>8 ; + report[9 ] = gain; + +mutex_lock (&steam->report_mutex); + ret =steam_send_report (steam, report,sizeof (report)); +mutex_unlock (&steam->report_mutex); +return ret; +} +static inline int steam_haptic_rumble (struct steam_device *steam,u16 intensity,u16 left_speed,u16 right_speed,u8 left_gain,u8 right_gain)
@@ -504,6 +543,9 @@ static int steam_play_effect(struct input_dev *dev, void *data,static void steam_set_lizard_mode (struct steam_device *steam,bool enable) { +if (steam->gamepad_mode) + enable = false; +if (enable) {mutex_lock (&steam->report_mutex);/* enable esc, enter, cursors */
@@ -541,11 +583,18 @@ static int steam_input_open(struct input_dev *dev)unsigned long flags;bool set_lizard_mode; -spin_lock_irqsave (&steam->lock, flags); - set_lizard_mode = !steam->client_opened && lizard_mode; -spin_unlock_irqrestore (&steam->lock, flags); -if (set_lizard_mode) -steam_set_lizard_mode (steam, false); +/* +* Disabling lizard mode automatically is only done on the Steam +* Controller. On the Steam Deck, this is toggled manually by holding +* the options button instead, handled by steam_mode_switch_cb. +*/ +if (!(steam->quirks &STEAM_QUIRK_DECK )) { +spin_lock_irqsave (&steam->lock, flags); + set_lizard_mode = !steam->client_opened && lizard_mode; +spin_unlock_irqrestore (&steam->lock, flags); +if (set_lizard_mode) +steam_set_lizard_mode (steam, false); + }return 0 ; }
@@ -556,11 +605,13 @@ static void steam_input_close(struct input_dev *dev)unsigned long flags;bool set_lizard_mode; -spin_lock_irqsave (&steam->lock, flags); - set_lizard_mode = !steam->client_opened && lizard_mode; -spin_unlock_irqrestore (&steam->lock, flags); -if (set_lizard_mode) -steam_set_lizard_mode (steam, true); +if (!(steam->quirks &STEAM_QUIRK_DECK )) { +spin_lock_irqsave (&steam->lock, flags); + set_lizard_mode = !steam->client_opened && lizard_mode; +spin_unlock_irqrestore (&steam->lock, flags); +if (set_lizard_mode) +steam_set_lizard_mode (steam, true); + } }static enum power_supply_property steam_battery_props[] = {
@@ -885,6 +936,34 @@ static void steam_work_connect_cb(struct work_struct *work) } } +static void steam_mode_switch_cb (struct work_struct *work) +{ +struct steam_device *steam =container_of (to_delayed_work (work), + struct steam_device, mode_switch); +unsigned long flags; +bool client_opened; + steam->gamepad_mode = !steam->gamepad_mode; +if (!lizard_mode) +return ; + +if (steam->gamepad_mode) +steam_set_lizard_mode (steam, false); +else { +spin_lock_irqsave (&steam->lock, flags); + client_opened = steam->client_opened; +spin_unlock_irqrestore (&steam->lock, flags); +if (!client_opened) +steam_set_lizard_mode (steam, lizard_mode); + } + +steam_haptic_pulse (steam,STEAM_PAD_RIGHT ,0x190 ,0 ,1 ,0 ); +if (steam->gamepad_mode) { +steam_haptic_pulse (steam,STEAM_PAD_LEFT ,0x14D ,0x14D ,0x2D ,0 ); + }else { +steam_haptic_pulse (steam,STEAM_PAD_LEFT ,0x1F4 ,0x1F4 ,0x1E ,0 ); + } +} +static bool steam_is_valve_interface (struct hid_device *hdev) {struct hid_report_enum *rep_enum;
@@ -1039,6 +1118,7 @@ static int steam_probe(struct hid_device *hdev,mutex_init (&steam->report_mutex); steam->quirks = id->driver_data;INIT_WORK (&steam->work_connect, steam_work_connect_cb); +INIT_DELAYED_WORK (&steam->mode_switch, steam_mode_switch_cb);INIT_LIST_HEAD (&steam->list);INIT_WORK (&steam->rumble_work, steam_haptic_rumble_cb);
@@ -1096,6 +1176,7 @@ static int steam_probe(struct hid_device *hdev, hid_hw_open_fail: hid_hw_start_fail:cancel_work_sync (&steam->work_connect); +cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->rumble_work); steam_alloc_fail: hid_err(hdev, "%s: failed with error %d\n",
@@ -1112,6 +1193,7 @@ static void steam_remove(struct hid_device *hdev)return ; } +cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->work_connect);hid_destroy_device (steam->client_hdev); steam->client_hdev =NULL ;
@@ -1397,6 +1479,17 @@ static void steam_do_deck_input_event(struct steam_device *steam, b13 = data[13 ]; b14 = data[14 ]; +if (!(b9 &BIT (6 )) && steam->did_mode_switch) { + steam->did_mode_switch = false; +cancel_delayed_work_sync (&steam->mode_switch); + }else if (!steam->client_opened && (b9 &BIT (6 )) && !steam->did_mode_switch) { + steam->did_mode_switch = true; +schedule_delayed_work (&steam->mode_switch,45 *HZ /100 ); + } + +if (!steam->gamepad_mode) +return ; + lpad_touched = b10 &BIT (3 ); rpad_touched = b10 &BIT (4 );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 116/152 HID: hid-steam: remove pointless error message
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit a9668169961106f3598384fe95004106ec191201 ]
This error message doesn't really add any information. If modprobe fails then the user will already know what the error code is. In the case of kmalloc() it's a style violation to print an error message for that because kmalloc has it's own better error messages built in.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/hid/hid-steam.c +3 -7
@@ -1108,10 +1108,9 @@ static int steam_probe(struct hid_device *hdev,return hid_hw_start (hdev,HID_CONNECT_DEFAULT ); steam =devm_kzalloc (&hdev->dev,sizeof (*steam),GFP_KERNEL ); -if (!steam) { - ret = -ENOMEM ; - goto steam_alloc_fail; - } +if (!steam) +return -ENOMEM ; + steam->hdev = hdev;hid_set_drvdata (hdev, steam);spin_lock_init (&steam->lock);
@@ -1178,9 +1177,6 @@ static int steam_probe(struct hid_device *hdev,cancel_work_sync (&steam->work_connect);cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->rumble_work); -steam_alloc_fail: -hid_err (hdev,"%s: failed with error %d\n" , - __func__, ret);return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 117/152 HID: hid-steam: Fix cleanup in probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit a9f1da09c69f13ef471db8b22107a28042d230ca ]
There are a number of issues in this code. First of all if steam_create_client_hid() fails then it leads to an error pointer dereference when we call hid_destroy_device(steam->client_hdev).
Also there are a number of leaks. hid_hw_stop() is not called if hid_hw_open() fails for example. And it doesn't call steam_unregister() or hid_hw_close().
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/hid/hid-steam.c +15 -11
@@ -1127,14 +1127,14 @@ static int steam_probe(struct hid_device *hdev,*/ ret =hid_hw_start (hdev,HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW );if (ret) - goto hid_hw_start_fail; + goto err_cancel_work; ret =hid_hw_open (hdev);if (ret) {hid_err (hdev,"%s:hid_hw_open\n" , __func__); - goto hid_hw_open_fail; + goto err_hw_stop; }if (steam->quirks &STEAM_QUIRK_WIRELESS ) {
@@ -1150,33 +1150,37 @@ static int steam_probe(struct hid_device *hdev,hid_err (hdev,"%s:steam_register failed with error %d\n" , __func__, ret); - goto input_register_fail; + goto err_hw_close; } } steam->client_hdev =steam_create_client_hid (hdev);if (IS_ERR (steam->client_hdev)) { ret =PTR_ERR (steam->client_hdev); - goto client_hdev_fail; + goto err_stream_unregister; } steam->client_hdev->driver_data = steam; ret =hid_add_device (steam->client_hdev);if (ret) - goto client_hdev_add_fail; + goto err_destroy;return 0 ; -client_hdev_add_fail: -hid_hw_stop (hdev); -client_hdev_fail: +err_destroy:hid_destroy_device (steam->client_hdev); -input_register_fail: -hid_hw_open_fail: -hid_hw_start_fail: +err_stream_unregister: +if (steam->connected) +steam_unregister (steam); +err_hw_close: +hid_hw_close (hdev); +err_hw_stop: +hid_hw_stop (hdev); +err_cancel_work:cancel_work_sync (&steam->work_connect);cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->rumble_work); +return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 118/152 HID: hid-steam: Add Deck IMU support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Maisel <[email protected]>
[ Upstream commit 3347e1654f24dbbd357ea4e3c0d8dcc12d8586c7 ]
The Deck's controller features an accelerometer and gyroscope which send their measurement values by default in the main HID input report. Expose both sensors to userspace through a separate evdev node as it is done by the hid-nintendo and hid-playstation drivers.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 155 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 147 insertions(+), 8 deletions(-)
drivers/hid/hid-steam.c +147 -8
@@ -66,6 +66,14 @@ static LIST_HEAD(steam_devices);#define STEAM_DECK_TRIGGER_RESOLUTION 5461/* Joystick runs are about 5 mm and 32768 units */ #define STEAM_DECK_JOYSTICK_RESOLUTION 6553 +/* Accelerometer has 16 bit resolution and a range of +/- 2g */ +#define STEAM_DECK_ACCEL_RES_PER_G 16384 +#define STEAM_DECK_ACCEL_RANGE 32768 +#define STEAM_DECK_ACCEL_FUZZ 32 +/* Gyroscope has 16 bit resolution and a range of +/- 2000 dps */ +#define STEAM_DECK_GYRO_RES_PER_DPS 16 +#define STEAM_DECK_GYRO_RANGE 32768 +#define STEAM_DECK_GYRO_FUZZ 1#define STEAM_PAD_FUZZ 256
@@ -288,6 +296,7 @@ struct steam_device {struct mutex report_mutex;bool client_opened;struct input_dev __rcu *input; +struct input_dev __rcu *sensors;unsigned long quirks;struct work_struct work_connect;bool connected;
@@ -302,6 +311,7 @@ struct steam_device {struct work_struct rumble_work;u16 rumble_left;u16 rumble_right; +unsigned int sensor_timestamp_us; }; static int steam_recv_report(struct steam_device *steam,
@@ -824,6 +834,74 @@ static int steam_input_register(struct steam_device *steam)return ret; } +static int steam_sensors_register (struct steam_device *steam) +{ +struct hid_device *hdev = steam->hdev; +struct input_dev *sensors; +int ret; + +if (!(steam->quirks &STEAM_QUIRK_DECK )) +return 0 ; + +rcu_read_lock (); + sensors =rcu_dereference (steam->sensors); +rcu_read_unlock (); +if (sensors) { +dbg_hid ("%s: already connected\n" , __func__); +return 0 ; + } + + sensors =input_allocate_device (); +if (!sensors) +return -ENOMEM ; + +input_set_drvdata (sensors, steam); + sensors->dev.parent = &hdev->dev; + + sensors->name ="Steam Deck Motion Sensors" ; + sensors->phys = hdev->phys; + sensors->uniq = steam->serial_no; + sensors->id.bustype = hdev->bus; + sensors->id.vendor = hdev->vendor; + sensors->id.product = hdev->product; + sensors->id.version = hdev->version; + +__set_bit (INPUT_PROP_ACCELEROMETER , sensors->propbit); +__set_bit (EV_MSC , sensors->evbit); +__set_bit (MSC_TIMESTAMP , sensors->mscbit); + +input_set_abs_params (sensors,ABS_X , -STEAM_DECK_ACCEL_RANGE , +STEAM_DECK_ACCEL_RANGE ,STEAM_DECK_ACCEL_FUZZ ,0 ); +input_set_abs_params (sensors,ABS_Y , -STEAM_DECK_ACCEL_RANGE , +STEAM_DECK_ACCEL_RANGE ,STEAM_DECK_ACCEL_FUZZ ,0 ); +input_set_abs_params (sensors,ABS_Z , -STEAM_DECK_ACCEL_RANGE , +STEAM_DECK_ACCEL_RANGE ,STEAM_DECK_ACCEL_FUZZ ,0 ); +input_abs_set_res (sensors,ABS_X ,STEAM_DECK_ACCEL_RES_PER_G ); +input_abs_set_res (sensors,ABS_Y ,STEAM_DECK_ACCEL_RES_PER_G ); +input_abs_set_res (sensors,ABS_Z ,STEAM_DECK_ACCEL_RES_PER_G ); + +input_set_abs_params (sensors,ABS_RX , -STEAM_DECK_GYRO_RANGE , +STEAM_DECK_GYRO_RANGE ,STEAM_DECK_GYRO_FUZZ ,0 ); +input_set_abs_params (sensors,ABS_RY , -STEAM_DECK_GYRO_RANGE , +STEAM_DECK_GYRO_RANGE ,STEAM_DECK_GYRO_FUZZ ,0 ); +input_set_abs_params (sensors,ABS_RZ , -STEAM_DECK_GYRO_RANGE , +STEAM_DECK_GYRO_RANGE ,STEAM_DECK_GYRO_FUZZ ,0 ); +input_abs_set_res (sensors,ABS_RX ,STEAM_DECK_GYRO_RES_PER_DPS ); +input_abs_set_res (sensors,ABS_RY ,STEAM_DECK_GYRO_RES_PER_DPS ); +input_abs_set_res (sensors,ABS_RZ ,STEAM_DECK_GYRO_RES_PER_DPS ); + + ret =input_register_device (sensors); +if (ret) + goto sensors_register_fail; + +rcu_assign_pointer (steam->sensors, sensors); +return 0 ; + +sensors_register_fail: +input_free_device (sensors); +return ret; +} +static void steam_input_unregister (struct steam_device *steam) {struct input_dev *input;
@@ -837,6 +915,24 @@ static void steam_input_unregister(struct steam_device *steam)input_unregister_device (input); } +static void steam_sensors_unregister (struct steam_device *steam) +{ +struct input_dev *sensors; + +if (!(steam->quirks &STEAM_QUIRK_DECK )) +return ; + +rcu_read_lock (); + sensors =rcu_dereference (steam->sensors); +rcu_read_unlock (); + +if (!sensors) +return ; +RCU_INIT_POINTER (steam->sensors,NULL ); +synchronize_rcu (); +input_unregister_device (sensors); +} +static void steam_battery_unregister (struct steam_device *steam) {struct power_supply *battery;
@@ -889,18 +985,28 @@ static int steam_register(struct steam_device *steam)spin_lock_irqsave (&steam->lock, flags); client_opened = steam->client_opened;spin_unlock_irqrestore (&steam->lock, flags); +if (!client_opened) {steam_set_lizard_mode (steam, lizard_mode); ret =steam_input_register (steam); - }else - ret =0 ; +if (ret !=0 ) + goto steam_register_input_fail; + ret =steam_sensors_register (steam); +if (ret !=0 ) + goto steam_register_sensors_fail; + } +return 0 ; +steam_register_sensors_fail: +steam_input_unregister (steam); +steam_register_input_fail:return ret; }static void steam_unregister (struct steam_device *steam) {steam_battery_unregister (steam); +steam_sensors_unregister (steam);steam_input_unregister (steam);if (steam->serial_no[0 ]) { hid_info(steam->hdev, "Steam Controller '%s' disconnected",
@@ -1009,6 +1115,7 @@ static int steam_client_ll_open(struct hid_device *hdev) steam->client_opened = true;spin_unlock_irqrestore (&steam->lock, flags); +steam_sensors_unregister (steam);steam_input_unregister (steam);return 0 ;
@@ -1029,6 +1136,7 @@ static void steam_client_ll_close(struct hid_device *hdev)if (connected) {steam_set_lizard_mode (steam, lizard_mode);steam_input_register (steam); +steam_sensors_register (steam); } }
@@ -1120,6 +1228,7 @@ static int steam_probe(struct hid_device *hdev,INIT_DELAYED_WORK (&steam->mode_switch, steam_mode_switch_cb);INIT_LIST_HEAD (&steam->list);INIT_WORK (&steam->rumble_work, steam_haptic_rumble_cb); + steam->sensor_timestamp_us =0 ;/* * With the real steam controller interface, do not connect hidraw.
@@ -1379,12 +1488,12 @@ static void steam_do_input_event(struct steam_device *steam,* 18-19 | s16 | ABS_HAT0Y | left-pad Y value * 20-21 | s16 | ABS_HAT1X | right-pad X value * 22-23 | s16 | ABS_HAT1Y | right-pad Y value -* 24-25 | s16 | -- | accelerometer X value -* 26-27 | s16 | -- | accelerometer Y value -* 28-29 | s16 | -- | accelerometer Z value -* 30-31 | s16 | -- | gyro X value -* 32-33 | s16 | -- | gyro Y value -* 34-35 | s16 | -- | gyro Z value +* 24-25 | s16 | IMU ABS_X | accelerometer X value +* 26-27 | s16 | IMU ABS_Z | accelerometer Y value +* 28-29 | s16 | IMU ABS_Y | accelerometer Z value +* 30-31 | s16 | IMU ABS_RX | gyro X value +* 32-33 | s16 | IMU ABS_RZ | gyro Y value +* 34-35 | s16 | IMU ABS_RY | gyro Z value * 36-37 | s16 | -- | quaternion W value * 38-39 | s16 | -- | quaternion X value * 40-41 | s16 | -- | quaternion Y value
@@ -1545,6 +1654,32 @@ static void steam_do_deck_input_event(struct steam_device *steam,input_sync (input); } +static void steam_do_deck_sensors_event (struct steam_device *steam, +struct input_dev *sensors,u8 *data) +{ +/* +* The deck input report is received every 4 ms on average, +* with a jitter of +/- 4 ms even though the USB descriptor claims +* that it uses 1 kHz. +* Since the HID report does not include a sensor timestamp, +* use a fixed increment here. +*/ + steam->sensor_timestamp_us +=4000 ; + +if (!steam->gamepad_mode) +return ; + +input_event (sensors,EV_MSC ,MSC_TIMESTAMP , steam->sensor_timestamp_us); +input_report_abs (sensors,ABS_X ,steam_le16 (data +24 )); +input_report_abs (sensors,ABS_Z , -steam_le16 (data +26 )); +input_report_abs (sensors,ABS_Y ,steam_le16 (data +28 )); +input_report_abs (sensors,ABS_RX ,steam_le16 (data +30 )); +input_report_abs (sensors,ABS_RZ , -steam_le16 (data +32 )); +input_report_abs (sensors,ABS_RY ,steam_le16 (data +34 )); + +input_sync (sensors); +} +/* * The size for this message payload is 11. * The known values are:
@@ -1582,6 +1717,7 @@ static int steam_raw_event(struct hid_device *hdev, {struct steam_device *steam =hid_get_drvdata (hdev);struct input_dev *input; +struct input_dev *sensors;struct power_supply *battery;if (!steam)
@@ -1627,6 +1763,9 @@ static int steam_raw_event(struct hid_device *hdev, input =rcu_dereference (steam->input);if (likely (input))steam_do_deck_input_event (steam, input, data); + sensors =rcu_dereference (steam->sensors); +if (likely (sensors)) +steam_do_deck_sensors_event (steam, sensors, data);rcu_read_unlock ();break ;case ID_CONTROLLER_WIRELESS :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 119/152 HID: hid-steam: Make sure rumble work is canceled on removal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit cc4f952427aaa44ecfd92542e10a65cce67bd6f4 ]
When a force feedback command is sent from userspace, work is scheduled to pass this data to the controller without blocking userspace itself. However, in theory, this work might not be properly canceled if the controller is removed at the exact right time. This patch ensures the work is properly canceled when the device is removed.
Stable-dep-of: 79504249d7e2 ("HID: hid-steam: Move hidraw input (un)registering to work")
--- drivers/hid/hid-steam.c | 1 + 1 file changed, 1 insertion(+)
drivers/hid/hid-steam.c +1 -0
@@ -1304,6 +1304,7 @@ static void steam_remove(struct hid_device *hdev)cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->work_connect); +cancel_work_sync (&steam->rumble_work);hid_destroy_device (steam->client_hdev); steam->client_hdev =NULL ; steam->client_opened = false;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 120/152 HID: hid-steam: Move hidraw input (un)registering to work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
[ Upstream commit 79504249d7e27cad4a3eeb9afc6386e418728ce0 ]
Due to an interplay between locking in the input and hid transport subsystems, attempting to register or deregister the relevant input devices during the hidraw open/close events can lead to a lock ordering issue. Though this shouldn't cause a deadlock, this commit moves the input device manipulation to deferred work to sidestep the issue.
--- drivers/hid/hid-steam.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-)
drivers/hid/hid-steam.c +31 -7
@@ -312,6 +312,7 @@ struct steam_device {u16 rumble_left;u16 rumble_right;unsigned int sensor_timestamp_us; +struct work_struct unregister_work; }; static int steam_recv_report(struct steam_device *steam,
@@ -1070,6 +1071,31 @@ static void steam_mode_switch_cb(struct work_struct *work) } } +static void steam_work_unregister_cb (struct work_struct *work) +{ + struct steam_device *steam = container_of(work, struct steam_device, + unregister_work); +unsigned long flags; +bool connected; +bool opened; + +spin_lock_irqsave (&steam->lock, flags); + opened = steam->client_opened; + connected = steam->connected; +spin_unlock_irqrestore (&steam->lock, flags); + +if (connected) { +if (opened) { +steam_sensors_unregister (steam); +steam_input_unregister (steam); + }else { +steam_set_lizard_mode (steam, lizard_mode); +steam_input_register (steam); +steam_sensors_register (steam); + } + } +} +static bool steam_is_valve_interface (struct hid_device *hdev) {struct hid_report_enum *rep_enum;
@@ -1115,8 +1141,7 @@ static int steam_client_ll_open(struct hid_device *hdev) steam->client_opened = true;spin_unlock_irqrestore (&steam->lock, flags); -steam_sensors_unregister (steam); -steam_input_unregister (steam); +schedule_work (&steam->unregister_work);return 0 ; }
@@ -1133,11 +1158,7 @@ static void steam_client_ll_close(struct hid_device *hdev) connected = steam->connected && !steam->client_opened;spin_unlock_irqrestore (&steam->lock, flags); -if (connected) { -steam_set_lizard_mode (steam, lizard_mode); -steam_input_register (steam); -steam_sensors_register (steam); - } +schedule_work (&steam->unregister_work); } static int steam_client_ll_raw_request(struct hid_device *hdev,
@@ -1229,6 +1250,7 @@ static int steam_probe(struct hid_device *hdev,INIT_LIST_HEAD (&steam->list);INIT_WORK (&steam->rumble_work, steam_haptic_rumble_cb); steam->sensor_timestamp_us =0 ; +INIT_WORK (&steam->unregister_work, steam_work_unregister_cb);/* * With the real steam controller interface, do not connect hidraw.
@@ -1289,6 +1311,7 @@ static int steam_probe(struct hid_device *hdev,cancel_work_sync (&steam->work_connect);cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->rumble_work); +cancel_work_sync (&steam->unregister_work);return ret; }
@@ -1305,6 +1328,7 @@ static void steam_remove(struct hid_device *hdev)cancel_delayed_work_sync (&steam->mode_switch);cancel_work_sync (&steam->work_connect);cancel_work_sync (&steam->rumble_work); +cancel_work_sync (&steam->unregister_work);hid_destroy_device (steam->client_hdev); steam->client_hdev =NULL ; steam->client_opened = false;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 121/152 ndisc: use RCU protection in ndisc_alloc_skb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 628e6d18930bbd21f2d4562228afe27694f66da9 ]
ndisc_alloc_skb() can be called without RTNL or RCU being held.
Add RCU protection to avoid possible UAF.
--- net/ipv6/ndisc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
net/ipv6/ndisc.c +4 -6
@@ -418,15 +418,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, {int hlen =LL_RESERVED_SPACE (dev);int tlen = dev->needed_tailroom; -struct sock *sk =dev_net (dev)->ipv6.ndisc_sk;struct sk_buff *skb; skb =alloc_skb (hlen +sizeof (struct ipv6hdr ) + len + tlen,GFP_ATOMIC ); -if (!skb) { -ND_PRINTK (0 , err,"ndisc: %s failed to allocate an skb\n" , - __func__); +if (!skb)return NULL ; - } skb->protocol =htons (ETH_P_IPV6 ); skb->dev = dev;
@@ -437,7 +433,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,/* Manually assign socket ownership as we avoid calling * sock_alloc_send_pskb() to bypass wmem buffer limits */ -skb_set_owner_w (skb, sk); +rcu_read_lock (); +skb_set_owner_w (skb,dev_net_rcu (dev)->ipv6.ndisc_sk); +rcu_read_unlock ();return skb; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 122/152 neighbour: delete redundant judgment statements
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Zetao <[email protected]>
[ Upstream commit c25bdd2ac8cf7da70a226f1a66cdce7af15ff86f ]
The initial value of err is -ENOBUFS, and err is guaranteed to be less than 0 before all goto errout. Therefore, on the error path of errout, there is no need to repeatedly judge that err is less than 0, and delete redundant judgments to make the code more concise.
Stable-dep-of: becbd5850c03 ("neighbour: use RCU protection in __neigh_notify()")
--- net/core/neighbour.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/core/neighbour.c +1 -2
@@ -3526,8 +3526,7 @@ static void __neigh_notify(struct neighbour *n, int type, int flags,rtnl_notify (skb, net,0 ,RTNLGRP_NEIGH ,NULL ,GFP_ATOMIC );return ; errout: -if (err <0 ) -rtnl_set_sk_err (net,RTNLGRP_NEIGH , err); +rtnl_set_sk_err (net,RTNLGRP_NEIGH , err); }void neigh_app_ns (struct neighbour *n)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 123/152 neighbour: use RCU protection in __neigh_notify()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit becbd5850c03ed33b232083dd66c6e38c0c0e569 ]
__neigh_notify() can be called without RTNL or RCU protection.
Use RCU protection to avoid potential UAF.
--- net/core/neighbour.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/core/neighbour.c +6 -2
@@ -3508,10 +3508,12 @@ static const struct seq_operations neigh_stat_seq_ops = {static void __neigh_notify (struct neighbour *n,int type,int flags,u32 pid) { -struct net *net =dev_net (n->dev);struct sk_buff *skb;int err = -ENOBUFS ; +struct net *net; +rcu_read_lock (); + net =dev_net_rcu (n->dev); skb =nlmsg_new (neigh_nlmsg_size (),GFP_ATOMIC );if (skb ==NULL ) goto errout;
@@ -3524,9 +3526,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, goto errout; }rtnl_notify (skb, net,0 ,RTNLGRP_NEIGH ,NULL ,GFP_ATOMIC ); -return ; + goto out; errout:rtnl_set_sk_err (net,RTNLGRP_NEIGH , err); +out: +rcu_read_unlock (); }void neigh_app_ns (struct neighbour *n)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 124/152 arp: use RCU protection in arp_xmit()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit a42b69f692165ec39db42d595f4f65a4c8f42e44 ]
arp_xmit() can be called without RTNL or RCU protection.
Use RCU protection to avoid potential UAF.
--- net/ipv4/arp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv4/arp.c +3 -1
@@ -658,10 +658,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb*/ void arp_xmit (struct sk_buff *skb) { +rcu_read_lock ();/* Send it off, maybe filter it using firewalling first. */ NF_HOOK (NFPROTO_ARP ,NF_ARP_OUT , -dev_net (skb->dev),NULL , skb,NULL , skb->dev, +dev_net_rcu (skb->dev),NULL , skb,NULL , skb->dev, arp_xmit_finish); +rcu_read_unlock (); }EXPORT_SYMBOL (arp_xmit);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 125/152 openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 90b2f49a502fa71090d9f4fe29a2f51fe5dff76d ]
ovs_vport_cmd_fill_info() can be called without RTNL or RCU.
Use RCU protection and dev_net_rcu() to avoid potential UAF.
--- net/openvswitch/datapath.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
net/openvswitch/datapath.c +9 -3
@@ -2103,6 +2103,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, {struct ovs_header *ovs_header;struct ovs_vport_stats vport_stats; +struct net *net_vport;int err; ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
@@ -2119,12 +2120,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) goto nla_put_failure; -if (!net_eq (net,dev_net (vport->dev))) { -int id =peernet2id_alloc (net,dev_net (vport->dev), gfp); +rcu_read_lock (); + net_vport =dev_net_rcu (vport->dev); +if (!net_eq (net, net_vport)) { +int id =peernet2id_alloc (net, net_vport,GFP_ATOMIC );if (nla_put_s32 (skb,OVS_VPORT_ATTR_NETNSID , id)) - goto nla_put_failure; + goto nla_put_failure_unlock; } +rcu_read_unlock ();ovs_vport_get_stats (vport, &vport_stats); if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
@@ -2145,6 +2149,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,genlmsg_end (skb, ovs_header);return 0 ; +nla_put_failure_unlock: +rcu_read_unlock (); nla_put_failure: err = -EMSGSIZE ; error:
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 126/152 ndisc: extend RCU protection in ndisc_send_skb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit ed6ae1f325d3c43966ec1b62ac1459e2b8e45640 ]
ndisc_send_skb() can be called without RTNL or RCU held.
Acquire rcu_read_lock() earlier, so that we can use dev_net_rcu() and avoid a potential UAF.
--- net/ipv6/ndisc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/ipv6/ndisc.c +8 -4
@@ -471,16 +471,20 @@ static void ip6_nd_hdr(struct sk_buff *skb,void ndisc_send_skb (struct sk_buff *skb,const struct in6_addr *daddr,const struct in6_addr *saddr) { +struct icmp6hdr *icmp6h =icmp6_hdr (skb);struct dst_entry *dst =skb_dst (skb); -struct net *net =dev_net (skb->dev); -struct sock *sk = net->ipv6.ndisc_sk;struct inet6_dev *idev; +struct net *net; +struct sock *sk;int err; -struct icmp6hdr *icmp6h =icmp6_hdr (skb);u8 type; type = icmp6h->icmp6_type; +rcu_read_lock (); + + net =dev_net_rcu (skb->dev); + sk = net->ipv6.ndisc_sk;if (!dst) {struct flowi6 fl6;int oif = skb->dev->ifindex;
@@ -488,6 +492,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,icmpv6_flow_init (sk, &fl6, type, saddr, daddr, oif); dst =icmp6_dst_alloc (skb->dev, &fl6);if (IS_ERR (dst)) { +rcu_read_unlock ();kfree_skb (skb);return ; }
@@ -502,7 +507,6 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,ip6_nd_hdr (skb, saddr, daddr,inet6_sk (sk)->hop_limit, skb->len); -rcu_read_lock (); idev =__in6_dev_get (dst->dev);IP6_INC_STATS (net, idev,IPSTATS_MIB_OUTREQUESTS );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 127/152 ipv6: mcast: extend RCU protection in igmp6_send()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 087c1faa594fa07a66933d750c0b2610aa1a2946 ]
igmp6_send() can be called without RTNL or RCU being held.
Extend RCU protection so that we can safely fetch the net pointer and avoid a potential UAF.
Note that we no longer can use sock_alloc_send_skb() because ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk socket under RCU protection.
--- net/ipv6/mcast.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)
net/ipv6/mcast.c +15 -16
@@ -2121,21 +2121,21 @@ static void mld_send_cr(struct inet6_dev *idev)static void igmp6_send (struct in6_addr *addr,struct net_device *dev,int type) { -struct net *net =dev_net (dev); -struct sock *sk = net->ipv6.igmp_sk; +const struct in6_addr *snd_addr, *saddr; +int err, len, payload_len, full_len; +struct in6_addr addr_buf;struct inet6_dev *idev;struct sk_buff *skb;struct mld_msg *hdr; -const struct in6_addr *snd_addr, *saddr; -struct in6_addr addr_buf;int hlen =LL_RESERVED_SPACE (dev);int tlen = dev->needed_tailroom; -int err, len, payload_len, full_len;u8 ra[8 ] = {IPPROTO_ICMPV6 ,0 ,IPV6_TLV_ROUTERALERT ,2 ,0 ,0 ,IPV6_TLV_PADN ,0 }; -struct flowi6 fl6;struct dst_entry *dst; +struct flowi6 fl6; +struct net *net; +struct sock *sk;if (type ==ICMPV6_MGM_REDUCTION ) snd_addr = &in6addr_linklocal_allrouters;
@@ -2146,19 +2146,21 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) payload_len = len +sizeof (ra); full_len =sizeof (struct ipv6hdr ) + payload_len; -rcu_read_lock (); -IP6_INC_STATS (net,__in6_dev_get (dev),IPSTATS_MIB_OUTREQUESTS ); -rcu_read_unlock (); + skb =alloc_skb (hlen + tlen + full_len,GFP_KERNEL ); - skb =sock_alloc_send_skb (sk, hlen + tlen + full_len,1 , &err); +rcu_read_lock (); + net =dev_net_rcu (dev); + idev =__in6_dev_get (dev); +IP6_INC_STATS (net, idev,IPSTATS_MIB_OUTREQUESTS );if (!skb) { -rcu_read_lock (); -IP6_INC_STATS (net,__in6_dev_get (dev), -IPSTATS_MIB_OUTDISCARDS ); +IP6_INC_STATS (net, idev,IPSTATS_MIB_OUTDISCARDS );rcu_read_unlock ();return ; } + sk = net->ipv6.igmp_sk; +skb_set_owner_w (skb, sk); + skb->priority =TC_PRIO_CONTROL ;skb_reserve (skb, hlen);
@@ -2183,9 +2185,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)IPPROTO_ICMPV6 , csum_partial(hdr, len, 0)); -rcu_read_lock (); - idev =__in6_dev_get (skb->dev); -icmpv6_flow_init (sk, &fl6, type, &ipv6_hdr (skb)->saddr, &ipv6_hdr (skb)->daddr, skb->dev->ifindex);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 128/152 ipv6: mcast: add RCU protection to mld_newpack()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit a527750d877fd334de87eef81f1cb5f0f0ca3373 ]
mld_newpack() can be called without RTNL or RCU being held.
Note that we no longer can use sock_alloc_send_skb() because ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk socket under RCU protection.
--- net/ipv6/mcast.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/ipv6/mcast.c +10 -4
@@ -1729,21 +1729,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)struct net_device *dev = idev->dev;int hlen =LL_RESERVED_SPACE (dev);int tlen = dev->needed_tailroom; -struct net *net =dev_net (dev);const struct in6_addr *saddr;struct in6_addr addr_buf;struct mld2_report *pmr;struct sk_buff *skb;unsigned int size;struct sock *sk; -int err; +struct net *net; - sk = net->ipv6.igmp_sk;/* we assume size > sizeof(ra) here * Also try to not allocate high-order pages for big MTU */ size =min_t (int, mtu,PAGE_SIZE /2 ) + hlen + tlen; - skb =sock_alloc_send_skb (sk, size,1 , &err); + skb =alloc_skb (size,GFP_KERNEL );if (!skb)return NULL ;
@@ -1751,6 +1749,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)skb_reserve (skb, hlen);skb_tailroom_reserve (skb, mtu, tlen); +rcu_read_lock (); + + net =dev_net_rcu (dev); + sk = net->ipv6.igmp_sk; +skb_set_owner_w (skb, sk); +if (ipv6_get_lladdr (dev, &addr_buf,IFA_F_TENTATIVE )) {/* <draft-ietf-magma-mld-source-05.txt>: * use unspecified address as the source address
@@ -1762,6 +1766,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)ip6_mc_hdr (sk, skb, dev, saddr, &mld2_all_mcr,NEXTHDR_HOP ,0 ); +rcu_read_unlock (); +skb_put_data (skb, ra,sizeof (ra));skb_set_transport_header (skb,skb_tail_pointer (skb) - skb->data);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 129/152 drm/tidss: Fix issue in irq handling causing irq-flood issue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
commit 44b6730ab53ef04944fbaf6da0e77397531517b7 upstream.
It has been observed that sometimes DSS will trigger an interrupt and the top level interrupt (DISPC_IRQSTATUS) is not zero, but the VP and VID level interrupt-statuses are zero.
As the top level irqstatus is supposed to tell whether we have VP/VID interrupts, the thinking of the driver authors was that this particular case could never happen. Thus the driver only clears the DISPC_IRQSTATUS bits which has corresponding interrupts in VP/VID status. So when this issue happens, the driver will not clear DISPC_IRQSTATUS, and we get an interrupt flood.
It is unclear why the issue happens. It could be a race issue in the driver, but no such race has been found. It could also be an issue with the HW. However a similar case can be easily triggered by manually writing to DISPC_IRQSTATUS_RAW. This will forcibly set a bit in the DISPC_IRQSTATUS and trigger an interrupt, and as the driver never clears the bit, we get an interrupt flood.
To fix the issue, always clear DISPC_IRQSTATUS. The concern with this solution is that if the top level irqstatus is the one that triggers the interrupt, always clearing DISPC_IRQSTATUS might leave some interrupts unhandled if VP/VID interrupt statuses have bits set. However, testing shows that if any of the irqstatuses is set (i.e. even if DISPC_IRQSTATUS == 0, but a VID irqstatus has a bit set), we will get an interrupt.
--- drivers/gpu/drm/tidss/tidss_dispc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/gpu/drm/tidss/tidss_dispc.c +4 -8
@@ -726,24 +726,20 @@ staticvoid dispc_k3_clear_irqstatus (struct dispc_device *dispc,dispc_irq_t clearmask) {unsigned int i; -u32 top_clear =0 ;for (i =0 ; i < dispc->feat->num_vps; ++i) { -if (clearmask &DSS_IRQ_VP_MASK (i)) { +if (clearmask &DSS_IRQ_VP_MASK (i))dispc_k3_vp_write_irqstatus (dispc, i, clearmask); - top_clear |=BIT (i); - } }for (i =0 ; i < dispc->feat->num_planes; ++i) { -if (clearmask &DSS_IRQ_PLANE_MASK (i)) { +if (clearmask &DSS_IRQ_PLANE_MASK (i))dispc_k3_vid_write_irqstatus (dispc, i, clearmask); - top_clear |=BIT (4 + i); - } }if (dispc->feat->subrev ==DISPC_K2G )return ; -dispc_write (dispc,DISPC_IRQSTATUS , top_clear); +/* always clear the top level irqstatus */ +dispc_write (dispc,DISPC_IRQSTATUS ,dispc_read (dispc,DISPC_IRQSTATUS ));/* Flush posted writes */ dispc_read (dispc,DISPC_IRQSTATUS );
Greg Kroah-Hartman
maintainerPATCH 130/152 drm/tidss: Clear the interrupt status for interrupts being disabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devarsh Thakkar <[email protected]>
commit 361a2ebb5cad211732ec3c5d962de49b21895590 upstream.
The driver does not touch the irqstatus register when it is disabling interrupts. This might cause an interrupt to trigger for an interrupt that was just disabled.
To fix the issue, clear the irqstatus registers right after disabling the interrupts.
--- drivers/gpu/drm/tidss/tidss_dispc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/gpu/drm/tidss/tidss_dispc.c +8 -2
@@ -646,7 +646,7 @@ void dispc_k2g_set_irqenable(struct disp {dispc_irq_t old_mask =dispc_k2g_read_irqenable (dispc); -/* clear the irqstatus for newly enabled irqs */ +/* clear the irqstatus for irqs that will be enabled */ dispc_k2g_clear_irqstatus (dispc, (mask ^ old_mask) & mask);dispc_k2g_vp_set_irqenable (dispc,0 , mask);
@@ -654,6 +654,9 @@ void dispc_k2g_set_irqenable(struct dispdispc_write (dispc,DISPC_IRQENABLE_SET , (1 <<0 ) | (1 <<7 )); +/* clear the irqstatus for irqs that were disabled */ +dispc_k2g_clear_irqstatus (dispc, (mask ^ old_mask) & old_mask); +/* flush posted write */ dispc_k2g_read_irqenable (dispc); }
@@ -785,7 +788,7 @@ static void dispc_k3_set_irqenable(struc old_mask =dispc_k3_read_irqenable (dispc); -/* clear the irqstatus for newly enabled irqs */ +/* clear the irqstatus for irqs that will be enabled */ dispc_k3_clear_irqstatus (dispc, (old_mask ^ mask) & mask);for (i =0 ; i < dispc->feat->num_vps; ++i) {
@@ -810,6 +813,9 @@ static void dispc_k3_set_irqenable(strucif (main_disable)dispc_write (dispc,DISPC_IRQENABLE_CLR , main_disable); +/* clear the irqstatus for irqs that were disabled */ +dispc_k3_clear_irqstatus (dispc, (old_mask ^ mask) & old_mask); +/* Flush posted writes */ dispc_read (dispc,DISPC_IRQENABLE_SET ); }
Greg Kroah-Hartman
maintainerPATCH 131/152 drm/rcar-du: dsi: Fix PHY lock bit check
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
commit 6389e616fae8a101ce00068f7690461ab57b29d8 upstream.
The driver checks for bit 16 (using CLOCKSET1_LOCK define) in CLOCKSET1 register when waiting for the PPI clock. However, the right bit to check is bit 17 (CLOCKSET1_LOCK_PHY define). Not only that, but there's nothing in the documents for bit 16 for V3U nor V4H.
So, fix the check to use bit 17, and drop the define for bit 16.
--- drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 2 +- drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +1 -1
@@ -587,7 +587,7 @@ static int rcar_mipi_dsi_startup(structfor (timeout =10 ; timeout >0 ; --timeout) {if ((rcar_mipi_dsi_read (dsi,PPICLSR ) &PPICLSR_STPST ) && (rcar_mipi_dsi_read (dsi,PPIDLSR ) &PPIDLSR_STPST ) && - (rcar_mipi_dsi_read (dsi,CLOCKSET1 ) &CLOCKSET1_LOCK )) + (rcar_mipi_dsi_read (dsi,CLOCKSET1 ) &CLOCKSET1_LOCK_PHY ))break ;usleep_range (1000 ,2000 );
drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +0 -1
@@ -142,7 +142,6 @@#define CLOCKSET1 0x101c#define CLOCKSET1_LOCK_PHY (1 << 17) -#define CLOCKSET1_LOCK (1 << 16)#define CLOCKSET1_CLKSEL (1 << 8)#define CLOCKSET1_CLKINSEL_EXTAL (0 << 2)#define CLOCKSET1_CLKINSEL_DIG (1 << 2)
Greg Kroah-Hartman
maintainerPATCH 132/152 drm/v3d: Stop active perfmon if it is being destroyed
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Gmeiner <[email protected]>
commit 21f1435b1e6b012a07c42f36b206d2b66fc8f13b upstream.
If the active performance monitor (v3d->active_perfmon) is being destroyed, stop it first. Currently, the active perfmon is not stopped during destruction, leaving the v3d->active_perfmon pointer stale. This can lead to undefined behavior and instability.
This patch ensures that the active perfmon is stopped before being destroyed, aligning with the behavior introduced in commit 7d1fd3638ee3 ("drm/v3d: Stop the active perfmon before being destroyed").
--- drivers/gpu/drm/v3d/v3d_perfmon.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/v3d/v3d_perfmon.c +5 -0
@@ -179,6 +179,7 @@ int v3d_perfmon_destroy_ioctl(struct drm {struct v3d_file_priv *v3d_priv = file_priv->driver_priv;struct drm_v3d_perfmon_destroy *req = data; +struct v3d_dev *v3d = v3d_priv->v3d;struct v3d_perfmon *perfmon;mutex_lock (&v3d_priv->perfmon.lock);
@@ -188,6 +189,10 @@ int v3d_perfmon_destroy_ioctl(struct drmif (!perfmon)return -EINVAL ; +/* If the active perfmon is being destroyed, stop it first */ +if (perfmon == v3d->active_perfmon) +v3d_perfmon_stop (v3d, perfmon, false); +v3d_perfmon_put (perfmon);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 133/152 x86/static-call: Remove early_boot_irqs_disabled check to fix Xen PVH dom0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Cooper <[email protected]>
commit 5cc2db37124bb33914996d6fdbb2ddb3811f2945 upstream.
__static_call_update_early() has a check for early_boot_irqs_disabled, but is used before early_boot_irqs_disabled is set up in start_kernel().
Xen PV has always special cased early_boot_irqs_disabled, but Xen PVH does not and falls over the BUG when booting as dom0.
It is very suspect that early_boot_irqs_disabled starts as 0, becomes 1 for a time, then becomes 0 again, but as this needs backporting to fix a breakage in a security fix, dropping the BUG_ON() is the far safer option.
--- arch/x86/kernel/static_call.c | 1 - 1 file changed, 1 deletion(-)
arch/x86/kernel/static_call.c +0 -1
@@ -175,7 +175,6 @@ EXPORT_SYMBOL_GPL(arch_static_call_trans noinstr void __static_call_update_early(void *tramp, void *func) {BUG_ON (system_state !=SYSTEM_BOOTING ); -BUG_ON (!early_boot_irqs_disabled);BUG_ON (static_call_initialized);__text_gen_insn (tramp,JMP32_INSN_OPCODE , tramp, func,JMP32_INSN_SIZE );sync_core ();
Greg Kroah-Hartman
maintainerPATCH 134/152 drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
commit f22f4754aaa47d8c59f166ba3042182859e5dff7 upstream.
This commit addresses a potential null pointer dereference issue in the dcn201_acquire_free_pipe_for_layer function. The issue could occur when head_pipe is null.
The fix adds a check to ensure head_pipe is not null before asserting it. If head_pipe is null, the function returns NULL to prevent a potential null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn201/dcn201_resource.c:1016 dcn201_acquire_free_pipe_for_layer() error: we previously assumed 'head_pipe' could be null (see line 1010)
[ dcn201 was moved from drivers/gpu/drm/amd/display/dc to
drivers/gpu/drm/amd/display/dc/resource since commit 8b8eed05a1c6 ("drm/amd/display: Refactor resource into component directory"). The path is changed accordingly to apply the patch on 6.6.y. ]
--- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +3 -1
@@ -1002,8 +1002,10 @@ static struct pipe_ctx *dcn201_acquire_fstruct pipe_ctx *head_pipe =resource_get_otg_master_for_stream (res_ctx, opp_head_pipe->stream);struct pipe_ctx *idle_pipe =resource_find_free_secondary_pipe_legacy (res_ctx, pool, head_pipe); -if (!head_pipe) +if (!head_pipe) {ASSERT (0 ); +return NULL ; + }if (!idle_pipe)return NULL ;
Greg Kroah-Hartman
maintainerPATCH 135/152 drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
commit 5559598742fb4538e4c51c48ef70563c49c2af23 upstream.
[WHAT & HOW]
"dcn20_validate_apply_pipe_split_flags" dereferences merge, and thus it cannot be a null pointer. Let's pass a valid pointer to avoid null dereference.
This fixes 2 FORWARD_NULL issues reported by Coverity.
[ dcn20 and dcn21 were moved from drivers/gpu/drm/amd/display/dc to
drivers/gpu/drm/amd/display/dc/resource since commit 8b8eed05a1c6 ("drm/amd/display: Refactor resource into component directory"). The path is changed accordingly to apply the patch on 6.6.y. ]
--- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +2 -1
@@ -2026,6 +2026,7 @@ bool dcn20_fast_validate_bw( {bool out = false;int split[MAX_PIPES ] = {0 }; +bool merge[MAX_PIPES ] = { false };int pipe_cnt, i, pipe_idx, vlevel;ASSERT (pipes);
@@ -2050,7 +2051,7 @@ bool dcn20_fast_validate_bw(if (vlevel > context->bw_ctx.dml.soc.num_states) goto validate_fail; - vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split,NULL ); + vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split, merge);/*initialize pipe_just_split_from to invalid idx*/ for (i =0 ; i <MAX_PIPES ; i++)
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +2 -1
@@ -800,6 +800,7 @@ bool dcn21_fast_validate_bw(struct dc *d {bool out = false;int split[MAX_PIPES ] = {0 }; +bool merge[MAX_PIPES ] = { false };int pipe_cnt, i, pipe_idx, vlevel;ASSERT (pipes);
@@ -842,7 +843,7 @@ bool dcn21_fast_validate_bw(struct dc *d goto validate_fail; } - vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split,NULL ); + vlevel =dcn20_validate_apply_pipe_split_flags (dc, context, vlevel, split, merge);for (i =0 , pipe_idx =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
Greg Kroah-Hartman
maintainerPATCH 136/152 netdevsim: print human readable IP address
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
commit c71bc6da6198a6d88df86094f1052bb581951d65 upstream.
Currently, IPSec addresses are printed in hexadecimal format, which is not user-friendly. e.g.
# cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec SA count=2 tx=20 sa[0] rx ipaddr=0x00000000 00000000 00000000 0100a8c0 sa[0] spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1 sa[0] key=0x3167608a ca4f1397 43565909 941fa627 sa[1] tx ipaddr=0x00000000 00000000 00000000 00000000 sa[1] spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1 sa[1] key=0x3167608a ca4f1397 43565909 941fa627
This patch updates the code to print the IPSec address in a human-readable format for easier debug. e.g.
# cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec SA count=4 tx=40 sa[0] tx ipaddr=0.0.0.0 sa[0] spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1 sa[0] key=0x3167608a ca4f1397 43565909 941fa627 sa[1] rx ipaddr=192.168.0.1 sa[1] spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1 sa[1] key=0x3167608a ca4f1397 43565909 941fa627 sa[2] tx ipaddr=:: sa[2] spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1 sa[2] key=0x3167608a ca4f1397 43565909 941fa627 sa[3] rx ipaddr=2000::1 sa[3] spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1 sa[3] key=0x3167608a ca4f1397 43565909 941fa627
--- drivers/net/netdevsim/ipsec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/netdevsim/ipsec.c +8 -4
@@ -39,10 +39,14 @@ static ssize_t nsim_dbg_netdev_ops_read(if (!sap->used)continue ; - p +=scnprintf (p, bufsize - (p - buf), -"sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n" , - i, (sap->rx ?'r' :'t' ), sap->ipaddr[0 ], - sap->ipaddr[1 ], sap->ipaddr[2 ], sap->ipaddr[3 ]); +if (sap->xs->props.family ==AF_INET6 ) + p +=scnprintf (p, bufsize - (p - buf), +"sa[%i] %cx ipaddr=%pI6c\n" , + i, (sap->rx ?'r' :'t' ), &sap->ipaddr); +else + p +=scnprintf (p, bufsize - (p - buf), +"sa[%i] %cx ipaddr=%pI4\n" , + i, (sap->rx ?'r' :'t' ), &sap->ipaddr[3 ]); p += scnprintf(p, bufsize - (p - buf), "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", i, be32_to_cpu(sap->xs->id.spi),
Greg Kroah-Hartman
maintainerPATCH 137/152 selftests: rtnetlink: update netdevsim ipsec output format
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
commit 3ec920bb978ccdc68a7dfb304d303d598d038cb1 upstream.
After the netdevsim update to use human-readable IP address formats for IPsec, we can now use the source and destination IPs directly in testing. Here is the result:
# ./rtnetlink.sh -t kci_test_ipsec_offload PASS: ipsec_offload
--- tools/testing/selftests/net/rtnetlink.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/net/rtnetlink.sh +2 -2
@@ -921,10 +921,10 @@ kci_test_ipsec_offload() # does driver have correct offload info diff $sysfsf - << EOF SA count=2 tx=3 -sa[0] tx ipaddr=0x00000000 00000000 00000000 00000000 +sa[0] tx ipaddr=$dstip sa[0] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 sa[0] key=0x34333231 38373635 32313039 36353433 -sa[1] rx ipaddr=0x00000000 00000000 00000000 037ba8c0 +sa[1] rx ipaddr=$srcip sa[1] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 sa[1] key=0x34333231 38373635 32313039 36353433 EOF
Greg Kroah-Hartman
maintainerPATCH 138/152 md/raid5: recheck if reshape has finished with device_lock held
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Marzinski <[email protected]>
commit 25b3a8237a03ec0b67b965b52d74862e77ef7115 upstream.
When handling an IO request, MD checks if a reshape is currently happening, and if so, where the IO sector is in relation to the reshape progress. MD uses conf->reshape_progress for both of these tasks. When the reshape finishes, conf->reshape_progress is set to MaxSector. If this occurs after MD checks if the reshape is currently happening but before it calls ahead_of_reshape(), then ahead_of_reshape() will end up comparing the IO sector against MaxSector. During a backwards reshape, this will make MD think the IO sector is in the area not yet reshaped, causing it to use the previous configuration, and map the IO to the sector where that data was before the reshape.
This bug can be triggered by running the lvm2 lvconvert-raid-reshape-linear_to_raid6-single-type.sh test in a loop, although it's very hard to reproduce.
Fix this by factoring the code that checks where the IO sector is in relation to the reshape out to a helper called get_reshape_loc(), which reads reshape_progress and reshape_safe while holding the device_lock, and then rechecks if the reshape has finished before calling ahead_of_reshape with the saved values.
Also use the helper during the REQ_NOWAIT check to see if the location is inside of the reshape region.
--- drivers/md/raid5.c | 64 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 23 deletions(-)
drivers/md/raid5.c +41 -23
@@ -5972,6 +5972,39 @@ static bool reshape_disabled(struct mddereturn is_md_suspended (mddev) || !md_is_rdwr (mddev); } +enum reshape_loc { +LOC_NO_RESHAPE , +LOC_AHEAD_OF_RESHAPE , +LOC_INSIDE_RESHAPE , +LOC_BEHIND_RESHAPE , +}; + +static enum reshape_loc get_reshape_loc (struct mddev *mddev, +struct r5conf *conf,sector_t logical_sector) +{ +sector_t reshape_progress, reshape_safe; +/* +* Spinlock is needed as reshape_progress may be +* 64bit on a 32bit platform, and so it might be +* possible to see a half-updated value +* Of course reshape_progress could change after +* the lock is dropped, so once we get a reference +* to the stripe that we think it is, we will have +* to check again. +*/ +spin_lock_irq (&conf->device_lock); + reshape_progress = conf->reshape_progress; + reshape_safe = conf->reshape_safe; +spin_unlock_irq (&conf->device_lock); +if (reshape_progress == MaxSector) +return LOC_NO_RESHAPE ; +if (ahead_of_reshape (mddev, logical_sector, reshape_progress)) +return LOC_AHEAD_OF_RESHAPE ; +if (ahead_of_reshape (mddev, logical_sector, reshape_safe)) +return LOC_INSIDE_RESHAPE ; +return LOC_BEHIND_RESHAPE ; +} +static enum stripe_result make_stripe_request (struct mddev *mddev,struct r5conf *conf,struct stripe_request_ctx *ctx,sector_t logical_sector,struct bio *bi)
@@ -5986,28 +6019,14 @@ static enum stripe_result make_stripe_re seq =read_seqcount_begin (&conf->gen_lock);if (unlikely (conf->reshape_progress != MaxSector)) { -/* -* Spinlock is needed as reshape_progress may be -* 64bit on a 32bit platform, and so it might be -* possible to see a half-updated value -* Of course reshape_progress could change after -* the lock is dropped, so once we get a reference -* to the stripe that we think it is, we will have -* to check again. -*/ -spin_lock_irq (&conf->device_lock); -if (ahead_of_reshape (mddev, logical_sector, - conf->reshape_progress)) { - previous =1 ; - }else { -if (ahead_of_reshape (mddev, logical_sector, - conf->reshape_safe)) { -spin_unlock_irq (&conf->device_lock); - ret =STRIPE_SCHEDULE_AND_RETRY ; - goto out; - } +enum reshape_loc loc =get_reshape_loc (mddev, conf, + logical_sector); +if (loc ==LOC_INSIDE_RESHAPE ) { + ret =STRIPE_SCHEDULE_AND_RETRY ; + goto out; } -spin_unlock_irq (&conf->device_lock); +if (loc ==LOC_AHEAD_OF_RESHAPE ) + previous =1 ; } new_sector = raid5_compute_sector(conf, logical_sector, previous,
@@ -6189,8 +6208,7 @@ static bool raid5_make_request(struct md/* Bail out if conflicts with reshape and REQ_NOWAIT is set */ if ((bi->bi_opf &REQ_NOWAIT ) && (conf->reshape_progress != MaxSector) && - !ahead_of_reshape (mddev, logical_sector, conf->reshape_progress) && -ahead_of_reshape (mddev, logical_sector, conf->reshape_safe)) { +get_reshape_loc (mddev, conf, logical_sector) ==LOC_INSIDE_RESHAPE ) {bio_wouldblock_error (bi);if (rw ==WRITE )md_write_end (mddev);
Greg Kroah-Hartman
maintainerPATCH 139/152 md/md-bitmap: factor behind write counters out from bitmap_{start/end}write()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
commit 08c50142a128dcb2d7060aa3b4c5db8837f7a46a upstream.
behind_write is only used in raid1, prepare to refactor bitmap_{start/end}write(), there are no functional changes.
[There is no bitmap_operations, resolve conflicts by exporting new api md_bitmap_{start,end}_behind_write]
--- drivers/md/md-bitmap.c | 60 +++++++++++++++++++++++++++++------------------ drivers/md/md-bitmap.h | 6 +++- drivers/md/raid1.c | 11 +++++--- drivers/md/raid10.c | 5 +-- drivers/md/raid5-cache.c | 4 +-- drivers/md/raid5.c | 13 ++++------ 6 files changed, 59 insertions(+), 40 deletions(-)
drivers/md/md-bitmap.c +38 -22
@@ -1465,22 +1465,12 @@ __acquires(bitmap->lock) &(bitmap->bp[page].map[pageoff]); } -int md_bitmap_startwrite (struct bitmap *bitmap,sector_t offset,unsigned long sectors,int behind) +int md_bitmap_startwrite (struct bitmap *bitmap,sector_t offset, +unsigned long sectors) {if (!bitmap)return 0 ; -if (behind) { -int bw; -atomic_inc (&bitmap->behind_writes); - bw =atomic_read (&bitmap->behind_writes); -if (bw > bitmap->behind_writes_used) - bitmap->behind_writes_used = bw; - -pr_debug ("inc write-behind count %d/%lu\n" , - bw, bitmap->mddev->bitmap_info.max_write_behind); - } -while (sectors) {sector_t blocks;bitmap_counter_t *bmc;
@@ -1527,20 +1517,13 @@ int md_bitmap_startwrite(struct bitmap * }return 0 ; } -EXPORT_SYMBOL (md_bitmap_startwrite); +EXPORT_SYMBOL_GPL (md_bitmap_startwrite);void md_bitmap_endwrite (struct bitmap *bitmap,sector_t offset, -unsigned long sectors,int success,int behind) +unsigned long sectors,int success) {if (!bitmap)return ; -if (behind) { -if (atomic_dec_and_test (&bitmap->behind_writes)) -wake_up (&bitmap->behind_wait); -pr_debug ("dec write-behind count %d/%lu\n" , -atomic_read (&bitmap->behind_writes), - bitmap->mddev->bitmap_info.max_write_behind); - }while (sectors) {sector_t blocks;
@@ -1580,7 +1563,7 @@ void md_bitmap_endwrite(struct bitmap *b sectors =0 ; } } -EXPORT_SYMBOL (md_bitmap_endwrite); +EXPORT_SYMBOL_GPL (md_bitmap_endwrite);static int __bitmap_start_sync (struct bitmap *bitmap,sector_t offset,sector_t *blocks,int degraded)
@@ -1842,6 +1825,39 @@ void md_bitmap_free(struct bitmap *bitma }EXPORT_SYMBOL (md_bitmap_free); +void md_bitmap_start_behind_write (struct mddev *mddev) +{ +struct bitmap *bitmap = mddev->bitmap; +int bw; + +if (!bitmap) +return ; + +atomic_inc (&bitmap->behind_writes); + bw =atomic_read (&bitmap->behind_writes); +if (bw > bitmap->behind_writes_used) + bitmap->behind_writes_used = bw; + +pr_debug ("inc write-behind count %d/%lu\n" , + bw, bitmap->mddev->bitmap_info.max_write_behind); +} +EXPORT_SYMBOL_GPL (md_bitmap_start_behind_write); + +void md_bitmap_end_behind_write (struct mddev *mddev) +{ +struct bitmap *bitmap = mddev->bitmap; + +if (!bitmap) +return ; + +if (atomic_dec_and_test (&bitmap->behind_writes)) +wake_up (&bitmap->behind_wait); +pr_debug ("dec write-behind count %d/%lu\n" , +atomic_read (&bitmap->behind_writes), + bitmap->mddev->bitmap_info.max_write_behind); +} +EXPORT_SYMBOL_GPL (md_bitmap_end_behind_write); +void md_bitmap_wait_behind_writes (struct mddev *mddev) {struct bitmap *bitmap = mddev->bitmap;
drivers/md/md-bitmap.h +4 -2
@@ -253,9 +253,11 @@ void md_bitmap_dirty_bits(struct bitmap/* these are exported */ int md_bitmap_startwrite (struct bitmap *bitmap,sector_t offset, -unsigned long sectors,int behind); +unsigned long sectors);void md_bitmap_endwrite (struct bitmap *bitmap,sector_t offset, -unsigned long sectors,int success,int behind); +unsigned long sectors,int success); +void md_bitmap_start_behind_write (struct mddev *mddev); +void md_bitmap_end_behind_write (struct mddev *mddev);int md_bitmap_start_sync (struct bitmap *bitmap,sector_t offset,sector_t *blocks,int degraded);void md_bitmap_end_sync (struct bitmap *bitmap,sector_t offset,sector_t *blocks,int aborted);void md_bitmap_close_sync (struct bitmap *bitmap);
drivers/md/raid1.c +7 -4
@@ -419,11 +419,12 @@ static void close_write(struct r1bio *r1bio_put (r1_bio->behind_master_bio); r1_bio->behind_master_bio =NULL ; } +if (test_bit (R1BIO_BehindIO, &r1_bio->state)) +md_bitmap_end_behind_write (r1_bio->mddev);/* clear the bitmap if all writes complete successfully */ md_bitmap_endwrite (r1_bio->mddev->bitmap, r1_bio->sector, r1_bio->sectors, - !test_bit (R1BIO_Degraded, &r1_bio->state), -test_bit (R1BIO_BehindIO, &r1_bio->state)); + !test_bit (R1BIO_Degraded, &r1_bio->state));md_write_end (r1_bio->mddev); }
@@ -1530,8 +1531,10 @@ static void raid1_write_request(struct malloc_behind_master_bio (r1_bio, bio); } -md_bitmap_startwrite (bitmap, r1_bio->sector, r1_bio->sectors, -test_bit (R1BIO_BehindIO, &r1_bio->state)); +if (test_bit (R1BIO_BehindIO, &r1_bio->state)) +md_bitmap_start_behind_write (mddev); +md_bitmap_startwrite (bitmap, r1_bio->sector, + r1_bio->sectors); first_clone =0 ; }
drivers/md/raid10.c +2 -3
@@ -430,8 +430,7 @@ static void close_write(struct r10bio *r/* clear the bitmap if all writes complete successfully */ md_bitmap_endwrite (r10_bio->mddev->bitmap, r10_bio->sector, r10_bio->sectors, - !test_bit (R10BIO_Degraded, &r10_bio->state), -0 ); + !test_bit (R10BIO_Degraded, &r10_bio->state));md_write_end (r10_bio->mddev); }
@@ -1554,7 +1553,7 @@ static void raid10_write_request(structmd_account_bio (mddev, &bio); r10_bio->master_bio = bio;atomic_set (&r10_bio->remaining,1 ); -md_bitmap_startwrite (mddev->bitmap, r10_bio->sector, r10_bio->sectors,0 ); +md_bitmap_startwrite (mddev->bitmap, r10_bio->sector, r10_bio->sectors);for (i =0 ; i < conf->copies; i++) {if (r10_bio->devs[i].bio)
drivers/md/raid5-cache.c +2 -2
@@ -315,8 +315,8 @@ void r5c_handle_cached_data_endio(structr5c_return_dev_pending_writes (conf, &sh->dev[i]);md_bitmap_endwrite (conf->mddev->bitmap, sh->sector,RAID5_STRIPE_SECTORS (conf), - !test_bit (STRIPE_DEGRADED , &sh->state), -0 ); + !test_bit (STRIPE_DEGRADED , + &sh->state)); } } }
drivers/md/raid5.c +6 -7
@@ -3606,7 +3606,7 @@ static void __add_stripe_bio(struct striset_bit (STRIPE_BITMAP_PENDING , &sh->state);spin_unlock_irq (&sh->stripe_lock);md_bitmap_startwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf),0 ); +RAID5_STRIPE_SECTORS (conf));spin_lock_irq (&sh->stripe_lock);clear_bit (STRIPE_BITMAP_PENDING , &sh->state);if (!sh->batch_head) {
@@ -3708,7 +3708,7 @@ handle_failed_stripe(struct r5conf *conf }if (bitmap_end)md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf),0 ,0 ); +RAID5_STRIPE_SECTORS (conf),0 ); bitmap_end =0 ;/* and fail all 'written' */ bi = sh->dev[i].written;
@@ -3754,7 +3754,7 @@ handle_failed_stripe(struct r5conf *conf }if (bitmap_end)md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf),0 ,0 ); +RAID5_STRIPE_SECTORS (conf),0 );/* If we were in the middle of a write the parity block might * still be locked - so just clear all R5_LOCKED flags */
@@ -4107,8 +4107,8 @@ returnbi: }md_bitmap_endwrite (conf->mddev->bitmap, sh->sector,RAID5_STRIPE_SECTORS (conf), - !test_bit (STRIPE_DEGRADED , &sh->state), -0 ); + !test_bit (STRIPE_DEGRADED , + &sh->state));if (head_sh->batch_head) { sh = list_first_entry(&sh->batch_list, struct stripe_head,
@@ -5853,8 +5853,7 @@ static void make_discard_request(struct d++)md_bitmap_startwrite (mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf), -0 ); +RAID5_STRIPE_SECTORS (conf)); sh->bm_seq = conf->seq_flush +1 ;set_bit (STRIPE_BIT_DELAY , &sh->state); }
Greg Kroah-Hartman
maintainerPATCH 140/152 md/md-bitmap: remove the last parameter for bimtap_ops->endwrite()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
commit 4f0e7d0e03b7b80af84759a9e7cfb0f81ac4adae upstream.
For the case that IO failed for one rdev, the bit will be mark as NEEDED in following cases:
1) If badblocks is set and rdev is not faulty;
2) If rdev is faulty;
Case 1) is useless because synchronize data to badblocks make no sense. Case 2) can be replaced with mddev->degraded.
Also remove R1BIO_Degraded, R10BIO_Degraded and STRIPE_DEGRADED since case 2) no longer use them.
--- drivers/md/md-bitmap.c | 19 ++++++++++--------- drivers/md/md-bitmap.h | 2 +- drivers/md/raid1.c | 27 +++------------------------ drivers/md/raid1.h | 1 - drivers/md/raid10.c | 23 +++-------------------- drivers/md/raid10.h | 1 - drivers/md/raid5-cache.c | 4 +--- drivers/md/raid5.c | 14 +++----------- drivers/md/raid5.h | 1 - 9 files changed, 21 insertions(+), 71 deletions(-)
drivers/md/md-bitmap.c +10 -9
@@ -1520,7 +1520,7 @@ int md_bitmap_startwrite(struct bitmap *EXPORT_SYMBOL_GPL (md_bitmap_startwrite);void md_bitmap_endwrite (struct bitmap *bitmap,sector_t offset, -unsigned long sectors,int success) +unsigned long sectors) {if (!bitmap)return ;
@@ -1537,15 +1537,16 @@ void md_bitmap_endwrite(struct bitmap *breturn ; } -if (success && !bitmap->mddev->degraded && - bitmap->events_cleared < bitmap->mddev->events) { - bitmap->events_cleared = bitmap->mddev->events; - bitmap->need_sync =1 ; -sysfs_notify_dirent_safe (bitmap->sysfs_can_clear); - } - -if (!success && !NEEDED (*bmc)) +if (!bitmap->mddev->degraded) { +if (bitmap->events_cleared < bitmap->mddev->events) { + bitmap->events_cleared = bitmap->mddev->events; + bitmap->need_sync =1 ; +sysfs_notify_dirent_safe ( + bitmap->sysfs_can_clear); + } + }else if (!NEEDED (*bmc)) { *bmc |=NEEDED_MASK ; + }if (COUNTER (*bmc) ==COUNTER_MAX )wake_up (&bitmap->overflow_wait);
drivers/md/md-bitmap.h +1 -1
@@ -255,7 +255,7 @@ void md_bitmap_dirty_bits(struct bitmapint md_bitmap_startwrite (struct bitmap *bitmap,sector_t offset,unsigned long sectors);void md_bitmap_endwrite (struct bitmap *bitmap,sector_t offset, -unsigned long sectors,int success); +unsigned long sectors);void md_bitmap_start_behind_write (struct mddev *mddev);void md_bitmap_end_behind_write (struct mddev *mddev);int md_bitmap_start_sync (struct bitmap *bitmap,sector_t offset,sector_t *blocks,int degraded);
drivers/md/raid1.c +3 -24
@@ -423,8 +423,7 @@ static void close_write(struct r1bio *r1md_bitmap_end_behind_write (r1_bio->mddev);/* clear the bitmap if all writes complete successfully */ md_bitmap_endwrite (r1_bio->mddev->bitmap, r1_bio->sector, - r1_bio->sectors, - !test_bit (R1BIO_Degraded, &r1_bio->state)); + r1_bio->sectors);md_write_end (r1_bio->mddev); }
@@ -481,8 +480,6 @@ static void raid1_end_write_request(struif (!test_bit (Faulty, &rdev->flags))set_bit (R1BIO_WriteError, &r1_bio->state);else { -/* Fail the request */ -set_bit (R1BIO_Degraded, &r1_bio->state);/* Finished with this branch */ r1_bio->bios[mirror] =NULL ; to_put = bio;
@@ -1415,11 +1412,8 @@ static void raid1_write_request(struct mbreak ; } r1_bio->bios[i] =NULL ; -if (!rdev ||test_bit (Faulty, &rdev->flags)) { -if (i < conf->raid_disks) -set_bit (R1BIO_Degraded, &r1_bio->state); +if (!rdev ||test_bit (Faulty, &rdev->flags))continue ; - }atomic_inc (&rdev->nr_pending);if (test_bit (WriteErrorSeen, &rdev->flags)) {
@@ -1445,16 +1439,6 @@ static void raid1_write_request(struct m*/ max_sectors = bad_sectors;rdev_dec_pending (rdev, mddev); -/* We don't set R1BIO_Degraded as that -* only applies if the disk is -* missing, so it might be re-added, -* and we want to know to recover this -* chunk. -* In this case the device is here, -* and the fact that this chunk is not -* in-sync is recorded in the bad -* block log -*/ continue ; }if (is_bad) {
@@ -2479,12 +2463,9 @@ static void handle_write_finished(struct* errors. */ fail = true; -if (!narrow_write_error (r1_bio, m)) { +if (!narrow_write_error (r1_bio, m))md_error (conf->mddev, conf->mirrors[m].rdev); -/* an I/O failed, we can't clear the bitmap */ -set_bit (R1BIO_Degraded, &r1_bio->state); - }rdev_dec_pending (conf->mirrors[m].rdev, conf->mddev); }
@@ -2576,8 +2557,6 @@ static void raid1d(struct md_thread *thrlist_del (&r1_bio->retry_list); idx =sector_to_idx (r1_bio->sector);atomic_dec (&conf->nr_queued[idx]); -if (mddev->degraded) -set_bit (R1BIO_Degraded, &r1_bio->state);if (test_bit (R1BIO_WriteError, &r1_bio->state))close_write (r1_bio);raid_end_bio_io (r1_bio);
drivers/md/raid1.h +0 -1
@@ -187,7 +187,6 @@ struct r1bio {enum r1bio_state { R1BIO_Uptodate, R1BIO_IsSync, - R1BIO_Degraded, R1BIO_BehindIO,/* Set ReadError on bios that experience a readerror so that * raid1d knows what to do with them.
drivers/md/raid10.c +3 -20
@@ -429,8 +429,7 @@ static void close_write(struct r10bio *r {/* clear the bitmap if all writes complete successfully */ md_bitmap_endwrite (r10_bio->mddev->bitmap, r10_bio->sector, - r10_bio->sectors, - !test_bit (R10BIO_Degraded, &r10_bio->state)); + r10_bio->sectors);md_write_end (r10_bio->mddev); }
@@ -500,7 +499,6 @@ static void raid10_end_write_request(strset_bit (R10BIO_WriteError, &r10_bio->state); else {/* Fail the request */ -set_bit (R10BIO_Degraded, &r10_bio->state); r10_bio->devs[slot].bio =NULL ; to_put = bio; dec_rdev =1 ;
@@ -1489,10 +1487,8 @@ static void raid10_write_request(struct r10_bio->devs[i].bio =NULL ; r10_bio->devs[i].repl_bio =NULL ; -if (!rdev && !rrdev) { -set_bit (R10BIO_Degraded, &r10_bio->state); +if (!rdev && !rrdev)continue ; - }if (rdev &&test_bit (WriteErrorSeen, &rdev->flags)) {sector_t first_bad;sector_t dev_sector = r10_bio->devs[i].addr;
@@ -1509,14 +1505,6 @@ static void raid10_write_request(struct* to other devices yet */ max_sectors = bad_sectors; -/* We don't set R10BIO_Degraded as that -* only applies if the disk is missing, -* so it might be re-added, and we want to -* know to recover this chunk. -* In this case the device is here, and the -* fact that this chunk is not in-sync is -* recorded in the bad block log. -*/ continue ; }if (is_bad) {
@@ -3062,11 +3050,8 @@ static void handle_write_completed(strucrdev_dec_pending (rdev, conf->mddev); }else if (bio !=NULL && bio->bi_status) { fail = true; -if (!narrow_write_error (r10_bio, m)) { +if (!narrow_write_error (r10_bio, m))md_error (conf->mddev, rdev); -set_bit (R10BIO_Degraded, - &r10_bio->state); - }rdev_dec_pending (rdev, conf->mddev); } bio = r10_bio->devs[m].repl_bio;
@@ -3125,8 +3110,6 @@ static void raid10d(struct md_thread *th r10_bio = list_first_entry(&tmp, struct r10bio, retry_list);list_del (&r10_bio->retry_list); -if (mddev->degraded) -set_bit (R10BIO_Degraded, &r10_bio->state);if (test_bit (R10BIO_WriteError, &r10_bio->state))
drivers/md/raid10.h +0 -1
@@ -161,7 +161,6 @@ enum r10bio_state { R10BIO_IsSync, R10BIO_IsRecover, R10BIO_IsReshape, - R10BIO_Degraded,/* Set ReadError on bios that experience a read error * so that raid10d knows what to do with them. */
drivers/md/raid5-cache.c +1 -3
@@ -314,9 +314,7 @@ void r5c_handle_cached_data_endio(structset_bit (R5_UPTODATE , &sh->dev[i].flags);r5c_return_dev_pending_writes (conf, &sh->dev[i]);md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf), - !test_bit (STRIPE_DEGRADED , - &sh->state)); +RAID5_STRIPE_SECTORS (conf)); } } }
drivers/md/raid5.c +3 -11
@@ -1359,8 +1359,6 @@ again:submit_bio_noacct (rbi); }if (!rdev && !rrdev) { -if (op_is_write (op)) -set_bit (STRIPE_DEGRADED , &sh->state);pr_debug ("skip op %d on disc %d for sector %llu\n" , bi->bi_opf, i, (unsigned long long )sh->sector);clear_bit (R5_LOCKED , &sh->dev[i].flags);
@@ -2925,7 +2923,6 @@ static void raid5_end_write_request(struset_bit (R5_MadeGoodRepl, &sh->dev[i].flags); }else {if (bi->bi_status) { -set_bit (STRIPE_DEGRADED , &sh->state);set_bit (WriteErrorSeen, &rdev->flags);set_bit (R5_WriteError, &sh->dev[i].flags);if (!test_and_set_bit (WantReplacement, &rdev->flags))
@@ -3708,7 +3705,7 @@ handle_failed_stripe(struct r5conf *conf }if (bitmap_end)md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf),0 ); +RAID5_STRIPE_SECTORS (conf)); bitmap_end =0 ;/* and fail all 'written' */ bi = sh->dev[i].written;
@@ -3754,7 +3751,7 @@ handle_failed_stripe(struct r5conf *conf }if (bitmap_end)md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf),0 ); +RAID5_STRIPE_SECTORS (conf));/* If we were in the middle of a write the parity block might * still be locked - so just clear all R5_LOCKED flags */
@@ -4106,9 +4103,7 @@ returnbi: wbi = wbi2; }md_bitmap_endwrite (conf->mddev->bitmap, sh->sector, -RAID5_STRIPE_SECTORS (conf), - !test_bit (STRIPE_DEGRADED , - &sh->state)); +RAID5_STRIPE_SECTORS (conf));if (head_sh->batch_head) { sh = list_first_entry(&sh->batch_list, struct stripe_head,
@@ -4385,7 +4380,6 @@ static void handle_parity_checks5(struct s->locked++;set_bit (R5_Wantwrite, &dev->flags); -clear_bit (STRIPE_DEGRADED , &sh->state);set_bit (STRIPE_INSYNC , &sh->state);break ;case check_state_run:
@@ -4542,7 +4536,6 @@ static void handle_parity_checks6(structclear_bit (R5_Wantwrite, &dev->flags); s->locked--; } -clear_bit (STRIPE_DEGRADED , &sh->state);set_bit (STRIPE_INSYNC , &sh->state);break ;
@@ -4951,7 +4944,6 @@ static void break_stripe_batch_list(struset_mask_bits (&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | (1 <<STRIPE_PREREAD_ACTIVE ) | - (1 <<STRIPE_DEGRADED ) | (1 <<STRIPE_ON_UNPLUG_LIST )), head_sh->state & (1 <<STRIPE_INSYNC ));
drivers/md/raid5.h +0 -1
@@ -358,7 +358,6 @@ enum {STRIPE_REPLACED ,STRIPE_PREREAD_ACTIVE ,STRIPE_DELAYED , -STRIPE_DEGRADED ,STRIPE_BIT_DELAY ,STRIPE_EXPANDING , STRIPE_EXPAND_SOURCE,