6.12.29-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 6.12.29-rc1 review
This is the start of the stable review cycle for the 6.12.29 release. There are 184 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 Wed, 14 May 2025 17:19:58 +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.12.29-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.12.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.12.29-rc1
Pawan Gupta <[email protected]>
selftest/x86/bugs: Add selftests for ITS
Peter Zijlstra <[email protected]>
x86/its: Use dynamic thunks for indirect branches
Pawan Gupta <[email protected]>
x86/ibt: Keep IBT disabled during alternative patching
Pawan Gupta <[email protected]>
x86/its: Align RETs in BHB clear sequence to avoid thunking
Pawan Gupta <[email protected]>
x86/its: Add support for RSB stuffing mitigation
Pawan Gupta <[email protected]>
x86/its: Add "vmexit" option to skip mitigation on some CPUs
Pawan Gupta <[email protected]>
x86/its: Enable Indirect Target Selection mitigation
Pawan Gupta <[email protected]>
x86/its: Add support for ITS-safe return thunk
Pawan Gupta <[email protected]>
x86/its: Add support for ITS-safe indirect thunk
Pawan Gupta <[email protected]>
x86/its: Enumerate Indirect Target Selection (ITS) bug
Pawan Gupta <[email protected]>
Documentation: x86/bugs/its: Add ITS documentation
Pawan Gupta <[email protected]>
x86/speculation: Remove the extra #ifdef around CALL_NOSPEC
Pawan Gupta <[email protected]>
x86/speculation: Add a conditional CS prefix to CALL_NOSPEC
Pawan Gupta <[email protected]>
x86/speculation: Simplify and make CALL_NOSPEC consistent
Pawan Gupta <[email protected]>
x86/bhi: Do not set BHI_DIS_S in 32-bit mode
Daniel Sneddon <[email protected]>
x86/bpf: Add IBHF call at end of classic BPF
Daniel Sneddon <[email protected]>
x86/bpf: Call branch history clearing sequence on exit
James Morse <[email protected]>
arm64: proton-pack: Add new CPUs 'k' values for branch mitigation
James Morse <[email protected]>
arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users
James Morse <[email protected]>
arm64: bpf: Add BHB mitigation to the epilogue for cBPF programs
James Morse <[email protected]>
arm64: proton-pack: Expose whether the branchy loop k value
James Morse <[email protected]>
arm64: proton-pack: Expose whether the platform is mitigated by firmware
James Morse <[email protected]>
arm64: insn: Add support for encoding DSB
Omar Sandoval <[email protected]>
sched/eevdf: Fix se->slice being set to U64_MAX and resulting crash
Johannes Weiner <[email protected]>
mm: page_alloc: speed up fallbacks in rmqueue_bulk()
Johannes Weiner <[email protected]>
mm: page_alloc: don't steal single pages from biggest buddy
Hao Qin <[email protected]>
Bluetooth: btmtk: Remove the resetting step before downloading the fw
Hao Qin <[email protected]>
Bluetooth: btmtk: Remove resetting mt7921 before downloading the fw
Jens Axboe <[email protected]>
io_uring: always arm linked timeouts prior to issue
Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's clippy::uninlined_format_args lint
Miguel Ojeda <[email protected]>
rust: allow Rust 1.87.0's `clippy::ptr_eq` lint
Christian Lamparter <[email protected]>
Revert "um: work around sched_yield not yielding in time-travel mode"
Al Viro <[email protected]>
do_umount(): add missing barrier before refcount checks in sync case
Gabriel Krisman Bertazi <[email protected]>
io_uring/sqpoll: Increase task_work submission batch size
Tejas Upadhyay <[email protected]>
drm/xe/tests/mocs: Hold XE_FORCEWAKE_ALL for LNCF regs
Himal Prasad Ghimiray <[email protected]>
drm/xe/tests/mocs: Update xe_force_wake_get() return handling
Clément Léger <[email protected]>
riscv: misaligned: enable IRQs while handling misaligned accesses
Clément Léger <[email protected]>
riscv: misaligned: factorize trap handling
Daniel Wagner <[email protected]>
nvme: unblock ctrl state transition for firmware update
Kevin Baker <[email protected]>
drm/panel: simple: Update timings for AUO G101EVN010
Lizhi Xu <[email protected]>
loop: Add sanity check for read/write_iter
Christoph Hellwig <[email protected]>
loop: factor out a loop_assign_backing_file helper
Christoph Hellwig <[email protected]>
loop: refactor queue limits updates
OGAWA Hirofumi <[email protected]>
loop: Fix ABBA locking race
John Garry <[email protected]>
loop: Simplify discard granularity calc
John Garry <[email protected]>
loop: Use bdev limit helpers for configuring discard
Nylon Chen <[email protected]>
riscv: misaligned: Add handling for ZCB instructions
Thorsten Blum <[email protected]>
MIPS: Fix MAX_REG_OFFSET
Marco Crivellari <[email protected]>
MIPS: Move r4k_wait() to .cpuidle.text section
Marco Crivellari <[email protected]>
MIPS: Fix idle VS timer enqueue
Jonathan Cameron <[email protected]>
iio: adc: dln2: Use aligned_s64 for timestamp
Jonathan Cameron <[email protected]>
iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64
Andy Shevchenko <[email protected]>
types: Complement the aligned types with signed 64-bit one
Jonathan Cameron <[email protected]>
iio: temp: maxim-thermocouple: Fix potential lack of DMA safe buffer.
Lothar Rubusch <[email protected]>
iio: accel: adxl367: fix setting odr for activity time update
Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous generic_read ioctl return
Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous wait_srq ioctl return
Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous get_stb ioctl error returns
Oliver Neukum <[email protected]>
USB: usbtmc: use interruptible sleep in usbtmc_read
Andrei Kuchynski <[email protected]>
usb: typec: ucsi: displayport: Fix NULL pointer access
RD Babiera <[email protected]>
usb: typec: tcpm: delay SNK_TRY_WAIT_DEBOUNCE to SRC_TRYWAIT transition
Lukasz Czechowski <[email protected]>
usb: misc: onboard_usb_dev: fix support for Cypress HX3 hubs
Jim Lin <[email protected]>
usb: host: tegra: Prevent host controller crash when OTG port is used
Prashanth K <[email protected]>
usb: gadget: Use get_status callback to set remote wakeup capability
Wayne Chang <[email protected]>
usb: gadget: tegra-xudc: ACK ST_RC after clearing CTRL_RUN
Prashanth K <[email protected]>
usb: gadget: f_ecm: Add get_status callback
Pawel Laszczak <[email protected]>
usb: cdnsp: fix L1 resume issue for RTL_REVISION_NEW_LPM version
Pawel Laszczak <[email protected]>
usb: cdnsp: Fix issue with resuming from L1
Prashanth K <[email protected]>
usb: dwc3: gadget: Make gadget_wakeup asynchronous
Jan Kara <[email protected]>
ocfs2: stop quota recovery before disabling quotas
Jan Kara <[email protected]>
ocfs2: implement handshaking with ocfs2 recovery thread
Jan Kara <[email protected]>
ocfs2: switch osb->disable_recovery to enum
Heming Zhao <[email protected]>
ocfs2: fix the issue with discontiguous allocation in the global_bitmap
Borislav Petkov (AMD) <[email protected]>
x86/microcode: Consolidate the loader enablement checking
Dmitry Antipov <[email protected]>
module: ensure that kobject_put() is safe for module type kobjects
Tom Lendacky <[email protected]>
memblock: Accept allocated memory before use in memblock_double_array()
Sebastian Andrzej Siewior <[email protected]>
clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable()
Yeoreum Yun <[email protected]>
arm64: cpufeature: Move arm64_use_ng_mappings to the .data section to prevent wrong idmap generation
Jacek Lawrynowicz <[email protected]>
accel/ivpu: Increase state dump msg timeout
Jason Andryuk <[email protected]>
xenbus: Use kref to track req lifetime
John Ernberg <[email protected]>
xen: swiotlb: Use swiotlb bouncing if kmalloc allocation demands it
Paul Aurich <[email protected]>
smb: client: Avoid race in open_cached_dir with lease breaks
Alexey Charkov <[email protected]>
usb: uhci-platform: Make the clock really optional
Alex Deucher <[email protected]>
drm/amdgpu/hdp7: use memcfg register to post the write for HDP flush
Alex Deucher <[email protected]>
drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
Alex Deucher <[email protected]>
drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
Alex Deucher <[email protected]>
drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
Alex Deucher <[email protected]>
drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
Wayne Lin <[email protected]>
drm/amd/display: Copy AUX read reply data whenever length > 0
Wayne Lin <[email protected]>
drm/amd/display: Fix wrong handling for AUX_DEFER case
Wayne Lin <[email protected]>
drm/amd/display: Remove incorrect checking in dmub aux handler
Wayne Lin <[email protected]>
drm/amd/display: Fix the checking condition in dmub aux handling
Aurabindo Pillai <[email protected]>
drm/amd/display: more liberal vmin/vmax update for freesync
Roman Li <[email protected]>
drm/amd/display: Fix invalid context error in dml helper
Ruijing Dong <[email protected]>
drm/amdgpu/vcn: using separate VCN1_AON_SOC offset
Matthew Brost <[email protected]>
drm/xe: Add page queue multiplier
Maíra Canal <[email protected]>
drm/v3d: Add job to pending list if the reset was skipped
Silvano Seva <[email protected]>
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_tagged_fifo
Silvano Seva <[email protected]>
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_fifo
David Lechner <[email protected]>
iio: imu: inv_mpu6050: align buffer for timestamp
Gabriel Shahrouzi <[email protected]>
iio: adis16201: Correct inclinometer channel resolution
Simon Xue <[email protected]>
iio: adc: rockchip: Fix clock initialization sequence
Angelo Dureghello <[email protected]>
iio: adc: ad7606: fix serial register access
Jens Axboe <[email protected]>
io_uring: ensure deferred completions are flushed for multishot
Wayne Lin <[email protected]>
drm/amd/display: Shift DMUB AUX reply command if necessary
Mikhail Lobanov <[email protected]>
KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception
Nysal Jan K.A. <[email protected]>
selftests/mm: fix a build failure on powerpc
Feng Tang <[email protected]>
selftests/mm: compaction_test: support platform with huge mount of memory
Peter Xu <[email protected]>
mm/userfaultfd: fix uninitialized output field for -EAGAIN race
Gavin Guo <[email protected]>
mm/huge_memory: fix dereferencing invalid pmd migration entry
Kees Cook <[email protected]>
mm: vmalloc: support more granular vrealloc() sizing
Petr Vaněk <[email protected]>
mm: fix folio_pte_batch() on XEN PV
Dave Hansen <[email protected]>
x86/mm: Eliminate window where TLB flushes may be inadvertently skipped
Gabriel Shahrouzi <[email protected]>
staging: axis-fifo: Correct handling of tx_fifo_depth for size validation
Gabriel Shahrouzi <[email protected]>
staging: axis-fifo: Remove hardware resets for user errors
Dave Stevenson <[email protected]>
staging: bcm2835-camera: Initialise dev in v4l2_dev
Gabriel Shahrouzi <[email protected]>
staging: iio: adc: ad7816: Correct conditional logic for store mode
Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's warning about clippy::disallowed_macros configuration
Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function for Rust 1.87.0
Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's unnecessary_transmutes lint
Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on TUXEDO InfinityBook Pro 14 v5
Dmitry Torokhov <[email protected]>
Input: synaptics - enable SMBus for HP Elitebook 850 G1
Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on Dell Precision M3800
Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on Dynabook Portege X30L-G
Manuel Fombuena <[email protected]>
Input: synaptics - enable InterTouch on Dynabook Portege X30-D
Vicki Pfau <[email protected]>
Input: xpad - fix two controller table values
Lode Willems <[email protected]>
Input: xpad - add support for 8BitDo Ultimate 2 Wireless Controller
Vicki Pfau <[email protected]>
Input: xpad - fix Share button on Xbox One controllers
Gary Bisson <[email protected]>
Input: mtk-pmic-keys - fix possible null pointer dereference
Mikael Gonella-Bolduc <[email protected]>
Input: cyttsp5 - fix power control issue on wakeup
Hugo Villeneuve <[email protected]>
Input: cyttsp5 - ensure minimum reset pulse width
Jakub Kicinski <[email protected]>
virtio-net: fix total qstat values
Jakub Kicinski <[email protected]>
net: export a helper for adding up queue stats
Alexander Duyck <[email protected]>
fbnic: Do not allow mailbox to toggle to ready outside fbnic_mbx_poll_tx_ready
Alexander Duyck <[email protected]>
fbnic: Pull fbnic_fw_xmit_cap_msg use out of interrupt context
Alexander Duyck <[email protected]>
fbnic: Improve responsiveness of fbnic_mbx_poll_tx_ready
Alexander Duyck <[email protected]>
fbnic: Actually flush_tx instead of stalling out
Alexander Duyck <[email protected]>
fbnic: Gate AXI read/write enabling on FW mailbox
Alexander Duyck <[email protected]>
fbnic: Fix initialization of mailbox descriptor rings
Jonas Gorski <[email protected]>
net: dsa: b53: do not set learning and unicast/multicast on up
Jonas Gorski <[email protected]>
net: dsa: b53: fix learning on VLAN unaware bridges
Jonas Gorski <[email protected]>
net: dsa: b53: fix toggling vlan_filtering
Jonas Gorski <[email protected]>
net: dsa: b53: do not program vlans when vlan filtering is off
Jonas Gorski <[email protected]>
net: dsa: b53: do not allow to configure VLAN 0
Jonas Gorski <[email protected]>
net: dsa: b53: always rejoin default untagged VLAN on bridge leave
Jonas Gorski <[email protected]>
net: dsa: b53: fix VLAN ID for untagged vlan on bridge leave
Jonas Gorski <[email protected]>
net: dsa: b53: fix flushing old pvid VLAN on pvid change
Jonas Gorski <[email protected]>
net: dsa: b53: fix clearing PVID of a port
Jonas Gorski <[email protected]>
net: dsa: b53: keep CPU port always tagged again
Jonas Gorski <[email protected]>
net: dsa: b53: allow leaky reserved multicast
Paul Chaignon <[email protected]>
bpf: Scrub packet on bpf_redirect_peer
Jozsef Kadlecsik <[email protected]>
netfilter: ipset: fix region locking in hash types
Julian Anastasov <[email protected]>
ipvs: fix uninit-value for saddr in do_output_route4
Gao Xiang <[email protected]>
erofs: ensure the extra temporary copy is valid for shortened bvecs
Przemek Kitszel <[email protected]>
ice: use DSN instead of PCI BDF for ice_adapter index
Sergey Temerkhanov <[email protected]>
ice: Initial support for E825C hardware in ice_adapter
Michael-CY Lee <[email protected]>
wifi: mac80211: fix the type of status_code for negotiated TID to Link Mapping
Oliver Hartkopp <[email protected]>
can: gw: fix RCU/BH usage in cgw_create_job()
Kelsey Maes <[email protected]>
can: mcp251xfd: fix TDC setting for low data bit rates
Antonios Salios <[email protected]>
can: m_can: m_can_class_allocate_dev(): initialize spin lock on device probe
Frank Wunderlich <[email protected]>
net: ethernet: mtk_eth_soc: do not reset PSE when setting FE
Daniel Golle <[email protected]>
net: ethernet: mtk_eth_soc: reset all TX queues on DMA free
Guillaume Nault <[email protected]>
gre: Fix again IPv6 link-local address generation.
Jakub Kicinski <[email protected]>
virtio-net: free xsk_buffs on error in virtnet_xsk_pool_enable()
Xuan Zhuo <[email protected]>
virtio_net: xsk: bind/unbind xsk for tx
Cong Wang <[email protected]>
sch_htb: make htb_deactivate() idempotent
Heiko Carstens <[email protected]>
s390/entry: Fix last breaking event handling in case of stack corruption
Wang Zhaolong <[email protected]>
ksmbd: fix memory leak in parse_lease_state()
Eelco Chaudron <[email protected]>
openvswitch: Fix unsafe attribute parsing in output_userspace()
Sean Heelan <[email protected]>
ksmbd: Fix UAF in __close_file_table_ids
Norbert Szetei <[email protected]>
ksmbd: prevent out-of-bounds stream writes by validating *pos
Namjae Jeon <[email protected]>
ksmbd: prevent rename with empty string
Marc Kleine-Budde <[email protected]>
can: rockchip_canfd: rkcanfd_remove(): fix order of unregistration calls
Marc Kleine-Budde <[email protected]>
can: mcp251xfd: mcp251xfd_remove(): fix order of unregistration calls
Niklas Schnelle <[email protected]>
s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has child VFs
Alex Williamson <[email protected]>
vfio/pci: Align huge faults to order
Veerendranath Jakkam <[email protected]>
wifi: cfg80211: fix out-of-bounds access during multi-link element defragmentation
Niklas Schnelle <[email protected]>
s390/pci: Fix missing check for zpci_create_device() error return
Marc Kleine-Budde <[email protected]>
can: mcan: m_can_class_unregister(): fix order of unregistration calls
Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix timeout checks on polling path
Wojciech Dubowik <[email protected]>
arm64: dts: imx8mm-verdin: Link reg_usdhc2_vqmmc to usdhc2
Qu Wenruo <[email protected]>
Revert "btrfs: canonicalize the device path before adding it"
Max Kellermann <[email protected]>
fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()
Dan Carpenter <[email protected]>
dm: add missing unlock on in dm_keyslot_evict()
-------------
Diffstat:
.clippy.toml | 2 +- Documentation/ABI/testing/sysfs-devices-system-cpu | 1 + Documentation/admin-guide/hw-vuln/index.rst | 1 + .../hw-vuln/indirect-target-selection.rst | 168 ++++++++++++++++ Documentation/admin-guide/kernel-parameters.txt | 18 ++ Makefile | 4 +- arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 25 ++- arch/arm64/include/asm/cputype.h | 2 + arch/arm64/include/asm/insn.h | 1 + arch/arm64/include/asm/spectre.h | 3 + arch/arm64/kernel/cpufeature.c | 9 +- arch/arm64/kernel/proton-pack.c | 13 +- arch/arm64/lib/insn.c | 76 +++++--- arch/arm64/net/bpf_jit_comp.c | 57 +++++- arch/mips/include/asm/idle.h | 3 +- arch/mips/include/asm/ptrace.h | 3 +- arch/mips/kernel/genex.S | 63 +++--- arch/mips/kernel/idle.c | 7 - arch/riscv/kernel/traps.c | 64 ++++--- arch/riscv/kernel/traps_misaligned.c | 17 ++ arch/s390/kernel/entry.S | 3 +- arch/s390/pci/pci_clp.c | 2 + arch/um/include/linux/time-internal.h | 2 - arch/um/kernel/skas/syscall.c | 11 -- arch/x86/Kconfig | 12 ++ arch/x86/entry/entry_64.S | 20 +- arch/x86/include/asm/alternative.h | 24 +++ arch/x86/include/asm/cpufeatures.h | 3 + arch/x86/include/asm/microcode.h | 2 + arch/x86/include/asm/msr-index.h | 8 + arch/x86/include/asm/nospec-branch.h | 38 ++-- arch/x86/kernel/alternative.c | 195 ++++++++++++++++++- arch/x86/kernel/cpu/bugs.c | 176 ++++++++++++++++- arch/x86/kernel/cpu/common.c | 72 +++++-- arch/x86/kernel/cpu/microcode/amd.c | 6 +- arch/x86/kernel/cpu/microcode/core.c | 60 +++--- arch/x86/kernel/cpu/microcode/intel.c | 2 +- arch/x86/kernel/cpu/microcode/internal.h | 1 - arch/x86/kernel/ftrace.c | 2 +- arch/x86/kernel/head32.c | 4 - arch/x86/kernel/module.c | 6 + arch/x86/kernel/static_call.c | 4 +- arch/x86/kernel/vmlinux.lds.S | 10 + arch/x86/kvm/smm.c | 1 + arch/x86/kvm/svm/svm.c | 4 + arch/x86/kvm/x86.c | 4 +- arch/x86/lib/retpoline.S | 39 ++++ arch/x86/mm/tlb.c | 23 ++- arch/x86/net/bpf_jit_comp.c | 58 +++++- drivers/accel/ivpu/ivpu_hw.c | 2 +- drivers/base/cpu.c | 3 + drivers/block/loop.c | 104 ++++++---- drivers/bluetooth/btmtk.c | 12 +- drivers/clocksource/i8253.c | 4 +- drivers/firmware/arm_scmi/driver.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 1 - drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c | 12 +- drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 3 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 ++-- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 28 ++- .../amd/display/dc/dml2/dml2_translation_helper.c | 14 +- drivers/gpu/drm/panel/panel-simple.c | 25 +-- drivers/gpu/drm/v3d/v3d_sched.c | 28 ++- drivers/gpu/drm/xe/tests/xe_mocs.c | 21 +- drivers/gpu/drm/xe/xe_gt_pagefault.c | 11 +- drivers/iio/accel/adis16201.c | 4 +- drivers/iio/accel/adxl355_core.c | 2 +- drivers/iio/accel/adxl367.c | 10 +- drivers/iio/adc/ad7606_spi.c | 2 +- drivers/iio/adc/dln2-adc.c | 2 +- drivers/iio/adc/rockchip_saradc.c | 17 +- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 6 + drivers/iio/temperature/maxim_thermocouple.c | 2 +- drivers/input/joystick/xpad.c | 40 ++-- drivers/input/keyboard/mtk-pmic-keys.c | 4 +- drivers/input/mouse/synaptics.c | 5 + drivers/input/touchscreen/cyttsp5.c | 7 +- drivers/md/dm-table.c | 3 +- drivers/net/can/m_can/m_can.c | 3 +- drivers/net/can/rockchip/rockchip_canfd-core.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 42 +++- drivers/net/dsa/b53/b53_common.c | 213 +++++++++++++++------ drivers/net/dsa/b53/b53_priv.h | 3 + drivers/net/dsa/bcm_sf2.c | 1 + drivers/net/ethernet/intel/ice/ice_adapter.c | 39 ++-- drivers/net/ethernet/intel/ice/ice_adapter.h | 6 +- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 19 +- drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 2 + drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 180 +++++++++-------- drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 6 - drivers/net/virtio_net.c | 61 ++++++ drivers/nvme/host/core.c | 3 +- drivers/pci/hotplug/s390_pci_hpc.c | 1 - drivers/staging/axis-fifo/axis-fifo.c | 14 +- drivers/staging/iio/adc/ad7816.c | 2 +- .../vc04_services/bcm2835-camera/bcm2835-camera.c | 1 + drivers/usb/cdns3/cdnsp-gadget.c | 31 +++ drivers/usb/cdns3/cdnsp-gadget.h | 6 + drivers/usb/cdns3/cdnsp-pci.c | 12 +- drivers/usb/cdns3/cdnsp-ring.c | 3 +- drivers/usb/cdns3/core.h | 3 + drivers/usb/class/usbtmc.c | 59 +++--- drivers/usb/dwc3/core.h | 4 + drivers/usb/dwc3/gadget.c | 60 +++--- drivers/usb/gadget/composite.c | 12 +- drivers/usb/gadget/function/f_ecm.c | 7 + drivers/usb/gadget/udc/tegra-xudc.c | 4 + drivers/usb/host/uhci-platform.c | 2 +- drivers/usb/host/xhci-tegra.c | 3 + drivers/usb/misc/onboard_usb_dev.c | 10 +- drivers/usb/typec/tcpm/tcpm.c | 2 +- drivers/usb/typec/ucsi/displayport.c | 2 + drivers/vfio/pci/vfio_pci_core.c | 12 +- drivers/xen/swiotlb-xen.c | 1 + drivers/xen/xenbus/xenbus.h | 2 + drivers/xen/xenbus/xenbus_comms.c | 9 +- drivers/xen/xenbus/xenbus_dev_frontend.c | 2 +- drivers/xen/xenbus/xenbus_xs.c | 18 +- fs/btrfs/volumes.c | 91 +-------- fs/erofs/fileio.c | 4 +- fs/erofs/zdata.c | 29 ++- fs/namespace.c | 3 +- fs/ocfs2/journal.c | 80 +++++--- fs/ocfs2/journal.h | 1 + fs/ocfs2/ocfs2.h | 17 +- fs/ocfs2/quota_local.c | 9 +- fs/ocfs2/suballoc.c | 38 +++- fs/ocfs2/suballoc.h | 1 + fs/ocfs2/super.c | 3 + fs/smb/client/cached_dir.c | 10 +- fs/smb/server/oplock.c | 7 +- fs/smb/server/smb2pdu.c | 5 + fs/smb/server/vfs.c | 7 + fs/smb/server/vfs_cache.c | 33 +++- fs/userfaultfd.c | 28 ++- include/linux/cpu.h | 2 + include/linux/execmem.h | 3 + include/linux/ieee80211.h | 2 +- include/linux/module.h | 5 + include/linux/types.h | 3 +- include/linux/vmalloc.h | 1 + include/net/netdev_queues.h | 6 + include/uapi/linux/types.h | 1 + init/Kconfig | 3 + io_uring/io_uring.c | 58 +++--- io_uring/sqpoll.c | 2 +- kernel/params.c | 4 +- kernel/sched/fair.c | 4 +- mm/huge_memory.c | 11 +- mm/internal.h | 27 ++- mm/memblock.c | 9 +- mm/page_alloc.c | 159 +++++++++------ mm/vmalloc.c | 31 ++- net/can/gw.c | 151 +++++++++------ net/core/filter.c | 1 + net/core/netdev-genl.c | 69 +++++-- net/ipv6/addrconf.c | 15 +- net/mac80211/mlme.c | 12 +- net/netfilter/ipset/ip_set_hash_gen.h | 2 +- net/netfilter/ipvs/ip_vs_xmit.c | 27 +-- net/openvswitch/actions.c | 3 +- net/sched/sch_htb.c | 15 +- net/wireless/scan.c | 2 +- rust/bindings/lib.rs | 1 + rust/kernel/alloc/kvec.rs | 3 + rust/kernel/list.rs | 3 + rust/kernel/str.rs | 46 ++--- rust/macros/module.rs | 19 +- rust/macros/pinned_drop.rs | 3 +- rust/uapi/lib.rs | 1 + tools/objtool/check.c | 1 + tools/testing/selftests/Makefile | 1 + tools/testing/selftests/mm/compaction_test.c | 19 +- tools/testing/selftests/mm/pkey-powerpc.h | 12 +- tools/testing/selftests/x86/bugs/Makefile | 3 + tools/testing/selftests/x86/bugs/common.py | 164 ++++++++++++++++ .../selftests/x86/bugs/its_indirect_alignment.py | 150 +++++++++++++++ .../testing/selftests/x86/bugs/its_permutations.py | 109 +++++++++++ .../selftests/x86/bugs/its_ret_alignment.py | 139 ++++++++++++++ tools/testing/selftests/x86/bugs/its_sysfs.py | 65 +++++++ 191 files changed, 3250 insertions(+), 1134 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/184 dm: add missing unlock on in dm_keyslot_evict()
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 650266ac4c7230c89bcd1307acf5c9c92cfa85e2 upstream.
We need to call dm_put_live_table() even if dm_get_live_table() returns NULL.
--- drivers/md/dm-table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/dm-table.c +2 -1
@@ -1183,7 +1183,7 @@ static int dm_keyslot_evict(struct blk_c t =dm_get_live_table (md, &srcu_idx);if (!t) -return 0 ; + goto put_live_table;for (unsigned int i =0 ; i < t->num_targets; i++) {struct dm_target *ti =dm_table_get_target (t, i);
@@ -1194,6 +1194,7 @@ static int dm_keyslot_evict(struct blk_c (void *)key); } +put_live_table:dm_put_live_table (md, srcu_idx);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 2/184 fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Kellermann <[email protected]>
commit bbfe756dc3062c1e934f06e5ba39c239aa953b92 upstream.
If bio_add_folio() fails (because it is full), erofs_fileio_scan_folio() needs to submit the I/O request via erofs_fileio_rq_submit() and allocate a new I/O request with an empty struct bio. Then it retries the bio_add_folio() call.
However, at this point, erofs_onlinefolio_split() has already been called which increments folio->private; the retry will call erofs_onlinefolio_split() again, but there will never be a matching erofs_onlinefolio_end() call. This leaves the folio locked forever and all waiters will be stuck in folio_wait_bit_common().
This bug has been added by commit ce63cb62d794 ("erofs: support unencoded inodes for fileio"), but was practically unreachable because there was room for 256 folios in the struct bio - until commit 9f74ae8c9ac9 ("erofs: shorten bvecs[] for file-backed mounts") which reduced the array capacity to 16 folios.
It was now trivial to trigger the bug by manually invoking readahead from userspace, e.g.:
posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED);
This should be fixed by invoking erofs_onlinefolio_split() only after bio_add_folio() has succeeded. This is safe: asynchronous completions invoking erofs_onlinefolio_end() will not unlock the folio because erofs_fileio_scan_folio() is still holding a reference to be released by erofs_onlinefolio_end() at the end.
--- fs/erofs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/erofs/fileio.c +2 -2
@@ -150,10 +150,10 @@ static int erofs_fileio_scan_folio(struct erofs_fileio *io, struct folio *folio) io->rq->bio.bi_iter.bi_sector = io->dev.m_pa >>9 ; attached =0 ; } -if (!attached++) -erofs_onlinefolio_split (folio);if (!bio_add_folio (&io->rq->bio, folio, len, cur)) goto io_retry; +if (!attached++) +erofs_onlinefolio_split (folio); io->dev.m_pa += len; } cur += len;
Signature · 1 line
2.49.0
Greg Kroah-Hartman
maintainerPATCH 3/184 Revert "btrfs: canonicalize the device path before adding it"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 8fb1dcbbcc1ffe6ed7cf3f0f96d2737491dd1fbf upstream.
This reverts commit 7e06de7c83a746e58d4701e013182af133395188.
Commit 7e06de7c83a7 ("btrfs: canonicalize the device path before adding it") tries to make btrfs to use "/dev/mapper/*" name first, then any filename inside "/dev/" as the device path.
This is mostly fine when there is only the root namespace involved, but when multiple namespace are involved, things can easily go wrong for the d_path() usage.
As d_path() returns a file path that is namespace dependent, the resulted string may not make any sense in another namespace.
Furthermore, the "/dev/" prefix checks itself is not reliable, one can still make a valid initramfs without devtmpfs, and fill all needed device nodes manually.
Overall the userspace has all its might to pass whatever device path for mount, and we are not going to win the war trying to cover every corner case.
So just revert that commit, and do no extra d_path() based file path sanity check.
--- fs/btrfs/volumes.c | 91 ----------------------------------------------------- 1 file changed, 1 insertion(+), 90 deletions(-)
fs/btrfs/volumes.c +1 -90
@@ -732,82 +732,6 @@ const u8 *btrfs_sb_fsid_ptr(const structreturn has_metadata_uuid ? sb->metadata_uuid : sb->fsid; } -/* -* We can have very weird soft links passed in. -* One example is "/proc/self/fd/<fd>", which can be a soft link to -* a block device. -* -* But it's never a good idea to use those weird names. -* Here we check if the path (not following symlinks) is a good one inside -* "/dev/". -*/ -static bool is_good_dev_path (const char *dev_path) -{ -struct path path = { .mnt =NULL , .dentry =NULL }; -char *path_buf =NULL ; -char *resolved_path; -bool is_good = false; -int ret; - -if (!dev_path) - goto out; - - path_buf =kmalloc (PATH_MAX ,GFP_KERNEL ); -if (!path_buf) - goto out; - -/* -* Do not follow soft link, just check if the original path is inside -* "/dev/". -*/ - ret =kern_path (dev_path,0 , &path); -if (ret) - goto out; - resolved_path =d_path (&path, path_buf,PATH_MAX ); -if (IS_ERR (resolved_path)) - goto out; -if (strncmp (resolved_path,"/dev/" ,strlen ("/dev/" ))) - goto out; - is_good = true; -out: -kfree (path_buf); -path_put (&path); -return is_good; -} - -static int get_canonical_dev_path (const char *dev_path,char *canonical) -{ -struct path path = { .mnt =NULL , .dentry =NULL }; -char *path_buf =NULL ; -char *resolved_path; -int ret; - -if (!dev_path) { - ret = -EINVAL ; - goto out; - } - - path_buf =kmalloc (PATH_MAX ,GFP_KERNEL ); -if (!path_buf) { - ret = -ENOMEM ; - goto out; - } - - ret =kern_path (dev_path,LOOKUP_FOLLOW , &path); -if (ret) - goto out; - resolved_path =d_path (&path, path_buf,PATH_MAX ); -if (IS_ERR (resolved_path)) { - ret =PTR_ERR (resolved_path); - goto out; - } - ret =strscpy (canonical, resolved_path,PATH_MAX ); -out: -kfree (path_buf); -path_put (&path); -return ret; -} -static bool is_same_device (struct btrfs_device *device,const char *new_path) {struct path old = { .mnt =NULL , .dentry =NULL };
@@ -1495,23 +1419,12 @@ struct btrfs_device *btrfs_scan_one_devibool new_device_added = false;struct btrfs_device *device =NULL ;struct file *bdev_file; -char *canonical_path =NULL ;u64 bytenr;dev_t devt;int ret;lockdep_assert_held (&uuid_mutex); -if (!is_good_dev_path (path)) { - canonical_path =kmalloc (PATH_MAX ,GFP_KERNEL ); -if (canonical_path) { - ret =get_canonical_dev_path (path, canonical_path); -if (ret <0 ) { -kfree (canonical_path); - canonical_path =NULL ; - } - } - }/* * Avoid an exclusive open here, as the systemd-udev may initiate the * device scan which may race with the user's mount or mkfs command,
@@ -1556,8 +1469,7 @@ struct btrfs_device *btrfs_scan_one_devi goto free_disk_super; } - device =device_list_add (canonical_path ? : path, disk_super, - &new_device_added); + device =device_list_add (path, disk_super, &new_device_added);if (!IS_ERR (device) && new_device_added)btrfs_free_stale_devices (device->devt, device);
@@ -1566,7 +1478,6 @@ free_disk_super: error_bdev_put:fput (bdev_file); -kfree (canonical_path);return device; }
Greg Kroah-Hartman
maintainerPATCH 4/184 arm64: dts: imx8mm-verdin: Link reg_usdhc2_vqmmc to usdhc2
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wojciech Dubowik <[email protected]>
commit 5591ce0069ddda97cdbbea596bed53e698f399c2 upstream.
Define vqmmc regulator-gpio for usdhc2 with vin-supply coming from LDO5.
Without this definition LDO5 will be powered down, disabling SD card after bootup. This has been introduced in commit f5aab0438ef1 ("regulator: pca9450: Fix enable register for LDO5").
--- arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +20 -5
@@ -165,6 +165,19 @@ startup-delay-us = <20000>; }; + reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2_vsel>; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + states = <1800000 0x1>, + <3300000 0x0>; + regulator-name = "PMIC_USDHC_VSELECT"; + vin-supply = <®_nvcc_sd>; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>;
@@ -290,7 +303,7 @@ "SODIMM_19", "", "", - "", + "PMIC_USDHC_VSELECT", "", "", "",
@@ -801,6 +814,7 @@ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>; pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>; vmmc-supply = <®_usdhc2_vmmc>; + vqmmc-supply = <®_usdhc2_vqmmc>; }; &wdog1 {
@@ -1222,13 +1236,17 @@ <MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6>; /* SODIMM 76 */ }; + pinctrl_usdhc2_vsel: usdhc2vselgrp { + fsl,pins = + <MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x10>; /* PMIC_USDHC_VSELECT */ + }; + /* * Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the * on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here. */ pinctrl_usdhc2: usdhc2grp { fsl,pins = - <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */ <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */ <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */
@@ -1239,7 +1257,6 @@ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = - <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>, <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>, <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>,
@@ -1250,7 +1267,6 @@ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = - <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>, <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>, <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>,
@@ -1262,7 +1278,6 @@ /* Avoid backfeeding with removed card power */ pinctrl_usdhc2_sleep: usdhc2slpgrp { fsl,pins = - <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x0>, <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>, <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>, <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>,
Greg Kroah-Hartman
maintainerPATCH 5/184 firmware: arm_scmi: Fix timeout checks on polling path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <[email protected]>
commit c23c03bf1faa1e76be1eba35bad6da6a2a7c95ee upstream.
Polling mode transactions wait for a reply busy-looping without holding a spinlock, but currently the timeout checks are based only on elapsed time:
as a result we could hit a false positive whenever our busy-looping thread is pre-empted and scheduled out for a time greater than the polling timeout.
Change the checks at the end of the busy-loop to make sure that the polling wasn't indeed successful or an out-of-order reply caused the polling to be forcibly terminated.
Message-Id: <[email protected]>
--- drivers/firmware/arm_scmi/driver.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/firmware/arm_scmi/driver.c +8 -5
@@ -1219,7 +1219,8 @@ static void xfer_put(const struct scmi_p }static bool scmi_xfer_done_no_timeout (struct scmi_chan_info *cinfo, -struct scmi_xfer *xfer,ktime_t stop) +struct scmi_xfer *xfer,ktime_t stop, +bool *ooo) {struct scmi_info *info =handle_to_scmi_info (cinfo->handle);
@@ -1228,7 +1229,7 @@ static bool scmi_xfer_done_no_timeout(st* in case of out-of-order receptions of delayed responses */ return info->desc->ops->poll_done (cinfo, xfer) || -try_wait_for_completion (&xfer->done) || + (*ooo =try_wait_for_completion (&xfer->done)) ||ktime_after (ktime_get (), stop); }
@@ -1245,15 +1246,17 @@ static int scmi_wait_for_reply(struct de* itself to support synchronous commands replies. */ if (!desc->sync_cmds_completed_on_ret) { +bool ooo = false; +/* * Poll on xfer using transport provided .poll_done(); * assumes no completion interrupt was available. */ ktime_t stop =ktime_add_ms (ktime_get (), timeout_ms); -spin_until_cond (scmi_xfer_done_no_timeout (cinfo, - xfer, stop)); -if (ktime_after (ktime_get (), stop)) { +spin_until_cond (scmi_xfer_done_no_timeout (cinfo, xfer, + stop, &ooo)); +if (!ooo && !info->desc->ops->poll_done (cinfo, xfer)) {dev_err (dev,"timed out in resp(caller: %pS) - polling\n" , (void *)_RET_IP_);
Greg Kroah-Hartman
maintainerPATCH 6/184 can: mcan: m_can_class_unregister(): fix order of unregistration calls
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 0713a1b3276b98c7dafbeefef00d7bc3a9119a84 upstream.
If a driver is removed, the driver framework invokes the driver's remove callback. A CAN driver's remove function calls unregister_candev(), which calls net_device_ops::ndo_stop further down in the call stack for interfaces which are in the "up" state.
The removal of the module causes a warning, as can_rx_offload_del() deletes the NAPI, while it is still active, because the interface is still up.
To fix the warning, first unregister the network interface, which calls net_device_ops::ndo_stop, which disables the NAPI, and then call can_rx_offload_del().
--- drivers/net/can/m_can/m_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/m_can/m_can.c +1 -1
@@ -2456,9 +2456,9 @@ EXPORT_SYMBOL_GPL(m_can_class_register);void m_can_class_unregister (struct m_can_classdev *cdev) { +unregister_candev (cdev->net);if (cdev->is_peripheral)can_rx_offload_del (&cdev->offload); -unregister_candev (cdev->net); }EXPORT_SYMBOL_GPL (m_can_class_unregister);
Greg Kroah-Hartman
maintainerPATCH 7/184 s390/pci: Fix missing check for zpci_create_device() error return
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Schnelle <[email protected]>
commit 42420c50c68f3e95e90de2479464f420602229fc upstream.
The zpci_create_device() function returns an error pointer that needs to be checked before dereferencing it as a struct zpci_dev pointer. Add the missing check in __clp_add() where it was missed when adding the scan_list in the fixed commit. Simply not adding the device to the scan list results in the previous behavior.
--- arch/s390/pci/pci_clp.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/pci/pci_clp.c +2 -0
@@ -422,6 +422,8 @@ static void __clp_add(struct clp_fh_listreturn ; } zdev =zpci_create_device (entry->fid, entry->fh, entry->config_state); +if (IS_ERR (zdev)) +return ;list_add_tail (&zdev->entry, scan_list); }
Greg Kroah-Hartman
maintainerPATCH 8/184 wifi: cfg80211: fix out-of-bounds access during multi-link element defragmentation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Veerendranath Jakkam <[email protected]>
commit 023c1f2f0609218103cbcb48e0104b144d4a16dc upstream.
Currently during the multi-link element defragmentation process, the multi-link element length added to the total IEs length when calculating the length of remaining IEs after the multi-link element in cfg80211_defrag_mle(). This could lead to out-of-bounds access if the multi-link element or its corresponding fragment elements are the last elements in the IEs buffer.
To address this issue, correctly calculate the remaining IEs length by deducting the multi-link element end offset from total IEs end offset.
--- net/wireless/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/scan.c +1 -1
@@ -2644,7 +2644,7 @@ cfg80211_defrag_mle(const struct element/* Required length for first defragmentation */ buf_len = mle->datalen -1 ;for_each_element (elem, mle->data + mle->datalen, - ielen -sizeof (*mle) + mle->datalen) { + ie + ielen - mle->data - mle->datalen) {if (elem->id !=WLAN_EID_FRAGMENT )break ;
Greg Kroah-Hartman
maintainerPATCH 9/184 vfio/pci: Align huge faults to order
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Williamson <[email protected]>
commit c1d9dac0db168198b6f63f460665256dedad9b6e upstream.
The vfio-pci huge_fault handler doesn't make any attempt to insert a mapping containing the faulting address, it only inserts mappings if the faulting address and resulting pfn are aligned. This works in a lot of cases, particularly in conjunction with QEMU where DMA mappings linearly fault the mmap. However, there are configurations where we don't get that linear faulting and pages are faulted on-demand.
The scenario reported in the bug below is such a case, where the physical address width of the CPU is greater than that of the IOMMU, resulting in a VM where guest firmware has mapped device MMIO beyond the address width of the IOMMU. In this configuration, the MMIO is faulted on demand and tracing indicates that occasionally the faults generate a VM_FAULT_OOM. Given the use case, this results in a "error: kvm run failed Bad address", killing the VM.
The host is not under memory pressure in this test, therefore it's suspected that VM_FAULT_OOM is actually the result of a NULL return from __pte_offset_map_lock() in the get_locked_pte() path from insert_pfn(). This suggests a potential race inserting a pte concurrent to a pmd, and maybe indicates some deficiency in the mm layer properly handling such a case.
Nevertheless, Peter noted the inconsistency of vfio-pci's huge_fault handler where our mapping granularity depends on the alignment of the faulting address relative to the order rather than aligning the faulting address to the order to more consistently insert huge mappings. This change not only uses the page tables more consistently and efficiently, but as any fault to an aligned page results in the same mapping, the race condition suspected in the VM_FAULT_OOM is avoided.
--- drivers/vfio/pci/vfio_pci_core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +6 -6
@@ -1658,14 +1658,14 @@ static vm_fault_t vfio_pci_mmap_huge_fau {struct vm_area_struct *vma = vmf->vma;struct vfio_pci_core_device *vdev = vma->vm_private_data; -unsigned long pfn, pgoff = vmf->pgoff - vma->vm_pgoff; +unsigned long addr = vmf->address & ~((PAGE_SIZE << order) -1 ); +unsigned long pgoff = (addr - vma->vm_start) >>PAGE_SHIFT ; +unsigned long pfn =vma_to_pfn (vma) + pgoff;vm_fault_t ret =VM_FAULT_SIGBUS ; - pfn =vma_to_pfn (vma) + pgoff; - -if (order && (pfn & ((1 << order) -1 ) || - vmf->address & ((PAGE_SIZE << order) -1 ) || - vmf->address + (PAGE_SIZE << order) > vma->vm_end)) { +if (order && (addr < vma->vm_start || + addr + (PAGE_SIZE << order) > vma->vm_end || + pfn & ((1 << order) -1 ))) { ret =VM_FAULT_FALLBACK ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 10/184 s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has child VFs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Schnelle <[email protected]>
commit 05a2538f2b48500cf4e8a0a0ce76623cc5bafcf1 upstream.
With commit bcb5d6c76903 ("s390/pci: introduce lock to synchronize state of zpci_dev's") the code to ignore power off of a PF that has child VFs was changed from a direct return to a goto to the unlock and pci_dev_put() section. The change however left the existing pci_dev_put() untouched resulting in a doubple put. This can subsequently cause a use after free if the struct pci_dev is released in an unexpected state. Fix this by removing the extra pci_dev_put().
--- drivers/pci/hotplug/s390_pci_hpc.c | 1 - 1 file changed, 1 deletion(-)
drivers/pci/hotplug/s390_pci_hpc.c +0 -1
@@ -59,7 +59,6 @@ static int disable_slot(struct hotplug_s pdev =pci_get_slot (zdev->zbus->bus, zdev->devfn);if (pdev &&pci_num_vf (pdev)) { -pci_dev_put (pdev); rc = -EBUSY ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 11/184 can: mcp251xfd: mcp251xfd_remove(): fix order of unregistration calls
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 84f5eb833f53ae192baed4cfb8d9eaab43481fc9 upstream.
If a driver is removed, the driver framework invokes the driver's remove callback. A CAN driver's remove function calls unregister_candev(), which calls net_device_ops::ndo_stop further down in the call stack for interfaces which are in the "up" state.
With the mcp251xfd driver the removal of the module causes the following warning:
| WARNING: CPU: 0 PID: 352 at net/core/dev.c:7342 __netif_napi_del_locked+0xc8/0xd8
as can_rx_offload_del() deletes the NAPI, while it is still active, because the interface is still up.
To fix the warning, first unregister the network interface, which calls net_device_ops::ndo_stop, which disables the NAPI, and then call can_rx_offload_del().
--- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +1 -1
@@ -2174,8 +2174,8 @@ static void mcp251xfd_remove(struct spi_struct mcp251xfd_priv *priv =spi_get_drvdata (spi);struct net_device *ndev = priv->ndev; -can_rx_offload_del (&priv->offload);mcp251xfd_unregister (priv); +can_rx_offload_del (&priv->offload); spi->max_speed_hz = priv->spi_max_speed_hz_orig;free_candev (ndev); }
Greg Kroah-Hartman
maintainerPATCH 12/184 can: rockchip_canfd: rkcanfd_remove(): fix order of unregistration calls
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 037ada7a3181300218e4fd78bef6a741cfa7f808 upstream.
If a driver is removed, the driver framework invokes the driver's remove callback. A CAN driver's remove function calls unregister_candev(), which calls net_device_ops::ndo_stop further down in the call stack for interfaces which are in the "up" state.
The removal of the module causes a warning, as can_rx_offload_del() deletes the NAPI, while it is still active, because the interface is still up.
To fix the warning, first unregister the network interface, which calls net_device_ops::ndo_stop, which disables the NAPI, and then call can_rx_offload_del().
--- drivers/net/can/rockchip/rockchip_canfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/rockchip/rockchip_canfd-core.c +1 -1
@@ -942,8 +942,8 @@ static void rkcanfd_remove(struct platfostruct rkcanfd_priv *priv =platform_get_drvdata (pdev);struct net_device *ndev = priv->ndev; -can_rx_offload_del (&priv->offload);rkcanfd_unregister (priv); +can_rx_offload_del (&priv->offload);free_candev (ndev); }
Greg Kroah-Hartman
maintainerPATCH 13/184 ksmbd: prevent rename with empty string
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit 53e3e5babc0963a92d856a5ec0ce92c59f54bc12 upstream.
Client can send empty newname string to ksmbd server. It will cause a kernel oops from d_alloc. This patch return the error when attempting to rename a file or directory with an empty new name string.
--- fs/smb/server/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/smb/server/smb2pdu.c +5 -0
@@ -633,6 +633,11 @@ smb2_get_name(const char *src, const intreturn name; } +if (*name =='\0' ) { +kfree (name); +return ERR_PTR (-EINVAL ); + } +if (*name =='\\' ) {pr_err ("not allow directory name included leading slash\n" );kfree (name);
Greg Kroah-Hartman
maintainerPATCH 14/184 ksmbd: prevent out-of-bounds stream writes by validating *pos
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <[email protected]>
commit 0ca6df4f40cf4c32487944aaf48319cb6c25accc upstream.
ksmbd_vfs_stream_write() did not validate whether the write offset (*pos) was within the bounds of the existing stream data length (v_len). If *pos was greater than or equal to v_len, this could lead to an out-of-bounds memory write.
This patch adds a check to ensure *pos is less than v_len before proceeding. If the condition fails, -EINVAL is returned.
--- fs/smb/server/vfs.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/smb/server/vfs.c +7 -0
@@ -443,6 +443,13 @@ static int ksmbd_vfs_stream_write(struct goto out; } +if (v_len <= *pos) { +pr_err ("stream write position %lld is out of bounds (stream length: %zd)\n" , + *pos, v_len); + err = -EINVAL ; + goto out; + } +if (v_len < size) { wbuf =kvzalloc (size,KSMBD_DEFAULT_GFP );if (!wbuf) {
Greg Kroah-Hartman
maintainerPATCH 15/184 ksmbd: Fix UAF in __close_file_table_ids
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Heelan <[email protected]>
commit 36991c1ccde2d5a521577c448ffe07fcccfe104d upstream.
A use-after-free is possible if one thread destroys the file via __ksmbd_close_fd while another thread holds a reference to it. The existing checks on fp->refcount are not sufficient to prevent this.
The fix takes ft->lock around the section which removes the file from the file table. This prevents two threads acquiring the same file pointer via __close_file_table_ids, as well as the other functions which retrieve a file from the IDR and which already use this same lock.
--- fs/smb/server/vfs_cache.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-)
fs/smb/server/vfs_cache.c +26 -7
@@ -661,21 +661,40 @@ __close_file_table_ids(struct ksmbd_filebool (*skip)(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp)) { -unsigned int id; -struct ksmbd_file *fp; -int num =0 ; +struct ksmbd_file *fp; +unsigned int id =0 ; +int num =0 ; -idr_for_each_entry (ft->idr, fp, id) { -if (skip (tcon, fp)) +while (1 ) { +write_lock (&ft->lock); + fp =idr_get_next (ft->idr, &id); +if (!fp) { +write_unlock (&ft->lock); +break ; + } + +if (skip (tcon, fp) || + !atomic_dec_and_test (&fp->refcount)) { + id++; +write_unlock (&ft->lock);continue ; + }set_close_state_blocked_works (fp); +idr_remove (ft->idr, fp->volatile_id); + fp->volatile_id =KSMBD_NO_FID ; +write_unlock (&ft->lock); + +down_write (&fp->f_ci->m_lock); +list_del_init (&fp->node); +up_write (&fp->f_ci->m_lock); -if (!atomic_dec_and_test (&fp->refcount)) -continue ;__ksmbd_close_fd (ft, fp); + num++; + id++; } +return num; }
Greg Kroah-Hartman
maintainerPATCH 16/184 openvswitch: Fix unsafe attribute parsing in output_userspace()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eelco Chaudron <[email protected]>
commit 6beb6835c1fbb3f676aebb51a5fee6b77fed9308 upstream.
This patch replaces the manual Netlink attribute iteration in output_userspace() with nla_for_each_nested(), which ensures that only well-formed attributes are processed.
--- net/openvswitch/actions.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/openvswitch/actions.c +1 -2
@@ -975,8 +975,7 @@ static int output_userspace(struct datap upcall.cmd =OVS_PACKET_CMD_ACTION ; upcall.mru =OVS_CB (skb)->mru; -for (a =nla_data (attr), rem =nla_len (attr); rem >0 ; - a =nla_next (a, &rem)) { +nla_for_each_nested (a, attr, rem) {switch (nla_type (a)) {case OVS_USERSPACE_ATTR_USERDATA : upcall.userdata = a;
Greg Kroah-Hartman
maintainerPATCH 17/184 ksmbd: fix memory leak in parse_lease_state()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Zhaolong <[email protected]>
[ Upstream commit eb4447bcce915b43b691123118893fca4f372a8f ]
The previous patch that added bounds check for create lease context introduced a memory leak. When the bounds check fails, the function returns NULL without freeing the previously allocated lease_ctx_info structure.
This patch fixes the issue by adding kfree(lreq) before returning NULL in both boundary check cases.
--- fs/smb/server/oplock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/smb/server/oplock.c +5 -2
@@ -1496,7 +1496,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)if (le16_to_cpu (cc->DataOffset) +le32_to_cpu (cc->DataLength) <sizeof (struct create_lease_v2 ) -4 ) -return NULL ; + goto err_out;memcpy (lreq->lease_key, lc->lcontext.LeaseKey,SMB2_LEASE_KEY_SIZE ); lreq->req_state = lc->lcontext.LeaseState;
@@ -1512,7 +1512,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)if (le16_to_cpu (cc->DataOffset) +le32_to_cpu (cc->DataLength) <sizeof (struct create_lease )) -return NULL ; + goto err_out;memcpy (lreq->lease_key, lc->lcontext.LeaseKey,SMB2_LEASE_KEY_SIZE ); lreq->req_state = lc->lcontext.LeaseState;
@@ -1521,6 +1521,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req) lreq->version =1 ; }return lreq; +err_out: +kfree (lreq); +return NULL ; }/**
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 18/184 s390/entry: Fix last breaking event handling in case of stack corruption
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
[ Upstream commit ae952eea6f4a7e2193f8721a5366049946e012e7 ]
In case of stack corruption stack_invalid() is called and the expectation is that register r10 contains the last breaking event address. This dependency is quite subtle and broke a couple of years ago without that anybody noticed.
Fix this by getting rid of the dependency and read the last breaking event address from lowcore.
--- arch/s390/kernel/entry.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/s390/kernel/entry.S +2 -1
@@ -636,7 +636,8 @@ SYM_CODE_START(stack_overflow) stmg %r0,%r7,__PT_R0(%r11) stmg %r8,%r9,__PT_PSW(%r11) mvc __PT_R8(64,%r11),0(%r14) - stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 + GET_LC %r2 + mvc __PT_ORIG_GPR2(8,%r11),__LC_PGM_LAST_BREAK(%r2) xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs jg kernel_stack_overflow
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 19/184 sch_htb: make htb_deactivate() idempotent
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 3769478610135e82b262640252d90f6efb05be71 ]
Alan reported a NULL pointer dereference in htb_next_rb_node() after we made htb_qlen_notify() idempotent.
It turns out in the following case it introduced some regression:
htb_dequeue_tree():
|-> fq_codel_dequeue()
|-> qdisc_tree_reduce_backlog()
|-> htb_qlen_notify()
|-> htb_deactivate() |-> htb_next_rb_node()
|-> htb_deactivate()
For htb_next_rb_node(), after calling the 1st htb_deactivate(), the clprio[prio]->ptr could be already set to NULL, which means htb_next_rb_node() is vulnerable here.
For htb_deactivate(), although we checked qlen before calling it, in case of qlen==0 after qdisc_tree_reduce_backlog(), we may call it again which triggers the warning inside.
To fix the issues here, we need to:
1) Make htb_deactivate() idempotent, that is, simply return if we already call it before.
2) Make htb_next_rb_node() safe against ptr==NULL.
Many thanks to Alan for testing and for the reproducer.
--- net/sched/sch_htb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
net/sched/sch_htb.c +6 -9
@@ -348,7 +348,8 @@ static void htb_add_to_wait_tree(struct htb_sched *q,*/ static inline void htb_next_rb_node (struct rb_node **n) { - *n =rb_next (*n); +if (*n) + *n =rb_next (*n); }/**
@@ -609,8 +610,8 @@ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl)*/ static inline void htb_deactivate (struct htb_sched *q,struct htb_class *cl) { -WARN_ON (!cl->prio_activity); - +if (!cl->prio_activity) +return ;htb_deactivate_prios (q, cl); cl->prio_activity =0 ; }
@@ -1485,8 +1486,6 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg) {struct htb_class *cl = (struct htb_class *)arg; -if (!cl->prio_activity) -return ;htb_deactivate (qdisc_priv (sch), cl); }
@@ -1740,8 +1739,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg,if (cl->parent) cl->parent->children--; -if (cl->prio_activity) -htb_deactivate (q, cl); +htb_deactivate (q, cl);if (cl->cmode !=HTB_CAN_SEND ) htb_safe_rb_erase(&cl->pq_node,
@@ -1949,8 +1947,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,/* turn parent into inner node */ qdisc_purge_queue (parent->leaf.q); parent_qdisc = parent->leaf.q; -if (parent->prio_activity) -htb_deactivate (q, parent); +htb_deactivate (q, parent);/* remove from evt list because of level change */ if (parent->cmode !=HTB_CAN_SEND ) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 20/184 virtio_net: xsk: bind/unbind xsk for tx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuan Zhuo <[email protected]>
[ Upstream commit 21a4e3ce6dc7b0a3bc882ebe1cb921a40235ddb0 ]
This patch implement the logic of bind/unbind xsk pool to sq and rq.
Stable-dep-of: 4397684a292a ("virtio-net: free xsk_buffs on error in virtnet_xsk_pool_enable()")
--- drivers/net/virtio_net.c | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
drivers/net/virtio_net.c +53 -0
@@ -298,6 +298,10 @@ struct send_queue {/* Record whether sq is in reset state. */ bool reset; + +struct xsk_buff_pool *xsk_pool; + +dma_addr_t xsk_hdr_dma_addr; };/* Internal representation of a receive virtqueue */
@@ -501,6 +505,8 @@ struct virtio_net_common_hdr { }; }; +static struct virtio_net_common_hdr xsk_hdr; +static void virtnet_sq_free_unused_buf (struct virtqueue *vq,void *buf);static void virtnet_sq_free_unused_buf_done (struct virtqueue *vq); static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
@@ -5556,6 +5562,29 @@ static int virtnet_rq_bind_xsk_pool(struct virtnet_info *vi, struct receive_queureturn err; } +static int virtnet_sq_bind_xsk_pool (struct virtnet_info *vi, +struct send_queue *sq, +struct xsk_buff_pool *pool) +{ +int err, qindex; + + qindex = sq - vi->sq; + +virtnet_tx_pause (vi, sq); + + err =virtqueue_reset (sq->vq, virtnet_sq_free_unused_buf); +if (err) { +netdev_err (vi->dev,"reset tx fail: tx queue index: %d err: %d\n" , qindex, err); + pool =NULL ; + } + + sq->xsk_pool = pool; + +virtnet_tx_resume (vi, sq); + +return err; +} +static int virtnet_xsk_pool_enable (struct net_device *dev,struct xsk_buff_pool *pool,u16 qid)
@@ -5564,6 +5593,7 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,struct receive_queue *rq;struct device *dma_dev;struct send_queue *sq; +dma_addr_t hdr_dma;int err, size;if (vi->hdr_len >xsk_pool_get_headroom (pool))
@@ -5601,6 +5631,11 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,if (!rq->xsk_buffs)return -ENOMEM ; + hdr_dma =virtqueue_dma_map_single_attrs (sq->vq, &xsk_hdr, vi->hdr_len, +DMA_TO_DEVICE ,0 ); +if (virtqueue_dma_mapping_error (sq->vq, hdr_dma)) +return -ENOMEM ; + err =xsk_pool_dma_map (pool, dma_dev,0 );if (err) goto err_xsk_map;
@@ -5609,11 +5644,24 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,if (err) goto err_rq; + err =virtnet_sq_bind_xsk_pool (vi, sq, pool); +if (err) + goto err_sq; + +/* Now, we do not support tx offload(such as tx csum), so all the tx +* virtnet hdr is zero. So all the tx packets can share a single hdr. +*/ + sq->xsk_hdr_dma_addr = hdr_dma; +return 0 ; +err_sq: +virtnet_rq_bind_xsk_pool (vi, rq,NULL ); err_rq:xsk_pool_dma_unmap (pool,0 ); err_xsk_map: +virtqueue_dma_unmap_single_attrs (rq->vq, hdr_dma, vi->hdr_len, +DMA_TO_DEVICE ,0 );return err; }
@@ -5622,19 +5670,24 @@ static int virtnet_xsk_pool_disable(struct net_device *dev, u16 qid)struct virtnet_info *vi =netdev_priv (dev);struct xsk_buff_pool *pool;struct receive_queue *rq; +struct send_queue *sq;int err;if (qid >= vi->curr_queue_pairs)return -EINVAL ; + sq = &vi->sq[qid]; rq = &vi->rq[qid]; pool = rq->xsk_pool; err =virtnet_rq_bind_xsk_pool (vi, rq,NULL ); + err |=virtnet_sq_bind_xsk_pool (vi, sq,NULL );xsk_pool_dma_unmap (pool,0 ); +virtqueue_dma_unmap_single_attrs (sq->vq, sq->xsk_hdr_dma_addr, + vi->hdr_len,DMA_TO_DEVICE ,0 );kvfree (rq->xsk_buffs);return err;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 21/184 virtio-net: free xsk_buffs on error in virtnet_xsk_pool_enable()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 4397684a292a71fbc1e815c3e283f7490ddce5ae ]
The selftests added to our CI by Bui Quang Minh recently reveals that there is a mem leak on the error path of virtnet_xsk_pool_enable():
unreferenced object 0xffff88800a68a000 (size 2048):
comm "xdp_helper", pid 318, jiffies 4294692778 hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
__kvmalloc_node_noprof+0x402/0x570
virtnet_xsk_pool_enable+0x293/0x6a0 (drivers/net/virtio_net.c:5882)
xp_assign_dev+0x369/0x670 (net/xdp/xsk_buff_pool.c:226)
xsk_bind+0x6a5/0x1ae0
__sys_bind+0x15e/0x230
__x64_sys_bind+0x72/0xb0
do_syscall_64+0xc1/0x1d0
entry_SYSCALL_64_after_hwframe+0x77/0x7f--- drivers/net/virtio_net.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/virtio_net.c +6 -2
@@ -5633,8 +5633,10 @@ static int virtnet_xsk_pool_enable(struct net_device *dev, hdr_dma =virtqueue_dma_map_single_attrs (sq->vq, &xsk_hdr, vi->hdr_len,DMA_TO_DEVICE ,0 ); -if (virtqueue_dma_mapping_error (sq->vq, hdr_dma)) -return -ENOMEM ; +if (virtqueue_dma_mapping_error (sq->vq, hdr_dma)) { + err = -ENOMEM ; + goto err_free_buffs; + } err =xsk_pool_dma_map (pool, dma_dev,0 );if (err)
@@ -5662,6 +5664,8 @@ static int virtnet_xsk_pool_enable(struct net_device *dev, err_xsk_map:virtqueue_dma_unmap_single_attrs (rq->vq, hdr_dma, vi->hdr_len,DMA_TO_DEVICE ,0 ); +err_free_buffs: +kvfree (rq->xsk_buffs);return err; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 22/184 gre: Fix again IPv6 link-local address generation.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 3e6a0243ff002ddbd7ee18a8974ae61d2e6ed00d ]
Use addrconf_addr_gen() to generate IPv6 link-local addresses on GRE devices in most cases and fall back to using add_v4_addrs() only in case the GRE configuration is incompatible with addrconf_addr_gen().
GRE used to use addrconf_addr_gen() until commit e5dd729460ca ("ip/ip6_gre:
use the same logic as SIT interfaces when computing v6LL address") restricted this use to gretap and ip6gretap devices, and created add_v4_addrs() (borrowed from SIT) for non-Ethernet GRE ones.
The original problem came when commit 9af28511be10 ("addrconf: refuse isatap eui64 for INADDR_ANY") made __ipv6_isatap_ifid() fail when its addr parameter was 0. The commit says that this would create an invalid address, however, I couldn't find any RFC saying that the generated interface identifier would be wrong. Anyway, since gre over IPv4 devices pass their local tunnel address to __ipv6_isatap_ifid(), that commit broke their IPv6 link-local address generation when the local address was unspecified.
Then commit e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") tried to fix that case by defining add_v4_addrs() and calling it to generate the IPv6 link-local address instead of using addrconf_addr_gen() (apart for gretap and ip6gretap devices, which would still use the regular addrconf_addr_gen(), since they have a MAC address).
That broke several use cases because add_v4_addrs() isn't properly integrated into the rest of IPv6 Neighbor Discovery code. Several of these shortcomings have been fixed over time, but add_v4_addrs() remains broken on several aspects. In particular, it doesn't send any Router Sollicitations, so the SLAAC process doesn't start until the interface receives a Router Advertisement. Also, add_v4_addrs() mostly ignores the address generation mode of the interface (/proc/sys/net/ipv6/conf/*/addr_gen_mode), thus breaking the IN6_ADDR_GEN_MODE_RANDOM and IN6_ADDR_GEN_MODE_STABLE_PRIVACY cases.
Fix the situation by using add_v4_addrs() only in the specific scenario where the normal method would fail. That is, for interfaces that have all of the following characteristics:
* run over IPv4,
* transport IP packets directly, not Ethernet (that is, not gretap interfaces),
* tunnel endpoint is INADDR_ANY (that is, 0),
* device address generation mode is EUI64.
In all other cases, revert back to the regular addrconf_addr_gen().
Also, remove the special case for ip6gre interfaces in add_v4_addrs(), since ip6gre devices now always use addrconf_addr_gen() instead.
Note:
This patch was originally applied as commit 183185a18ff9 ("gre: Fix IPv6 link-local address generation."). However, it was then reverted by commit fc486c2d060f ("Revert "gre: Fix IPv6 link-local address generation."") because it uncovered another bug that ended up breaking net/forwarding/ip6gre_custom_multipath_hash.sh. That other bug has now been fixed by commit 4d0ab3a6885e ("ipv6: Start path selection from the first nexthop"). Therefore we can now revive this GRE patch (no changes since original commit 183185a18ff9 ("gre: Fix IPv6 link-local address generation.").
--- net/ipv6/addrconf.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
net/ipv6/addrconf.c +9 -6
@@ -3237,16 +3237,13 @@ static void add_v4_addrs(struct inet6_dev *idev)struct in6_addr addr;struct net_device *dev;struct net *net =dev_net (idev->dev); -int scope, plen, offset =0 ; +int scope, plen;u32 pflags =0 ;ASSERT_RTNL ();memset (&addr,0 ,sizeof (struct in6_addr )); -/* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */ -if (idev->dev->addr_len ==sizeof (struct in6_addr )) - offset =sizeof (struct in6_addr ) -4 ; -memcpy (&addr.s6_addr32[3 ], idev->dev->dev_addr + offset,4 ); +memcpy (&addr.s6_addr32[3 ], idev->dev->dev_addr,4 );if (!(idev->dev->flags &IFF_POINTOPOINT ) && idev->dev->type ==ARPHRD_SIT ) { scope = IPV6_ADDR_COMPATv4;
@@ -3557,7 +3554,13 @@ static void addrconf_gre_config(struct net_device *dev)return ; } -if (dev->type ==ARPHRD_ETHER ) { +/* Generate the IPv6 link-local address using addrconf_addr_gen(), +* unless we have an IPv4 GRE device not bound to an IP address and +* which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this +* case). Such devices fall back to add_v4_addrs() instead. +*/ +if (!(dev->type ==ARPHRD_IPGRE && *(__be32 *)dev->dev_addr ==0 && + idev->cnf.addr_gen_mode ==IN6_ADDR_GEN_MODE_EUI64 )) {addrconf_addr_gen (idev, true);return ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 23/184 net: ethernet: mtk_eth_soc: reset all TX queues on DMA free
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle <[email protected]>
[ Upstream commit 4db6c75124d871fbabf8243f947d34cc7e0697fc ]
The purpose of resetting the TX queue is to reset the byte and packet count as well as to clear the software flow control XOFF bit.
MediaTek developers pointed out that netdev_reset_queue would only resets queue 0 of the network device.
Queues that are not reset may cause unexpected issues.
Packets may stop being sent after reset and "transmit timeout" log may be displayed.
Import fix from MediaTek's SDK to resolve this issue.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +12 -4
@@ -3140,11 +3140,19 @@ static int mtk_dma_init(struct mtk_eth *eth)static void mtk_dma_free (struct mtk_eth *eth) {const struct mtk_soc_data *soc = eth->soc; -int i; +int i, j, txqs =1 ; + +if (MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) + txqs =MTK_QDMA_NUM_QUEUES ; + +for (i =0 ; i <MTK_MAX_DEVS ; i++) { +if (!eth->netdev[i]) +continue ; + +for (j =0 ; j < txqs; j++) +netdev_tx_reset_subqueue (eth->netdev[i], j); + } -for (i =0 ; i <MTK_MAX_DEVS ; i++) -if (eth->netdev[i]) -netdev_reset_queue (eth->netdev[i]);if (!MTK_HAS_CAPS (soc->caps,MTK_SRAM ) && eth->scratch_ring) { dma_free_coherent(eth->dma_dev, MTK_QDMA_RING_SIZE * soc->tx.desc_size,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 24/184 net: ethernet: mtk_eth_soc: do not reset PSE when setting FE
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Wunderlich <[email protected]>
[ Upstream commit e8716b5b0dff1b3d523b4a83fd5e94d57b887c5c ]
Remove redundant PSE reset.
When setting FE register there is no need to reset PSE, doing so may cause FE to work abnormal.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 --- 1 file changed, 3 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +0 -3
@@ -3427,9 +3427,6 @@ static int mtk_open(struct net_device *dev) }mtk_gdm_config (eth, target_mac->id, gdm_config); } -/* Reset and enable PSE */ -mtk_w32 (eth,RST_GL_PSE ,MTK_RST_GL ); -mtk_w32 (eth,0 ,MTK_RST_GL );napi_enable (ð->tx_napi);napi_enable (ð->rx_napi);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 25/184 can: m_can: m_can_class_allocate_dev(): initialize spin lock on device probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antonios Salios <[email protected]>
[ Upstream commit dcaeeb8ae84c5506ebc574732838264f3887738c ]
The spin lock tx_handling_spinlock in struct m_can_classdev is not being initialized. This leads the following spinlock bad magic complaint from the kernel, eg. when trying to send CAN frames with cansend from can-utils:
| BUG: spinlock bad magic on CPU#0, cansend/95 | lock: 0xff60000002ec1010, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 | CPU: 0 UID: 0 PID: 95 Comm: cansend Not tainted 6.15.0-rc3-00032-ga79be02bba5c #5 NONE | Hardware name: MachineWare SIM-V (DT) | Call Trace: | [<ffffffff800133e0>] dump_backtrace+0x1c/0x24 | [<ffffffff800022f2>] show_stack+0x28/0x34 | [<ffffffff8000de3e>] dump_stack_lvl+0x4a/0x68 | [<ffffffff8000de70>] dump_stack+0x14/0x1c | [<ffffffff80003134>] spin_dump+0x62/0x6e | [<ffffffff800883ba>] do_raw_spin_lock+0xd0/0x142 | [<ffffffff807a6fcc>] _raw_spin_lock_irqsave+0x20/0x2c | [<ffffffff80536dba>] m_can_start_xmit+0x90/0x34a | [<ffffffff806148b0>] dev_hard_start_xmit+0xa6/0xee | [<ffffffff8065b730>] sch_direct_xmit+0x114/0x292 | [<ffffffff80614e2a>] __dev_queue_xmit+0x3b0/0xaa8 | [<ffffffff8073b8fa>] can_send+0xc6/0x242 | [<ffffffff8073d1c0>] raw_sendmsg+0x1a8/0x36c | [<ffffffff805ebf06>] sock_write_iter+0x9a/0xee | [<ffffffff801d06ea>] vfs_write+0x184/0x3a6 | [<ffffffff801d0a88>] ksys_write+0xa0/0xc0 | [<ffffffff801d0abc>] __riscv_sys_write+0x14/0x1c | [<ffffffff8079ebf8>] do_trap_ecall_u+0x168/0x212 | [<ffffffff807a830a>] handle_exception+0x146/0x152
Initializing the spin lock in m_can_class_allocate_dev solves that problem.
--- drivers/net/can/m_can/m_can.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/can/m_can/m_can.c +1 -0
@@ -2372,6 +2372,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,SET_NETDEV_DEV (net_dev, dev);m_can_of_parse_mram (class_dev, mram_config_vals); +spin_lock_init (&class_dev->tx_handling_spinlock); out:return class_dev; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 26/184 can: mcp251xfd: fix TDC setting for low data bit rates
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kelsey Maes <[email protected]>
[ Upstream commit 5e1663810e11c64956aa7e280cf74b2f3284d816 ]
The TDC is currently hardcoded enabled. This means that even for lower CAN-FD data bitrates (with a DBRP (data bitrate prescaler) > 2) a TDC is configured. This leads to a bus-off condition.
ISO 11898-1 section 11.3.3 says "Transmitter delay compensation" (TDC) is only applicable if DBRP is 1 or 2.
To fix the problem, switch the driver to use the TDC calculation provided by the CAN driver framework (which respects ISO 11898-1 section 11.3.3). This has the positive side effect that userspace can control TDC as needed.
Demonstration of the feature in action:
| $ ip link set can0 up type can bitrate 125000 dbitrate 500000 fd on | $ ip -details link show can0 | 3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10 | link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 | can <FD> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0 | bitrate 125000 sample-point 0.875 | tq 50 prop-seg 69 phase-seg1 70 phase-seg2 20 sjw 10 brp 2 | mcp251xfd: tseg1 2..256 tseg2 1..128 sjw 1..128 brp 1..256 brp_inc 1 | dbitrate 500000 dsample-point 0.875 | dtq 125 dprop-seg 6 dphase-seg1 7 dphase-seg2 2 dsjw 1 dbrp 5 | mcp251xfd: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..256 dbrp_inc 1 | tdcv 0..63 tdco 0..63 | clock 40000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 parentbus spi parentdev spi0.0 | $ ip link set can0 up type can bitrate 1000000 dbitrate 4000000 fd on | $ ip -details link show can0 | 3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10 | link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 | can <FD,TDC-AUTO> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0 | bitrate 1000000 sample-point 0.750 | tq 25 prop-seg 14 phase-seg1 15 phase-seg2 10 sjw 5 brp 1 | mcp251xfd: tseg1 2..256 tseg2 1..128 sjw 1..128 brp 1..256 brp_inc 1 | dbitrate 4000000 dsample-point 0.700 | dtq 25 dprop-seg 3 dphase-seg1 3 dphase-seg2 3 dsjw 1 dbrp 1 | tdco 7 | mcp251xfd: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..256 dbrp_inc 1 | tdcv 0..63 tdco 0..63 | clock 40000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 parentbus spi parentdev spi0.0
There has been some confusion about the MCP2518FD using a relative or absolute TDCO due to the datasheet specifying a range of [-64,63]. I have a custom board with a 40 MHz clock and an estimated loop delay of 100 to 216 ns. During testing at a data bit rate of 4 Mbit/s I found that using can_get_relative_tdco() resulted in bus-off errors. The final TDCO value was 1 which corresponds to a 10% SSP in an absolute configuration. This behavior is expected if the TDCO value is really absolute and not relative. Using priv->can.tdc.tdco instead results in a final TDCO of 8, setting the SSP at exactly 80%. This configuration works.
The automatic, manual, and off TDC modes were tested at speeds up to, and including, 8 Mbit/s on real hardware and behave as expected.
--- .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-)
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +32 -8
@@ -75,6 +75,24 @@ static const struct can_bittiming_const mcp251xfd_data_bittiming_const = { .brp_inc = 1, }; +/* The datasheet of the mcp2518fd (DS20006027B) specifies a range of +* [-64,63] for TDCO, indicating a relative TDCO. +* +* Manual tests have shown, that using a relative TDCO configuration +* results in bus off, while an absolute configuration works. +* +* For TDCO use the max value (63) from the data sheet, but 0 as the +* minimum. +*/ +static const struct can_tdc_const mcp251xfd_tdc_const = { + .tdcv_min =0 , + .tdcv_max =63 , + .tdco_min =0 , + .tdco_max =63 , + .tdcf_min =0 , + .tdcf_max =0 , +}; +static const char *__mcp251xfd_get_model_str (enum mcp251xfd_model model) {switch (model) {
@@ -510,8 +528,7 @@ static int mcp251xfd_set_bittiming(const struct mcp251xfd_priv *priv) {const struct can_bittiming *bt = &priv->can.bittiming;const struct can_bittiming *dbt = &priv->can.data_bittiming; -u32 val =0 ; -s8 tdco; +u32 tdcmod, val =0 ;int err;/* CAN Control Register
@@ -575,11 +592,16 @@ static int mcp251xfd_set_bittiming(const struct mcp251xfd_priv *priv)return err;/* Transmitter Delay Compensation */ - tdco =clamp_t (int, dbt->brp * (dbt->prop_seg + dbt->phase_seg1), --64 ,63 ); - val =FIELD_PREP (MCP251XFD_REG_TDC_TDCMOD_MASK , -MCP251XFD_REG_TDC_TDCMOD_AUTO ) | -FIELD_PREP (MCP251XFD_REG_TDC_TDCO_MASK , tdco); +if (priv->can.ctrlmode &CAN_CTRLMODE_TDC_AUTO ) + tdcmod =MCP251XFD_REG_TDC_TDCMOD_AUTO ; +else if (priv->can.ctrlmode &CAN_CTRLMODE_TDC_MANUAL ) + tdcmod =MCP251XFD_REG_TDC_TDCMOD_MANUAL ; +else + tdcmod =MCP251XFD_REG_TDC_TDCMOD_DISABLED ; + + val =FIELD_PREP (MCP251XFD_REG_TDC_TDCMOD_MASK , tdcmod) | +FIELD_PREP (MCP251XFD_REG_TDC_TDCV_MASK , priv->can.tdc.tdcv) | +FIELD_PREP (MCP251XFD_REG_TDC_TDCO_MASK , priv->can.tdc.tdco);return regmap_write (priv->map_reg,MCP251XFD_REG_TDC , val); }
@@ -2083,10 +2105,12 @@ static int mcp251xfd_probe(struct spi_device *spi) priv->can.do_get_berr_counter = mcp251xfd_get_berr_counter; priv->can.bittiming_const = &mcp251xfd_bittiming_const; priv->can.data_bittiming_const = &mcp251xfd_data_bittiming_const; + priv->can.tdc_const = &mcp251xfd_tdc_const; priv->can.ctrlmode_supported =CAN_CTRLMODE_LOOPBACK |CAN_CTRLMODE_LISTENONLY |CAN_CTRLMODE_BERR_REPORTING |CAN_CTRLMODE_FD |CAN_CTRLMODE_FD_NON_ISO | -CAN_CTRLMODE_CC_LEN8_DLC ; +CAN_CTRLMODE_CC_LEN8_DLC |CAN_CTRLMODE_TDC_AUTO | +CAN_CTRLMODE_TDC_MANUAL ;set_bit (MCP251XFD_FLAGS_DOWN , priv->flags); priv->ndev = ndev; priv->spi = spi;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 27/184 can: gw: fix RCU/BH usage in cgw_create_job()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
[ Upstream commit 511e64e13d8cc72853275832e3f372607466c18c ]
As reported by Sebastian Andrzej Siewior the use of local_bh_disable() is only feasible in uni processor systems to update the modification rules. The usual use-case to update the modification rules is to update the data of the modifications but not the modification types (AND/OR/XOR/SET) or the checksum functions itself.
To omit additional memory allocations to maintain fast modification switching times, the modification description space is doubled at gw-job creation time so that only the reference to the active modification description is changed under rcu protection.
Rename cgw_job::mod to cf_mod and make it a RCU pointer. Allocate in cgw_create_job() and free it together with cgw_job in cgw_job_free_rcu(). Update all users to dereference cgw_job::cf_mod with a RCU accessor and if possible once.
[bigeasy: Replace mod1/mod2 from the Oliver's original patch with dynamic allocation, use RCU annotation and accessor]
--- net/can/gw.c | 149 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 59 deletions(-)
net/can/gw.c +90 -59
@@ -130,7 +130,7 @@ struct cgw_job {u32 handled_frames;u32 dropped_frames;u32 deleted_frames; -struct cf_mod mod; +struct cf_mod __rcu *cf_mod;union {/* CAN frame data source */ struct net_device *dev;
@@ -459,6 +459,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)struct cgw_job *gwj = (struct cgw_job *)data;struct canfd_frame *cf;struct sk_buff *nskb; +struct cf_mod *mod;int modidx =0 ;/* process strictly Classic CAN or CAN FD frames */
@@ -506,7 +507,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)* When there is at least one modification function activated, * we need to copy the skb as we want to modify skb->data. */ -if (gwj->mod.modfunc[0 ]) + mod =rcu_dereference (gwj->cf_mod); +if (mod->modfunc[0 ]) nskb =skb_copy (skb,GFP_ATOMIC );else nskb =skb_clone (skb,GFP_ATOMIC );
@@ -529,8 +531,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) cf = (struct canfd_frame *)nskb->data;/* perform preprocessed modification functions if there are any */ -while (modidx <MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx]) - (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod); +while (modidx <MAX_MODFUNCTIONS && mod->modfunc[modidx]) + (*mod->modfunc[modidx++])(cf, mod);/* Has the CAN frame been modified? */ if (modidx) {
@@ -546,11 +548,11 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) }/* check for checksum updates */ -if (gwj->mod.csumfunc.crc8) - (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8); +if (mod->csumfunc.crc8) + (*mod->csumfunc.crc8)(cf, &mod->csum.crc8); -if (gwj->mod.csumfunc.xor) - (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor); +if (mod->csumfunc.xor) + (*mod->csumfunc.xor)(cf, &mod->csum.xor); }/* clear the skb timestamp if not configured the other way */
@@ -581,9 +583,20 @@ static void cgw_job_free_rcu(struct rcu_head *rcu_head) { struct cgw_job *gwj = container_of(rcu_head, struct cgw_job, rcu); +/* cgw_job::cf_mod is always accessed from the same cgw_job object within +* the same RCU read section. Once cgw_job is scheduled for removal, +* cf_mod can also be removed without mandating an additional grace period. +*/ +kfree (rcu_access_pointer (gwj->cf_mod));kmem_cache_free (cgw_cache, gwj); } +/* Return cgw_job::cf_mod with RTNL protected section */ +static struct cf_mod *cgw_job_cf_mod (struct cgw_job *gwj) +{ +return rcu_dereference_protected (gwj->cf_mod,rtnl_is_locked ()); +} +static int cgw_notifier (struct notifier_block *nb,unsigned long msg,void *ptr) {
@@ -616,6 +629,7 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, {struct rtcanmsg *rtcan;struct nlmsghdr *nlh; +struct cf_mod *mod; nlh =nlmsg_put (skb, pid, seq, type,sizeof (*rtcan), flags);if (!nlh)
@@ -650,82 +664,83 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, goto cancel; } + mod =cgw_job_cf_mod (gwj);if (gwj->flags &CGW_FLAGS_CAN_FD ) {struct cgw_fdframe_mod mb; -if (gwj->mod.modtype.and) { -memcpy (&mb.cf, &gwj->mod.modframe.and,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.and; +if (mod->modtype.and) { +memcpy (&mb.cf, &mod->modframe.and,sizeof (mb.cf)); + mb.modtype = mod->modtype.and;if (nla_put (skb,CGW_FDMOD_AND ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.or) { -memcpy (&mb.cf, &gwj->mod.modframe.or,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.or; +if (mod->modtype.or) { +memcpy (&mb.cf, &mod->modframe.or,sizeof (mb.cf)); + mb.modtype = mod->modtype.or;if (nla_put (skb,CGW_FDMOD_OR ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.xor) { -memcpy (&mb.cf, &gwj->mod.modframe.xor,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.xor; +if (mod->modtype.xor) { +memcpy (&mb.cf, &mod->modframe.xor,sizeof (mb.cf)); + mb.modtype = mod->modtype.xor;if (nla_put (skb,CGW_FDMOD_XOR ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.set) { -memcpy (&mb.cf, &gwj->mod.modframe.set,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.set; +if (mod->modtype.set) { +memcpy (&mb.cf, &mod->modframe.set,sizeof (mb.cf)); + mb.modtype = mod->modtype.set;if (nla_put (skb,CGW_FDMOD_SET ,sizeof (mb), &mb) <0 ) goto cancel; } }else {struct cgw_frame_mod mb; -if (gwj->mod.modtype.and) { -memcpy (&mb.cf, &gwj->mod.modframe.and,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.and; +if (mod->modtype.and) { +memcpy (&mb.cf, &mod->modframe.and,sizeof (mb.cf)); + mb.modtype = mod->modtype.and;if (nla_put (skb,CGW_MOD_AND ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.or) { -memcpy (&mb.cf, &gwj->mod.modframe.or,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.or; +if (mod->modtype.or) { +memcpy (&mb.cf, &mod->modframe.or,sizeof (mb.cf)); + mb.modtype = mod->modtype.or;if (nla_put (skb,CGW_MOD_OR ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.xor) { -memcpy (&mb.cf, &gwj->mod.modframe.xor,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.xor; +if (mod->modtype.xor) { +memcpy (&mb.cf, &mod->modframe.xor,sizeof (mb.cf)); + mb.modtype = mod->modtype.xor;if (nla_put (skb,CGW_MOD_XOR ,sizeof (mb), &mb) <0 ) goto cancel; } -if (gwj->mod.modtype.set) { -memcpy (&mb.cf, &gwj->mod.modframe.set,sizeof (mb.cf)); - mb.modtype = gwj->mod.modtype.set; +if (mod->modtype.set) { +memcpy (&mb.cf, &mod->modframe.set,sizeof (mb.cf)); + mb.modtype = mod->modtype.set;if (nla_put (skb,CGW_MOD_SET ,sizeof (mb), &mb) <0 ) goto cancel; } } -if (gwj->mod.uid) { -if (nla_put_u32 (skb,CGW_MOD_UID , gwj->mod.uid) <0 ) +if (mod->uid) { +if (nla_put_u32 (skb,CGW_MOD_UID , mod->uid) <0 ) goto cancel; } -if (gwj->mod.csumfunc.crc8) { +if (mod->csumfunc.crc8) {if (nla_put (skb,CGW_CS_CRC8 ,CGW_CS_CRC8_LEN , - &gwj->mod.csum.crc8) <0 ) + &mod->csum.crc8) <0 ) goto cancel; } -if (gwj->mod.csumfunc.xor) { +if (mod->csumfunc.xor) {if (nla_put (skb,CGW_CS_XOR ,CGW_CS_XOR_LEN , - &gwj->mod.csum.xor) <0 ) + &mod->csum.xor) <0 ) goto cancel; }
@@ -1059,7 +1074,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,struct net *net =sock_net (skb->sk);struct rtcanmsg *r;struct cgw_job *gwj; -struct cf_mod mod; +struct cf_mod *mod;struct can_can_gw ccgw;u8 limhops =0 ;int err =0 ;
@@ -1078,37 +1093,48 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,if (r->gwtype !=CGW_TYPE_CAN_CAN )return -EINVAL ; - err =cgw_parse_attr (nlh, &mod,CGW_TYPE_CAN_CAN , &ccgw, &limhops); + mod =kmalloc (sizeof (*mod),GFP_KERNEL ); +if (!mod) +return -ENOMEM ; + + err =cgw_parse_attr (nlh, mod,CGW_TYPE_CAN_CAN , &ccgw, &limhops);if (err <0 ) -return err; + goto out_free_cf; -if (mod.uid) { +if (mod->uid) {ASSERT_RTNL ();/* check for updating an existing job with identical uid */ hlist_for_each_entry (gwj, &net->can.cgw_list, list) { -if (gwj->mod.uid != mod.uid) +struct cf_mod *old_cf; + + old_cf =cgw_job_cf_mod (gwj); +if (old_cf->uid != mod->uid)continue ;/* interfaces & filters must be identical */ -if (memcmp (&gwj->ccgw, &ccgw,sizeof (ccgw))) -return -EINVAL ; +if (memcmp (&gwj->ccgw, &ccgw,sizeof (ccgw))) { + err = -EINVAL ; + goto out_free_cf; + } -/* update modifications with disabled softirq & quit */ -local_bh_disable (); -memcpy (&gwj->mod, &mod,sizeof (mod)); -local_bh_enable (); +rcu_assign_pointer (gwj->cf_mod, mod); +kfree_rcu_mightsleep (old_cf);return 0 ; } }/* ifindex == 0 is not allowed for job creation */ -if (!ccgw.src_idx || !ccgw.dst_idx) -return -ENODEV ; +if (!ccgw.src_idx || !ccgw.dst_idx) { + err = -ENODEV ; + goto out_free_cf; + } gwj =kmem_cache_alloc (cgw_cache,GFP_KERNEL ); -if (!gwj) -return -ENOMEM ; +if (!gwj) { + err = -ENOMEM ; + goto out_free_cf; + } gwj->handled_frames =0 ; gwj->dropped_frames =0 ;
@@ -1118,7 +1144,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh, gwj->limit_hops = limhops;/* insert already parsed information */ -memcpy (&gwj->mod, &mod,sizeof (mod)); +RCU_INIT_POINTER (gwj->cf_mod, mod);memcpy (&gwj->ccgw, &ccgw,sizeof (ccgw)); err = -ENODEV ;
@@ -1152,9 +1178,11 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,if (!err)hlist_add_head_rcu (&gwj->list, &net->can.cgw_list); out: -if (err) +if (err) {kmem_cache_free (cgw_cache, gwj); - +out_free_cf: +kfree (mod); + }return err; }
@@ -1214,19 +1242,22 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh,/* remove only the first matching entry */ hlist_for_each_entry_safe (gwj, nx, &net->can.cgw_list, list) { +struct cf_mod *cf_mod; +if (gwj->flags != r->flags)continue ;if (gwj->limit_hops != limhops)continue ; + cf_mod =cgw_job_cf_mod (gwj);/* we have a match when uid is enabled and identical */ -if (gwj->mod.uid || mod.uid) { -if (gwj->mod.uid != mod.uid) +if (cf_mod->uid || mod.uid) { +if (cf_mod->uid != mod.uid)continue ; }else {/* no uid => check for identical modifications */ -if (memcmp (&gwj->mod, &mod,sizeof (mod))) +if (memcmp (cf_mod, &mod,sizeof (mod)))continue ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 28/184 wifi: mac80211: fix the type of status_code for negotiated TID to Link Mapping
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael-CY Lee <[email protected]>
[ Upstream commit e12a42f64fc3d74872b349eedd47f90c6676b78a ]
The status code should be type of __le16.
--- include/linux/ieee80211.h | 2 +- net/mac80211/mlme.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
include/linux/ieee80211.h +1 -1
@@ -1524,7 +1524,7 @@ struct ieee80211_mgmt {struct {u8 action_code;u8 dialog_token; -u8 status_code; +__le16 status_code;u8 variable[]; } __packed ttlm_res;struct {
net/mac80211/mlme.c +6 -6
@@ -7177,6 +7177,7 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata, int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res);int ttlm_max_len =2 +1 +sizeof (struct ieee80211_ttlm_elem ) +1 +2 *2 *IEEE80211_TTLM_NUM_TIDS ; +u16 status_code; skb =dev_alloc_skb (local->tx_headroom + hdr_len + ttlm_max_len);if (!skb)
@@ -7199,19 +7200,18 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,WARN_ON (1 ); fallthrough;case NEG_TTLM_RES_REJECT : - mgmt->u.action.u.ttlm_res.status_code = -WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING ; + status_code =WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING ;break ;case NEG_TTLM_RES_ACCEPT : - mgmt->u.action.u.ttlm_res.status_code =WLAN_STATUS_SUCCESS ; + status_code =WLAN_STATUS_SUCCESS ;break ;case NEG_TTLM_RES_SUGGEST_PREFERRED : - mgmt->u.action.u.ttlm_res.status_code = -WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED ; + status_code =WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED ;ieee80211_neg_ttlm_add_suggested_map (skb, neg_ttlm);break ; } + mgmt->u.action.u.ttlm_res.status_code =cpu_to_le16 (status_code);ieee80211_tx_skb (sdata, skb); }
@@ -7377,7 +7377,7 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,* This can be better implemented in the future, to handle request * rejections. */ -if (mgmt->u.action.u.ttlm_res.status_code !=WLAN_STATUS_SUCCESS ) +if (le16_to_cpu (mgmt->u.action.u.ttlm_res.status_code) !=WLAN_STATUS_SUCCESS )__ieee80211_disconnect (sdata); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 29/184 ice: Initial support for E825C hardware in ice_adapter
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Temerkhanov <[email protected]>
[ Upstream commit fdb7f54700b1c88e734323a62fea986d9ce5a9c6 ]
Address E825C devices by PCI ID since dual IP core configurations need 1 ice_adapter for both devices.
Stable-dep-of: 0093cb194a75 ("ice: use DSN instead of PCI BDF for ice_adapter index")
--- drivers/net/ethernet/intel/ice/ice_adapter.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/ice/ice_adapter.c +13 -3
@@ -9,12 +9,14 @@#include <linux/spinlock.h> #include <linux/xarray.h> #include "ice_adapter.h" +#include "ice.h" static DEFINE_XARRAY (ice_adapters);static DEFINE_MUTEX (ice_adapters_mutex);/* PCI bus number is 8 bits. Slot is 5 bits. Domain can have the rest. */ #define INDEX_FIELD_DOMAIN GENMASK(BITS_PER_LONG - 1, 13) +#define INDEX_FIELD_DEV GENMASK(31, 16)#define INDEX_FIELD_BUS GENMASK(12, 5)#define INDEX_FIELD_SLOT GENMASK(4, 0)
@@ -24,9 +26,17 @@ static unsigned long ice_adapter_index(const struct pci_dev *pdev)WARN_ON (domain >FIELD_MAX (INDEX_FIELD_DOMAIN )); -return FIELD_PREP (INDEX_FIELD_DOMAIN , domain) | -FIELD_PREP (INDEX_FIELD_BUS , pdev->bus->number) | -FIELD_PREP (INDEX_FIELD_SLOT ,PCI_SLOT (pdev->devfn)); +switch (pdev->device) { +case ICE_DEV_ID_E825C_BACKPLANE : +case ICE_DEV_ID_E825C_QSFP : +case ICE_DEV_ID_E825C_SFP : +case ICE_DEV_ID_E825C_SGMII : +return FIELD_PREP (INDEX_FIELD_DEV , pdev->device); +default : +return FIELD_PREP (INDEX_FIELD_DOMAIN , domain) | +FIELD_PREP (INDEX_FIELD_BUS , pdev->bus->number) | +FIELD_PREP (INDEX_FIELD_SLOT ,PCI_SLOT (pdev->devfn)); + } }static struct ice_adapter *ice_adapter_new (void )
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 30/184 ice: use DSN instead of PCI BDF for ice_adapter index
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Przemek Kitszel <[email protected]>
[ Upstream commit 0093cb194a7511d1e68865fa35b763c72e44c2f0 ]
Use Device Serial Number instead of PCI bus/device/function for the index of struct ice_adapter.
Functions on the same physical device should point to the very same ice_adapter instance, but with two PFs, when at least one of them is PCI-e passed-through to a VM, it is no longer the case - PFs will get seemingly random PCI BDF values, and thus indices, what finally leds to each of them being on their own instance of ice_adapter. That causes them to don't attempt any synchronization of the PTP HW clock usage, or any other future resources.
DSN works nicely in place of the index, as it is "immutable" in terms of virtualization.
--- drivers/net/ethernet/intel/ice/ice_adapter.c | 47 ++++++++------------ drivers/net/ethernet/intel/ice/ice_adapter.h | 6 ++- 2 files changed, 22 insertions(+), 31 deletions(-)
drivers/net/ethernet/intel/ice/ice_adapter.c +18 -29
@@ -1,7 +1,6 @@// SPDX-License-Identifier: GPL-2.0-only // SPDX-FileCopyrightText: Copyright Red Hat -#include <linux/bitfield.h> #include <linux/cleanup.h> #include <linux/mutex.h> #include <linux/pci.h>
@@ -14,32 +13,16 @@static DEFINE_XARRAY (ice_adapters);static DEFINE_MUTEX (ice_adapters_mutex); -/* PCI bus number is 8 bits. Slot is 5 bits. Domain can have the rest. */ -#define INDEX_FIELD_DOMAIN GENMASK(BITS_PER_LONG - 1, 13) -#define INDEX_FIELD_DEV GENMASK(31, 16) -#define INDEX_FIELD_BUS GENMASK(12, 5) -#define INDEX_FIELD_SLOT GENMASK(4, 0) - -static unsigned long ice_adapter_index (const struct pci_dev *pdev) +static unsigned long ice_adapter_index (u64 dsn) { -unsigned int domain =pci_domain_nr (pdev->bus); - -WARN_ON (domain >FIELD_MAX (INDEX_FIELD_DOMAIN )); - -switch (pdev->device) { -case ICE_DEV_ID_E825C_BACKPLANE : -case ICE_DEV_ID_E825C_QSFP : -case ICE_DEV_ID_E825C_SFP : -case ICE_DEV_ID_E825C_SGMII : -return FIELD_PREP (INDEX_FIELD_DEV , pdev->device); -default : -return FIELD_PREP (INDEX_FIELD_DOMAIN , domain) | -FIELD_PREP (INDEX_FIELD_BUS , pdev->bus->number) | -FIELD_PREP (INDEX_FIELD_SLOT ,PCI_SLOT (pdev->devfn)); - } +#if BITS_PER_LONG ==64 +return dsn; +#else +return (u32 )dsn ^ (u32)(dsn >>32 ); +#endif } -static struct ice_adapter *ice_adapter_new (void ) +static struct ice_adapter *ice_adapter_new (u64 dsn) {struct ice_adapter *adapter;
@@ -47,6 +30,7 @@ static struct ice_adapter *ice_adapter_new(void)if (!adapter)return NULL ; + adapter->device_serial_number = dsn;spin_lock_init (&adapter->ptp_gltsyn_time_lock);refcount_set (&adapter->refcount,1 );
@@ -77,23 +61,26 @@ static void ice_adapter_free(struct ice_adapter *adapter)* Return: Pointer to ice_adapter on success. * ERR_PTR() on error. -ENOMEM is the only possible error. */ -struct ice_adapter *ice_adapter_get (const struct pci_dev *pdev) +struct ice_adapter *ice_adapter_get (struct pci_dev *pdev) { -unsigned long index =ice_adapter_index (pdev); +u64 dsn =pci_get_dsn (pdev);struct ice_adapter *adapter; +unsigned long index;int err; + index =ice_adapter_index (dsn); scoped_guard(mutex, &ice_adapters_mutex) { err =xa_insert (&ice_adapters, index,NULL ,GFP_KERNEL );if (err == -EBUSY ) { adapter =xa_load (&ice_adapters, index);refcount_inc (&adapter->refcount); +WARN_ON_ONCE (adapter->device_serial_number != dsn);return adapter; }if (err)return ERR_PTR (err); - adapter =ice_adapter_new (); + adapter =ice_adapter_new (dsn);if (!adapter)return ERR_PTR (-ENOMEM );xa_store (&ice_adapters, index, adapter,GFP_KERNEL );
@@ -110,11 +97,13 @@ struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)* * Context: Process, may sleep. */ -void ice_adapter_put (const struct pci_dev *pdev) +void ice_adapter_put (struct pci_dev *pdev) { -unsigned long index =ice_adapter_index (pdev); +u64 dsn =pci_get_dsn (pdev);struct ice_adapter *adapter; +unsigned long index; + index =ice_adapter_index (dsn); scoped_guard(mutex, &ice_adapters_mutex) { adapter =xa_load (&ice_adapters, index);if (WARN_ON (!adapter))
drivers/net/ethernet/intel/ice/ice_adapter.h +4 -2
@@ -32,6 +32,7 @@ struct ice_port_list {* @refcount: Reference count. struct ice_pf objects hold the references. * @ctrl_pf: Control PF of the adapter * @ports: Ports list +* @device_serial_number: DSN cached for collision detection on 32bit systems */ struct ice_adapter {refcount_t refcount;
@@ -40,9 +41,10 @@ struct ice_adapter {struct ice_pf *ctrl_pf;struct ice_port_list ports; + u64 device_serial_number; }; -struct ice_adapter *ice_adapter_get (const struct pci_dev *pdev); -void ice_adapter_put (const struct pci_dev *pdev); +struct ice_adapter *ice_adapter_get (struct pci_dev *pdev); +void ice_adapter_put (struct pci_dev *pdev);#endif /* _ICE_ADAPTER_H */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 31/184 erofs: ensure the extra temporary copy is valid for shortened bvecs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit 35076d2223c731f7be75af61e67f90807384d030 ]
When compressed data deduplication is enabled, multiple logical extents may reference the same compressed physical cluster.
The previous commit 94c43de73521 ("erofs: fix wrong primary bvec selection on deduplicated extents") already avoids using shortened bvecs. However, in such cases, the extra temporary buffers also need to be preserved for later use in z_erofs_fill_other_copies() to to prevent data corruption.
IOWs, extra temporary buffers have to be retained not only due to varying start relative offsets (pageofs_out, as indicated by pcl->multibases) but also because of shortened bvecs.
[email protected] : 270696 bytes
0: 0.. 204185 | 204185 : 628019200.. 628084736 | 65536 -> 1: 204185.. 225536 | 21351 : 544063488.. 544129024 | 65536 2: 225536.. 270696 | 45160 : 0.. 0 | 0
com.android.vndk.v28.apex : 93814897 bytes
...
364: 53869896..54095257 | 225361 : 543997952.. 544063488 | 65536 -> 365: 54095257..54309344 | 214087 : 544063488.. 544129024 | 65536 366: 54309344..54514557 | 205213 : 544129024.. 544194560 | 65536
...
Both 204185 and 54095257 have the same start relative offset of 3481, but the logical page 55 of [email protected] ranges from 225280 to 229632, forming a shortened bvec [225280, 225536) that cannot be used for decompressing the range from 54095257 to 54309344 of com.android.vndk.v28.apex.
Since pcl->multibases is already meaningless, just mark be->keepxcpy on demand for simplicity.
Again, this issue can only lead to data corruption if -Ededupe is on.
--- fs/erofs/zdata.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
fs/erofs/zdata.c +14 -17
@@ -82,9 +82,6 @@ struct z_erofs_pcluster {/* L: whether partial decompression or not */ bool partial; -/* L: indicate several pageofs_outs or not */ -bool multibases; -/* L: whether extra buffer allocations are best-effort */ bool besteffort;
@@ -1073,8 +1070,6 @@ static int z_erofs_scan_folio(struct z_erofs_decompress_frontend *f,break ;erofs_onlinefolio_split (folio); -if (f->pcl->pageofs_out != (map->m_la & ~PAGE_MASK )) - f->pcl->multibases = true;if (f->pcl->length < offset + end - map->m_la) { f->pcl->length = offset + end - map->m_la; f->pcl->pageofs_out = map->m_la & ~PAGE_MASK ;
@@ -1120,7 +1115,6 @@ struct z_erofs_decompress_backend {struct page *onstack_pages[Z_EROFS_ONSTACK_PAGES ];struct super_block *sb;struct z_erofs_pcluster *pcl; -/* pages with the longest decompressed length for deduplication */ struct page **decompressed_pages;/* pages to keep the compressed data */
@@ -1129,6 +1123,8 @@ struct z_erofs_decompress_backend {struct list_head decompressed_secondary_bvecs;struct page **pagepool;unsigned int onstack_used, nr_pages; +/* indicate if temporary copies should be preserved for later use */ +bool keepxcpy; };struct z_erofs_bvec_item {
@@ -1139,18 +1135,20 @@ struct z_erofs_bvec_item {static void z_erofs_do_decompressed_bvec (struct z_erofs_decompress_backend *be,struct z_erofs_bvec *bvec) { +int poff = bvec->offset + be->pcl->pageofs_out;struct z_erofs_bvec_item *item; -unsigned int pgnr; - -if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK ) && - (bvec->end ==PAGE_SIZE || - bvec->offset + bvec->end == be->pcl->length)) { - pgnr = (bvec->offset + be->pcl->pageofs_out) >>PAGE_SHIFT ; -DBG_BUGON (pgnr >= be->nr_pages); -if (!be->decompressed_pages[pgnr]) { - be->decompressed_pages[pgnr] = bvec->page; +struct page **page; + +if (!(poff & ~PAGE_MASK ) && (bvec->end ==PAGE_SIZE || + bvec->offset + bvec->end == be->pcl->length)) { +DBG_BUGON ((poff >>PAGE_SHIFT ) >= be->nr_pages); + page = be->decompressed_pages + (poff >>PAGE_SHIFT ); +if (!*page) { + *page = bvec->page;return ; } + }else { + be->keepxcpy = true; }/* (cold path) one pcluster is requested multiple times */
@@ -1316,7 +1314,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, .alg = pcl->algorithmformat, .inplace_io = overlapped, .partial_decoding = pcl->partial, - .fillgaps = pcl->multibases, + .fillgaps = be->keepxcpy, .gfp = pcl->besteffort ?GFP_KERNEL :GFP_NOWAIT | __GFP_NORETRY }, be->pagepool);
@@ -1370,7 +1368,6 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, pcl->length =0 ; pcl->partial = true; - pcl->multibases = false; pcl->besteffort = false; pcl->bvset.nextpage =NULL ; pcl->vcnt =0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 32/184 ipvs: fix uninit-value for saddr in do_output_route4
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <[email protected]>
[ Upstream commit e34090d7214e0516eb8722aee295cb2507317c07 ]
syzbot reports for uninit-value for the saddr argument [1]. commit 4754957f04f5 ("ipvs: do not use random local source address for tunnels") already implies that the input value of saddr should be ignored but the code is still reading it which can prevent to connect the route. Fix it by changing the argument to ret_saddr.
[1]
BUG: KMSAN: uninit-value in do_output_route4+0x42c/0x4d0 net/netfilter/ipvs/ip_vs_xmit.c:147 do_output_route4+0x42c/0x4d0 net/netfilter/ipvs/ip_vs_xmit.c:147 __ip_vs_get_out_rt+0x403/0x21d0 net/netfilter/ipvs/ip_vs_xmit.c:330 ip_vs_tunnel_xmit+0x205/0x2380 net/netfilter/ipvs/ip_vs_xmit.c:1136 ip_vs_in_hook+0x1aa5/0x35b0 net/netfilter/ipvs/ip_vs_core.c:2063 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf7/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] __ip_local_out+0x758/0x7e0 net/ipv4/ip_output.c:118 ip_local_out net/ipv4/ip_output.c:127 [inline] ip_send_skb+0x6a/0x3c0 net/ipv4/ip_output.c:1501 udp_send_skb+0xfda/0x1b70 net/ipv4/udp.c:1195 udp_sendmsg+0x2fe3/0x33c0 net/ipv4/udp.c:1483 inet_sendmsg+0x1fc/0x280 net/ipv4/af_inet.c:851 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x267/0x380 net/socket.c:727 ____sys_sendmsg+0x91b/0xda0 net/socket.c:2566 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2620 __sys_sendmmsg+0x41d/0x880 net/socket.c:2702 __compat_sys_sendmmsg net/compat.c:360 [inline] __do_compat_sys_sendmmsg net/compat.c:367 [inline] __se_compat_sys_sendmmsg net/compat.c:364 [inline] __ia32_compat_sys_sendmmsg+0xc8/0x140 net/compat.c:364 ia32_sys_call+0x3ffa/0x41f0 arch/x86/include/generated/asm/syscalls_32.h:346 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline] __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/syscall_32.c:306 do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:331 do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:369 entry_SYSENTER_compat_after_hwframe+0x84/0x8e
Uninit was created at:
slab_post_alloc_hook mm/slub.c:4167 [inline] slab_alloc_node mm/slub.c:4210 [inline] __kmalloc_cache_noprof+0x8fa/0xe00 mm/slub.c:4367 kmalloc_noprof include/linux/slab.h:905 [inline] ip_vs_dest_dst_alloc net/netfilter/ipvs/ip_vs_xmit.c:61 [inline] __ip_vs_get_out_rt+0x35d/0x21d0 net/netfilter/ipvs/ip_vs_xmit.c:323 ip_vs_tunnel_xmit+0x205/0x2380 net/netfilter/ipvs/ip_vs_xmit.c:1136 ip_vs_in_hook+0x1aa5/0x35b0 net/netfilter/ipvs/ip_vs_core.c:2063 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf7/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] __ip_local_out+0x758/0x7e0 net/ipv4/ip_output.c:118 ip_local_out net/ipv4/ip_output.c:127 [inline] ip_send_skb+0x6a/0x3c0 net/ipv4/ip_output.c:1501 udp_send_skb+0xfda/0x1b70 net/ipv4/udp.c:1195 udp_sendmsg+0x2fe3/0x33c0 net/ipv4/udp.c:1483 inet_sendmsg+0x1fc/0x280 net/ipv4/af_inet.c:851 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x267/0x380 net/socket.c:727 ____sys_sendmsg+0x91b/0xda0 net/socket.c:2566 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2620 __sys_sendmmsg+0x41d/0x880 net/socket.c:2702 __compat_sys_sendmmsg net/compat.c:360 [inline] __do_compat_sys_sendmmsg net/compat.c:367 [inline] __se_compat_sys_sendmmsg net/compat.c:364 [inline] __ia32_compat_sys_sendmmsg+0xc8/0x140 net/compat.c:364 ia32_sys_call+0x3ffa/0x41f0 arch/x86/include/generated/asm/syscalls_32.h:346 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline] __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/syscall_32.c:306 do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:331 do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:369 entry_SYSENTER_compat_after_hwframe+0x84/0x8e CPU: 0 UID: 0 PID: 22408 Comm: syz.4.5165 Not tainted 6.15.0-rc3-syzkaller-00019-gbc3372351d0c #0 PREEMPT(undef) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
--- net/netfilter/ipvs/ip_vs_xmit.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c +8 -19
@@ -119,13 +119,12 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)return false; } -/* Get route to daddr, update *saddr, optionally bind route to saddr */ +/* Get route to daddr, optionally bind route to saddr */ static struct rtable *do_output_route4 (struct net *net,__be32 daddr, -int rt_mode,__be32 *saddr) +int rt_mode,__be32 *ret_saddr) {struct flowi4 fl4;struct rtable *rt; -bool loop = false;memset (&fl4,0 ,sizeof (fl4)); fl4.daddr = daddr;
@@ -135,23 +134,17 @@ static struct rtable *do_output_route4(struct net *net, __be32 daddr, retry: rt =ip_route_output_key (net, &fl4);if (IS_ERR (rt)) { -/* Invalid saddr ? */ -if (PTR_ERR (rt) == -EINVAL && *saddr && - rt_mode &IP_VS_RT_MODE_CONNECT && !loop) { - *saddr =0 ; -flowi4_update_output (&fl4,0 , daddr,0 ); - goto retry; - }IP_VS_DBG_RL ("ip_route_output error, dest: %pI4\n" , &daddr);return NULL ; - }else if (!*saddr && rt_mode &IP_VS_RT_MODE_CONNECT && fl4.saddr) { + } +if (rt_mode &IP_VS_RT_MODE_CONNECT && fl4.saddr) {ip_rt_put (rt); - *saddr = fl4.saddr;flowi4_update_output (&fl4,0 , daddr, fl4.saddr); - loop = true; + rt_mode =0 ; goto retry; } - *saddr = fl4.saddr; +if (ret_saddr) + *ret_saddr = fl4.saddr;return rt; }
@@ -344,19 +337,15 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,if (ret_saddr) *ret_saddr = dest_dst->dst_saddr.ip; }else { -__be32 saddr =htonl (INADDR_ANY ); - noref =0 ;/* For such unconfigured boxes avoid many route lookups * for performance reasons because we do not remember saddr */ rt_mode &= ~IP_VS_RT_MODE_CONNECT ; - rt =do_output_route4 (net, daddr, rt_mode, &saddr); + rt =do_output_route4 (net, daddr, rt_mode, ret_saddr);if (!rt) goto err_unreach; -if (ret_saddr) - *ret_saddr = saddr; } local = (rt->rt_flags &RTCF_LOCAL ) ?1 :0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 33/184 netfilter: ipset: fix region locking in hash types
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jozsef Kadlecsik <[email protected]>
[ Upstream commit 8478a729c0462273188263136880480729e9efca ]
Region locking introduced in v5.6-rc4 contained three macros to handle the region locks: ahash_bucket_start(), ahash_bucket_end() which gave back the start and end hash bucket values belonging to a given region lock and ahash_region() which should give back the region lock belonging to a given hash bucket. The latter was incorrect which can lead to a race condition between the garbage collector and adding new elements when a hash type of set is defined with timeouts.
--- net/netfilter/ipset/ip_set_hash_gen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/ipset/ip_set_hash_gen.h +1 -1
@@ -64,7 +64,7 @@ struct hbucket {#define ahash_sizeof_regions (htable_bits) \ (ahash_numof_locks(htable_bits) * sizeof(struct ip_set_region))#define ahash_region (n, htable_bits) \ - ((n) % ahash_numof_locks(htable_bits)) + ((n) / jhash_size(HTABLE_REGION_BITS))#define ahash_bucket_start (h, htable_bits) \ ((htable_bits) < HTABLE_REGION_BITS ? 0 \ : (h) * jhash_size(HTABLE_REGION_BITS))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 34/184 bpf: Scrub packet on bpf_redirect_peer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Chaignon <[email protected]>
[ Upstream commit c4327229948879814229b46aa26a750718888503 ]
When bpf_redirect_peer is used to redirect packets to a device in another network namespace, the skb isn't scrubbed. That can lead skb information from one namespace to be "misused" in another namespace.
As one example, this is causing Cilium to drop traffic when using bpf_redirect_peer to redirect packets that just went through IPsec decryption to a container namespace. The following pwru trace shows (1) the packet path from the host's XFRM layer to the container's XFRM layer where it's dropped and (2) the number of active skb extensions at each function.
NETNS MARK IFACE TUPLE FUNC
4026533547 d00 eth0 10.244.3.124:35473->10.244.2.158:53 xfrm_rcv_cb
.active_extensions = (__u8)2,
4026533547 d00 eth0 10.244.3.124:35473->10.244.2.158:53 xfrm4_rcv_cb
.active_extensions = (__u8)2,
4026533547 d00 eth0 10.244.3.124:35473->10.244.2.158:53 gro_cells_receive
.active_extensions = (__u8)2,
[...]
4026533547 0 eth0 10.244.3.124:35473->10.244.2.158:53 skb_do_redirect
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 ip_rcv
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 ip_rcv_core
.active_extensions = (__u8)2,
[...]
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 udp_queue_rcv_one_skb
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 __xfrm_policy_check
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 __xfrm_decode_session
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 security_xfrm_decode_session
.active_extensions = (__u8)2,
4026534999 0 eth0 10.244.3.124:35473->10.244.2.158:53 kfree_skb_reason(SKB_DROP_REASON_XFRM_POLICY)
.active_extensions = (__u8)2,In this case, there are no XFRM policies in the container's network namespace so the drop is unexpected. When we decrypt the IPsec packet, the XFRM state used for decryption is set in the skb extensions. This information is preserved across the netns switch. When we reach the XFRM policy check in the container's netns, __xfrm_policy_check drops the packet with LINUX_MIB_XFRMINNOPOLS because a (container-side) XFRM policy can't be found that matches the (host-side) XFRM state used for decryption.
This patch fixes this by scrubbing the packet when using bpf_redirect_peer, as is done on typical netns switches via veth devices except skb->mark and skb->tstamp are not zeroed.
--- net/core/filter.c | 1 + 1 file changed, 1 insertion(+)
net/core/filter.c +1 -0
@@ -2526,6 +2526,7 @@ int skb_do_redirect(struct sk_buff *skb) goto out_drop; skb->dev = dev;dev_sw_netstats_rx_add (dev, skb->len); +skb_scrub_packet (skb, false);return -EAGAIN ; } return flags & BPF_F_NEIGH ?
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 35/184 net: dsa: b53: allow leaky reserved multicast
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 5f93185a757ff38b36f849c659aeef368db15a68 ]
Allow reserved multicast to ignore VLAN membership so STP and other management protocols work without a PVID VLAN configured when using a vlan aware bridge.
--- drivers/net/dsa/b53/b53_common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/dsa/b53/b53_common.c +4 -2
@@ -373,9 +373,11 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,b53_read8 (dev,B53_VLAN_PAGE ,B53_VLAN_CTRL5 , &vc5); } + vc1 &= ~VC1_RX_MCST_FWD_EN ; +if (enable) { vc0 |=VC0_VLAN_EN |VC0_VID_CHK_EN |VC0_VID_HASH_VID ; - vc1 |=VC1_RX_MCST_UNTAG_EN |VC1_RX_MCST_FWD_EN ; + vc1 |=VC1_RX_MCST_UNTAG_EN ; vc4 &= ~VC4_ING_VID_CHECK_MASK ;if (enable_filtering) { vc4 |=VC4_ING_VID_VIO_DROP <<VC4_ING_VID_CHECK_S ;
@@ -393,7 +395,7 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable, }else { vc0 &= ~(VC0_VLAN_EN |VC0_VID_CHK_EN |VC0_VID_HASH_VID ); - vc1 &= ~(VC1_RX_MCST_UNTAG_EN |VC1_RX_MCST_FWD_EN ); + vc1 &= ~VC1_RX_MCST_UNTAG_EN ; vc4 &= ~VC4_ING_VID_CHECK_MASK ; vc5 &= ~VC5_DROP_VTABLE_MISS ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 36/184 net: dsa: b53: keep CPU port always tagged again
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 425f11d4cc9bd9e97e6825d9abb2c51a068ca7b5 ]
The Broadcom management header does not carry the original VLAN tag state information, just the ingress port, so for untagged frames we do not know from which VLAN they originated.
Therefore keep the CPU port always tagged except for VLAN 0.
Fixes the following setup:
$ ip link add br0 type bridge vlan_filtering 1 $ ip link set sw1p1 master br0 $ bridge vlan add dev br0 pvid untagged self $ ip link add sw1p2.10 link sw1p2 type vlan id 10
Where VID 10 would stay untagged on the CPU port.
--- drivers/net/dsa/b53/b53_common.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/dsa/b53/b53_common.c +8 -0
@@ -1136,6 +1136,11 @@ static int b53_setup(struct dsa_switch *ds)*/ ds->untag_bridge_pvid = dev->tag_protocol ==DSA_TAG_PROTO_NONE ; +/* The switch does not tell us the original VLAN for untagged +* packets, so keep the CPU port always tagged. +*/ + ds->untag_vlan_aware_bridge_pvid = true; + ret =b53_reset_switch (dev);if (ret) {dev_err (ds->dev,"failed to reset switch\n" );
@@ -1546,6 +1551,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,if (vlan->vid ==0 && vlan->vid ==b53_default_pvid (dev)) untagged = true; +if (vlan->vid >0 &&dsa_is_cpu_port (ds, port)) + untagged = false; + vl->members |=BIT (port);if (untagged && !b53_vlan_port_needs_forced_tagged (ds, port)) vl->untag |=BIT (port);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 37/184 net: dsa: b53: fix clearing PVID of a port
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit f480851981043d9bb6447ca9883ade9247b9a0ad ]
Currently the PVID of ports are only set when adding/updating VLANs with PVID set or removing VLANs, but not when clearing the PVID flag of a VLAN.
E.g. the following flow
$ ip link add br0 type bridge vlan_filtering 1 $ ip link set sw1p1 master bridge $ bridge vlan add dev sw1p1 vid 10 pvid untagged $ bridge vlan add dev sw1p1 vid 10 untagged
Would keep the PVID set as 10, despite the flag being cleared. Fix this by checking if we need to unset the PVID on vlan updates.
--- drivers/net/dsa/b53/b53_common.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/net/dsa/b53/b53_common.c +11 -2
@@ -1538,12 +1538,21 @@ int b53_vlan_add(struct dsa_switch *ds, int port,bool untagged = vlan->flags &BRIDGE_VLAN_INFO_UNTAGGED ;bool pvid = vlan->flags &BRIDGE_VLAN_INFO_PVID ;struct b53_vlan *vl; +u16 old_pvid, new_pvid;int err; err =b53_vlan_prepare (ds, port, vlan);if (err)return err; +b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &old_pvid); +if (pvid) + new_pvid = vlan->vid; +else if (!pvid && vlan->vid == old_pvid) + new_pvid =b53_default_pvid (dev); +else + new_pvid = old_pvid; + vl = &dev->vlans[vlan->vid];b53_get_vlan_entry (dev, vlan->vid, vl);
@@ -1563,9 +1572,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,b53_set_vlan_entry (dev, vlan->vid, vl);b53_fast_age_vlan (dev, vlan->vid); -if (pvid && !dsa_is_cpu_port (ds, port)) { +if (!dsa_is_cpu_port (ds, port) && new_pvid != old_pvid) {b53_write16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), - vlan->vid); + new_pvid);b53_fast_age_vlan (dev, vlan->vid); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 38/184 net: dsa: b53: fix flushing old pvid VLAN on pvid change
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 083c6b28c0cbcd83b6af1a10f2c82937129b3438 ]
Presumably the intention here was to flush the VLAN of the old pvid, not the added VLAN again, which we already flushed before.
--- drivers/net/dsa/b53/b53_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +1 -1
@@ -1575,7 +1575,7 @@ int b53_vlan_add(struct dsa_switch *ds, int port,if (!dsa_is_cpu_port (ds, port) && new_pvid != old_pvid) {b53_write16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), new_pvid); -b53_fast_age_vlan (dev, vlan->vid); +b53_fast_age_vlan (dev, old_pvid); }return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 39/184 net: dsa: b53: fix VLAN ID for untagged vlan on bridge leave
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit a1c1901c5cc881425cc45992ab6c5418174e9e5a ]
The untagged default VLAN is added to the default vlan, which may be one, but we modify the VLAN 0 entry on bridge leave.
Fix this to use the correct VLAN entry for the default pvid.
--- drivers/net/dsa/b53/b53_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +2 -1
@@ -1987,7 +1987,7 @@ EXPORT_SYMBOL(b53_br_join);void b53_br_leave (struct dsa_switch *ds,int port,struct dsa_bridge bridge) {struct b53_device *dev = ds->priv; -struct b53_vlan *vl = &dev->vlans[0 ]; +struct b53_vlan *vl;s8 cpu_port =dsa_to_port (ds, port)->cpu_dp->index;unsigned int i;u16 pvlan, reg, pvid;
@@ -2013,6 +2013,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge) dev->ports[port].vlan_ctl_mask = pvlan; pvid =b53_default_pvid (dev); + vl = &dev->vlans[pvid];/* Make this port join all VLANs without VLAN entries */ if (is58xx (dev)) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 40/184 net: dsa: b53: always rejoin default untagged VLAN on bridge leave
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 13b152ae40495966501697693f048f47430c50fd ]
While JOIN_ALL_VLAN allows to join all VLANs, we still need to keep the default VLAN enabled so that untagged traffic stays untagged.
So rejoin the default VLAN even for switches with JOIN_ALL_VLAN support.
--- drivers/net/dsa/b53/b53_common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/dsa/b53/b53_common.c +5 -5
@@ -2022,12 +2022,12 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)if (!(reg &BIT (cpu_port))) reg |=BIT (cpu_port);b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); - }else { -b53_get_vlan_entry (dev, pvid, vl); - vl->members |=BIT (port) |BIT (cpu_port); - vl->untag |=BIT (port) |BIT (cpu_port); -b53_set_vlan_entry (dev, pvid, vl); } + +b53_get_vlan_entry (dev, pvid, vl); + vl->members |=BIT (port) |BIT (cpu_port); + vl->untag |=BIT (port) |BIT (cpu_port); +b53_set_vlan_entry (dev, pvid, vl); }EXPORT_SYMBOL (b53_br_leave);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 41/184 net: dsa: b53: do not allow to configure VLAN 0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 45e9d59d39503bb3e6ab4d258caea4ba6496e2dc ]
Since we cannot set forwarding destinations per VLAN, we should not have a VLAN 0 configured, as it would allow untagged traffic to work across ports on VLAN aware bridges regardless if a PVID untagged VLAN exists.
So remove the VLAN 0 on join, an re-add it on leave. But only do so if we have a VLAN aware bridge, as without it, untagged traffic would become tagged with VID 0 on a VLAN unaware bridge.
--- drivers/net/dsa/b53/b53_common.c | 36 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-)
drivers/net/dsa/b53/b53_common.c +27 -9
@@ -1545,6 +1545,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,if (err)return err; +if (vlan->vid ==0 ) +return 0 ; +b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &old_pvid);if (pvid) new_pvid = vlan->vid;
@@ -1557,10 +1560,7 @@ int b53_vlan_add(struct dsa_switch *ds, int port,b53_get_vlan_entry (dev, vlan->vid, vl); -if (vlan->vid ==0 && vlan->vid ==b53_default_pvid (dev)) - untagged = true; - -if (vlan->vid >0 &&dsa_is_cpu_port (ds, port)) +if (dsa_is_cpu_port (ds, port)) untagged = false; vl->members |=BIT (port);
@@ -1590,6 +1590,9 @@ int b53_vlan_del(struct dsa_switch *ds, int port,struct b53_vlan *vl;u16 pvid; +if (vlan->vid ==0 ) +return 0 ; +b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &pvid); vl = &dev->vlans[vlan->vid];
@@ -1936,8 +1939,9 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, bool *tx_fwd_offload, struct netlink_ext_ack *extack) { struct b53_device *dev = ds->priv; +struct b53_vlan *vl;s8 cpu_port =dsa_to_port (ds, port)->cpu_dp->index; -u16 pvlan, reg; +u16 pvlan, reg, pvid;unsigned int i;/* On 7278, port 7 which connects to the ASP should only receive
@@ -1946,6 +1950,9 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,if (dev->chip_id ==BCM7278_DEVICE_ID && port ==7 )return -EINVAL ; + pvid =b53_default_pvid (dev); + vl = &dev->vlans[pvid]; +/* Make this port leave the all VLANs join since we will have proper * VLAN entries from now on */
@@ -1957,6 +1964,15 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); } +if (ds->vlan_filtering) { +b53_get_vlan_entry (dev, pvid, vl); + vl->members &= ~BIT (port); +if (vl->members ==BIT (cpu_port)) + vl->members &= ~BIT (cpu_port); + vl->untag = vl->members; +b53_set_vlan_entry (dev, pvid, vl); + } +b53_read16 (dev,B53_PVLAN_PAGE ,B53_PVLAN_PORT_MASK (port), &pvlan);b53_for_each_port (dev, i) {
@@ -2024,10 +2040,12 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); } -b53_get_vlan_entry (dev, pvid, vl); - vl->members |=BIT (port) |BIT (cpu_port); - vl->untag |=BIT (port) |BIT (cpu_port); -b53_set_vlan_entry (dev, pvid, vl); +if (ds->vlan_filtering) { +b53_get_vlan_entry (dev, pvid, vl); + vl->members |=BIT (port) |BIT (cpu_port); + vl->untag |=BIT (port) |BIT (cpu_port); +b53_set_vlan_entry (dev, pvid, vl); + } }EXPORT_SYMBOL (b53_br_leave);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 42/184 net: dsa: b53: do not program vlans when vlan filtering is off
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit f089652b6b16452535dcc5cbaa6e2bb05acd3f93 ]
Documentation/networking/switchdev.rst says:
- with VLAN filtering turned off: the bridge is strictly VLAN unaware and its data path will process all Ethernet frames as if they are VLAN-untagged. The bridge VLAN database can still be modified, but the modifications should have no effect while VLAN filtering is turned off.
This breaks if we immediately apply the VLAN configuration, so skip writing it when vlan_filtering is off.
--- drivers/net/dsa/b53/b53_common.c | 48 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-)
drivers/net/dsa/b53/b53_common.c +28 -20
@@ -1548,6 +1548,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,if (vlan->vid ==0 )return 0 ; +if (!ds->vlan_filtering) +return 0 ; +b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &old_pvid);if (pvid) new_pvid = vlan->vid;
@@ -1593,6 +1596,9 @@ int b53_vlan_del(struct dsa_switch *ds, int port,if (vlan->vid ==0 )return 0 ; +if (!ds->vlan_filtering) +return 0 ; +b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &pvid); vl = &dev->vlans[vlan->vid];
@@ -1953,18 +1959,20 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, pvid =b53_default_pvid (dev); vl = &dev->vlans[pvid]; -/* Make this port leave the all VLANs join since we will have proper -* VLAN entries from now on -*/ -if (is58xx (dev)) { -b53_read16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , ®); - reg &= ~BIT (port); -if ((reg &BIT (cpu_port)) ==BIT (cpu_port)) - reg &= ~BIT (cpu_port); -b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); - } -if (ds->vlan_filtering) { +/* Make this port leave the all VLANs join since we will have +* proper VLAN entries from now on +*/ +if (is58xx (dev)) { +b53_read16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , + ®); + reg &= ~BIT (port); +if ((reg &BIT (cpu_port)) ==BIT (cpu_port)) + reg &= ~BIT (cpu_port); +b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , + reg); + } +b53_get_vlan_entry (dev, pvid, vl); vl->members &= ~BIT (port);if (vl->members ==BIT (cpu_port))
@@ -2031,16 +2039,16 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge) pvid =b53_default_pvid (dev); vl = &dev->vlans[pvid]; -/* Make this port join all VLANs without VLAN entries */ -if (is58xx (dev)) { -b53_read16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , ®); - reg |=BIT (port); -if (!(reg &BIT (cpu_port))) - reg |=BIT (cpu_port); -b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); - } -if (ds->vlan_filtering) { +/* Make this port join all VLANs without VLAN entries */ +if (is58xx (dev)) { +b53_read16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , ®); + reg |=BIT (port); +if (!(reg &BIT (cpu_port))) + reg |=BIT (cpu_port); +b53_write16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , reg); + } +b53_get_vlan_entry (dev, pvid, vl); vl->members |=BIT (port) |BIT (cpu_port); vl->untag |=BIT (port) |BIT (cpu_port);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 43/184 net: dsa: b53: fix toggling vlan_filtering
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 2dc2bd57111582895e10f54ea380329c89873f1c ]
To allow runtime switching between vlan aware and vlan non-aware mode, we need to properly keep track of any bridge VLAN configuration. Likewise, we need to know when we actually switch between both modes, to not have to rewrite the full VLAN table every time we update the VLANs.
So keep track of the current vlan_filtering mode, and on changes, apply the appropriate VLAN configuration.
--- drivers/net/dsa/b53/b53_common.c | 104 ++++++++++++++++++++++--------- drivers/net/dsa/b53/b53_priv.h | 2 + 2 files changed, 75 insertions(+), 31 deletions(-)
drivers/net/dsa/b53/b53_common.c +73 -31
@@ -763,6 +763,22 @@ static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)return dev->tag_protocol ==DSA_TAG_PROTO_NONE &&dsa_is_cpu_port (ds, port); } +static bool b53_vlan_port_may_join_untagged (struct dsa_switch *ds,int port) +{ +struct b53_device *dev = ds->priv; +struct dsa_port *dp; + +if (!dev->vlan_filtering) +return true; + + dp =dsa_to_port (ds, port); + +if (dsa_port_is_cpu (dp)) +return true; + +return dp->bridge ==NULL ; +} +int b53_configure_vlan (struct dsa_switch *ds) {struct b53_device *dev = ds->priv;
@@ -781,7 +797,7 @@ int b53_configure_vlan(struct dsa_switch *ds)b53_do_vlan_op (dev,VTA_CMD_CLEAR ); } -b53_enable_vlan (dev,-1 , dev->vlan_enabled, ds->vlan_filtering); +b53_enable_vlan (dev,-1 , dev->vlan_enabled, dev->vlan_filtering);/* Create an untagged VLAN entry for the default PVID in case * CONFIG_VLAN_8021Q is disabled and there are no calls to
@@ -789,26 +805,39 @@ int b53_configure_vlan(struct dsa_switch *ds)* entry. Do this only when the tagging protocol is not * DSA_TAG_PROTO_NONE */ + v = &dev->vlans[def_vid];b53_for_each_port (dev, i) { - v = &dev->vlans[def_vid]; - v->members |=BIT (i); +if (!b53_vlan_port_may_join_untagged (ds, i)) +continue ; + + vl.members |=BIT (i);if (!b53_vlan_port_needs_forced_tagged (ds, i)) - v->untag = v->members; -b53_write16 (dev,B53_VLAN_PAGE , -B53_VLAN_PORT_DEF_TAG (i), def_vid); + vl.untag = vl.members; +b53_write16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (i), + def_vid); } +b53_set_vlan_entry (dev, def_vid, &vl); -/* Upon initial call we have not set-up any VLANs, but upon -* system resume, we need to restore all VLAN entries. -*/ -for (vid = def_vid; vid < dev->num_vlans; vid++) { - v = &dev->vlans[vid]; +if (dev->vlan_filtering) { +/* Upon initial call we have not set-up any VLANs, but upon +* system resume, we need to restore all VLAN entries. +*/ +for (vid = def_vid +1 ; vid < dev->num_vlans; vid++) { + v = &dev->vlans[vid]; -if (!v->members) -continue ; +if (!v->members) +continue ; + +b53_set_vlan_entry (dev, vid, v); +b53_fast_age_vlan (dev, vid); + } -b53_set_vlan_entry (dev, vid, v); -b53_fast_age_vlan (dev, vid); +b53_for_each_port (dev, i) { +if (!dsa_is_cpu_port (ds, i)) +b53_write16 (dev,B53_VLAN_PAGE , +B53_VLAN_PORT_DEF_TAG (i), + dev->ports[i].pvid); + } }return 0 ;
@@ -1128,7 +1157,9 @@ EXPORT_SYMBOL(b53_setup_devlink_resources);static int b53_setup (struct dsa_switch *ds) {struct b53_device *dev = ds->priv; +struct b53_vlan *vl;unsigned int port; +u16 pvid;int ret;/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
@@ -1147,6 +1178,15 @@ static int b53_setup(struct dsa_switch *ds)return ret; } +/* setup default vlan for filtering mode */ + pvid =b53_default_pvid (dev); + vl = &dev->vlans[pvid]; +b53_for_each_port (dev, port) { + vl->members |=BIT (port); +if (!b53_vlan_port_needs_forced_tagged (ds, port)) + vl->untag |=BIT (port); + } +b53_reset_mib (dev); ret =b53_apply_config (dev);
@@ -1500,7 +1540,10 @@ int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, {struct b53_device *dev = ds->priv; -b53_enable_vlan (dev, port, dev->vlan_enabled, vlan_filtering); +if (dev->vlan_filtering != vlan_filtering) { + dev->vlan_filtering = vlan_filtering; +b53_apply_config (dev); + }return 0 ; }
@@ -1525,7 +1568,7 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,if (vlan->vid >= dev->num_vlans)return -ERANGE ; -b53_enable_vlan (dev, port, true, ds->vlan_filtering); +b53_enable_vlan (dev, port, true, dev->vlan_filtering);return 0 ; }
@@ -1548,21 +1591,17 @@ int b53_vlan_add(struct dsa_switch *ds, int port,if (vlan->vid ==0 )return 0 ; -if (!ds->vlan_filtering) -return 0 ; - -b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &old_pvid); + old_pvid = dev->ports[port].pvid;if (pvid) new_pvid = vlan->vid;else if (!pvid && vlan->vid == old_pvid) new_pvid =b53_default_pvid (dev);else new_pvid = old_pvid; + dev->ports[port].pvid = new_pvid; vl = &dev->vlans[vlan->vid]; -b53_get_vlan_entry (dev, vlan->vid, vl); -if (dsa_is_cpu_port (ds, port)) untagged = false;
@@ -1572,6 +1611,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,else vl->untag &= ~BIT (port); +if (!dev->vlan_filtering) +return 0 ; +b53_set_vlan_entry (dev, vlan->vid, vl);b53_fast_age_vlan (dev, vlan->vid);
@@ -1596,23 +1638,22 @@ int b53_vlan_del(struct dsa_switch *ds, int port,if (vlan->vid ==0 )return 0 ; -if (!ds->vlan_filtering) -return 0 ; - -b53_read16 (dev,B53_VLAN_PAGE ,B53_VLAN_PORT_DEF_TAG (port), &pvid); + pvid = dev->ports[port].pvid; vl = &dev->vlans[vlan->vid]; -b53_get_vlan_entry (dev, vlan->vid, vl); - vl->members &= ~BIT (port);if (pvid == vlan->vid) pvid =b53_default_pvid (dev); + dev->ports[port].pvid = pvid;if (untagged && !b53_vlan_port_needs_forced_tagged (ds, port)) vl->untag &= ~(BIT (port)); +if (!dev->vlan_filtering) +return 0 ; +b53_set_vlan_entry (dev, vlan->vid, vl);b53_fast_age_vlan (dev, vlan->vid);
@@ -1959,7 +2000,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, pvid =b53_default_pvid (dev); vl = &dev->vlans[pvid]; -if (ds->vlan_filtering) { +if (dev->vlan_filtering) {/* Make this port leave the all VLANs join since we will have * proper VLAN entries from now on */
@@ -2039,7 +2080,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge) pvid =b53_default_pvid (dev); vl = &dev->vlans[pvid]; -if (ds->vlan_filtering) { +if (dev->vlan_filtering) {/* Make this port join all VLANs without VLAN entries */ if (is58xx (dev)) {b53_read16 (dev,B53_VLAN_PAGE ,B53_JOIN_ALL_VLAN_EN , ®);
@@ -2797,6 +2838,7 @@ struct b53_device *b53_switch_alloc(struct device *base, ds->ops = &b53_switch_ops; ds->phylink_mac_ops = &b53_phylink_mac_ops; dev->vlan_enabled = true; + dev->vlan_filtering = false;/* Let DSA handle the case were multiple bridges span the same switch * device and different VLAN awareness settings are requested, which * would be breaking filtering semantics for any of the other bridge
drivers/net/dsa/b53/b53_priv.h +2 -0
@@ -95,6 +95,7 @@ struct b53_pcs {struct b53_port {u16 vlan_ctl_mask; +u16 pvid;struct ethtool_keee eee; };
@@ -146,6 +147,7 @@ struct b53_device {unsigned int num_vlans;struct b53_vlan *vlans;bool vlan_enabled; +bool vlan_filtering;unsigned int num_ports;struct b53_port *ports;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 44/184 net: dsa: b53: fix learning on VLAN unaware bridges
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 9f34ad89bcf0e6df6f8b01f1bdab211493fc66d1 ]
When VLAN filtering is off, we configure the switch to forward, but not learn on VLAN table misses. This effectively disables learning while not filtering.
Fix this by switching to forward and learn. Setting the learning disable register will still control whether learning actually happens.
--- drivers/net/dsa/b53/b53_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +1 -1
@@ -383,7 +383,7 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable, vc4 |=VC4_ING_VID_VIO_DROP <<VC4_ING_VID_CHECK_S ; vc5 |=VC5_DROP_VTABLE_MISS ; }else { - vc4 |=VC4_ING_VID_VIO_FWD <<VC4_ING_VID_CHECK_S ; + vc4 |=VC4_NO_ING_VID_CHK <<VC4_ING_VID_CHECK_S ; vc5 &= ~VC5_DROP_VTABLE_MISS ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 45/184 net: dsa: b53: do not set learning and unicast/multicast on up
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 2e7179c628d3cb9aee75e412473813b099e11ed4 ]
When a port gets set up, b53 disables learning and enables the port for flooding. This can undo any bridge configuration on the port.
E.g. the following flow would disable learning on a port:
$ ip link add br0 type bridge $ ip link set sw1p1 master br0 <- enables learning for sw1p1 $ ip link set br0 up $ ip link set sw1p1 up <- disables learning again
Fix this by populating dsa_switch_ops::port_setup(), and set up initial config there.
--- drivers/net/dsa/b53/b53_common.c | 21 +++++++++++++-------- drivers/net/dsa/b53/b53_priv.h | 1 + drivers/net/dsa/bcm_sf2.c | 1 + 3 files changed, 15 insertions(+), 8 deletions(-)
drivers/net/dsa/b53/b53_common.c +13 -8
@@ -578,6 +578,18 @@ static void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable)b53_write16 (dev,B53_EEE_PAGE ,B53_EEE_EN_CTRL , reg); } +int b53_setup_port (struct dsa_switch *ds,int port) +{ +struct b53_device *dev = ds->priv; + +b53_port_set_ucast_flood (dev, port, true); +b53_port_set_mcast_flood (dev, port, true); +b53_port_set_learning (dev, port, false); + +return 0 ; +} +EXPORT_SYMBOL (b53_setup_port); +int b53_enable_port (struct dsa_switch *ds,int port,struct phy_device *phy) {struct b53_device *dev = ds->priv;
@@ -590,10 +602,6 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) cpu_port =dsa_to_port (ds, port)->cpu_dp->index; -b53_port_set_ucast_flood (dev, port, true); -b53_port_set_mcast_flood (dev, port, true); -b53_port_set_learning (dev, port, false); -if (dev->ops->irq_enable) ret = dev->ops->irq_enable (dev, port);if (ret)
@@ -724,10 +732,6 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port)b53_write8 (dev,B53_CTRL_PAGE ,B53_PORT_CTRL (port), port_ctrl);b53_brcm_hdr_setup (dev->ds, port); - -b53_port_set_ucast_flood (dev, port, true); -b53_port_set_mcast_flood (dev, port, true); -b53_port_set_learning (dev, port, false); }static void b53_enable_mib (struct b53_device *dev)
@@ -2394,6 +2398,7 @@ static const struct dsa_switch_ops b53_switch_ops = { .phy_read = b53_phy_read16, .phy_write = b53_phy_write16, .phylink_get_caps = b53_phylink_get_caps, + .port_setup = b53_setup_port, .port_enable = b53_enable_port, .port_disable = b53_disable_port, .get_mac_eee = b53_get_mac_eee,
drivers/net/dsa/b53/b53_priv.h +1 -0
@@ -382,6 +382,7 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot);void b53_mirror_del (struct dsa_switch *ds,int port,struct dsa_mall_mirror_tc_entry *mirror); +int b53_setup_port (struct dsa_switch *ds,int port);int b53_enable_port (struct dsa_switch *ds,int port,struct phy_device *phy);void b53_disable_port (struct dsa_switch *ds,int port);void b53_brcm_hdr_setup (struct dsa_switch *ds,int port);
drivers/net/dsa/bcm_sf2.c +1 -0
@@ -1230,6 +1230,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = { .resume = bcm_sf2_sw_resume, .get_wol = bcm_sf2_sw_get_wol, .set_wol = bcm_sf2_sw_set_wol, + .port_setup = b53_setup_port, .port_enable = bcm_sf2_port_setup, .port_disable = bcm_sf2_port_disable, .get_mac_eee = b53_get_mac_eee,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 46/184 fbnic: Fix initialization of mailbox descriptor rings
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit f34343cc11afc7bb1f881c3492bee3484016bf71 ]
Address to issues with the FW mailbox descriptor initialization.
We need to reverse the order of accesses when we invalidate an entry versus writing an entry. When writing an entry we write upper and then lower as the lower 32b contain the valid bit that makes the entire address valid. However for invalidation we should write it in the reverse order so that the upper is marked invalid before we update it.
Without this change we may see FW attempt to access pages with the upper 32b of the address set to 0 which will likely result in DMAR faults due to write access failures on mailbox shutdown.
--- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 32 ++++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +23 -9
@@ -17,11 +17,29 @@ static void __fbnic_mbx_wr_desc(struct fbnic_dev *fbd, int mbx_idx, {u32 desc_offset =FBNIC_IPC_MBX (mbx_idx, desc_idx); +/* Write the upper 32b and then the lower 32b. Doing this the +* FW can then read lower, upper, lower to verify that the state +* of the descriptor wasn't changed mid-transaction. +*/ fw_wr32 (fbd, desc_offset +1 ,upper_32_bits (desc));fw_wrfl (fbd);fw_wr32 (fbd, desc_offset,lower_32_bits (desc)); } +static void __fbnic_mbx_invalidate_desc (struct fbnic_dev *fbd,int mbx_idx, +int desc_idx,u32 desc) +{ +u32 desc_offset =FBNIC_IPC_MBX (mbx_idx, desc_idx); + +/* For initialization we write the lower 32b of the descriptor first. +* This way we can set the state to mark it invalid before we clear the +* upper 32b. +*/ +fw_wr32 (fbd, desc_offset, desc); +fw_wrfl (fbd); +fw_wr32 (fbd, desc_offset +1 ,0 ); +} +static u64 __fbnic_mbx_rd_desc (struct fbnic_dev *fbd,int mbx_idx,int desc_idx) {u32 desc_offset =FBNIC_IPC_MBX (mbx_idx, desc_idx);
@@ -41,21 +59,17 @@ static void fbnic_mbx_init_desc_ring(struct fbnic_dev *fbd, int mbx_idx)* solid stop for the firmware to hit when it is done looping * through the ring. */ -__fbnic_mbx_wr_desc (fbd, mbx_idx,0 ,0 ); - -fw_wrfl (fbd); +__fbnic_mbx_invalidate_desc (fbd, mbx_idx,0 ,0 );/* We then fill the rest of the ring starting at the end and moving * back toward descriptor 0 with skip descriptors that have no * length nor address, and tell the firmware that they can skip * them and just move past them to the one we initialized to 0. */ -for (desc_idx =FBNIC_IPC_MBX_DESC_LEN ; --desc_idx;) { -__fbnic_mbx_wr_desc (fbd, mbx_idx, desc_idx, -FBNIC_IPC_MBX_DESC_FW_CMPL | -FBNIC_IPC_MBX_DESC_HOST_CMPL ); -fw_wrfl (fbd); - } +for (desc_idx =FBNIC_IPC_MBX_DESC_LEN ; --desc_idx;) +__fbnic_mbx_invalidate_desc (fbd, mbx_idx, desc_idx, +FBNIC_IPC_MBX_DESC_FW_CMPL | +FBNIC_IPC_MBX_DESC_HOST_CMPL ); }void fbnic_mbx_init (struct fbnic_dev *fbd)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 47/184 fbnic: Gate AXI read/write enabling on FW mailbox
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 3b12f00ddd08e888273b2ac0488d396d90a836fc ]
In order to prevent the device from throwing spurious writes and/or reads at us we need to gate the AXI fabric interface to the PCIe until such time as we know the FW is in a known good state.
To accomplish this we use the mailbox as a mechanism for us to recognize that the FW has acknowledged our presence and is no longer sending any stale message data to us.
We start in fbnic_mbx_init by calling fbnic_mbx_reset_desc_ring function, disabling the DMA in both directions, and then invalidating all the descriptors in each ring.
We then poll the mailbox in fbnic_mbx_poll_tx_ready and when the interrupt is set by the FW we pick it up and mark the mailboxes as ready, while also enabling the DMA.
Once we have completed all the transactions and need to shut down we call into fbnic_mbx_clean which will in turn call fbnic_mbx_reset_desc_ring for each ring and shut down the DMA and once again invalidate the descriptors.
--- drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 2 ++ drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 38 +++++++++++++++++---- drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 6 ---- 3 files changed, 33 insertions(+), 13 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_csr.h +2 -0
@@ -700,8 +700,10 @@ enum {/* PUL User Registers */ #define FBNIC_CSR_START_PUL_USER 0x31000/* CSR section delimiter */ #define FBNIC_PUL_OB_TLP_HDR_AW_CFG 0x3103d/* 0xc40f4 */ +#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH CSR_BIT(19)#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME CSR_BIT(18)#define FBNIC_PUL_OB_TLP_HDR_AR_CFG 0x3103e/* 0xc40f8 */ +#define FBNIC_PUL_OB_TLP_HDR_AR_CFG_FLUSH CSR_BIT(19)#define FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME CSR_BIT(18)#define FBNIC_CSR_END_PUL_USER 0x31080/* CSR section delimiter */
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +31 -7
@@ -51,10 +51,26 @@ static u64 __fbnic_mbx_rd_desc(struct fbnic_dev *fbd, int mbx_idx, int desc_idx)return desc; } -static void fbnic_mbx_init_desc_ring (struct fbnic_dev *fbd,int mbx_idx) +static void fbnic_mbx_reset_desc_ring (struct fbnic_dev *fbd,int mbx_idx) {int desc_idx; +/* Disable DMA transactions from the device, +* and flush any transactions triggered during cleaning +*/ +switch (mbx_idx) { +case FBNIC_IPC_MBX_RX_IDX : +wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AW_CFG , +FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH ); +break ; +case FBNIC_IPC_MBX_TX_IDX : +wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AR_CFG , +FBNIC_PUL_OB_TLP_HDR_AR_CFG_FLUSH ); +break ; + } + +wrfl (fbd); +/* Initialize first descriptor to all 0s. Doing this gives us a * solid stop for the firmware to hit when it is done looping * through the ring.
@@ -90,7 +106,7 @@ void fbnic_mbx_init(struct fbnic_dev *fbd)wr32 (fbd,FBNIC_INTR_CLEAR (0 ),1u <<FBNIC_FW_MSIX_ENTRY );for (i =0 ; i <FBNIC_IPC_MBX_INDICES ; i++) -fbnic_mbx_init_desc_ring (fbd, i); +fbnic_mbx_reset_desc_ring (fbd, i); } static int fbnic_mbx_map_msg(struct fbnic_dev *fbd, int mbx_idx,
@@ -155,7 +171,7 @@ static void fbnic_mbx_clean_desc_ring(struct fbnic_dev *fbd, int mbx_idx) {int i; -fbnic_mbx_init_desc_ring (fbd, mbx_idx); +fbnic_mbx_reset_desc_ring (fbd, mbx_idx);for (i =FBNIC_IPC_MBX_DESC_LEN ; i--;)fbnic_mbx_unmap_and_free_msg (fbd, mbx_idx, i);
@@ -297,7 +313,7 @@ static int fbnic_fw_xmit_cap_msg(struct fbnic_dev *fbd)return (err == -EOPNOTSUPP ) ?0 : err; } -static void fbnic_mbx_postinit_desc_ring (struct fbnic_dev *fbd,int mbx_idx) +static void fbnic_mbx_init_desc_ring (struct fbnic_dev *fbd,int mbx_idx) {struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
@@ -309,10 +325,18 @@ static void fbnic_mbx_postinit_desc_ring(struct fbnic_dev *fbd, int mbx_idx)switch (mbx_idx) {case FBNIC_IPC_MBX_RX_IDX : +/* Enable DMA writes from the device */ +wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AW_CFG , +FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME ); +/* Make sure we have a page for the FW to write to */ fbnic_mbx_alloc_rx_msgs (fbd);break ;case FBNIC_IPC_MBX_TX_IDX : +/* Enable DMA reads from the device */ +wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AR_CFG , +FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME ); +/* Force version to 1 if we successfully requested an update * from the firmware. This should be overwritten once we get * the actual version from the firmware in the capabilities
@@ -329,7 +353,7 @@ static void fbnic_mbx_postinit(struct fbnic_dev *fbd) {int i; -/* We only need to do this on the first interrupt following init. +/* We only need to do this on the first interrupt following reset. * this primes the mailbox so that we will have cleared all the * skip descriptors. */
@@ -339,7 +363,7 @@ static void fbnic_mbx_postinit(struct fbnic_dev *fbd)wr32 (fbd,FBNIC_INTR_CLEAR (0 ),1u <<FBNIC_FW_MSIX_ENTRY );for (i =0 ; i <FBNIC_IPC_MBX_INDICES ; i++) -fbnic_mbx_postinit_desc_ring (fbd, i); +fbnic_mbx_init_desc_ring (fbd, i); }/**
@@ -761,7 +785,7 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)* avoid the mailbox getting stuck closed if the interrupt * is reset. */ -fbnic_mbx_init_desc_ring (fbd,FBNIC_IPC_MBX_TX_IDX ); +fbnic_mbx_reset_desc_ring (fbd,FBNIC_IPC_MBX_TX_IDX );msleep (200 );
drivers/net/ethernet/meta/fbnic/fbnic_mac.c +0 -6
@@ -79,12 +79,6 @@ static void fbnic_mac_init_axi(struct fbnic_dev *fbd)fbnic_init_readrq (fbd,FBNIC_QM_RNI_RBP_CTL , cls, readrq);fbnic_init_mps (fbd,FBNIC_QM_RNI_RDE_CTL , cls, mps);fbnic_init_mps (fbd,FBNIC_QM_RNI_RCM_CTL , cls, mps); - -/* Enable XALI AR/AW outbound */ -wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AW_CFG , -FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME ); -wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AR_CFG , -FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME ); }static void fbnic_mac_init_qm (struct fbnic_dev *fbd)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 48/184 fbnic: Actually flush_tx instead of stalling out
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 0f9a959a0addd9bbc47e5d16c36b3a7f97981915 ]
The fbnic_mbx_flush_tx function had a number of issues.
First, we were waiting 200ms for the firmware to process the packets. We can drop this to 20ms and in almost all cases this should be more than enough time. So by changing this we can significantly reduce shutdown time.
Second, we were not making sure that the Tx path was actually shut off. As such we could still have packets added while we were flushing the mailbox. To prevent that we can now clear the ready flag for the Tx side and it should stay down since the interrupt is disabled.
Third, we kept re-reading the tail due to the second issue. The tail should not move after we have started the flush so we can just read it once while we are holding the mailbox Tx lock. By doing that we are guaranteed that the value should be consistent.
Fourth, we were keeping a count of descriptors cleaned due to the second and third issues called out. That count is not a valid reason to be exiting the cleanup, and with the tail only being read once we shouldn't see any cases where the tail moves after the disable so the tracking of count can be dropped.
Fifth, we were using attempts * sleep time to determine how long we would wait in our polling loop to flush out the Tx. This can be very imprecise. In order to tighten up the timing we are shifting over to using a jiffies value of jiffies + 10 * HZ + 1 to determine the jiffies value we should stop polling at as this should be accurate within once sleep cycle for the total amount of time spent polling.
--- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +16 -15
@@ -797,35 +797,36 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)void fbnic_mbx_flush_tx (struct fbnic_dev *fbd) { +unsigned long timeout = jiffies +10 *HZ +1 ;struct fbnic_fw_mbx *tx_mbx; -int attempts =50 ; -u8 count =0 ; - -/* Nothing to do if there is no mailbox */ -if (!fbnic_fw_present (fbd)) -return ; +u8 tail;/* Record current Rx stats */ tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX ]; -/* Nothing to do if mailbox never got to ready */ -if (!tx_mbx->ready) -return ; +spin_lock_irq (&fbd->fw_tx_lock); + +/* Clear ready to prevent any further attempts to transmit */ + tx_mbx->ready = false; + +/* Read tail to determine the last tail state for the ring */ + tail = tx_mbx->tail; + +spin_unlock_irq (&fbd->fw_tx_lock);/* Give firmware time to process packet, -* we will wait up to 10 seconds which is 50 waits of 200ms. +* we will wait up to 10 seconds which is 500 waits of 20ms. */ do {u8 head = tx_mbx->head; -if (head == tx_mbx->tail) +/* Tx ring is empty once head == tail */ +if (head == tail)break ; -msleep (200 ); +msleep (20 );fbnic_mbx_process_tx_msgs (fbd); - - count += (tx_mbx->head - head) %FBNIC_IPC_MBX_DESC_LEN ; - }while (count <FBNIC_IPC_MBX_DESC_LEN && --attempts); + }while (time_is_after_jiffies (timeout)); } void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 49/184 fbnic: Improve responsiveness of fbnic_mbx_poll_tx_ready
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit ab064f6005973d456f95ae99cd9ea0d8ab676cce ]
There were a couple different issues found in fbnic_mbx_poll_tx_ready. Among them were the fact that we were sleeping much longer than we actually needed to as the actual FW could respond in under 20ms. The other issue was that we would just keep polling the mailbox even if the device itself had gone away.
To address the responsiveness issues we can decrease the sleeps to 20ms and use a jiffies based timeout value rather than just counting the number of times we slept and then polled.
To address the hardware going away we can move the check for the firmware BAR being present from where it was and place it inside the loop after the mailbox descriptor ring is initialized and before we sleep so that we just abort and return an error if the device went away during initialization.
With these two changes we see a significant improvement in boot times for the driver.
--- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +11 -8
@@ -772,27 +772,30 @@ void fbnic_mbx_poll(struct fbnic_dev *fbd)int fbnic_mbx_poll_tx_ready (struct fbnic_dev *fbd) { +unsigned long timeout = jiffies +10 *HZ +1 ;struct fbnic_fw_mbx *tx_mbx; -int attempts =50 ; - -/* Immediate fail if BAR4 isn't there */ -if (!fbnic_fw_present (fbd)) -return -ENODEV ; tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX ]; -while (!tx_mbx->ready && --attempts) { +while (!tx_mbx->ready) { +if (!time_is_after_jiffies (timeout)) +return -ETIMEDOUT ; +/* Force the firmware to trigger an interrupt response to * avoid the mailbox getting stuck closed if the interrupt * is reset. */ fbnic_mbx_reset_desc_ring (fbd,FBNIC_IPC_MBX_TX_IDX ); -msleep (200 ); +/* Immediate fail if BAR4 went away */ +if (!fbnic_fw_present (fbd)) +return -ENODEV ; + +msleep (20 );fbnic_mbx_poll (fbd); } -return attempts ?0 : -ETIMEDOUT ; +return 0 ; }void fbnic_mbx_flush_tx (struct fbnic_dev *fbd)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 50/184 fbnic: Pull fbnic_fw_xmit_cap_msg use out of interrupt context
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 1b34d1c1dc8384884febd83140c9afbc7c4b9eb8 ]
This change pulls the call to fbnic_fw_xmit_cap_msg out of fbnic_mbx_init_desc_ring and instead places it in the polling function for getting the Tx ready. Doing that we can avoid the potential issue with an interrupt coming in later from the firmware that causes it to get fired in interrupt context.
--- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 43 ++++++++-------------- 1 file changed, 16 insertions(+), 27 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +16 -27
@@ -295,24 +295,6 @@ static int fbnic_fw_xmit_simple_msg(struct fbnic_dev *fbd, u32 msg_type)return err; } -/** -* fbnic_fw_xmit_cap_msg - Allocate and populate a FW capabilities message -* @fbd: FBNIC device structure -* -* Return: NULL on failure to allocate, error pointer on error, or pointer -* to new TLV test message. -* -* Sends a single TLV header indicating the host wants the firmware to -* confirm the capabilities and version. -**/ -static int fbnic_fw_xmit_cap_msg (struct fbnic_dev *fbd) -{ -int err =fbnic_fw_xmit_simple_msg (fbd,FBNIC_TLV_MSG_ID_HOST_CAP_REQ ); - -/* Return 0 if we are not calling this on ASIC */ -return (err == -EOPNOTSUPP ) ?0 : err; -} -static void fbnic_mbx_init_desc_ring (struct fbnic_dev *fbd,int mbx_idx) {struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
@@ -336,15 +318,6 @@ static void fbnic_mbx_init_desc_ring(struct fbnic_dev *fbd, int mbx_idx)/* Enable DMA reads from the device */ wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AR_CFG ,FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME ); - -/* Force version to 1 if we successfully requested an update -* from the firmware. This should be overwritten once we get -* the actual version from the firmware in the capabilities -* request message. -*/ -if (!fbnic_fw_xmit_cap_msg (fbd) && - !fbd->fw_cap.running.mgmt.version) - fbd->fw_cap.running.mgmt.version =1 ;break ; } }
@@ -774,6 +747,7 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd) {unsigned long timeout = jiffies +10 *HZ +1 ;struct fbnic_fw_mbx *tx_mbx; +int err; tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX ];while (!tx_mbx->ready) {
@@ -795,7 +769,22 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)fbnic_mbx_poll (fbd); } +/* Request an update from the firmware. This should overwrite +* mgmt.version once we get the actual version from the firmware +* in the capabilities request message. +*/ + err =fbnic_fw_xmit_simple_msg (fbd,FBNIC_TLV_MSG_ID_HOST_CAP_REQ ); +if (err) + goto clean_mbx; + +/* Use "1" to indicate we entered the state waiting for a response */ + fbd->fw_cap.running.mgmt.version =1 ; +return 0 ; +clean_mbx: +/* Cleanup Rx buffers and disable mailbox */ +fbnic_mbx_clean (fbd); +return err; }void fbnic_mbx_flush_tx (struct fbnic_dev *fbd)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 51/184 fbnic: Do not allow mailbox to toggle to ready outside fbnic_mbx_poll_tx_ready
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit ce2fa1dba204c761582674cf2eb9cbe0b949b5c7 ]
We had originally thought to have the mailbox go to ready in the background while we were doing other things. One issue with this though is that we can't disable it by clearing the ready state without also blocking interrupts or calls to mbx_poll as it will just pop back to life during an interrupt.
In order to prevent that from happening we can pull the code for toggling to ready out of the interrupt path and instead place it in the fbnic_mbx_poll_tx_ready path so that it becomes the only spot where the Rx/Tx can toggle to the ready state. By doing this we can prevent races where we disable the DMA and/or free buffers only to have an interrupt fire and undo what we have done.
--- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 27 ++++++++-------------- 1 file changed, 10 insertions(+), 17 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +10 -17
@@ -299,10 +299,6 @@ static void fbnic_mbx_init_desc_ring(struct fbnic_dev *fbd, int mbx_idx) {struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx]; -/* This is a one time init, so just exit if it is completed */ -if (mbx->ready) -return ; - mbx->ready = true;switch (mbx_idx) {
@@ -322,21 +318,18 @@ static void fbnic_mbx_init_desc_ring(struct fbnic_dev *fbd, int mbx_idx) } } -static void fbnic_mbx_postinit (struct fbnic_dev *fbd) +static bool fbnic_mbx_event (struct fbnic_dev *fbd) { -int i; -/* We only need to do this on the first interrupt following reset. * this primes the mailbox so that we will have cleared all the * skip descriptors. */ if (!(rd32 (fbd,FBNIC_INTR_STATUS (0 )) & (1u <<FBNIC_FW_MSIX_ENTRY ))) -return ; +return false;wr32 (fbd,FBNIC_INTR_CLEAR (0 ),1u <<FBNIC_FW_MSIX_ENTRY ); -for (i =0 ; i <FBNIC_IPC_MBX_INDICES ; i++) -fbnic_mbx_init_desc_ring (fbd, i); +return true; }/**
@@ -737,7 +730,7 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)void fbnic_mbx_poll (struct fbnic_dev *fbd) { -fbnic_mbx_postinit (fbd); +fbnic_mbx_event (fbd);fbnic_mbx_process_tx_msgs (fbd);fbnic_mbx_process_rx_msgs (fbd);
@@ -746,11 +739,9 @@ void fbnic_mbx_poll(struct fbnic_dev *fbd)int fbnic_mbx_poll_tx_ready (struct fbnic_dev *fbd) {unsigned long timeout = jiffies +10 *HZ +1 ; -struct fbnic_fw_mbx *tx_mbx; -int err; +int err, i; - tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX ]; -while (!tx_mbx->ready) { + do { if (!time_is_after_jiffies(timeout)) return -ETIMEDOUT;
@@ -765,9 +756,11 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)return -ENODEV ;msleep (20 ); + }while (!fbnic_mbx_event (fbd)); -fbnic_mbx_poll (fbd); - } +/* FW has shown signs of life. Enable DMA and start Tx/Rx */ +for (i =0 ; i <FBNIC_IPC_MBX_INDICES ; i++) +fbnic_mbx_init_desc_ring (fbd, i);/* Request an update from the firmware. This should overwrite * mgmt.version once we get the actual version from the firmware
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 52/184 net: export a helper for adding up queue stats
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 23fa6a23d97182d36ca3c71e43c804fa91e46a03 ]
Older drivers and drivers with lower queue counts often have a static array of queues, rather than allocating structs for each queue on demand. Add a helper for adding up qstats from a queue range. Expectation is that driver will pass a queue range [netdev->real_num_*x_queues, MAX). It was tempting to always use num_*x_queues as the end, but virtio seems to clamp its queue count after allocating the netdev. And this way we can trivaly reuse the helper for [0, real_..).
Stable-dep-of: 001160ec8c59 ("virtio-net: fix total qstat values")
--- include/net/netdev_queues.h | 6 ++++ net/core/netdev-genl.c | 69 +++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 19 deletions(-)
include/net/netdev_queues.h +6 -0
@@ -92,6 +92,12 @@ struct netdev_stat_ops { struct netdev_queue_stats_tx *tx); }; +void netdev_stat_queue_sum (struct net_device *netdev, +int rx_start,int rx_end, +struct netdev_queue_stats_rx *rx_sum, +int tx_start,int tx_end, +struct netdev_queue_stats_tx *tx_sum); +/** * struct netdev_queue_mgmt_ops - netdev ops for queue management *
net/core/netdev-genl.c +50 -19
93 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 53/184 virtio-net: fix total qstat values
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 001160ec8c59115efc39e197d40829bdafd4d7f5 ]
NIPA tests report that the interface statistics reported via qstat are lower than those reported via ip link. Looks like this is because some tests flip the queue count up and down, and we end up with some of the traffic accounted on disabled queues.
Add up counters from disabled queues.
--- drivers/net/virtio_net.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/virtio_net.c +4 -0
@@ -5427,6 +5427,10 @@ static void virtnet_get_base_stats(struct net_device *dev,if (vi->device_stats_cap &VIRTIO_NET_STATS_TYPE_TX_SPEED ) tx->hw_drop_ratelimits =0 ; + +netdev_stat_queue_sum (dev, + dev->real_num_rx_queues, vi->max_queue_pairs, rx, + dev->real_num_tx_queues, vi->max_queue_pairs, tx); }static const struct netdev_stat_ops virtnet_stat_ops = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 54/184 Input: cyttsp5 - ensure minimum reset pulse width
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit c6cb8bf79466ae66bd0d07338c7c505ce758e9d7 upstream.
The current reset pulse width is measured to be 5us on a Renesas RZ/G2L SOM. The manufacturer's minimum reset pulse width is specified as 10us.
Extend reset pulse width to make sure it is long enough on all platforms.
Also reword confusing comments about reset pin assertion.
--- drivers/input/touchscreen/cyttsp5.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/input/touchscreen/cyttsp5.c +4 -1
@@ -870,13 +870,16 @@ static int cyttsp5_probe(struct device * ts->input->phys = ts->phys;input_set_drvdata (ts->input, ts); -/* Reset the gpio to be in a reset state */ +/* Assert gpio to be in a reset state */ ts->reset_gpio =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH );if (IS_ERR (ts->reset_gpio)) { error =PTR_ERR (ts->reset_gpio);dev_err (dev,"Failed to request reset gpio, error %d\n" , error);return error; } + +fsleep (10 );/* Ensure long-enough reset pulse (minimum 10us). */ +gpiod_set_value_cansleep (ts->reset_gpio,0 );/* Need a delay to have device up */
Greg Kroah-Hartman
maintainerPATCH 55/184 Input: cyttsp5 - fix power control issue on wakeup
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikael Gonella-Bolduc <[email protected]>
commit 7675b5efd81fe6d524e29d5a541f43201e98afa8 upstream.
The power control function ignores the "on" argument when setting the report ID, and thus is always sending HID_POWER_SLEEP. This causes a problem when trying to wakeup.
Fix by sending the state variable, which contains the proper HID_POWER_ON or HID_POWER_SLEEP based on the "on" argument.
--- drivers/input/touchscreen/cyttsp5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/touchscreen/cyttsp5.c +1 -1
@@ -580,7 +580,7 @@ static int cyttsp5_power_control(structint rc;SET_CMD_REPORT_TYPE (cmd[0 ],0 ); -SET_CMD_REPORT_ID (cmd[0 ],HID_POWER_SLEEP ); +SET_CMD_REPORT_ID (cmd[0 ], state);SET_CMD_OPCODE (cmd[1 ],HID_CMD_SET_POWER ); rc =cyttsp5_write (ts,HID_COMMAND_REG , cmd,sizeof (cmd));
Greg Kroah-Hartman
maintainerPATCH 56/184 Input: mtk-pmic-keys - fix possible null pointer dereference
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Bisson <[email protected]>
commit 11cdb506d0fbf5ac05bf55f5afcb3a215c316490 upstream.
In mtk_pmic_keys_probe, the regs parameter is only set if the button is parsed in the device tree. However, on hardware where the button is left floating, that node will most likely be removed not to enable that input. In that case the code will try to dereference a null pointer.
Let's use the regs struct instead as it is defined for all supported platforms. Note that it is ok setting the key reg even if that latter is disabled as the interrupt won't be enabled anyway.
--- drivers/input/keyboard/mtk-pmic-keys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/input/keyboard/mtk-pmic-keys.c +2 -2
@@ -147,8 +147,8 @@ static void mtk_pmic_keys_lp_reset_setupu32 value, mask;int error; - kregs_home = keys->keys[MTK_PMIC_HOMEKEY_INDEX ].regs; - kregs_pwr = keys->keys[MTK_PMIC_PWRKEY_INDEX ].regs; + kregs_home = ®s->keys_regs[MTK_PMIC_HOMEKEY_INDEX ]; + kregs_pwr = ®s->keys_regs[MTK_PMIC_PWRKEY_INDEX ]; error =of_property_read_u32 (keys->dev->of_node,"power-off-time-sec" , &long_press_debounce);
Greg Kroah-Hartman
maintainerPATCH 57/184 Input: xpad - fix Share button on Xbox One controllers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
commit 4ef46367073b107ec22f46fe5f12176e87c238e8 upstream.
The Share button, if present, is always one of two offsets from the end of the file, depending on the presence of a specific interface. As we lack parsing for the identify packet we can't automatically determine the presence of that interface, but we can hardcode which of these offsets is correct for a given controller.
More controllers are probably fixable by adding the MAP_SHARE_BUTTON in the future, but for now I only added the ones that I have the ability to test directly.
--- drivers/input/joystick/xpad.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-)
drivers/input/joystick/xpad.c +20 -15
@@ -77,12 +77,13 @@* xbox d-pads should map to buttons, as is required for DDR pads * but we map them to axes when possible to simplify things */ -#define MAP_DPAD_TO_BUTTONS (1 << 0) -#define MAP_TRIGGERS_TO_BUTTONS (1 << 1) -#define MAP_STICKS_TO_NULL (1 << 2) -#define MAP_SELECT_BUTTON (1 << 3) -#define MAP_PADDLES (1 << 4) -#define MAP_PROFILE_BUTTON (1 << 5) +#define MAP_DPAD_TO_BUTTONS BIT(0) +#define MAP_TRIGGERS_TO_BUTTONS BIT(1) +#define MAP_STICKS_TO_NULL BIT(2) +#define MAP_SHARE_BUTTON BIT(3) +#define MAP_PADDLES BIT(4) +#define MAP_PROFILE_BUTTON BIT(5) +#define MAP_SHARE_OFFSET BIT(6)#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
@@ -135,7 +136,7 @@ static const struct xpad_device { { 0x03f0, 0x048D, "HyperX Clutch", 0, XTYPE_XBOX360 }, /* wireless */ { 0x03f0, 0x0495, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE }, { 0x03f0, 0x07A0, "HyperX Clutch Gladiate RGB", 0, XTYPE_XBOXONE }, - { 0x03f0, 0x08B6, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE }, /* v2 */ + { 0x03f0, 0x08B6, "HyperX Clutch Gladiate", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, /* v2 */ { 0x03f0, 0x09B4, "HyperX Clutch Tanto", 0, XTYPE_XBOXONE }, { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
@@ -159,7 +160,7 @@ static const struct xpad_device { { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE }, - { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, + { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SHARE_BUTTON | MAP_SHARE_OFFSET, XTYPE_XBOXONE }, { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
@@ -211,7 +212,7 @@ static const struct xpad_device { { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 }, { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 }, { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 }, - { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE }, + { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE }, { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX }, { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
@@ -390,7 +391,7 @@ static const struct xpad_device { { 0x2dc8, 0x6001, "8BitDo SN30 Pro", 0, XTYPE_XBOX360 }, { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, { 0x2e24, 0x1688, "Hyperkin X91 X-Box One pad", 0, XTYPE_XBOXONE }, - { 0x2e95, 0x0504, "SCUF Gaming Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, + { 0x2e95, 0x0504, "SCUF Gaming Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
@@ -1027,7 +1028,7 @@ static void xpad360w_process_packet(stru* The report format was gleaned from * https://github.com/kylelemons/xbox/blob/master/xbox.go */ -static void xpadone_process_packet (struct usb_xpad *xpad,u16 cmd,unsigned char *data) +static void xpadone_process_packet (struct usb_xpad *xpad,u16 cmd,unsigned char *data,u32 len) {struct input_dev *dev = xpad->dev;bool do_sync = false;
@@ -1068,8 +1069,12 @@ static void xpadone_process_packet(struc/* menu/view buttons */ input_report_key (dev,BTN_START , data[4 ] &BIT (2 ));input_report_key (dev,BTN_SELECT , data[4 ] &BIT (3 )); -if (xpad->mapping &MAP_SELECT_BUTTON ) -input_report_key (dev,KEY_RECORD , data[22 ] &BIT (0 )); +if (xpad->mapping &MAP_SHARE_BUTTON ) { +if (xpad->mapping &MAP_SHARE_OFFSET ) +input_report_key (dev,KEY_RECORD , data[len -26 ] &BIT (0 )); +else +input_report_key (dev,KEY_RECORD , data[len -18 ] &BIT (0 )); + }/* buttons A,B,X,Y */ input_report_key (dev,BTN_A , data[4 ] &BIT (4 ));
@@ -1217,7 +1222,7 @@ static void xpad_irq_in(struct urb *urb)xpad360w_process_packet (xpad,0 , xpad->idata);break ;case XTYPE_XBOXONE : -xpadone_process_packet (xpad,0 , xpad->idata); +xpadone_process_packet (xpad,0 , xpad->idata, urb->actual_length);break ;default :xpad_process_packet (xpad,0 , xpad->idata);
@@ -1974,7 +1979,7 @@ static int xpad_init_input(struct usb_xp xpad->xtype == XTYPE_XBOXONE) { for (i = 0; xpad360_btn[i] >= 0; i++) input_set_capability(input_dev, EV_KEY, xpad360_btn[i]); - if (xpad->mapping & MAP_SELECT_BUTTON) + if (xpad->mapping & MAP_SHARE_BUTTON) input_set_capability(input_dev, EV_KEY, KEY_RECORD); } else {for (i =0 ; xpad_btn[i] >=0 ; i++)
Greg Kroah-Hartman
maintainerPATCH 58/184 Input: xpad - add support for 8BitDo Ultimate 2 Wireless Controller
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lode Willems <[email protected]>
commit 22cd66a5db56a07d9e621367cb4d16ff0f6baf56 upstream.
This patch adds support for the 8BitDo Ultimate 2 Wireless Controller. Tested using the wireless dongle and plugged in.
--- drivers/input/joystick/xpad.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/joystick/xpad.c +1 -0
@@ -388,6 +388,7 @@ static const struct xpad_device { { 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, { 0x2dc8, 0x3109, "8BitDo Ultimate Wireless Bluetooth", 0, XTYPE_XBOX360 }, { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, + { 0x2dc8, 0x310b, "8BitDo Ultimate 2 Wireless Controller", 0, XTYPE_XBOX360 }, { 0x2dc8, 0x6001, "8BitDo SN30 Pro", 0, XTYPE_XBOX360 }, { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, { 0x2e24, 0x1688, "Hyperkin X91 X-Box One pad", 0, XTYPE_XBOXONE },
Greg Kroah-Hartman
maintainerPATCH 59/184 Input: xpad - fix two controller table values
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
commit d05a424bea9aa3435009d5c462055008cc1545d8 upstream.
Two controllers -- Mad Catz JOYTECH NEO SE Advanced and PDP Mirror's Edge Official -- were missing the value of the mapping field, and thus wouldn't detect properly.
--- drivers/input/joystick/xpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/input/joystick/xpad.c +2 -2
@@ -206,7 +206,7 @@ static const struct xpad_device { { 0x0738, 0x9871, "Mad Catz Portable Drum", 0, XTYPE_XBOX360 }, { 0x0738, 0xb726, "Mad Catz Xbox controller - MW2", 0, XTYPE_XBOX360 }, { 0x0738, 0xb738, "Mad Catz MVC2TE Stick 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, + { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", 0, XTYPE_XBOX360 }, { 0x0738, 0xcb02, "Saitek Cyborg Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 }, { 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 }, { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
@@ -241,7 +241,7 @@ static const struct xpad_device { { 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0147, "PDP Marvel Xbox One Controller", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, - { 0x0e6f, 0x015d, "PDP Mirror's Edge Official Wired Controller for Xbox One", XTYPE_XBOXONE }, + { 0x0e6f, 0x015d, "PDP Mirror's Edge Official Wired Controller for Xbox One", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0162, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0163, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
Greg Kroah-Hartman
maintainerPATCH 60/184 Input: synaptics - enable InterTouch on Dynabook Portege X30-D
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manuel Fombuena <[email protected]>
commit 6d7ea0881000966607772451b789b5fb5766f11d upstream.
[ 5.989588] psmouse serio1: synaptics: Your touchpad (PNP: TOS0213 PNP0f03) says it can support a different bus. If i2c-hid and hid-rmi are not used, you might want to try setting psmouse.synaptics_intertouch to 1 and report this to [email protected]. [ 6.039923] psmouse serio1: synaptics: Touchpad model: 1, fw: 9.32, id: 0x1e2a1, caps: 0xf00223/0x840300/0x12e800/0x52d884, board id: 3322, fw id: 2658004
The board is labelled TM3322.
Present on the Toshiba / Dynabook Portege X30-D and possibly others.
Confirmed working well with psmouse.synaptics_intertouch=1 and local build.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -194,6 +194,7 @@ static const char * const smbus_pnp_ids["SYN3221" ,/* HP 15-ay000 */ "SYN323d" ,/* HP Spectre X360 13-w013dx */ "SYN3257" ,/* HP Envy 13-ad105ng */ +"TOS0213" ,/* Dynabook Portege X30-D */ NULL };
Greg Kroah-Hartman
maintainerPATCH 61/184 Input: synaptics - enable InterTouch on Dynabook Portege X30L-G
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Garg <[email protected]>
commit 47d768b32e644b56901bb4bbbdb1feb01ea86c85 upstream.
Enable InterTouch mode on Dynabook Portege X30L-G by adding "TOS01f6" to the list of SMBus-enabled variants.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -194,6 +194,7 @@ static const char * const smbus_pnp_ids["SYN3221" ,/* HP 15-ay000 */ "SYN323d" ,/* HP Spectre X360 13-w013dx */ "SYN3257" ,/* HP Envy 13-ad105ng */ +"TOS01f6" ,/* Dynabook Portege X30L-G */ "TOS0213" ,/* Dynabook Portege X30-D */ NULL };
Greg Kroah-Hartman
maintainerPATCH 62/184 Input: synaptics - enable InterTouch on Dell Precision M3800
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Garg <[email protected]>
commit a609cb4cc07aa9ab8f50466622814356c06f2c17 upstream.
Enable InterTouch mode on Dell Precision M3800 by adding "DLL060d" to the list of SMBus-enabled variants.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -163,6 +163,7 @@ static const char * const topbuttonpad_pstatic const char *const smbus_pnp_ids[] = {/* all of the topbuttonpad_pnp_ids are valid, we just add some extras */ +"DLL060d" ,/* Dell Precision M3800 */ "LEN0048" ,/* X1 Carbon 3 */ "LEN0046" ,/* X250 */ "LEN0049" ,/* Yoga 11e */
Greg Kroah-Hartman
maintainerPATCH 63/184 Input: synaptics - enable SMBus for HP Elitebook 850 G1
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit f04f03d3e99bc8f89b6af5debf07ff67d961bc23 upstream.
The kernel reports that the touchpad for this device can support SMBus mode.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -190,6 +190,7 @@ static const char * const smbus_pnp_ids["LEN2054" ,/* E480 */ "LEN2055" ,/* E580 */ "LEN2068" ,/* T14 Gen 1 */ +"SYN3003" ,/* HP EliteBook 850 G1 */ "SYN3015" ,/* HP EliteBook 840 G2 */ "SYN3052" ,/* HP EliteBook 840 G4 */ "SYN3221", /* HP 15-ay000 */
Greg Kroah-Hartman
maintainerPATCH 64/184 Input: synaptics - enable InterTouch on TUXEDO InfinityBook Pro 14 v5
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Garg <[email protected]>
commit 2abc698ac77314e0de5b33a6d96a39c5159d88e4 upstream.
Enable InterTouch mode on TUXEDO InfinityBook Pro 14 v5 by adding "SYN1221" to the list of SMBus-enabled variants.
Add support for InterTouch on SYN1221 by adding it to the list of SMBus-enabled variants.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -190,6 +190,7 @@ static const char * const smbus_pnp_ids["LEN2054" ,/* E480 */ "LEN2055" ,/* E580 */ "LEN2068" ,/* T14 Gen 1 */ +"SYN1221" ,/* TUXEDO InfinityBook Pro 14 v5 */ "SYN3003" ,/* HP EliteBook 850 G1 */ "SYN3015" ,/* HP EliteBook 840 G2 */ "SYN3052", /* HP EliteBook 840 G4 */
Greg Kroah-Hartman
maintainerPATCH 65/184 rust: clean Rust 1.88.0s `unnecessary_transmutes` lint
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 7129ea6e242b00938532537da41ddf5fa3e21471 upstream.
Starting with Rust 1.88.0 (expected 2025-06-26) [1][2], rustc may introduce a new lint that catches unnecessary transmutes, e.g.:
error: unnecessary transmute
--> rust/uapi/uapi_generated.rs:23242:18
|
23242 | unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `(self._bitfield_1.get(0usize, 1u8) as u8 == 1)`
|
= note: `-D unnecessary-transmutes` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unnecessary_transmutes)]`There are a lot of them (at least 300), but luckily they are all in bindgen-generated code.
Thus clean all up by allowing it there.
Since unknown lints trigger a lint itself in older compilers, do it conditionally so that we can keep the unknown_lints lint enabled.
--- init/Kconfig | 3 +++ rust/bindings/lib.rs | 1 + rust/uapi/lib.rs | 1 + 3 files changed, 5 insertions(+)
init/Kconfig +3 -0
@@ -134,6 +134,9 @@ config LD_CAN_USE_KEEP_IN_OVERLAY # https://github.com/llvm/llvm-project/pull/130661 def_bool LD_IS_BFD || LLD_VERSION >= 210000 +config RUSTC_HAS_UNNECESSARY_TRANSMUTES + def_bool RUSTC_VERSION >= 108800 + config PAHOLE_VERSION int default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
rust/bindings/lib.rs +1 -0
@@ -26,6 +26,7 @@#[allow(dead_code)] #[allow(clippy::undocumented_unsafe_blocks)] +#[cfg_attr( CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES , allow(unnecessary_transmutes))] mod bindings_raw {// Manual definition for blocklisted types. type __kernel_size_t =usize ;
rust/uapi/lib.rs +1 -0
@@ -24,6 +24,7 @@ unreachable_pub, unsafe_op_in_unsafe_fn )] +#![cfg_attr( CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES , allow(unnecessary_transmutes))] // Manual definition of blocklisted types. type __kernel_size_t =usize ;
Greg Kroah-Hartman
maintainerPATCH 66/184 objtool/rust: add one more `noreturn` Rust function for Rust 1.87.0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 19f5ca461d5fc09bdf93a9f8e4bd78ed3a49dc71 upstream.
Starting with Rust 1.87.0 (expected 2025-05-15), objtool may report:
rust/core.o: warning: objtool: _R..._4core9panicking9panic_fmt() falls through to next function _R..._4core9panicking18panic_nounwind_fmt()
rust/core.o: warning: objtool: _R..._4core9panicking18panic_nounwind_fmt() falls through to next function _R..._4core9panicking5panic()
The reason is that rust_begin_unwind is now mangled:
_R..._7___rustc17rust_begin_unwind
Thus add the mangled one to the list so that objtool knows it is actually noreturn.
See commit 56d680dd23c3 ("objtool/rust: list noreturn Rust functions") for more details.
Alternatively, we could remove the fixed one in noreturn.h and relax this test to cover both, but it seems best to be strict as long as we can.
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -219,6 +219,7 @@ static bool is_rust_noreturn(const strucstr_ends_with (func->name,"_4core9panicking19assert_failed_inner" ) ||str_ends_with (func->name,"_4core9panicking30panic_null_pointer_dereference" ) ||str_ends_with (func->name,"_4core9panicking36panic_misaligned_pointer_dereference" ) || +str_ends_with (func->name,"_7___rustc17rust_begin_unwind" ) ||strstr (func->name,"_4core9panicking13assert_failed" ) || strstr(func->name, "_4core9panicking11panic_const24panic_const_") || (strstr(func->name, "_4core5slice5index24slice_") &&
Greg Kroah-Hartman
maintainerPATCH 67/184 rust: clean Rust 1.88.0s warning about `clippy::disallowed_macros` configuration
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit c016722fd57551f8a6fcf472c9d2bcf2130ea0ec upstream.
Starting with Rust 1.88.0 (expected 2025-06-26) [1], Clippy may start warning about paths that do not resolve in the disallowed_macros configuration:
warning: `kernel::dbg` does not refer to an existing macro
--> .clippy.toml:10:5
|
10 | { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^This is a lint we requested at [2], due to the trouble debugging the lint due to false negatives (e.g. [3]), which we use to emulate clippy::dbg_macro [4]. See commit 8577c9dca799 ("rust: replace clippy::dbg_macro with disallowed_macros") for more details.
Given the false negatives are not resolved yet, it is expected that Clippy complains about not finding this macro.
Thus, until the false negatives are fixed (and, even then, probably we will need to wait for the MSRV to raise enough), use the escape hatch to allow an invalid path.
--- .clippy.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
.clippy.toml +1 -1
@@ -5,5 +5,5 @@ check-private-items = true disallowed-macros = [ # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303. - { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" }, + { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool", allow-invalid = true }, ]
Greg Kroah-Hartman
maintainerPATCH 68/184 staging: iio: adc: ad7816: Correct conditional logic for store mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Shahrouzi <[email protected]>
commit 2e922956277187655ed9bedf7b5c28906e51708f upstream.
The mode setting logic in ad7816_store_mode was reversed due to incorrect handling of the strcmp return value. strcmp returns 0 on match, so the if (strcmp(buf, "full")) block executed when the input was not "full".
This resulted in "full" setting the mode to AD7816_PD (power-down) and other inputs setting it to AD7816_FULL.
Fix this by checking it against 0 to correctly check for "full" and "power-down", mapping them to AD7816_FULL and AD7816_PD respectively.
--- drivers/staging/iio/adc/ad7816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/iio/adc/ad7816.c +1 -1
@@ -136,7 +136,7 @@ static ssize_t ad7816_store_mode(structstruct iio_dev *indio_dev =dev_to_iio_dev (dev);struct ad7816_chip_info *chip =iio_priv (indio_dev); -if (strcmp (buf,"full" )) { +if (strcmp (buf,"full" ) ==0 ) {gpiod_set_value (chip->rdwr_pin,1 ); chip->mode =AD7816_FULL ; }else {
Greg Kroah-Hartman
maintainerPATCH 69/184 staging: bcm2835-camera: Initialise dev in v4l2_dev
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Stevenson <[email protected]>
commit 98698ca0e58734bc5c1c24e5bbc7429f981cd186 upstream.
Commit 42a2f6664e18 ("staging: vc04_services: Move global g_state to vchiq_state") changed mmal_init to pass dev->v4l2_dev.dev to vchiq_mmal_init, however nothing iniitialised dev->v4l2_dev, so we got a NULL pointer dereference.
Set dev->v4l2_dev.dev during bcm2835_mmal_probe. The device pointer could be passed into v4l2_device_register to set it, however that also has other effects that would need additional changes.
--- drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +1 -0
@@ -1902,6 +1902,7 @@ static int bcm2835_mmal_probe(struct vch __func__, ret); goto free_dev; } + dev->v4l2_dev.dev = &device->dev;/* setup v4l controls */ ret =bcm2835_mmal_init_controls (dev, &dev->ctrl_handler);
Greg Kroah-Hartman
maintainerPATCH 70/184 staging: axis-fifo: Remove hardware resets for user errors
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Shahrouzi <[email protected]>
commit c6e8d85fafa7193613db37da29c0e8d6e2515b13 upstream.
The axis-fifo driver performs a full hardware reset (via reset_ip_core()) in several error paths within the read and write functions. This reset flushes both TX and RX FIFOs and resets the AXI-Stream links.
Allow the user to handle the error without causing hardware disruption or data loss in other FIFO paths.
--- drivers/staging/axis-fifo/axis-fifo.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/staging/axis-fifo/axis-fifo.c +3 -8
@@ -393,16 +393,14 @@ static ssize_t axis_fifo_read(struct fil bytes_available =ioread32 (fifo->base_addr +XLLF_RLR_OFFSET );if (!bytes_available) { -dev_err (fifo->dt_device,"received a packet of length 0 - fifo core will be reset\n" ); -reset_ip_core (fifo); +dev_err (fifo->dt_device,"received a packet of length 0\n" ); ret = -EIO ; goto end_unlock; }if (bytes_available > len) { -dev_err (fifo->dt_device,"user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n" , +dev_err (fifo->dt_device,"user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n" , bytes_available, len); -reset_ip_core (fifo); ret = -EINVAL ; goto end_unlock; }
@@ -411,8 +409,7 @@ static ssize_t axis_fifo_read(struct fil/* this probably can't happen unless IP * registers were previously mishandled */ -dev_err (fifo->dt_device,"received a packet that isn't word-aligned - fifo core will be reset\n" ); -reset_ip_core (fifo); +dev_err (fifo->dt_device,"received a packet that isn't word-aligned\n" ); ret = -EIO ; goto end_unlock; }
@@ -433,7 +430,6 @@ static ssize_t axis_fifo_read(struct filif (copy_to_user (buf + copied *sizeof (u32), tmp_buf, copy *sizeof (u32))) { -reset_ip_core (fifo); ret = -EFAULT ; goto end_unlock; }
@@ -542,7 +538,6 @@ static ssize_t axis_fifo_write(struct fiif (copy_from_user (tmp_buf, buf + copied *sizeof (u32), copy *sizeof (u32))) { -reset_ip_core (fifo); ret = -EFAULT ; goto end_unlock; }
Greg Kroah-Hartman
maintainerPATCH 71/184 staging: axis-fifo: Correct handling of tx_fifo_depth for size validation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Shahrouzi <[email protected]>
commit 2ca34b508774aaa590fc3698a54204706ecca4ba upstream.
Remove erroneous subtraction of 4 from the total FIFO depth read from device tree. The stored depth is for checking against total capacity, not initial vacancy. This prevented writes near the FIFO's full size.
The check performed just before data transfer, which uses live reads of the TDFV register to determine current vacancy, correctly handles the initial Depth - 4 hardware state and subsequent FIFO fullness.
--- drivers/staging/axis-fifo/axis-fifo.c | 3 --- 1 file changed, 3 deletions(-)
drivers/staging/axis-fifo/axis-fifo.c +0 -3
@@ -770,9 +770,6 @@ static int axis_fifo_parse_dt(struct axi goto end; } -/* IP sets TDFV to fifo depth - 4 so we will do the same */ - fifo->tx_fifo_depth -=4 ; - ret =get_dts_property (fifo,"xlnx,use-rx-data" , &fifo->has_rx_fifo);if (ret) {dev_err (fifo->dt_device,"missing xlnx,use-rx-data property\n" );
Greg Kroah-Hartman
maintainerPATCH 72/184 x86/mm: Eliminate window where TLB flushes may be inadvertently skipped
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Hansen <[email protected]>
commit fea4e317f9e7e1f449ce90dedc27a2d2a95bee5a upstream.
tl;dr: There is a window in the mm switching code where the new CR3 is set and the CPU should be getting TLB flushes for the new mm. But should_flush_tlb() has a bug and suppresses the flush. Fix it by widening the window where should_flush_tlb() sends an IPI.
Long Version:
=== History ===
There were a few things leading up to this.
First, updating mm_cpumask() was observed to be too expensive, so it was made lazier. But being lazy caused too many unnecessary IPIs to CPUs due to the now-lazy mm_cpumask(). So code was added to cull mm_cpumask() periodically[2]. But that culling was a bit too aggressive and skipped sending TLB flushes to CPUs that need them. So here we are again.
=== Problem ===
The too-aggressive code in should_flush_tlb() strikes in this window:
// Turn on IPIs for this CPU/mm combination, but only
// if should_flush_tlb() agrees:
cpumask_set_cpu(cpu, mm_cpumask(next));
next_tlb_gen = atomic64_read(&next->context.tlb_gen);
choose_new_asid(next, next_tlb_gen, &new_asid, &need_flush);
load_new_mm_cr3(need_flush);
// ^ After 'need_flush' is set to false, IPIs *MUST*
// be sent to this CPU and not be ignored.
this_cpu_write(cpu_tlbstate.loaded_mm, next);
// ^ Not until this point does should_flush_tlb()
// become true!should_flush_tlb() will suppress TLB flushes between load_new_mm_cr3() and writing to 'loaded_mm', which is a window where they should not be suppressed. Whoops.
=== Solution ===
Thankfully, the fuzzy "just about to write CR3" window is already marked with loaded_mm==LOADED_MM_SWITCHING. Simply checking for that state in should_flush_tlb() is sufficient to ensure that the CPU is targeted with an IPI.
This will cause more TLB flush IPIs. But the window is relatively small and I do not expect this to cause any kind of measurable performance impact.
Update the comment where LOADED_MM_SWITCHING is written since it grew yet another user.
Peter Z also raised a concern that should_flush_tlb() might not observe 'loaded_mm' and 'is_lazy' in the same order that switch_mm_irqs_off() writes them. Add a barrier to ensure that they are observed in the order they are written.
--- arch/x86/mm/tlb.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
arch/x86/mm/tlb.c +21 -2
@@ -624,7 +624,11 @@ void switch_mm_irqs_off(struct mm_structchoose_new_asid (next, next_tlb_gen, &new_asid, &need_flush); -/* Let nmi_uaccess_okay() know that we're changing CR3. */ +/* +* Indicate that CR3 is about to change. nmi_uaccess_okay() +* and others are sensitive to the window where mm_cpumask(), +* CR3 and cpu_tlbstate.loaded_mm are not all in sync. +*/ this_cpu_write (cpu_tlbstate.loaded_mm,LOADED_MM_SWITCHING );barrier (); }
@@ -895,8 +899,16 @@ done:static bool should_flush_tlb (int cpu,void *data) { +struct mm_struct *loaded_mm =per_cpu (cpu_tlbstate.loaded_mm, cpu);struct flush_tlb_info *info = data; +/* +* Order the 'loaded_mm' and 'is_lazy' against their +* write ordering in switch_mm_irqs_off(). Ensure +* 'is_lazy' is at least as new as 'loaded_mm'. +*/ +smp_rmb (); +/* Lazy TLB will get flushed at the next context switch. */ if (per_cpu (cpu_tlbstate_shared.is_lazy, cpu))return false;
@@ -905,8 +917,15 @@ static bool should_flush_tlb(int cpu, voif (!info->mm)return true; +/* +* While switching, the remote CPU could have state from +* either the prev or next mm. Assume the worst and flush. +*/ +if (loaded_mm ==LOADED_MM_SWITCHING ) +return true; +/* The target mm is loaded, and the CPU is not lazy. */ -if (per_cpu (cpu_tlbstate.loaded_mm, cpu) == info->mm) +if (loaded_mm == info->mm)return true;/* In cpumask, but not the loaded mm? Periodically remove by flushing. */
Greg Kroah-Hartman
maintainerPATCH 73/184 mm: fix folio_pte_batch() on XEN PV
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Vaněk <[email protected]>
commit 7b08b74f3d99f6b801250683c751d391128799ec upstream.
On XEN PV, folio_pte_batch() can incorrectly batch beyond the end of a folio due to a corner case in pte_advance_pfn(). Specifically, when the PFN following the folio maps to an invalidated MFN,
expected_pte = pte_advance_pfn(expected_pte, nr);
produces a pte_none(). If the actual next PTE in memory is also pte_none(), the pte_same() succeeds,
if (!pte_same(pte, expected_pte)) break;
the loop is not broken, and batching continues into unrelated memory.
For example, with a 4-page folio, the PTE layout might look like this:
[ 53.465673] [ T2552] folio_pte_batch: printing PTE values at addr=0x7f1ac9dc5000 [ 53.465674] [ T2552] PTE[453] = 000000010085c125 [ 53.465679] [ T2552] PTE[454] = 000000010085d125 [ 53.465682] [ T2552] PTE[455] = 000000010085e125 [ 53.465684] [ T2552] PTE[456] = 000000010085f125 [ 53.465686] [ T2552] PTE[457] = 0000000000000000 <-- not present [ 53.465689] [ T2552] PTE[458] = 0000000101da7125
pte_advance_pfn(PTE[456]) returns a pte_none() due to invalid PFN->MFN mapping. The next actual PTE (PTE[457]) is also pte_none(), so the loop continues and includes PTE[457] in the batch, resulting in 5 batched entries for a 4-page folio. This triggers the following warning:
[ 53.465751] [ T2552] page: refcount:85 mapcount:20 mapping:ffff88813ff4f6a8 index:0x110 pfn:0x10085c [ 53.465754] [ T2552] head: order:2 mapcount:80 entire_mapcount:0 nr_pages_mapped:4 pincount:0 [ 53.465756] [ T2552] memcg:ffff888003573000 [ 53.465758] [ T2552] aops:0xffffffff8226fd20 ino:82467c dentry name(?):"libc.so.6" [ 53.465761] [ T2552] flags: 0x2000000000416c(referenced|uptodate|lru|active|private|head|node=0|zone=2) [ 53.465764] [ T2552] raw: 002000000000416c ffffea0004021f08 ffffea0004021908 ffff88813ff4f6a8 [ 53.465767] [ T2552] raw: 0000000000000110 ffff888133d8bd40 0000005500000013 ffff888003573000 [ 53.465768] [ T2552] head: 002000000000416c ffffea0004021f08 ffffea0004021908 ffff88813ff4f6a8 [ 53.465770] [ T2552] head: 0000000000000110 ffff888133d8bd40 0000005500000013 ffff888003573000 [ 53.465772] [ T2552] head: 0020000000000202 ffffea0004021701 000000040000004f 00000000ffffffff [ 53.465774] [ T2552] head: 0000000300000003 8000000300000002 0000000000000013 0000000000000004 [ 53.465775] [ T2552] page dumped because: VM_WARN_ON_FOLIO((_Generic((page + nr_pages - 1), const struct page *: (const struct folio *)_compound_head(page + nr_pages - 1), struct page *: (struct folio *)_compound_head(page + nr_pages - 1))) != folio)
Original code works as expected everywhere, except on XEN PV, where pte_advance_pfn() can yield a pte_none() after balloon inflation due to MFNs invalidation. In XEN, pte_advance_pfn() ends up calling __pte()->xen_make_pte()->pte_pfn_to_mfn(), which returns pte_none() when mfn == INVALID_P2M_ENTRY.
The pte_pfn_to_mfn() documents that nastiness:
If there's no mfn for the pfn, then just create an empty non-present pte. Unfortunately this loses information about the original pfn, so pte_mfn_to_pfn is asymmetric.
While such hacks should certainly be removed, we can do better in folio_pte_batch() and simply check ahead of time how many PTEs we can possibly batch in our folio.
This way, we can not only fix the issue but cleanup the code: removing the pte_pfn() check inside the loop body and avoiding end_ptr comparison + arithmetic.
--- mm/internal.h | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-)
mm/internal.h +11 -16
@@ -204,11 +204,9 @@ static inline int folio_pte_batch(struct pte_t *start_ptep, pte_t pte, int max_nr, fpb_t flags, bool *any_writable, bool *any_young, bool *any_dirty) { - unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio); -const pte_t *end_ptep = start_ptep + max_nr; pte_t expected_pte, *ptep;bool writable, young, dirty; -int nr; +int nr, cur_nr;if (any_writable) *any_writable = false;
@@ -221,11 +219,15 @@ static inline int folio_pte_batch(structVM_WARN_ON_FOLIO (!folio_test_large (folio) || max_nr <1 , folio);VM_WARN_ON_FOLIO (page_folio (pfn_to_page (pte_pfn (pte))) != folio, folio); +/* Limit max_nr to the actual remaining PFNs in the folio we could batch. */ + max_nr = min_t(unsigned long, max_nr, +folio_pfn (folio) +folio_nr_pages (folio) -pte_pfn (pte)); + nr =pte_batch_hint (start_ptep, pte); expected_pte =__pte_batch_clear_ignored (pte_advance_pfn (pte, nr), flags); ptep = start_ptep + nr; -while (ptep < end_ptep) { +while (nr < max_nr) { pte =ptep_get (ptep);if (any_writable) writable = !!pte_write (pte);
@@ -238,14 +240,6 @@ static inline int folio_pte_batch(structif (!pte_same (pte, expected_pte))break ; -/* -* Stop immediately once we reached the end of the folio. In -* corner cases the next PFN might fall into a different -* folio. -*/ -if (pte_pfn (pte) >= folio_end_pfn) -break ; -if (any_writable) *any_writable |= writable;if (any_young)
@@ -253,12 +247,13 @@ static inline int folio_pte_batch(structif (any_dirty) *any_dirty |= dirty; - nr =pte_batch_hint (ptep, pte); - expected_pte =pte_advance_pfn (expected_pte, nr); - ptep += nr; + cur_nr =pte_batch_hint (ptep, pte); + expected_pte =pte_advance_pfn (expected_pte, cur_nr); + ptep += cur_nr; + nr += cur_nr; } -return min (ptep - start_ptep, max_nr); +return min (nr, max_nr); }/**
Greg Kroah-Hartman
maintainerPATCH 74/184 mm: vmalloc: support more granular vrealloc() sizing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit a0309faf1cb0622cac7c820150b7abf2024acff5 upstream.
Introduce struct vm_struct::requested_size so that the requested (re)allocation size is retained separately from the allocated area size. This means that KASAN will correctly poison the correct spans of requested bytes. This also means we can support growing the usable portion of an allocation that can already be supported by the existing area's existing allocation.
--- include/linux/vmalloc.h | 1 + mm/vmalloc.c | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-)
include/linux/vmalloc.h +1 -0
@@ -61,6 +61,7 @@ struct vm_struct {unsigned int nr_pages;phys_addr_t phys_addr;const void *caller; +unsigned long requested_size; };struct vmap_area {
mm/vmalloc.c +24 -7
@@ -1940,7 +1940,7 @@ static inline void setup_vmalloc_vm(stru { vm->flags = flags; vm->addr = (void *)va->va_start; - vm->size =va_size (va); + vm->size = vm->requested_size =va_size (va); vm->caller = caller; va->vm = vm; }
@@ -3128,6 +3128,7 @@ static struct vm_struct *__get_vm_area_n area->flags = flags; area->caller = caller; + area->requested_size = requested_size; va =alloc_vmap_area (size, align, start, end, node, gfp_mask,0 , area);if (IS_ERR (va)) {
@@ -4067,6 +4068,8 @@ EXPORT_SYMBOL(vzalloc_node_noprof);*/ void *vrealloc_noprof (const void *p,size_t size,gfp_t flags) { +struct vm_struct *vm =NULL ; +size_t alloced_size =0 ;size_t old_size =0 ;void *n;
@@ -4076,15 +4079,17 @@ void *vrealloc_noprof(const void *p, siz }if (p) { -struct vm_struct *vm; - vm =find_vm_area (p);if (unlikely (!vm)) {WARN (1 ,"Trying to vrealloc() nonexistent vm area (%p)\n" , p);return NULL ; } - old_size =get_vm_area_size (vm); + alloced_size =get_vm_area_size (vm); + old_size = vm->requested_size; +if (WARN (alloced_size < old_size, +"vrealloc() has mismatched area vs requested sizes (%p)\n" , p)) +return NULL ; }/*
@@ -4092,14 +4097,26 @@ void *vrealloc_noprof(const void *p, siz* would be a good heuristic for when to shrink the vm_area? */ if (size <= old_size) { -/* Zero out spare memory. */ -if (want_init_on_alloc (flags)) +/* Zero out "freed" memory. */ +if (want_init_on_free ())memset ((void *)p + size,0 , old_size - size); + vm->requested_size = size;kasan_poison_vmalloc (p + size, old_size - size); -kasan_unpoison_vmalloc (p, size,KASAN_VMALLOC_PROT_NORMAL );return (void *)p; } +/* +* We already have the bytes available in the allocation; use them. +*/ +if (size <= alloced_size) { +kasan_unpoison_vmalloc (p + old_size, size - old_size, +KASAN_VMALLOC_PROT_NORMAL ); +/* Zero out "alloced" memory. */ +if (want_init_on_alloc (flags)) +memset ((void *)p + old_size,0 , size - old_size); + vm->requested_size = size; + } +/* TODO: Grow the vm_area, i.e. allocate and map additional pages. */ n =__vmalloc_noprof (size, flags);if (!n)
Greg Kroah-Hartman
maintainerPATCH 75/184 mm/huge_memory: fix dereferencing invalid pmd migration entry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gavin Guo <[email protected]>
commit be6e843fc51a584672dfd9c4a6a24c8cb81d5fb7 upstream.
When migrating a THP, concurrent access to the PMD migration entry during a deferred split scan can lead to an invalid address access, as illustrated below. To prevent this invalid access, it is necessary to check the PMD migration entry and return early. In this context, there is no need to use pmd_to_swp_entry and pfn_swap_entry_to_page to verify the equality of the target folio. Since the PMD migration entry is locked, it cannot be served as the target.
Mailing list discussion and explanation from Hugh Dickins: "An anon_vma lookup points to a location which may contain the folio of interest, but might instead contain another folio: and weeding out those other folios is precisely what the "folio != pmd_folio((*pmd)" check (and the "risk of replacing the wrong folio" comment a few lines above it) is for."
BUG: unable to handle page fault for address: ffffea60001db008 CPU: 0 UID: 0 PID: 2199114 Comm: tee Not tainted 6.14.0+ #4 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:split_huge_pmd_locked+0x3b5/0x2b60 Call Trace: <TASK> try_to_migrate_one+0x28c/0x3730 rmap_walk_anon+0x4f6/0x770 unmap_folio+0x196/0x1f0 split_huge_page_to_list_to_order+0x9f6/0x1560 deferred_split_scan+0xac5/0x12a0 shrinker_debugfs_scan_write+0x376/0x470 full_proxy_write+0x15c/0x220 vfs_write+0x2fc/0xcb0 ksys_write+0x146/0x250 do_syscall_64+0x6a/0x120 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The bug is found by syzkaller on an internal kernel, then confirmed on upstream.
--- mm/huge_memory.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
mm/huge_memory.c +8 -3
@@ -2879,6 +2879,8 @@ static void __split_huge_pmd_locked(struvoid split_huge_pmd_locked (struct vm_area_struct *vma,unsigned long address,pmd_t *pmd,bool freeze,struct folio *folio) { +bool pmd_migration =is_pmd_migration_entry (*pmd); +VM_WARN_ON_ONCE (folio && !folio_test_pmd_mappable (folio));VM_WARN_ON_ONCE (!IS_ALIGNED (address,HPAGE_PMD_SIZE ));VM_WARN_ON_ONCE (folio && !folio_test_locked (folio));
@@ -2889,9 +2891,12 @@ void split_huge_pmd_locked(struct vm_are* require a folio to check the PMD against. Otherwise, there * is a risk of replacing the wrong folio. */ -if (pmd_trans_huge (*pmd) ||pmd_devmap (*pmd) || -is_pmd_migration_entry (*pmd)) { -if (folio && folio !=pmd_folio (*pmd)) +if (pmd_trans_huge (*pmd) ||pmd_devmap (*pmd) || pmd_migration) { +/* +* Do not apply pmd_folio() to a migration entry; and folio lock +* guarantees that it must be of the wrong folio anyway. +*/ +if (folio && (pmd_migration || folio !=pmd_folio (*pmd)))return ;__split_huge_pmd_locked (vma, pmd, address, freeze); }
Greg Kroah-Hartman
maintainerPATCH 76/184 mm/userfaultfd: fix uninitialized output field for -EAGAIN race
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Xu <[email protected]>
commit 95567729173e62e0e60a1f8ad9eb2e1320a8ccac upstream.
While discussing some userfaultfd relevant issues recently, Andrea noticed a potential ABI breakage with -EAGAIN on almost all userfaultfd ioctl()s.
Quote from Andrea, explaining how -EAGAIN was processed, and how this should fix it (taking example of UFFDIO_COPY ioctl):
The "mmap_changing" and "stale pmd" conditions are already reported as -EAGAIN written in the copy field, this does not change it. This change removes the subnormal case that left copy.copy uninitialized and required apps to explicitly set the copy field to get deterministic behavior (which is a requirement contrary to the documentation in both the manpage and source code). In turn there's no alteration to backwards compatibility as result of this change because userland will find the copy field consistently set to -EAGAIN, and not anymore sometime -EAGAIN and sometime uninitialized.
Even then the change only can make a difference to non cooperative users of userfaultfd, so when UFFD_FEATURE_EVENT_* is enabled, which is not true for the vast majority of apps using userfaultfd or this unintended uninitialized field may have been noticed sooner.
Meanwhile, since this bug existed for years, it also almost affects all ioctl()s that was introduced later. Besides UFFDIO_ZEROPAGE, these also get affected in the same way:
- UFFDIO_CONTINUE
- UFFDIO_POISON
- UFFDIO_MOVE
This patch should have fixed all of them.
--- fs/userfaultfd.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
fs/userfaultfd.c +22 -6
@@ -1585,8 +1585,11 @@ static int userfaultfd_copy(struct userf user_uffdio_copy = (struct uffdio_copy __user *) arg; ret = -EAGAIN ; -if (atomic_read (&ctx->mmap_changing)) +if (unlikely (atomic_read (&ctx->mmap_changing))) { +if (unlikely (put_user (ret, &user_uffdio_copy->copy))) +return -EFAULT ; goto out; + } ret = -EFAULT ; if (copy_from_user(&uffdio_copy, user_uffdio_copy,
@@ -1641,8 +1644,11 @@ static int userfaultfd_zeropage(struct u user_uffdio_zeropage = (struct uffdio_zeropage __user *) arg; ret = -EAGAIN ; -if (atomic_read (&ctx->mmap_changing)) +if (unlikely (atomic_read (&ctx->mmap_changing))) { +if (unlikely (put_user (ret, &user_uffdio_zeropage->zeropage))) +return -EFAULT ; goto out; + } ret = -EFAULT ; if (copy_from_user(&uffdio_zeropage, user_uffdio_zeropage,
@@ -1744,8 +1750,11 @@ static int userfaultfd_continue(struct u user_uffdio_continue = (struct uffdio_continue __user *)arg; ret = -EAGAIN ; -if (atomic_read (&ctx->mmap_changing)) +if (unlikely (atomic_read (&ctx->mmap_changing))) { +if (unlikely (put_user (ret, &user_uffdio_continue->mapped))) +return -EFAULT ; goto out; + } ret = -EFAULT ; if (copy_from_user(&uffdio_continue, user_uffdio_continue,
@@ -1801,8 +1810,11 @@ static inline int userfaultfd_poison(str user_uffdio_poison = (struct uffdio_poison __user *)arg; ret = -EAGAIN ; -if (atomic_read (&ctx->mmap_changing)) +if (unlikely (atomic_read (&ctx->mmap_changing))) { +if (unlikely (put_user (ret, &user_uffdio_poison->updated))) +return -EFAULT ; goto out; + } ret = -EFAULT ; if (copy_from_user(&uffdio_poison, user_uffdio_poison,
@@ -1870,8 +1882,12 @@ static int userfaultfd_move(struct userf user_uffdio_move = (struct uffdio_move __user *) arg; -if (atomic_read (&ctx->mmap_changing)) -return -EAGAIN ; + ret = -EAGAIN ; +if (unlikely (atomic_read (&ctx->mmap_changing))) { +if (unlikely (put_user (ret, &user_uffdio_move->move))) +return -EFAULT ; + goto out; + } if (copy_from_user(&uffdio_move, user_uffdio_move,/* don't copy "move" last field */
Greg Kroah-Hartman
maintainerPATCH 77/184 selftests/mm: compaction_test: support platform with huge mount of memory
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Feng Tang <[email protected]>
commit ab00ddd802f80e31fc9639c652d736fe3913feae upstream.
When running mm selftest to verify mm patches, 'compaction_test' case failed on an x86 server with 1TB memory. And the root cause is that it has too much free memory than what the test supports.
The test case tries to allocate 100000 huge pages, which is about 200 GB for that x86 server, and when it succeeds, it expects it's large than 1/3 of 80% of the free memory in system. This logic only works for platform with 750 GB ( 200 / (1/3) / 80% ) or less free memory, and may raise false alarm for others.
Fix it by changing the fixed page number to self-adjustable number according to the real number of free memory.
--- tools/testing/selftests/mm/compaction_test.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
tools/testing/selftests/mm/compaction_test.c +14 -5
@@ -90,6 +90,8 @@ int check_compaction(unsigned long mem_fint compaction_index =0 ;char nr_hugepages[20 ] = {0 };char init_nr_hugepages[24 ] = {0 }; +char target_nr_hugepages[24 ] = {0 }; +int slen;snprintf (init_nr_hugepages,sizeof (init_nr_hugepages),"%lu" , initial_nr_hugepages);
@@ -106,11 +108,18 @@ int check_compaction(unsigned long mem_f goto out; } -/* Request a large number of huge pages. The Kernel will allocate -as much as it can */ -if (write (fd,"100000" , (6 *sizeof (char ))) != (6 *sizeof (char ))) { -ksft_print_msg ("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n" , -strerror (errno)); +/* +* Request huge pages for about half of the free memory. The Kernel +* will allocate as much as it can, and we expect it will get at least 1/3 +*/ + nr_hugepages_ul = mem_free / hugepage_size /2 ; +snprintf (target_nr_hugepages,sizeof (target_nr_hugepages), +"%lu" , nr_hugepages_ul); + + slen =strlen (target_nr_hugepages); +if (write (fd, target_nr_hugepages, slen) != slen) { +ksft_print_msg ("Failed to write %lu to /proc/sys/vm/nr_hugepages: %s\n" , + nr_hugepages_ul,strerror (errno)); goto close_fd; }
Greg Kroah-Hartman
maintainerPATCH 78/184 selftests/mm: fix a build failure on powerpc
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nysal Jan K.A. <[email protected]>
commit 8cf6ecb18baac867585fe1cba5dde6dbf3b6d29a upstream.
The compiler is unaware of the size of code generated by the ".rept" assembler directive. This results in the compiler emitting branch instructions where the offset to branch to exceeds the maximum allowed value, resulting in build failures like the following:
CC protection_keys
/tmp/ccypKWAE.s: Assembler messages:
/tmp/ccypKWAE.s:2073: Error: operand out of range (0x0000000000020158 is not between 0xffffffffffff8000 and 0x0000000000007ffc) /tmp/ccypKWAE.s:2509: Error: operand out of range (0x0000000000020130 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
Fix the issue by manually adding nop instructions using the preprocessor.
--- tools/testing/selftests/mm/pkey-powerpc.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
tools/testing/selftests/mm/pkey-powerpc.h +11 -1
@@ -102,8 +102,18 @@ void expect_fault_on_read_execonly_key(vreturn ; } +#define REPEAT_8 (s) s s s s s s s s +#define REPEAT_64 (s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) \ + REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) +#define REPEAT_512 (s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) \ + REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) +#define REPEAT_4096 (s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) \ + REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) +#define REPEAT_16384 (s) REPEAT_4096(s) REPEAT_4096(s) \ + REPEAT_4096(s) REPEAT_4096(s) +/* 4-byte instructions * 16384 = 64K page */ -#define __page_o_noops () asm(".rept 16384 ; nop; .endr") +#define __page_o_noops () asm(REPEAT_16384("nop\n"))void *malloc_pkey_with_mprotect_subpage (long size,int prot,u16 pkey) {
Greg Kroah-Hartman
maintainerPATCH 79/184 KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <[email protected]>
commit a2620f8932fa9fdabc3d78ed6efb004ca409019f upstream.
Previously, commit ed129ec9057f ("KVM: x86: forcibly leave nested mode on vCPU reset") addressed an issue where a triple fault occurring in nested mode could lead to use-after-free scenarios. However, the commit did not handle the analogous situation for System Management Mode (SMM).
This omission results in triggering a WARN when KVM forces a vCPU INIT after SHUTDOWN interception while the vCPU is in SMM. This situation was reprodused using Syzkaller by:
1) Creating a KVM VM and vCPU
2) Sending a KVM_SMI ioctl to explicitly enter SMM
3) Executing invalid instructions causing consecutive exceptions and eventually a triple fault
The issue manifests as follows:
WARNING: CPU: 0 PID: 25506 at arch/x86/kvm/x86.c:12112 kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 Modules linked in: CPU: 0 PID: 25506 Comm: syz-executor.0 Not tainted 6.1.130-syzkaller-00157-g164fe5dde9b6 #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 Call Trace: <TASK> shutdown_interception+0x66/0xb0 arch/x86/kvm/svm/svm.c:2136 svm_invoke_exit_handler+0x110/0x530 arch/x86/kvm/svm/svm.c:3395 svm_handle_exit+0x424/0x920 arch/x86/kvm/svm/svm.c:3457 vcpu_enter_guest arch/x86/kvm/x86.c:10959 [inline] vcpu_run+0x2c43/0x5a90 arch/x86/kvm/x86.c:11062 kvm_arch_vcpu_ioctl_run+0x50f/0x1cf0 arch/x86/kvm/x86.c:11283 kvm_vcpu_ioctl+0x570/0xf00 arch/x86/kvm/../../../virt/kvm/kvm_main.c:4122 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Architecturally, INIT is blocked when the CPU is in SMM, hence KVM's WARN() in kvm_vcpu_reset() to guard against KVM bugs, e.g. to detect improper emulation of INIT. SHUTDOWN on SVM is a weird edge case where KVM needs to do _something_ sane with the VMCB, since it's technically undefined, and INIT is the least awful choice given KVM's ABI.
So, double down on stuffing INIT on SHUTDOWN, and force the vCPU out of SMM to avoid any weirdness (and the WARN).
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- arch/x86/kvm/smm.c | 1 + arch/x86/kvm/svm/svm.c | 4 ++++ 2 files changed, 5 insertions(+)
arch/x86/kvm/smm.c +1 -0
@@ -131,6 +131,7 @@ void kvm_smm_changed(struct kvm_vcpu *vckvm_mmu_reset_context (vcpu); } +EXPORT_SYMBOL_GPL (kvm_smm_changed);void process_smi (struct kvm_vcpu *vcpu) {
arch/x86/kvm/svm/svm.c +4 -0
@@ -2222,6 +2222,10 @@ static int shutdown_interception(struct*/ if (!sev_es_guest (vcpu->kvm)) {clear_page (svm->vmcb); +#ifdef CONFIG_KVM_SMM +if (is_smm (vcpu)) +kvm_smm_changed (vcpu, false); +#endif kvm_vcpu_reset (vcpu, true); }
Greg Kroah-Hartman
maintainerPATCH 80/184 drm/amd/display: Shift DMUB AUX reply command if necessary
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 5a3846648c0523fd850b7f0aec78c0139453ab8b upstream.
[Why]
Defined value of dmub AUX reply command field get updated but didn't adjust dm receiving side accordingly.
[How]
Check the received reply command value to see if it's updated version or not. Adjust it if necessary.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +4 -1
@@ -12535,8 +12535,11 @@ int amdgpu_dm_process_dmub_aux_transfer_ goto out; } + payload->reply[0 ] = adev->dm.dmub_notify->aux_reply.command &0xF ; +if (adev->dm.dmub_notify->aux_reply.command &0xF0 ) +/* The reply is stored in the top nibble of the command. */ + payload->reply[0 ] = (adev->dm.dmub_notify->aux_reply.command >>4 ) &0xF ; - payload->reply[0 ] = adev->dm.dmub_notify->aux_reply.command;if (!payload->write && p_notify->aux_reply.length && (payload->reply[0 ] ==AUX_TRANSACTION_REPLY_AUX_ACK )) {
Greg Kroah-Hartman
maintainerPATCH 81/184 io_uring: ensure deferred completions are flushed for multishot
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 687b2bae0efff9b25e071737d6af5004e6e35af5 upstream.
Multishot normally uses io_req_post_cqe() to post completions, but when stopping it, it may finish up with a deferred completion. This is fine, except if another multishot event triggers before the deferred completions get flushed. If this occurs, then CQEs may get reordered in the CQ ring, as new multishot completions get posted before the deferred ones are flushed. This can cause confusion on the application side, if strict ordering is required for the use case.
When multishot posting via io_req_post_cqe(), flush any pending deferred completions first, if any.
--- io_uring/io_uring.c | 8 ++++++++ 1 file changed, 8 insertions(+)
io_uring/io_uring.c +8 -0
@@ -884,6 +884,14 @@ bool io_req_post_cqe(struct io_kiocb *restruct io_ring_ctx *ctx = req->ctx;bool posted; +/* +* If multishot has already posted deferred completions, ensure that +* those are flushed first before posting this one. If not, CQEs +* could get reordered. +*/ +if (!wq_list_empty (&ctx->submit_state.compl_reqs)) +__io_submit_flush_completions (ctx); +lockdep_assert (!io_wq_current_is_worker ());lockdep_assert_held (&ctx->uring_lock);
Greg Kroah-Hartman
maintainerPATCH 82/184 iio: adc: ad7606: fix serial register access
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Angelo Dureghello <[email protected]>
commit f083f8a21cc785ebe3a33f756a3fa3660611f8db upstream.
Fix register read/write routine as per datasheet.
When reading multiple consecutive registers, only the first one is read properly. This is due to missing chip select deassert and assert again between first and second 16bit transfer, as shown in the datasheet AD7606C-16, rev 0, figure 110.
--- drivers/iio/adc/ad7606_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad7606_spi.c +1 -1
@@ -127,7 +127,7 @@ static int ad7606_spi_reg_read(struct ad { .tx_buf = &st->d16[0], .len = 2, - .cs_change = 0, + .cs_change = 1, }, { .rx_buf = &st->d16[1], .len = 2,
Greg Kroah-Hartman
maintainerPATCH 83/184 iio: adc: rockchip: Fix clock initialization sequence
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Xue <[email protected]>
commit 839f81de397019f55161c5982d670ac19d836173 upstream.
clock_set_rate should be executed after devm_clk_get_enabled.
--- drivers/iio/adc/rockchip_saradc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/iio/adc/rockchip_saradc.c +8 -9
@@ -480,15 +480,6 @@ static int rockchip_saradc_probe(structif (info->reset)rockchip_saradc_reset_controller (info->reset); -/* -* Use a default value for the converter clock. -* This may become user-configurable in the future. -*/ - ret =clk_set_rate (info->clk, info->data->clk_rate); -if (ret <0 ) -return dev_err_probe (&pdev->dev, ret, -"failed to set adc clk rate\n" ); - ret =regulator_enable (info->vref);if (ret <0 ) return dev_err_probe(&pdev->dev, ret,
@@ -515,6 +506,14 @@ static int rockchip_saradc_probe(structif (IS_ERR (info->clk))return dev_err_probe (&pdev->dev,PTR_ERR (info->clk),"failed to get adc clock\n" ); +/* +* Use a default value for the converter clock. +* This may become user-configurable in the future. +*/ + ret =clk_set_rate (info->clk, info->data->clk_rate); +if (ret <0 ) +return dev_err_probe (&pdev->dev, ret, +"failed to set adc clk rate\n" );platform_set_drvdata (pdev, indio_dev);
Greg Kroah-Hartman
maintainerPATCH 84/184 iio: adis16201: Correct inclinometer channel resolution
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Shahrouzi <[email protected]>
commit 609bc31eca06c7408e6860d8b46311ebe45c1fef upstream.
The inclinometer channels were previously defined with 14 realbits. However, the ADIS16201 datasheet states the resolution for these output channels is 12 bits (Page 14, text description; Page 15, table 7).
Correct the realbits value to 12 to accurately reflect the hardware.
--- drivers/iio/accel/adis16201.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/accel/adis16201.c +2 -2
@@ -211,9 +211,9 @@ static const struct iio_chan_spec adis16 BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),ADIS_AUX_ADC_CHAN (ADIS16201_AUX_ADC_REG ,ADIS16201_SCAN_AUX_ADC ,0 ,12 ),ADIS_INCLI_CHAN (X ,ADIS16201_XINCL_OUT_REG ,ADIS16201_SCAN_INCLI_X , -BIT (IIO_CHAN_INFO_CALIBBIAS ),0 ,14 ), +BIT (IIO_CHAN_INFO_CALIBBIAS ),0 ,12 ),ADIS_INCLI_CHAN (Y ,ADIS16201_YINCL_OUT_REG ,ADIS16201_SCAN_INCLI_Y , -BIT (IIO_CHAN_INFO_CALIBBIAS ),0 ,14 ), +BIT (IIO_CHAN_INFO_CALIBBIAS ),0 ,12 ), IIO_CHAN_SOFT_TIMESTAMP(7) };
Greg Kroah-Hartman
maintainerPATCH 85/184 iio: imu: inv_mpu6050: align buffer for timestamp
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 1d2d8524eaffc4d9a116213520d2c650e07c9cc6 upstream.
Align the buffer used with iio_push_to_buffers_with_timestamp() to ensure the s64 timestamp is aligned to 8 bytes.
--- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +1 -1
@@ -50,7 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int iru16 fifo_count;u32 fifo_period;s64 timestamp; -u8 data[INV_MPU6050_OUTPUT_DATA_SIZE ]; +u8 data[INV_MPU6050_OUTPUT_DATA_SIZE ]__aligned(8) ;size_t i, nb;mutex_lock (&st->lock);
Greg Kroah-Hartman
maintainerPATCH 86/184 iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_fifo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Silvano Seva <[email protected]>
commit 159ca7f18129834b6f4c7eae67de48e96c752fc9 upstream.
Prevent st_lsm6dsx_read_fifo from falling in an infinite loop in case pattern_len is equal to zero and the device FIFO is not empty.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +3 -0
@@ -392,6 +392,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dif (fifo_status &cpu_to_le16 (ST_LSM6DSX_FIFO_EMPTY_MASK ))return 0 ; +if (!pattern_len) + pattern_len =ST_LSM6DSX_SAMPLE_SIZE ; + fifo_len = (le16_to_cpu (fifo_status) & fifo_diff_mask) *ST_LSM6DSX_CHAN_SIZE ; fifo_len = (fifo_len / pattern_len) * pattern_len;
Greg Kroah-Hartman
maintainerPATCH 87/184 iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_tagged_fifo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Silvano Seva <[email protected]>
commit 8114ef86e2058e2554111b793596f17bee23fa15 upstream.
Prevent st_lsm6dsx_read_tagged_fifo from falling in an infinite loop in case pattern_len is equal to zero and the device FIFO is not empty.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +3 -0
@@ -626,6 +626,9 @@ int st_lsm6dsx_read_tagged_fifo(struct sif (!fifo_len)return 0 ; +if (!pattern_len) + pattern_len =ST_LSM6DSX_TAGGED_SAMPLE_SIZE ; +for (read_len =0 ; read_len < fifo_len; read_len += pattern_len) { err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
Greg Kroah-Hartman
maintainerPATCH 88/184 drm/v3d: Add job to pending list if the reset was skipped
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <[email protected]>
commit 35e4079bf1a2570abffce6ababa631afcf8ea0e5 upstream.
When a CL/CSD job times out, we check if the GPU has made any progress since the last timeout. If so, instead of resetting the hardware, we skip the reset and let the timer get rearmed. This gives long-running jobs a chance to complete.
However, when timedout_job() is called, the job in question is removed from the pending list, which means it won't be automatically freed through free_job(). Consequently, when we skip the reset and keep the job running, the job won't be freed when it finally completes.
This situation leads to a memory leak, as exposed in [1] and [2].
Similarly to commit 704d3d60fec4 ("drm/etnaviv: don't block scheduler when GPU is still active"), this patch ensures the job is put back on the pending list when extending the timeout.
--- drivers/gpu/drm/v3d/v3d_sched.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/gpu/drm/v3d/v3d_sched.c +21 -7
@@ -728,11 +728,16 @@ v3d_gpu_reset_for_timeout(struct v3d_devreturn DRM_GPU_SCHED_STAT_NOMINAL ; } -/* If the current address or return address have changed, then the GPU -* has probably made progress and we should delay the reset. This -* could fail if the GPU got in an infinite loop in the CL, but that -* is pretty unlikely outside of an i-g-t testcase. -*/ +static void +v3d_sched_skip_reset (struct drm_sched_job *sched_job) +{ +struct drm_gpu_scheduler *sched = sched_job->sched; + +spin_lock (&sched->job_list_lock); +list_add (&sched_job->list, &sched->pending_list); +spin_unlock (&sched->job_list_lock); +} +static enum drm_gpu_sched_stat v3d_cl_job_timedout (struct drm_sched_job *sched_job,enum v3d_queue q,u32 *timedout_ctca,u32 *timedout_ctra)
@@ -742,9 +747,16 @@ v3d_cl_job_timedout(struct drm_sched_jobu32 ctca =V3D_CORE_READ (0 ,V3D_CLE_CTNCA (q));u32 ctra =V3D_CORE_READ (0 ,V3D_CLE_CTNRA (q)); +/* If the current address or return address have changed, then the GPU +* has probably made progress and we should delay the reset. This +* could fail if the GPU got in an infinite loop in the CL, but that +* is pretty unlikely outside of an i-g-t testcase. +*/ if (*timedout_ctca != ctca || *timedout_ctra != ctra) { *timedout_ctca = ctca; *timedout_ctra = ctra; + +v3d_sched_skip_reset (sched_job);return DRM_GPU_SCHED_STAT_NOMINAL ; }
@@ -784,11 +796,13 @@ v3d_csd_job_timedout(struct drm_sched_jostruct v3d_dev *v3d = job->base.v3d;u32 batches =V3D_CORE_READ (0 ,V3D_CSD_CURRENT_CFG4 (v3d->ver)); -/* If we've made progress, skip reset and let the timer get -* rearmed. +/* If we've made progress, skip reset, add the job to the pending +* list, and let the timer get rearmed. */ if (job->timedout_batches != batches) { job->timedout_batches = batches; + +v3d_sched_skip_reset (sched_job);return DRM_GPU_SCHED_STAT_NOMINAL ; }
Greg Kroah-Hartman
maintainerPATCH 89/184 drm/xe: Add page queue multiplier
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
commit 391008f34e711253c5983b0bf52277cc43723127 upstream.
For an unknown reason the math to determine the PF queue size does is not correct - compute UMD applications are overflowing the PF queue which is fatal. A multippier of 8 fixes the problem.
--- drivers/gpu/drm/xe/xe_gt_pagefault.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/gpu/drm/xe/xe_gt_pagefault.c +9 -2
@@ -423,9 +423,16 @@ static int xe_alloc_pf_queue(struct xe_g num_eus =bitmap_weight (gt->fuse_topo.eu_mask_per_dss,XE_MAX_EU_FUSE_BITS ) * num_dss; -/* user can issue separate page faults per EU and per CS */ +/* +* user can issue separate page faults per EU and per CS +* +* XXX: Multiplier required as compute UMD are getting PF queue errors +* without it. Follow on why this multiplier is required. +*/ +#define PF_MULTIPLIER 8 pf_queue->num_dw = - (num_eus +XE_NUM_HW_ENGINES ) *PF_MSG_LEN_DW ; + (num_eus +XE_NUM_HW_ENGINES ) *PF_MSG_LEN_DW *PF_MULTIPLIER ; +#undef PF_MULTIPLIER pf_queue->gt = gt; pf_queue->data = devm_kcalloc(xe->drm.dev, pf_queue->num_dw,
Greg Kroah-Hartman
maintainerPATCH 90/184 drm/amdgpu/vcn: using separate VCN1_AON_SOC offset
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruijing Dong <[email protected]>
commit b7e84fb708392b37e5dbb2a95db9b94a0e3f0aa2 upstream.
VCN1_AON_SOC_ADDRESS_3_0 offset varies on different VCN generations, the issue in vcn4.0.5 is caused by a different VCN1_AON_SOC_ADDRESS_3_0 offset.
This patch does the following:
1. use the same offset for other VCN generations.
2. use the vcn4.0.5 special offset
3. update vcn_4_0 and vcn_5_0
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 1 - drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 4 +++- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 3 ++- 8 files changed, 10 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +0 -1
@@ -66,7 +66,6 @@#define VCN_ENC_CMD_REG_WAIT 0x0000000c#define VCN_AON_SOC_ADDRESS_2_0 0x1f800 -#define VCN1_AON_SOC_ADDRESS_3_0 0x48000#define VCN_VID_IP_ADDRESS_2_0 0x0#define VCN_AON_IP_ADDRESS_2_0 0x30000
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +1 -0
@@ -39,6 +39,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00#define VCN1_VID_SOC_ADDRESS_3_0 0x48200 +#define VCN1_AON_SOC_ADDRESS_3_0 0x48000#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x1fd#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x503
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +1 -0
@@ -39,6 +39,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00#define VCN1_VID_SOC_ADDRESS_3_0 0x48200 +#define VCN1_AON_SOC_ADDRESS_3_0 0x48000#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +1 -0
@@ -40,6 +40,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00#define VCN1_VID_SOC_ADDRESS_3_0 0x48200 +#define VCN1_AON_SOC_ADDRESS_3_0 0x48000#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +3 -1
@@ -46,6 +46,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00#define VCN1_VID_SOC_ADDRESS_3_0 0x48300 +#define VCN1_AON_SOC_ADDRESS_3_0 0x48000#define VCN_HARVEST_MMSCH 0
@@ -575,7 +576,8 @@ static void vcn_v4_0_mc_resume_dpg_mode(/* VCN global tiling registers */ WREG32_SOC15_DPG_MODE (inst_idx,SOC15_DPG_MODE_OFFSET ( -VCN ,0 , regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config,0 , indirect); +VCN , inst_idx, regUVD_GFX10_ADDR_CONFIG), + adev->gfx.config.gb_addr_config,0 , indirect); }/**
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +1 -0
@@ -44,6 +44,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00#define VCN1_VID_SOC_ADDRESS_3_0 0x48300 +#define VCN1_AON_SOC_ADDRESS_3_0 0x48000static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0_3[] = {SOC15_REG_ENTRY_STR (VCN ,0 , regUVD_POWER_STATUS),
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +1 -0
@@ -46,6 +46,7 @@#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00#define VCN1_VID_SOC_ADDRESS_3_0 (0x48300 + 0x38000) +#define VCN1_AON_SOC_ADDRESS_3_0 (0x48000 + 0x38000)#define VCN_HARVEST_MMSCH 0
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +2 -1
@@ -488,7 +488,8 @@ static void vcn_v5_0_0_mc_resume_dpg_mod/* VCN global tiling registers */ WREG32_SOC24_DPG_MODE (inst_idx,SOC24_DPG_MODE_OFFSET ( -VCN ,0 , regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config,0 , indirect); +VCN , inst_idx, regUVD_GFX10_ADDR_CONFIG), + adev->gfx.config.gb_addr_config,0 , indirect);return ; }
Greg Kroah-Hartman
maintainerPATCH 91/184 drm/amd/display: Fix invalid context error in dml helper
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li <[email protected]>
commit 9984db63742099ee3f3cff35cf71306d10e64356 upstream.
[Why]
"BUG: sleeping function called from invalid context" error. after:
"drm/amd/display: Protect FPU in dml2_validate()/dml21_validate()"
The populate_dml_plane_cfg_from_plane_state() uses the GFP_KERNEL flag for memory allocation, which shouldn't be used in atomic contexts.
The allocation is needed only for using another helper function get_scaler_data_for_plane().
[How]
Modify helpers to pass a pointer to scaler_data within existing context, eliminating the need for dynamic memory allocation/deallocation and copying.
--- drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c | 14 +++------- 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +5 -9
@@ -929,7 +929,9 @@ static void populate_dml_surface_cfg_fro } } -static void get_scaler_data_for_plane (const struct dc_plane_state *in,struct dc_state *context,struct scaler_data *out) +static struct scaler_data *get_scaler_data_for_plane ( +const struct dc_plane_state *in, +struct dc_state *context) {int i;struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe;
@@ -950,7 +952,7 @@ static void get_scaler_data_for_plane(co }ASSERT (i <MAX_PIPES ); -memcpy (out, &temp_pipe->plane_res.scl_data,sizeof (*out)); +return &temp_pipe->plane_res.scl_data; } static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location,
@@ -1013,11 +1015,7 @@ static void populate_dml_plane_cfg_from_ const struct dc_plane_state *in, struct dc_state *context, const struct soc_bounding_box_st *soc) { - struct scaler_data *scaler_data = kzalloc(sizeof(*scaler_data), GFP_KERNEL); -if (!scaler_data) -return ; - -get_scaler_data_for_plane (in, context, scaler_data); + struct scaler_data *scaler_data = get_scaler_data_for_plane(in, context); out->CursorBPP[location] = dml_cur_32bit; out->CursorWidth[location] =256 ;
@@ -1082,8 +1080,6 @@ static void populate_dml_plane_cfg_from_ out->DynamicMetadataTransmittedBytes[location] =0 ; out->NumberOfCursors[location] =1 ; - -kfree (scaler_data); } static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml2,
Greg Kroah-Hartman
maintainerPATCH 92/184 drm/amd/display: more liberal vmin/vmax update for freesync
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurabindo Pillai <[email protected]>
commit f1c6be3999d2be2673a51a9be0caf9348e254e52 upstream.
[Why]
FAMS2 expects vmin/vmax to be updated in the case when freesync is off, but supported. But we only update it when freesync is enabled.
[How]
Change the vsync handler such that dc_stream_adjust_vmin_vmax() its called irrespective of whether freesync is enabled. If freesync is supported, then there is no harm in updating vmin/vmax registers.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +11 -5
@@ -666,15 +666,21 @@ static void dm_crtc_high_irq(void *interspin_lock_irqsave (&adev_to_drm (adev)->event_lock, flags);if (acrtc->dm_irq_params.stream && - acrtc->dm_irq_params.vrr_params.supported && - acrtc->dm_irq_params.freesync_config.state == -VRR_STATE_ACTIVE_VARIABLE ) { + acrtc->dm_irq_params.vrr_params.supported) { +bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; +bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; +bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state ==VRR_STATE_ACTIVE_VARIABLE ; +mod_freesync_handle_v_update (adev->dm.freesync_module, acrtc->dm_irq_params.stream, &acrtc->dm_irq_params.vrr_params); -dc_stream_adjust_vmin_vmax (adev->dm.dc, acrtc->dm_irq_params.stream, - &acrtc->dm_irq_params.vrr_params.adjust); +/* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */ +if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { +dc_stream_adjust_vmin_vmax (adev->dm.dc, + acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); + } }/*
Greg Kroah-Hartman
maintainerPATCH 93/184 drm/amd/display: Fix the checking condition in dmub aux handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit bc70e11b550d37fbd9eaed0f113ba560894f1609 upstream.
[Why & How]
Fix the checking condition for detecting AUX_RET_ERROR_PROTOCOL_ERROR. It was wrongly checking by "not equals to"
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -12532,7 +12532,7 @@ int amdgpu_dm_process_dmub_aux_transfer_* Transient states before tunneling is enabled could * lead to this error. We can ignore this for now. */ -if (p_notify->result !=AUX_RET_ERROR_PROTOCOL_ERROR ) { +if (p_notify->result ==AUX_RET_ERROR_PROTOCOL_ERROR ) {DRM_WARN ("DPIA AUX failed on 0x%x(%d), error %d\n" , payload->address, payload->length, p_notify->result);
Greg Kroah-Hartman
maintainerPATCH 94/184 drm/amd/display: Remove incorrect checking in dmub aux handler
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 396dc51b3b7ea524bf8061f478332d0039e96d5d upstream.
[Why & How]
"Request length != reply length" is expected behavior defined in spec. It's not an invalid reply. Besides, replied data handling logic is not designed to be written in amdgpu_dm_process_dmub_aux_transfer_sync(). Remove the incorrectly handling section.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -11
@@ -12547,19 +12547,9 @@ int amdgpu_dm_process_dmub_aux_transfer_ payload->reply[0 ] = (adev->dm.dmub_notify->aux_reply.command >>4 ) &0xF ;if (!payload->write && p_notify->aux_reply.length && - (payload->reply[0 ] ==AUX_TRANSACTION_REPLY_AUX_ACK )) { - -if (payload->length != p_notify->aux_reply.length) { -DRM_WARN ("invalid read length %d from DPIA AUX 0x%x(%d)!\n" , - p_notify->aux_reply.length, - payload->address, payload->length); - *operation_result =AUX_RET_ERROR_INVALID_REPLY ; - goto out; - } - + (payload->reply[0 ] ==AUX_TRANSACTION_REPLY_AUX_ACK ))memcpy (payload->data, p_notify->aux_reply.data, p_notify->aux_reply.length); - }/* success */ ret = p_notify->aux_reply.length;
Greg Kroah-Hartman
maintainerPATCH 95/184 drm/amd/display: Fix wrong handling for AUX_DEFER case
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 65924ec69b29296845c7f628112353438e63ea56 upstream.
[Why]
We incorrectly ack all bytes get written when the reply actually is defer. When it's defer, means sink is not ready for the request. We should retry the request.
[How]
Only reply all data get written when receive I2C_ACK|AUX_ACK. Otherwise, reply the number of actual written bytes received from the sink. Add some messages to facilitate debugging as well.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 28 ++++++++++-- 1 file changed, 24 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +24 -4
@@ -51,6 +51,9 @@#define PEAK_FACTOR_X1000 1006 +/* +* This function handles both native AUX and I2C-Over-AUX transactions. +*/ static ssize_t dm_dp_aux_transfer (struct drm_dp_aux *aux,struct drm_dp_aux_msg *msg) {
@@ -87,15 +90,25 @@ static ssize_t dm_dp_aux_transfer(structif (adev->dm.aux_hpd_discon_quirk) {if (msg->address ==DP_SIDEBAND_MSG_DOWN_REQ_BASE && operation_result ==AUX_RET_ERROR_HPD_DISCON ) { - result =0 ; + result = msg->size; operation_result =AUX_RET_SUCCESS ; } } -if (payload.write && result >=0 ) - result = msg->size; +/* +* result equals to 0 includes the cases of AUX_DEFER/I2C_DEFER +*/ +if (payload.write && result >=0 ) { +if (result) { +/*one byte indicating partially written bytes. Force 0 to retry*/ +drm_info (adev_to_drm (adev),"amdgpu: AUX partially written\n" ); + result =0 ; + }else if (!payload.reply[0 ]) +/*I2C_ACK|AUX_ACK*/ + result = msg->size; + } -if (result <0 ) +if (result <0 ) {switch (operation_result) {case AUX_RET_SUCCESS :break ;
@@ -114,6 +127,13 @@ static ssize_t dm_dp_aux_transfer(structbreak ; } +drm_info (adev_to_drm (adev),"amdgpu: DP AUX transfer fail:%d\n" , operation_result); + } + +if (payload.reply[0 ]) +drm_info (adev_to_drm (adev),"amdgpu: AUX reply command not ACK: 0x%02x." , + payload.reply[0 ]); +return result; }
Greg Kroah-Hartman
maintainerPATCH 96/184 drm/amd/display: Copy AUX read reply data whenever length > 0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 3924f45d4de7250a603fd7b50379237a6a0e5adf upstream.
[Why]amdgpu_dm_process_dmub_aux_transfer_sync() should return all exact data reply from the sink side. Don't do the analysis job in it.
[How]
Remove unnecessary check condition AUX_TRANSACTION_REPLY_AUX_ACK.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -2
@@ -12546,8 +12546,7 @@ int amdgpu_dm_process_dmub_aux_transfer_/* The reply is stored in the top nibble of the command. */ payload->reply[0 ] = (adev->dm.dmub_notify->aux_reply.command >>4 ) &0xF ; -if (!payload->write && p_notify->aux_reply.length && - (payload->reply[0 ] ==AUX_TRANSACTION_REPLY_AUX_ACK )) +if (!payload->write && p_notify->aux_reply.length)memcpy (payload->data, p_notify->aux_reply.data, p_notify->aux_reply.length);
Greg Kroah-Hartman
maintainerPATCH 97/184 drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit f690e3974755a650259a45d71456decc9c96a282 upstream.
Reading back the remapped HDP flush register seems to cause problems on some platforms. All we need is a read, so read back the memcfg register.
--- drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +6 -1
@@ -42,7 +42,12 @@ static void hdp_v4_0_flush_hdp(struct am {if (!ring || !ring->funcs->emit_wreg) {WREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); -RREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); +/* We just need to read back a register to post the write. +* Reading back the remapped register causes problems on +* some platforms so just read back the memory size register. +*/ +if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize (adev); }else {amdgpu_ring_emit_wreg (ring, (adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 98/184 drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit dbc988c689333faeeed44d5561f372ff20395304 upstream.
Reading back the remapped HDP flush register seems to cause problems on some platforms. All we need is a read, so read back the memcfg register.
--- drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c +11 -1
@@ -34,7 +34,17 @@ static void hdp_v5_2_flush_hdp(struct amif (!ring || !ring->funcs->emit_wreg) {WREG32_NO_KIQ ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); -RREG32_NO_KIQ ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); +if (amdgpu_sriov_vf (adev)) { +/* this is fine because SR_IOV doesn't remap the register */ +RREG32_NO_KIQ ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); + }else { +/* We just need to read back a register to post the write. +* Reading back the remapped register causes problems on +* some platforms so just read back the memory size register. +*/ +if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize (adev); + } }else { amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
Greg Kroah-Hartman
maintainerPATCH 99/184 drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 0e33e0f339b91eecd9558311449a3d1e728722d4 upstream.
Reading back the remapped HDP flush register seems to cause problems on some platforms. All we need is a read, so read back the memcfg register.
--- drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c +6 -1
@@ -33,7 +33,12 @@ static void hdp_v5_0_flush_hdp(struct am {if (!ring || !ring->funcs->emit_wreg) {WREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); -RREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); +/* We just need to read back a register to post the write. +* Reading back the remapped register causes problems on +* some platforms so just read back the memory size register. +*/ +if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize (adev); }else {amdgpu_ring_emit_wreg (ring, (adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 100/184 drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit ca28e80abe4219c8f1a2961ae05102d70af6dc87 upstream.
Reading back the remapped HDP flush register seems to cause problems on some platforms. All we need is a read, so read back the memcfg register.
--- drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c +6 -1
@@ -36,7 +36,12 @@ static void hdp_v6_0_flush_hdp(struct am {if (!ring || !ring->funcs->emit_wreg) {WREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); -RREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); +/* We just need to read back a register to post the write. +* Reading back the remapped register causes problems on +* some platforms so just read back the memory size register. +*/ +if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize (adev); }else {amdgpu_ring_emit_wreg (ring, (adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 101/184 drm/amdgpu/hdp7: use memcfg register to post the write for HDP flush
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 5a11a2767731139bf87e667331aa2209e33a1d19 upstream.
Reading back the remapped HDP flush register seems to cause problems on some platforms. All we need is a read, so read back the memcfg register.
--- drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c +6 -1
@@ -33,7 +33,12 @@ static void hdp_v7_0_flush_hdp(struct am {if (!ring || !ring->funcs->emit_wreg) {WREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); -RREG32 ((adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ); +/* We just need to read back a register to post the write. +* Reading back the remapped register causes problems on +* some platforms so just read back the memory size register. +*/ +if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize (adev); }else {amdgpu_ring_emit_wreg (ring, (adev->rmmio_remap.reg_offset +KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL ) >>2 ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 102/184 usb: uhci-platform: Make the clock really optional
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Charkov <[email protected]>
commit a5c7973539b010874a37a0e846e62ac6f00553ba upstream.
Device tree bindings state that the clock is optional for UHCI platform controllers, and some existing device trees don't provide those - such as those for VIA/WonderMedia devices.
The driver however fails to probe now if no clock is provided, because devm_clk_get returns an error pointer in such case.
Switch to devm_clk_get_optional instead, so that it could probe again on those platforms where no clocks are given.
--- drivers/usb/host/uhci-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/uhci-platform.c +1 -1
@@ -121,7 +121,7 @@ static int uhci_hcd_platform_probe(struc }/* Get and enable clock if any specified */ - uhci->clk =devm_clk_get (&pdev->dev,NULL ); + uhci->clk =devm_clk_get_optional (&pdev->dev,NULL );if (IS_ERR (uhci->clk)) { ret =PTR_ERR (uhci->clk); goto err_rmr;
Greg Kroah-Hartman
maintainerPATCH 103/184 smb: client: Avoid race in open_cached_dir with lease breaks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
commit 3ca02e63edccb78ef3659bebc68579c7224a6ca2 upstream.
A pre-existing valid cfid returned from find_or_create_cached_dir might race with a lease break, meaning open_cached_dir doesn't consider it valid, and thinks it's newly-constructed. This leaks a dentry reference if the allocation occurs before the queued lease break work runs.
Avoid the race by extending holding the cfid_list_lock across find_or_create_cached_dir and when the result is checked.
--- fs/smb/client/cached_dir.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
fs/smb/client/cached_dir.c +2 -8
@@ -29,7 +29,6 @@ static struct cached_fid *find_or_create {struct cached_fid *cfid; -spin_lock (&cfids->cfid_list_lock);list_for_each_entry (cfid, &cfids->entries, entry) {if (!strcmp (cfid->path, path)) {/*
@@ -38,25 +37,20 @@ static struct cached_fid *find_or_create* being deleted due to a lease break. */ if (!cfid->time || !cfid->has_lease) { -spin_unlock (&cfids->cfid_list_lock);return NULL ; }kref_get (&cfid->refcount); -spin_unlock (&cfids->cfid_list_lock);return cfid; } }if (lookup_only) { -spin_unlock (&cfids->cfid_list_lock);return NULL ; }if (cfids->num_entries >= max_cached_dirs) { -spin_unlock (&cfids->cfid_list_lock);return NULL ; } cfid =init_cached_dir (path);if (cfid ==NULL ) { -spin_unlock (&cfids->cfid_list_lock);return NULL ; } cfid->cfids = cfids;
@@ -74,7 +68,6 @@ static struct cached_fid *find_or_create*/ cfid->has_lease = true; -spin_unlock (&cfids->cfid_list_lock);return cfid; }
@@ -185,8 +178,10 @@ replay_again:if (!utf16_path)return -ENOMEM ; +spin_lock (&cfids->cfid_list_lock); cfid =find_or_create_cached_dir (cfids, path, lookup_only, tcon->max_cached_dirs);if (cfid ==NULL ) { +spin_unlock (&cfids->cfid_list_lock);kfree (utf16_path);return -ENOENT ; }
@@ -195,7 +190,6 @@ replay_again:* Otherwise, it is either a new entry or laundromat worker removed it * from @cfids->entries. Caller will put last reference if the latter. */ -spin_lock (&cfids->cfid_list_lock);if (cfid->has_lease && cfid->time) {spin_unlock (&cfids->cfid_list_lock); *ret_cfid = cfid;
Greg Kroah-Hartman
maintainerPATCH 104/184 xen: swiotlb: Use swiotlb bouncing if kmalloc allocation demands it
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Ernberg <[email protected]>
commit cd9c058489053e172a6654cad82ee936d1b09fab upstream.
Xen swiotlb support was missed when the patch set starting with 4ab5f8ec7d71 ("mm/slab: decouple ARCH_KMALLOC_MINALIGN from ARCH_DMA_MINALIGN") was merged.
When running Xen on iMX8QXP, a SoC without IOMMU, the effect was that USB transfers ended up corrupted when there was more than one URB inflight at the same time.
Add a call to dma_kmalloc_needs_bounce() to make sure that allocations too small for DMA get bounced via swiotlb.
Message-ID: <[email protected]>
--- drivers/xen/swiotlb-xen.c | 1 + 1 file changed, 1 insertion(+)
drivers/xen/swiotlb-xen.c +1 -0
@@ -217,6 +217,7 @@ static dma_addr_t xen_swiotlb_map_page(s* buffering it. */ if (dma_capable (dev, dev_addr, size, true) && + !dma_kmalloc_needs_bounce (dev, size, dir) && !range_straddles_page_boundary (phys, size) && !xen_arch_need_swiotlb (dev, phys, dev_addr) && !is_swiotlb_force_bounce (dev))
Greg Kroah-Hartman
maintainerPATCH 105/184 xenbus: Use kref to track req lifetime
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <[email protected]>
commit 1f0304dfd9d217c2f8b04a9ef4b3258a66eedd27 upstream.
Marek reported seeing a NULL pointer fault in the xenbus_thread callstack:
BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: e030:__wake_up_common+0x4c/0x180 Call Trace: <TASK> __wake_up_common_lock+0x82/0xd0 process_msg+0x18e/0x2f0 xenbus_thread+0x165/0x1c0
process_msg+0x18e is req->cb(req). req->cb is set to xs_wake_up(), a thin wrapper around wake_up(), or xenbus_dev_queue_reply(). It seems like it was xs_wake_up() in this case.
It seems like req may have woken up the xs_wait_for_reply(), which kfree()ed the req. When xenbus_thread resumes, it faults on the zero-ed data.
Linux Device Drivers 2nd edition states:
"Normally, a wake_up call can cause an immediate reschedule to happen, meaning that other processes might run before wake_up returns." ... which would match the behaviour observed.
Change to keeping two krefs on each request. One for the caller, and one for xenbus_thread. Each will kref_put() when finished, and the last will free it.
This use of kref matches the description inDocumentation/core-api/kref.rst
Message-ID: <[email protected]>
--- drivers/xen/xenbus/xenbus.h | 2 ++ drivers/xen/xenbus/xenbus_comms.c | 9 ++++----- drivers/xen/xenbus/xenbus_dev_frontend.c | 2 +- drivers/xen/xenbus/xenbus_xs.c | 18 ++++++++++++++++-- 4 files changed, 23 insertions(+), 8 deletions(-)
drivers/xen/xenbus/xenbus.h +2 -0
@@ -77,6 +77,7 @@ enum xb_req_state {struct xb_req_data {struct list_head list;wait_queue_head_t wq; +struct kref kref;struct xsd_sockmsg msg;uint32_t caller_req_id;enum xsd_sockmsg_type type;
@@ -103,6 +104,7 @@ int xb_init_comms(void);void xb_deinit_comms (void );int xs_watch_msg (struct xs_watch_event *event);void xs_request_exit (struct xb_req_data *req); +void xs_free_req (struct kref *kref);int xenbus_match (struct device *_dev,const struct device_driver *_drv);int xenbus_dev_probe (struct device *_dev);
drivers/xen/xenbus/xenbus_comms.c +4 -5
@@ -309,8 +309,8 @@ static int process_msg(void)virt_wmb (); req->state = xb_req_state_got_reply; req->cb (req); - }else -kfree (req); + } +kref_put (&req->kref, xs_free_req); }mutex_unlock (&xs_response_mutex);
@@ -386,14 +386,13 @@ static int process_writes(void) state.req->msg.type =XS_ERROR ; state.req->err = err;list_del (&state.req->list); -if (state.req->state == xb_req_state_aborted) -kfree (state.req); -else { +if (state.req->state != xb_req_state_aborted) {/* write err, then update state */ virt_wmb (); state.req->state = xb_req_state_got_reply;wake_up (&state.req->wq); } +kref_put (&state.req->kref, xs_free_req);mutex_unlock (&xb_write_mutex);
drivers/xen/xenbus/xenbus_dev_frontend.c +1 -1
@@ -406,7 +406,7 @@ void xenbus_dev_queue_reply(struct xb_remutex_unlock (&u->reply_mutex);kfree (req->body); -kfree (req); +kref_put (&req->kref, xs_free_req);kref_put (&u->kref, xenbus_file_free);
drivers/xen/xenbus/xenbus_xs.c +16 -2
@@ -112,6 +112,12 @@ static void xs_suspend_exit(void)wake_up_all (&xs_state_enter_wq); } +void xs_free_req (struct kref *kref) +{ + struct xb_req_data *req = container_of(kref, struct xb_req_data, kref); +kfree (req); +} +static uint32_t xs_request_enter (struct xb_req_data *req) {uint32_t rq_id;
@@ -237,6 +243,12 @@ static void xs_send(struct xb_req_data * req->caller_req_id = req->msg.req_id; req->msg.req_id =xs_request_enter (req); +/* +* Take 2nd ref. One for this thread, and the second for the +* xenbus_thread. +*/ +kref_get (&req->kref); +mutex_lock (&xb_write_mutex);list_add_tail (&req->list, &xb_write_list); notify =list_is_singular (&xb_write_list);
@@ -261,8 +273,8 @@ static void *xs_wait_for_reply(struct xbif (req->state == xb_req_state_queued || req->state == xb_req_state_wait_reply) req->state = xb_req_state_aborted; -else -kfree (req); + +kref_put (&req->kref, xs_free_req);mutex_unlock (&xb_write_mutex);return ret;
@@ -291,6 +303,7 @@ int xenbus_dev_request_and_reply(struct req->cb = xenbus_dev_queue_reply; req->par = par; req->user_req = true; +kref_init (&req->kref);xs_send (req, msg);
@@ -319,6 +332,7 @@ static void *xs_talkv(struct xenbus_tran req->num_vecs = num_vecs; req->cb = xs_wake_up; req->user_req = false; +kref_init (&req->kref); msg.req_id =0 ; msg.tx_id = t.id;
Greg Kroah-Hartman
maintainerPATCH 106/184 accel/ivpu: Increase state dump msg timeout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacek Lawrynowicz <[email protected]>
commit c4eb2f88d2796ab90c5430e11c48709716181364 upstream.
Increase JMS message state dump command timeout to 100 ms. On some platforms, the FW may take a bit longer than 50 ms to dump its state to the log buffer and we don't want to miss any debug info during TDR.
--- drivers/accel/ivpu/ivpu_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/ivpu/ivpu_hw.c +1 -1
@@ -106,7 +106,7 @@ static void timeouts_init(struct ivpu_deelse vdev->timeout.autosuspend =100 ; vdev->timeout.d0i3_entry_msg =5 ; - vdev->timeout.state_dump_msg =10 ; + vdev->timeout.state_dump_msg =100 ; } }
Greg Kroah-Hartman
maintainerPATCH 107/184 arm64: cpufeature: Move arm64_use_ng_mappings to the .data section to prevent wrong idmap generation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeoreum Yun <[email protected]>
commit 363cd2b81cfdf706bbfc9ec78db000c9b1ecc552 upstream.
The PTE_MAYBE_NG macro sets the nG page table bit according to the value of "arm64_use_ng_mappings". This variable is currently placed in the .bss section. create_init_idmap() is called before the .bss section initialisation which is done in early_map_kernel(). Therefore, data/test_prot in create_init_idmap() could be set incorrectly through the PAGE_KERNEL -> PROT_DEFAULT -> PTE_MAYBE_NG macros.
# llvm-objdump-21 --syms vmlinux-gcc | grep arm64_use_ng_mappings
ffff800082f242a8 g O .bss 0000000000000001 arm64_use_ng_mappingsThe create_init_idmap() function disassembly compiled with llvm-21:
// create_init_idmap()
ffff80008255c058: d10103ff sub sp, sp, #0x40 ffff80008255c05c: a9017bfd stp x29, x30, [sp, #0x10] ffff80008255c060: a90257f6 stp x22, x21, [sp, #0x20] ffff80008255c064: a9034ff4 stp x20, x19, [sp, #0x30] ffff80008255c068: 910043fd add x29, sp, #0x10 ffff80008255c06c: 90003fc8 adrp x8, 0xffff800082d54000 ffff80008255c070: d280e06a mov x10, #0x703 // =1795 ffff80008255c074: 91400409 add x9, x0, #0x1, lsl #12 // =0x1000 ffff80008255c078: 394a4108 ldrb w8, [x8, #0x290] ------------- (1) ffff80008255c07c: f2e00d0a movk x10, #0x68, lsl #48 ffff80008255c080: f90007e9 str x9, [sp, #0x8] ffff80008255c084: aa0103f3 mov x19, x1 ffff80008255c088: aa0003f4 mov x20, x0 ffff80008255c08c: 14000000 b 0xffff80008255c08c <__pi_create_init_idmap+0x34> ffff80008255c090: aa082d56 orr x22, x10, x8, lsl #11 -------- (2)
Note (1) is loading the arm64_use_ng_mappings value in w8 and (2) is set the text or data prot with the w8 value to set PTE_NG bit. If the .bss section isn't initialized, x8 could include a garbage value and generate an incorrect mapping.
Annotate arm64_use_ng_mappings as __read_mostly so that it is placed in the .data section.
--- arch/arm64/kernel/cpufeature.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/arm64/kernel/cpufeature.c +8 -1
@@ -111,7 +111,14 @@ static struct arm64_cpu_capabilities conDECLARE_BITMAP (boot_cpucaps,ARM64_NCAPS ); -bool arm64_use_ng_mappings = false; +/* +* arm64_use_ng_mappings must be placed in the .data section, otherwise it +* ends up in the .bss section where it is initialized in early_map_kernel() +* after the MMU (with the idmap) was enabled. create_init_idmap() - which +* runs before early_map_kernel() and reads the variable via PTE_MAYBE_NG - +* may end up generating an incorrect idmap page table attributes. +*/ +bool arm64_use_ng_mappings__read_mostly = false;EXPORT_SYMBOL (arm64_use_ng_mappings); DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
Greg Kroah-Hartman
maintainerPATCH 108/184 clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 94cff94634e506a4a44684bee1875d2dbf782722 upstream.
On x86 during boot, clockevent_i8253_disable() can be invoked via x86_late_time_init -> hpet_time_init() -> pit_timer_init() which happens with enabled interrupts.
If some of the old i8253 hardware is actually used then lockdep will notice that i8253_lock is used in hard interrupt context. This causes lockdep to complain because it observed the lock being acquired with interrupts enabled and in hard interrupt context.
Make clockevent_i8253_disable() acquire the lock with raw_spinlock_irqsave() to cure this.
[ tglx: Massage change log and use guard() ]
--- drivers/clocksource/i8253.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/clocksource/i8253.c +1 -3
@@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void)#ifdef CONFIG_CLKEVT_I8253 void clockevent_i8253_disable (void ) { -raw_spin_lock (&i8253_lock); +guard (raw_spinlock_irqsave)(&i8253_lock);/* * Writing the MODE register should stop the counter, according to
@@ -132,8 +132,6 @@ void clockevent_i8253_disable(void)outb_p (0 ,PIT_CH0 );outb_p (0x30 ,PIT_MODE ); - -raw_spin_unlock (&i8253_lock); }static int pit_shutdown (struct clock_event_device *evt)
Greg Kroah-Hartman
maintainerPATCH 109/184 memblock: Accept allocated memory before use in memblock_double_array()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Lendacky <[email protected]>
commit da8bf5daa5e55a6af2b285ecda460d6454712ff4 upstream.
When increasing the array size in memblock_double_array() and the slab is not yet available, a call to memblock_find_in_range() is used to reserve/allocate memory. However, the range returned may not have been accepted, which can result in a crash when booting an SNP guest:
RIP: 0010:memcpy_orig+0x68/0x130 Code: ... RSP: 0000:ffffffff9cc03ce8 EFLAGS: 00010006 RAX: ff11001ff83e5000 RBX: 0000000000000000 RCX: fffffffffffff000 RDX: 0000000000000bc0 RSI: ffffffff9dba8860 RDI: ff11001ff83e5c00 RBP: 0000000000002000 R08: 0000000000000000 R09: 0000000000002000 R10: 000000207fffe000 R11: 0000040000000000 R12: ffffffff9d06ef78 R13: ff11001ff83e5000 R14: ffffffff9dba7c60 R15: 0000000000000c00 memblock_double_array+0xff/0x310 memblock_add_range+0x1fb/0x2f0 memblock_reserve+0x4f/0xa0 memblock_alloc_range_nid+0xac/0x130 memblock_alloc_internal+0x53/0xc0 memblock_alloc_try_nid+0x3d/0xa0 swiotlb_init_remap+0x149/0x2f0 mem_init+0xb/0xb0 mm_core_init+0x8f/0x350 start_kernel+0x17e/0x5d0 x86_64_start_reservations+0x14/0x30 x86_64_start_kernel+0x92/0xa0 secondary_startup_64_no_verify+0x194/0x19b
Mitigate this by calling accept_memory() on the memory range returned before the slab is available.
Prior to v6.12, the accept_memory() interface used a 'start' and 'end' parameter instead of 'start' and 'size', therefore the accept_memory() call must be adjusted to specify 'start + size' for 'end' when applying to kernels prior to v6.12.
--- mm/memblock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/memblock.c +8 -1
@@ -456,7 +456,14 @@ static int __init_memblock memblock_doubmin (new_area_start, memblock.current_limit), new_alloc_size, PAGE_SIZE); - new_array = addr ?__va (addr) :NULL ; +if (addr) { +/* The memory may not have been accepted, yet. */ +accept_memory (addr, new_alloc_size); + + new_array =__va (addr); + }else { + new_array =NULL ; + } }if (!addr) { pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
Greg Kroah-Hartman
maintainerPATCH 110/184 module: ensure that kobject_put() is safe for module type kobjects
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
commit a6aeb739974ec73e5217c75a7c008a688d3d5cf1 upstream.
In 'lookup_or_create_module_kobject()', an internal kobject is created using 'module_ktype'. So call to 'kobject_put()' on error handling path causes an attempt to use an uninitialized completion pointer in 'module_kobject_release()'. In this scenario, we just want to release kobject without an extra synchronization required for a regular module unloading process, so adding an extra check whether 'complete()' is actually required makes 'kobject_put()' safe.
--- kernel/params.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/params.c +3 -1
@@ -949,7 +949,9 @@ struct kset *module_kset;static void module_kobj_release (struct kobject *kobj) {struct module_kobject *mk =to_module_kobject (kobj); -complete (mk->kobj_completion); + +if (mk->kobj_completion) +complete (mk->kobj_completion); }const struct kobj_type module_ktype = {
Greg Kroah-Hartman
maintainerPATCH 111/184 x86/microcode: Consolidate the loader enablement checking
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov (AMD) <[email protected]>
commit 5214a9f6c0f56644acb9d2cbb58facf1856d322b upstream.
Consolidate the whole logic which determines whether the microcode loader should be enabled or not into a single function and call it everywhere.
Well, almost everywhere - not in mk_early_pgtbl_32() because there the kernel is running without paging enabled and checking dis_ucode_ldr et al would require physical addresses and uglification of the code.
But since this is 32-bit, the easier thing to do is to simply map the initrd unconditionally especially since that mapping is getting removed later anyway by zap_early_initrd_mapping() and avoid the uglification.
In doing so, address the issue of old 486er machines without CPUID support, not booting current kernels.
[ mingo: Fix no previous prototype for ‘microcode_loader_disabled’ [-Wmissing-prototypes] ]
--- arch/x86/include/asm/microcode.h | 2 + arch/x86/kernel/cpu/microcode/amd.c | 6 ++- arch/x86/kernel/cpu/microcode/core.c | 58 ++++++++++++++++++------------- arch/x86/kernel/cpu/microcode/intel.c | 2 - arch/x86/kernel/cpu/microcode/internal.h | 1 arch/x86/kernel/head32.c | 4 -- 6 files changed, 41 insertions(+), 32 deletions(-)
arch/x86/include/asm/microcode.h +2 -0
@@ -17,10 +17,12 @@ struct ucode_cpu_info {void load_ucode_bsp (void );void load_ucode_ap (void );void microcode_bsp_resume (void ); +bool __init microcode_loader_disabled (void );#else static inline void load_ucode_bsp (void ) { }static inline void load_ucode_ap (void ) { }static inline void microcode_bsp_resume (void ) { } +static inline bool __init microcode_loader_disabled (void ) {return false; }#endif extern unsigned long initrd_start_early;
arch/x86/kernel/cpu/microcode/amd.c +4 -2
@@ -1099,15 +1099,17 @@ static enum ucode_state load_microcode_astatic int __init save_microcode_in_initrd (void ) { -unsigned int cpuid_1_eax =native_cpuid_eax (1 );struct cpuinfo_x86 *c = &boot_cpu_data;struct cont_desc desc = {0 }; +unsigned int cpuid_1_eax;enum ucode_state ret;struct cpio_data cp; -if (dis_ucode_ldr || c->x86_vendor !=X86_VENDOR_AMD || c->x86 <0x10 ) +if (microcode_loader_disabled () || c->x86_vendor !=X86_VENDOR_AMD || c->x86 <0x10 )return 0 ; + cpuid_1_eax =native_cpuid_eax (1 ); +if (!find_blobs_in_containers (&cp))return -EINVAL ;
arch/x86/kernel/cpu/microcode/core.c +34 -24
104 lines not on this page · raw message
arch/x86/kernel/cpu/microcode/intel.c +1 -1
@@ -395,7 +395,7 @@ static int __init save_builtin_microcodeif (xchg (&ucode_patch_va,NULL ) !=UCODE_BSP_LOADED )return 0 ; -if (dis_ucode_ldr || boot_cpu_data.x86_vendor !=X86_VENDOR_INTEL ) +if (microcode_loader_disabled () || boot_cpu_data.x86_vendor !=X86_VENDOR_INTEL )return 0 ; uci.mc =get_microcode_blob (&uci, true);
arch/x86/kernel/cpu/microcode/internal.h +0 -1
@@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_famreturn x86_family (eax); } -extern bool dis_ucode_ldr;extern bool force_minrev;#ifdef CONFIG_CPU_SUP_AMD
arch/x86/kernel/head32.c +0 -4
@@ -145,10 +145,6 @@ void __init __no_stack_protector mk_earl *ptr = (unsigned long )ptep +PAGE_OFFSET ;#ifdef CONFIG_MICROCODE_INITRD32 -/* Running on a hypervisor? */ -if (native_cpuid_ecx (1 ) &BIT (31 )) -return ; - params = (struct boot_params *)__pa_nodebug (&boot_params);if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image)return ;
Greg Kroah-Hartman
maintainerPATCH 112/184 ocfs2: fix the issue with discontiguous allocation in the global_bitmap
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heming Zhao <[email protected]>
commit bd1261b16d9131d79723d982d54295e7f309797a upstream.
commit 4eb7b93e0310 ("ocfs2: improve write IO performance when fragmentation is high") introduced another regression.
The following ocfs2-test case can trigger this issue:
Quoted 3 lines
discontig_runner.sh=>activate_discontig_bg.sh=>resv_unwritten:
${RESV_UNWRITTEN_BIN} -f ${WORK_PLACE}/large_testfile -s 0 -l \
$((${FILE_MAJOR_SIZE_M}*1024*1024))
In my env, test disk size (by "fdisk -l <dev>"):
Quoted 1 line
53687091200 bytes, 104857600 sectors.
Above command is:
Quoted 3 lines
/usr/local/ocfs2-test/bin/resv_unwritten-f \/mnt/ocfs2/ocfs2-activate-discontig-bg-dir/large_testfile-s 0 -l \
53187969024
Error log:
Quoted 4 lines
[*] Reserve 50724M space for a LARGE file, reserve 200M space for future test. ioctl error 28: "No space left on device"
resv allocation failed Unknown error -1
reserve unwritten region from 0 to 53187969024.
Call flow:__ocfs2_change_file_space //by ioctl OCFS2_IOC_RESVSP64
ocfs2_allocate_unwritten_extents //start:0 len:53187969024
while()
+ ocfs2_get_clusters //cpos:0, alloc_size:1623168 (cluster number)
+ ocfs2_extend_allocation
+ ocfs2_lock_allocators
| + choose OCFS2_AC_USE_MAIN & ocfs2_cluster_group_search |
+ ocfs2_add_inode_data
ocfs2_add_clusters_in_btree
__ocfs2_claim_clusters
ocfs2_claim_suballoc_bits
+ During the allocation of the final part of the large file (after ~47GB), no chain had the required contiguous bits_wanted. Consequently, the allocation failed.
How to fix:
When OCFS2 is encountering fragmented allocation, the file system should stop attempting bits_wanted contiguous allocation and instead provide the largest available contiguous free bits from the cluster groups.
--- fs/ocfs2/suballoc.c | 38 ++++++++++++++++++++++++++++++++------ fs/ocfs2/suballoc.h | 1 + 2 files changed, 33 insertions(+), 6 deletions(-)
fs/ocfs2/suballoc.c +32 -6
@@ -698,10 +698,12 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, bg_bh =ocfs2_block_group_alloc_contig (osb, handle, alloc_inode, ac, cl); -if (PTR_ERR (bg_bh) == -ENOSPC ) +if (PTR_ERR (bg_bh) == -ENOSPC ) { + ac->ac_which =OCFS2_AC_USE_MAIN_DISCONTIG ; bg_bh =ocfs2_block_group_alloc_discontig (handle, alloc_inode, ac, cl); + }if (IS_ERR (bg_bh)) { status =PTR_ERR (bg_bh); bg_bh =NULL ;
@@ -1794,6 +1796,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, {int status;u16 chain; +u32 contig_bits;u64 next_group;struct inode *alloc_inode = ac->ac_inode;struct buffer_head *group_bh =NULL ;
@@ -1819,10 +1822,21 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, status = -ENOSPC ;/* for now, the chain search is a bit simplistic. We just use * the 1st group with any empty bits. */ -while ((status = ac->ac_group_search (alloc_inode, group_bh, - bits_wanted, min_bits, - ac->ac_max_block, - res)) == -ENOSPC ) { +while (1 ) { +if (ac->ac_which ==OCFS2_AC_USE_MAIN_DISCONTIG ) { + contig_bits =le16_to_cpu (bg->bg_contig_free_bits); +if (!contig_bits) + contig_bits =ocfs2_find_max_contig_free_bits (bg->bg_bitmap, +le16_to_cpu (bg->bg_bits),0 ); +if (bits_wanted > contig_bits && contig_bits >= min_bits) + bits_wanted = contig_bits; + } + + status = ac->ac_group_search (alloc_inode, group_bh, + bits_wanted, min_bits, + ac->ac_max_block, res); +if (status != -ENOSPC ) +break ;if (!bg->bg_next_group)break ;
@@ -1982,6 +1996,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, victim =ocfs2_find_victim_chain (cl); ac->ac_chain = victim; +search: status =ocfs2_search_chain (ac, handle, bits_wanted, min_bits, res, &bits_left);if (!status) {
@@ -2022,6 +2037,16 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, } } +/* Chains can't supply the bits_wanted contiguous space. +* We should switch to using every single bit when allocating +* from the global bitmap. */ +if (i ==le16_to_cpu (cl->cl_next_free_rec) && + status == -ENOSPC && ac->ac_which ==OCFS2_AC_USE_MAIN ) { + ac->ac_which =OCFS2_AC_USE_MAIN_DISCONTIG ; + ac->ac_chain = victim; + goto search; + } + set_hint:if (status != -ENOSPC ) {/* If the next search of this group is not likely to
@@ -2365,7 +2390,8 @@ int __ocfs2_claim_clusters(handle_t *handle,BUG_ON (ac->ac_bits_given >= ac->ac_bits_wanted);BUG_ON (ac->ac_which !=OCFS2_AC_USE_LOCAL - && ac->ac_which !=OCFS2_AC_USE_MAIN ); + && ac->ac_which !=OCFS2_AC_USE_MAIN + && ac->ac_which !=OCFS2_AC_USE_MAIN_DISCONTIG );if (ac->ac_which ==OCFS2_AC_USE_LOCAL ) {WARN_ON (min_clusters >1 );
fs/ocfs2/suballoc.h +1 -0
@@ -29,6 +29,7 @@ struct ocfs2_alloc_context {#define OCFS2_AC_USE_MAIN 2#define OCFS2_AC_USE_INODE 3#define OCFS2_AC_USE_META 4 +#define OCFS2_AC_USE_MAIN_DISCONTIG 5u32 ac_which;/* these are used by the chain search */
Signature · 1 line
2.49.0
Greg Kroah-Hartman
maintainerPATCH 113/184 ocfs2: switch osb->disable_recovery to enum
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit c0fb83088f0cc4ee4706e0495ee8b06f49daa716 upstream.
Patch series "ocfs2: Fix deadlocks in quota recovery", v3.
This implements another approach to fixing quota recovery deadlocks. We avoid grabbing sb->s_umount semaphore from ocfs2_finish_quota_recovery() and instead stop quota recovery early in ocfs2_dismount_volume().
This patch (of 3):
We will need more recovery states than just pure enable / disable to fix deadlocks with quota recovery. Switch osb->disable_recovery to enum.
--- fs/ocfs2/journal.c | 14 ++++++++------ fs/ocfs2/ocfs2.h | 7 ++++++- 2 files changed, 14 insertions(+), 7 deletions(-)
fs/ocfs2/journal.c +8 -6
@@ -174,7 +174,7 @@ int ocfs2_recovery_init(struct ocfs2_supstruct ocfs2_recovery_map *rm;mutex_init (&osb->recovery_lock); - osb->disable_recovery =0 ; + osb->recovery_state =OCFS2_REC_ENABLED ; osb->recovery_thread_task =NULL ;init_waitqueue_head (&osb->recovery_event);
@@ -206,7 +206,7 @@ void ocfs2_recovery_exit(struct ocfs2_su/* disable any new recovery threads and wait for any currently * running ones to exit. Do this before setting the vol_state. */ mutex_lock (&osb->recovery_lock); - osb->disable_recovery =1 ; + osb->recovery_state =OCFS2_REC_DISABLED ;mutex_unlock (&osb->recovery_lock);wait_event (osb->recovery_event, !ocfs2_recovery_thread_running (osb));
@@ -1582,14 +1582,16 @@ bail:void ocfs2_recovery_thread (struct ocfs2_super *osb,int node_num) { +int was_set =-1 ; +mutex_lock (&osb->recovery_lock); +if (osb->recovery_state <OCFS2_REC_DISABLED ) + was_set =ocfs2_recovery_map_set (osb, node_num);trace_ocfs2_recovery_thread (node_num, osb->node_num, - osb->disable_recovery, osb->recovery_thread_task, - osb->disable_recovery ? --1 :ocfs2_recovery_map_set (osb, node_num)); + osb->recovery_state, osb->recovery_thread_task, was_set); -if (osb->disable_recovery) +if (osb->recovery_state ==OCFS2_REC_DISABLED ) goto out;if (osb->recovery_thread_task)
fs/ocfs2/ocfs2.h +6 -1
@@ -308,6 +308,11 @@ enum ocfs2_journal_trigger_type {void ocfs2_initialize_journal_triggers (struct super_block *sb,struct ocfs2_triggers triggers[]); +enum ocfs2_recovery_state { +OCFS2_REC_ENABLED =0 , +OCFS2_REC_DISABLED , +}; +struct ocfs2_journal ;struct ocfs2_slot_info ;struct ocfs2_recovery_map ;
@@ -370,7 +375,7 @@ struct ocfs2_superstruct ocfs2_recovery_map *recovery_map;struct ocfs2_replay_map *replay_map;struct task_struct *recovery_thread_task; -int disable_recovery; +enum ocfs2_recovery_state recovery_state;wait_queue_head_t checkpoint_event;struct ocfs2_journal *journal;unsigned long osb_commit_interval;
Greg Kroah-Hartman
maintainerPATCH 114/184 ocfs2: implement handshaking with ocfs2 recovery thread
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 8f947e0fd595951460f5a6e1ac29baa82fa02eab upstream.
We will need ocfs2 recovery thread to acknowledge transitions of recovery_state when disabling particular types of recovery. This is similar to what currently happens when disabling recovery completely, just more general. Implement the handshake and use it for exit from recovery.
--- fs/ocfs2/journal.c | 52 +++++++++++++++++++++++++++++++++++----------------- fs/ocfs2/ocfs2.h | 4 ++++ 2 files changed, 39 insertions(+), 17 deletions(-)
fs/ocfs2/journal.c +35 -17
@@ -190,31 +190,48 @@ int ocfs2_recovery_init(struct ocfs2_supreturn 0 ; } -/* we can't grab the goofy sem lock from inside wait_event, so we use -* memory barriers to make sure that we'll see the null task before -* being woken up */ static int ocfs2_recovery_thread_running (struct ocfs2_super *osb) { -mb ();return osb->recovery_thread_task !=NULL ; } -void ocfs2_recovery_exit (struct ocfs2_super *osb) +static void ocfs2_recovery_disable (struct ocfs2_super *osb, +enum ocfs2_recovery_state state) { -struct ocfs2_recovery_map *rm; - -/* disable any new recovery threads and wait for any currently -* running ones to exit. Do this before setting the vol_state. */ mutex_lock (&osb->recovery_lock); - osb->recovery_state =OCFS2_REC_DISABLED ; +/* +* If recovery thread is not running, we can directly transition to +* final state. +*/ +if (!ocfs2_recovery_thread_running (osb)) { + osb->recovery_state = state +1 ; + goto out_lock; + } + osb->recovery_state = state; +/* Wait for recovery thread to acknowledge state transition */ +wait_event_cmd (osb->recovery_event, + !ocfs2_recovery_thread_running (osb) || + osb->recovery_state >= state +1 , +mutex_unlock (&osb->recovery_lock), +mutex_lock (&osb->recovery_lock)); +out_lock:mutex_unlock (&osb->recovery_lock); -wait_event (osb->recovery_event, !ocfs2_recovery_thread_running (osb)); -/* At this point, we know that no more recovery threads can be -* launched, so wait for any recovery completion work to -* complete. */ +/* +* At this point we know that no more recovery work can be queued so +* wait for any recovery completion work to complete. +*/ if (osb->ocfs2_wq)flush_workqueue (osb->ocfs2_wq); +} + +void ocfs2_recovery_exit (struct ocfs2_super *osb) +{ +struct ocfs2_recovery_map *rm; + +/* disable any new recovery threads and wait for any currently +* running ones to exit. Do this before setting the vol_state. */ +ocfs2_recovery_disable (osb,OCFS2_REC_WANT_DISABLE );/* * Now that recovery is shut down, and the osb is about to be
@@ -1569,7 +1586,8 @@ bail:ocfs2_free_replay_slots (osb); osb->recovery_thread_task =NULL ; -mb ();/* sync with ocfs2_recovery_thread_running */ +if (osb->recovery_state ==OCFS2_REC_WANT_DISABLE ) + osb->recovery_state =OCFS2_REC_DISABLED ;wake_up (&osb->recovery_event);mutex_unlock (&osb->recovery_lock);
@@ -1585,13 +1603,13 @@ void ocfs2_recovery_thread(struct ocfs2_int was_set =-1 ;mutex_lock (&osb->recovery_lock); -if (osb->recovery_state <OCFS2_REC_DISABLED ) +if (osb->recovery_state <OCFS2_REC_WANT_DISABLE ) was_set =ocfs2_recovery_map_set (osb, node_num);trace_ocfs2_recovery_thread (node_num, osb->node_num, osb->recovery_state, osb->recovery_thread_task, was_set); -if (osb->recovery_state ==OCFS2_REC_DISABLED ) +if (osb->recovery_state >=OCFS2_REC_WANT_DISABLE ) goto out;if (osb->recovery_thread_task)
fs/ocfs2/ocfs2.h +4 -0
@@ -310,6 +310,10 @@ void ocfs2_initialize_journal_triggers(senum ocfs2_recovery_state {OCFS2_REC_ENABLED =0 , +OCFS2_REC_WANT_DISABLE , +/* +* Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work +*/ OCFS2_REC_DISABLED , };
Greg Kroah-Hartman
maintainerPATCH 115/184 ocfs2: stop quota recovery before disabling quotas
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit fcaf3b2683b05a9684acdebda706a12025a6927a upstream.
Currently quota recovery is synchronized with unmount using sb->s_umount semaphore. That is however prone to deadlocks because flush_workqueue(osb->ocfs2_wq) called from umount code can wait for quota recovery to complete while ocfs2_finish_quota_recovery() waits for sb->s_umount semaphore.
Grabbing of sb->s_umount semaphore in ocfs2_finish_quota_recovery() is only needed to protect that function from disabling of quotas from ocfs2_dismount_volume(). Handle this problem by disabling quota recovery early during unmount in ocfs2_dismount_volume() instead so that we can drop acquisition of sb->s_umount from ocfs2_finish_quota_recovery().
--- fs/ocfs2/journal.c | 20 ++++++++++++++++++-- fs/ocfs2/journal.h | 1 + fs/ocfs2/ocfs2.h | 6 ++++++ fs/ocfs2/quota_local.c | 9 ++------- fs/ocfs2/super.c | 3 +++ 5 files changed, 30 insertions(+), 9 deletions(-)
fs/ocfs2/journal.c +18 -2
@@ -225,6 +225,11 @@ out_lock:flush_workqueue (osb->ocfs2_wq); } +void ocfs2_recovery_disable_quota (struct ocfs2_super *osb) +{ +ocfs2_recovery_disable (osb,OCFS2_REC_QUOTA_WANT_DISABLE ); +} +void ocfs2_recovery_exit (struct ocfs2_super *osb) {struct ocfs2_recovery_map *rm;
@@ -1489,6 +1494,18 @@ static int __ocfs2_recovery_thread(void } } restart: +if (quota_enabled) { +mutex_lock (&osb->recovery_lock); +/* Confirm that recovery thread will no longer recover quotas */ +if (osb->recovery_state ==OCFS2_REC_QUOTA_WANT_DISABLE ) { + osb->recovery_state =OCFS2_REC_QUOTA_DISABLED ; +wake_up (&osb->recovery_event); + } +if (osb->recovery_state >=OCFS2_REC_QUOTA_DISABLED ) + quota_enabled =0 ; +mutex_unlock (&osb->recovery_lock); + } + status =ocfs2_super_lock (osb,1 );if (status <0 ) {mlog_errno (status);
@@ -1592,8 +1609,7 @@ bail:mutex_unlock (&osb->recovery_lock); -if (quota_enabled) -kfree (rm_quota); +kfree (rm_quota);return status; }
fs/ocfs2/journal.h +1 -0
@@ -148,6 +148,7 @@ void ocfs2_wait_for_recovery(struct ocfsint ocfs2_recovery_init (struct ocfs2_super *osb);void ocfs2_recovery_exit (struct ocfs2_super *osb); +void ocfs2_recovery_disable_quota (struct ocfs2_super *osb);int ocfs2_compute_replay_slots (struct ocfs2_super *osb);void ocfs2_free_replay_slots (struct ocfs2_super *osb);
fs/ocfs2/ocfs2.h +6 -0
@@ -310,6 +310,12 @@ void ocfs2_initialize_journal_triggers(senum ocfs2_recovery_state {OCFS2_REC_ENABLED =0 , +OCFS2_REC_QUOTA_WANT_DISABLE , +/* +* Must be OCFS2_REC_QUOTA_WANT_DISABLE + 1 for +* ocfs2_recovery_disable_quota() to work. +*/ +OCFS2_REC_QUOTA_DISABLED ,OCFS2_REC_WANT_DISABLE ,/* * Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work
fs/ocfs2/quota_local.c +2 -7
@@ -453,8 +453,7 @@ out:/* Sync changes in local quota file into global quota file and * reinitialize local quota file. -* The function expects local quota file to be already locked and -* s_umount locked in shared mode. */ +* The function expects local quota file to be already locked. */ static int ocfs2_recover_local_quota_file (struct inode *lqinode,int type,struct ocfs2_quota_recovery *rec)
@@ -588,7 +587,6 @@ int ocfs2_finish_quota_recovery(struct o {unsigned int ino[OCFS2_MAXQUOTAS ] = {LOCAL_USER_QUOTA_SYSTEM_INODE ,LOCAL_GROUP_QUOTA_SYSTEM_INODE }; -struct super_block *sb = osb->sb;struct ocfs2_local_disk_dqinfo *ldinfo;struct buffer_head *bh;handle_t *handle;
@@ -600,7 +598,6 @@ int ocfs2_finish_quota_recovery(struct oprintk (KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for " "slot %u\n" , osb->dev_str, slot_num); -down_read (&sb->s_umount);for (type =0 ; type <OCFS2_MAXQUOTAS ; type++) {if (list_empty (&(rec->r_list[type])))continue ;
@@ -677,7 +674,6 @@ out_put:break ; } out: -up_read (&sb->s_umount);kfree (rec);return status; }
@@ -843,8 +839,7 @@ static int ocfs2_local_free_info(structocfs2_release_local_quota_bitmaps (&oinfo->dqi_chunk);/* -* s_umount held in exclusive mode protects us against racing with -* recovery thread... +* ocfs2_dismount_volume() has already aborted quota recovery... */ if (oinfo->dqi_rec) {ocfs2_free_quota_recovery (oinfo->dqi_rec);
fs/ocfs2/super.c +3 -0
@@ -1867,6 +1867,9 @@ static void ocfs2_dismount_volume(struct/* Orphan scan should be stopped as early as possible */ ocfs2_orphan_scan_stop (osb); +/* Stop quota recovery so that we can disable quotas */ +ocfs2_recovery_disable_quota (osb); +ocfs2_disable_quotas (osb);/* All dquots should be freed by now */
Greg Kroah-Hartman
maintainerPATCH 116/184 usb: dwc3: gadget: Make gadget_wakeup asynchronous
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth K <[email protected]>
commit 2372f1caeca433c4c01c2482f73fbe057f5168ce upstream.
Currently gadget_wakeup() waits for U0 synchronously if it was called from func_wakeup(), this is because we need to send the function wakeup command soon after the link is active. And the call is made synchronous by polling DSTS continuosly for 20000 times in __dwc3_gadget_wakeup(). But it observed that sometimes the link is not active even after polling 20K times, leading to remote wakeup failures. Adding a small delay between each poll helps, but that won't guarantee resolution in future. Hence make the gadget_wakeup completely asynchronous.
Since multiple interfaces can issue a function wakeup at once, add a new variable wakeup_pending_funcs which will indicate the functions that has issued func_wakup, this is represented in a bitmap format. If the link is in U3, dwc3_gadget_func_wakeup() will set the bit corresponding to interface_id and bail out. Once link comes back to U0, linksts_change irq is triggered, where the function wakeup command is sent based on bitmap.
--- drivers/usb/dwc3/core.h | 4 +++ drivers/usb/dwc3/gadget.c | 60 +++++++++++++++++----------------------------- 2 files changed, 27 insertions(+), 37 deletions(-)
drivers/usb/dwc3/core.h +4 -0
@@ -1168,6 +1168,9 @@ struct dwc3_scratchpad_array {* @gsbuscfg0_reqinfo: store GSBUSCFG0.DATRDREQINFO, DESRDREQINFO, * DATWRREQINFO, and DESWRREQINFO value passed from * glue driver. +* @wakeup_pending_funcs: Indicates whether any interface has requested for +* function wakeup in bitmap format where bit position +* represents interface_id. */ struct dwc3 {struct work_struct drd_work;
@@ -1398,6 +1401,7 @@ struct dwc3 {int num_ep_resized;struct dentry *debug_root;u32 gsbuscfg0_reqinfo; +u32 wakeup_pending_funcs; };#define INCRX_BURST_MODE 0
drivers/usb/dwc3/gadget.c +23 -37
116 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 117/184 usb: cdnsp: Fix issue with resuming from L1
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
commit 241e2ce88e5a494be7a5d44c0697592f1632fbee upstream.
In very rare cases after resuming controller from L1 to L0 it reads registers before the clock UTMI have been enabled and as the result driver reads incorrect value.
Most of registers are in APB domain clock but some of them (e.g. PORTSC) are in UTMI domain clock.
After entering to L1 state the UTMI clock can be disabled. When controller transition from L1 to L0 the port status change event is reported and in interrupt runtime function driver reads PORTSC. During this read operation controller synchronize UTMI and APB domain but UTMI clock is still disabled and in result it reads 0xFFFFFFFF value. To fix this issue driver increases APB timeout value.
The issue is platform specific and if the default value of APB timeout is not sufficient then this time should be set Individually for each platform.
--- drivers/usb/cdns3/cdnsp-gadget.c | 29 +++++++++++++++++++++++++++++ drivers/usb/cdns3/cdnsp-gadget.h | 3 +++ drivers/usb/cdns3/cdnsp-pci.c | 12 ++++++++++-- drivers/usb/cdns3/core.h | 3 +++ 4 files changed, 45 insertions(+), 2 deletions(-)
drivers/usb/cdns3/cdnsp-gadget.c +29 -0
@@ -138,6 +138,26 @@ static void cdnsp_clear_port_change_bit( (portsc & PORT_CHANGE_BITS), port_regs); } +static void cdnsp_set_apb_timeout_value (struct cdnsp_device *pdev) +{ +struct cdns *cdns =dev_get_drvdata (pdev->dev); +__le32 __iomem *reg; +void __iomem *base; +u32 offset =0 ; +u32 val; + +if (!cdns->override_apb_timeout) +return ; + + base = &pdev->cap_regs->hc_capbase; + offset =cdnsp_find_next_ext_cap (base, offset,D_XEC_PRE_REGS_CAP ); + reg = base + offset +REG_CHICKEN_BITS_3_OFFSET ; + + val =le32_to_cpu (readl (reg)); + val =CHICKEN_APB_TIMEOUT_SET (val, cdns->override_apb_timeout); +writel (cpu_to_le32 (val), reg); +} +static void cdnsp_set_chicken_bits_2 (struct cdnsp_device *pdev,u32 bit) {__le32 __iomem *reg;
@@ -1797,6 +1817,15 @@ static int cdnsp_gen_setup(struct cdnsp_ pdev->hci_version =HC_VERSION (pdev->hcc_params); pdev->hcc_params =readl (&pdev->cap_regs->hcc_params); +/* +* Override the APB timeout value to give the controller more time for +* enabling UTMI clock and synchronizing APB and UTMI clock domains. +* This fix is platform specific and is required to fixes issue with +* reading incorrect value from PORTSC register after resuming +* from L1 state. +*/ +cdnsp_set_apb_timeout_value (pdev); +cdnsp_get_rev_cap (pdev);/* Make sure the Device Controller is halted. */
drivers/usb/cdns3/cdnsp-gadget.h +3 -0
@@ -520,6 +520,9 @@ struct cdnsp_rev_cap {#define REG_CHICKEN_BITS_2_OFFSET 0x48#define CHICKEN_XDMA_2_TP_CACHE_DIS BIT(28) +#define REG_CHICKEN_BITS_3_OFFSET 0x4C +#define CHICKEN_APB_TIMEOUT_SET (p, val) (((p) & ~GENMASK(21, 0)) | (val)) +/* XBUF Extended Capability ID. */ #define XBUF_CAP_ID 0xCB#define XBUF_RX_TAG_MASK_0_OFFSET 0x1C
drivers/usb/cdns3/cdnsp-pci.c +10 -2
@@ -34,6 +34,8 @@#define PCI_CLASS_SERIAL_USB_CDNS_USB3 (PCI_CLASS_SERIAL_USB << 8 | 0x80)#define PCI_CLASS_SERIAL_USB_CDNS_UDC PCI_CLASS_SERIAL_USB_DEVICE +#define CHICKEN_APB_TIMEOUT_VALUE 0x1C20 +static struct pci_dev *cdnsp_get_second_fun (struct pci_dev *pdev) {/*
@@ -145,6 +147,14 @@ static int cdnsp_pci_probe(struct pci_de cdnsp->otg_irq = pdev->irq; } +/* +* Cadence PCI based platform require some longer timeout for APB +* to fixes domain clock synchronization issue after resuming +* controller from L1 state. +*/ + cdnsp->override_apb_timeout =CHICKEN_APB_TIMEOUT_VALUE ; +pci_set_drvdata (pdev, cdnsp); +if (pci_is_enabled (func)) { cdnsp->dev = dev; cdnsp->gadget_init = cdnsp_gadget_init;
@@ -154,8 +164,6 @@ static int cdnsp_pci_probe(struct pci_de goto free_cdnsp; } -pci_set_drvdata (pdev, cdnsp); -device_wakeup_enable (&pdev->dev);if (pci_dev_run_wake (pdev))pm_runtime_put_noidle (&pdev->dev);
drivers/usb/cdns3/core.h +3 -0
@@ -79,6 +79,8 @@ struct cdns3_platform_data {* @pdata: platform data from glue layer * @lock: spinlock structure * @xhci_plat_data: xhci private data structure pointer +* @override_apb_timeout: hold value of APB timeout. For value 0 the default +* value in CHICKEN_BITS_3 will be preserved. * @gadget_init: pointer to gadget initialization function */ struct cdns {
@@ -117,6 +119,7 @@ struct cdns {struct cdns3_platform_data *pdata;spinlock_t lock;struct xhci_plat_priv *xhci_plat_data; +u32 override_apb_timeout;int (*gadget_init)(struct cdns *cdns); };
Greg Kroah-Hartman
maintainerPATCH 118/184 usb: cdnsp: fix L1 resume issue for RTL_REVISION_NEW_LPM version
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
commit 8614ecdb1570e4fffe87ebdc62b613ed66f1f6a6 upstream.
The controllers with rtl version larger than RTL_REVISION_NEW_LPM (0x00002700) has bug which causes that controller doesn't resume from L1 state. It happens if after receiving LPM packet controller starts transitioning to L1 and in this moment the driver force resuming by write operation to PORTSC.PLS.
It's corner case and happens when write operation to PORTSC occurs during device delay before transitioning to L1 after transmitting ACK time (TL1TokenRetry).
Forcing transition from L1->L0 by driver for revision larger than RTL_REVISION_NEW_LPM is not needed, so driver can simply fix this issue through block call of cdnsp_force_l0_go function.
--- drivers/usb/cdns3/cdnsp-gadget.c | 2 ++ drivers/usb/cdns3/cdnsp-gadget.h | 3 +++ drivers/usb/cdns3/cdnsp-ring.c | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-)
drivers/usb/cdns3/cdnsp-gadget.c +2 -0
@@ -1792,6 +1792,8 @@ static void cdnsp_get_rev_cap(struct cdn reg +=cdnsp_find_next_ext_cap (reg,0 ,RTL_REV_CAP ); pdev->rev_cap = reg; + pdev->rtl_revision =readl (&pdev->rev_cap->rtl_revision); + dev_info(pdev->dev, "Rev: %08x/%08x, eps: %08x, buff: %08x/%08x\n", readl(&pdev->rev_cap->ctrl_revision), readl(&pdev->rev_cap->rtl_revision),
drivers/usb/cdns3/cdnsp-gadget.h +3 -0
@@ -1360,6 +1360,7 @@ struct cdnsp_port {* @rev_cap: Controller Capabilities Registers. * @hcs_params1: Cached register copies of read-only HCSPARAMS1 * @hcc_params: Cached register copies of read-only HCCPARAMS1 +* @rtl_revision: Cached controller rtl revision. * @setup: Temporary buffer for setup packet. * @ep0_preq: Internal allocated request used during enumeration. * @ep0_stage: ep0 stage during enumeration process.
@@ -1414,6 +1415,8 @@ struct cdnsp_device {__u32 hcs_params1;__u32 hcs_params3;__u32 hcc_params; +#define RTL_REVISION_NEW_LPM 0x2700 +__u32 rtl_revision;/* Lock used in interrupt thread context. */ spinlock_t lock;struct usb_ctrlrequest setup;
drivers/usb/cdns3/cdnsp-ring.c +2 -1
@@ -308,7 +308,8 @@ static bool cdnsp_ring_ep_doorbell(strucwritel (db_value, reg_addr); -cdnsp_force_l0_go (pdev); +if (pdev->rtl_revision <RTL_REVISION_NEW_LPM ) +cdnsp_force_l0_go (pdev);/* Doorbell was set. */ return true;
Greg Kroah-Hartman
maintainerPATCH 119/184 usb: gadget: f_ecm: Add get_status callback
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth K <[email protected]>
commit 8e3820271c517ceb89ab7442656ba49fa23ee1d0 upstream.
When host sends GET_STATUS to ECM interface, handle the request from the function driver. Since the interface is wakeup capable, set the corresponding bit, and set RW bit if the function is already armed for wakeup by the host.
--- drivers/usb/gadget/function/f_ecm.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/gadget/function/f_ecm.c +7 -0
@@ -892,6 +892,12 @@ static void ecm_resume(struct usb_functigether_resume (&ecm->port); } +static int ecm_get_status (struct usb_function *f) +{ +return (f->func_wakeup_armed ?USB_INTRF_STAT_FUNC_RW :0 ) | +USB_INTRF_STAT_FUNC_RW_CAP ; +} +static void ecm_free (struct usb_function *f) {struct f_ecm *ecm;
@@ -960,6 +966,7 @@ static struct usb_function *ecm_alloc(st ecm->port.func.disable = ecm_disable; ecm->port.func.free_func = ecm_free; ecm->port.func.suspend = ecm_suspend; + ecm->port.func.get_status = ecm_get_status; ecm->port.func.resume = ecm_resume;return &ecm->port.func;
Greg Kroah-Hartman
maintainerPATCH 120/184 usb: gadget: tegra-xudc: ACK ST_RC after clearing CTRL_RUN
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Chang <[email protected]>
commit 59820fde001500c167342257650541280c622b73 upstream.
We identified a bug where the ST_RC bit in the status register was not being acknowledged after clearing the CTRL_RUN bit in the control register. This could lead to unexpected behavior in the USB gadget drivers.
This patch resolves the issue by adding the necessary code to explicitly acknowledge ST_RC after clearing CTRL_RUN based on the programming sequence, ensuring proper state transition.
--- drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/gadget/udc/tegra-xudc.c +4 -0
@@ -1749,6 +1749,10 @@ static int __tegra_xudc_ep_disable(struc val =xudc_readl (xudc,CTRL ); val &= ~CTRL_RUN ;xudc_writel (xudc, val,CTRL ); + + val =xudc_readl (xudc,ST ); +if (val &ST_RC ) +xudc_writel (xudc,ST_RC ,ST ); }dev_info (xudc->dev,"ep %u disabled\n" , ep->index);
Greg Kroah-Hartman
maintainerPATCH 121/184 usb: gadget: Use get_status callback to set remote wakeup capability
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth K <[email protected]>
commit 5977a58dd5a4865198b0204b998adb0f634abe19 upstream.
Currently when the host sends GET_STATUS request for an interface, we use get_status callbacks to set/clear remote wakeup capability of that interface. And if get_status callback isn't present for that interface, then we assume its remote wakeup capability based on bmAttributes.
Now consider a scenario, where we have a USB configuration with multiple interfaces (say ECM + ADB), here ECM is remote wakeup capable and as of now ADB isn't. And bmAttributes will indicate the device as wakeup capable. With the current implementation, when host sends GET_STATUS request for both interfaces, we will set FUNC_RW_CAP for both. This results in USB3 CV Chapter 9.15 (Function Remote Wakeup Test) failures as host expects remote wakeup from both interfaces.
The above scenario is just an example, and the failure can be observed if we use configuration with any interface except ECM. Hence avoid configuring remote wakeup capability from composite driver based on bmAttributes, instead use get_status callbacks and let the function drivers decide this.
--- drivers/usb/gadget/composite.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/usb/gadget/composite.c +5 -7
@@ -2011,15 +2011,13 @@ composite_setup(struct usb_gadget *gadgeif (f->get_status) { status = f->get_status (f); +if (status <0 )break ; - }else { -/* Set D0 and D1 bits based on func wakeup capability */ -if (f->config->bmAttributes &USB_CONFIG_ATT_WAKEUP ) { - status |=USB_INTRF_STAT_FUNC_RW_CAP ; -if (f->func_wakeup_armed) - status |=USB_INTRF_STAT_FUNC_RW ; - } + +/* if D5 is not set, then device is not wakeup capable */ +if (!(f->config->bmAttributes &USB_CONFIG_ATT_WAKEUP )) + status &= ~(USB_INTRF_STAT_FUNC_RW_CAP |USB_INTRF_STAT_FUNC_RW ); }put_unaligned_le16 (status &0x0000ffff , req->buf);
Greg Kroah-Hartman
maintainerPATCH 122/184 usb: host: tegra: Prevent host controller crash when OTG port is used
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Lin <[email protected]>
commit 732f35cf8bdfece582f6e4a9c659119036577308 upstream.
When a USB device is connected to the OTG port, the tegra_xhci_id_work() routine transitions the PHY to host mode and calls xhci_hub_control() with the SetPortFeature command to enable port power.
In certain cases, the XHCI controller may be in a low-power state when this operation occurs. If xhci_hub_control() is invoked while the controller is suspended, the PORTSC register may return 0xFFFFFFFF, indicating a read failure. This causes xhci_hc_died() to be triggered, leading to host controller shutdown.
Example backtrace:
[ 105.445736] Workqueue: events tegra_xhci_id_work [ 105.445747] dump_backtrace+0x0/0x1e8 [ 105.445759] xhci_hc_died.part.48+0x40/0x270 [ 105.445769] tegra_xhci_set_port_power+0xc0/0x240 [ 105.445774] tegra_xhci_id_work+0x130/0x240
To prevent this, ensure the controller is fully resumed before interacting with hardware registers by calling pm_runtime_get_sync() prior to the host mode transition and xhci_hub_control().
--- drivers/usb/host/xhci-tegra.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/host/xhci-tegra.c +3 -0
@@ -1363,6 +1363,7 @@ static void tegra_xhci_id_work(struct wo tegra->otg_usb3_port =tegra_xusb_padctl_get_usb3_companion (tegra->padctl, tegra->otg_usb2_port); +pm_runtime_get_sync (tegra->dev);if (tegra->host_mode) {/* switch to host mode */ if (tegra->otg_usb3_port >=0 ) {
@@ -1392,6 +1393,7 @@ static void tegra_xhci_id_work(struct wo }tegra_xhci_set_port_power (tegra, true, true); +pm_runtime_mark_last_busy (tegra->dev); }else {if (tegra->otg_usb3_port >=0 )
@@ -1399,6 +1401,7 @@ static void tegra_xhci_id_work(struct wotegra_xhci_set_port_power (tegra, true, false); } +pm_runtime_put_autosuspend (tegra->dev); }#if IS_ENABLED (CONFIG_PM ) ||IS_ENABLED (CONFIG_PM_SLEEP )
Greg Kroah-Hartman
maintainerPATCH 123/184 usb: misc: onboard_usb_dev: fix support for Cypress HX3 hubs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukasz Czechowski <[email protected]>
commit 9f657a92805cfc98e11cf5da9e8f4e02ecff2260 upstream.
The Cypress HX3 USB3.0 hubs use different PID values depending on the product variant. The comment in compatibles table is misleading, as the currently used PIDs (0x6504 and 0x6506 for USB 3.0 and USB 2.0, respectively) are defaults for the CYUSB331x, while CYUSB330x and CYUSB332x variants use different values. Based on the datasheet [1], update the compatible usb devices table to handle different types of the hub.
The change also includes vendor mode PIDs, which are used by the hub in I2C Master boot mode, if connected EEPROM contains invalid signature or is blank. This allows to correctly boot the hub even if the EEPROM will have broken content.
Number of vcc supplies and timing requirements are the same for all HX variants, so the platform driver's match table does not have to be extended.
[1] https://www.infineon.com/dgdl/Infineon-HX3_USB_3_0_Hub_Consumer_Industrial-DataSheet-v22_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0ecb53f644b8
Table 9. PID Values
--- drivers/usb/misc/onboard_usb_dev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/usb/misc/onboard_usb_dev.c +8 -2
@@ -569,8 +569,14 @@ static void onboard_dev_usbdev_disconnec }static const struct usb_device_id onboard_dev_id_table[] = { - {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6504 ) },/* CYUSB33{0,1,2}x/CYUSB230x 3.0 HUB */ - {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6506 ) },/* CYUSB33{0,1,2}x/CYUSB230x 2.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6500 ) },/* CYUSB330x 3.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6502 ) },/* CYUSB330x 2.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6503 ) },/* CYUSB33{0,1}x 2.0 HUB, Vendor Mode */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6504 ) },/* CYUSB331x 3.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6506 ) },/* CYUSB331x 2.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6507 ) },/* CYUSB332x 2.0 HUB, Vendor Mode */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6508 ) },/* CYUSB332x 3.0 HUB */ + {USB_DEVICE (VENDOR_ID_CYPRESS ,0x650a ) },/* CYUSB332x 2.0 HUB */ {USB_DEVICE (VENDOR_ID_CYPRESS ,0x6570 ) },/* CY7C6563x 2.0 HUB */ {USB_DEVICE (VENDOR_ID_GENESYS ,0x0608 ) },/* Genesys Logic GL850G USB 2.0 HUB */ {USB_DEVICE (VENDOR_ID_GENESYS ,0x0610 ) },/* Genesys Logic GL852G USB 2.0 HUB */
Greg Kroah-Hartman
maintainerPATCH 124/184 usb: typec: tcpm: delay SNK_TRY_WAIT_DEBOUNCE to SRC_TRYWAIT transition
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: RD Babiera <[email protected]>
commit e918d3959b5ae0e793b8f815ce62240e10ba03a4 upstream.
This patch fixes Type-C Compliance Test TD 4.7.6 - Try.SNK DRP Connect SNKAS.
The compliance tester moves into SNK_UNATTACHED during toggling and expects the PUT to apply Rp after tPDDebounce of detection. If the port is in SNK_TRY_WAIT_DEBOUNCE, it will move into SRC_TRYWAIT immediately and apply Rp. This violates TD 4.7.5.V.3, where the tester confirms that the PUT attaches Rp after the transitions to Unattached.SNK for tPDDebounce.
Change the tcpm_set_state delay between SNK_TRY_WAIT_DEBOUNCE and SRC_TRYWAIT to tPDDebounce.
--- drivers/usb/typec/tcpm/tcpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/typec/tcpm/tcpm.c +1 -1
@@ -5890,7 +5890,7 @@ static void _tcpm_cc_change(struct tcpm_case SNK_TRY_WAIT_DEBOUNCE :if (!tcpm_port_is_sink (port)) { port->max_wait =0 ; -tcpm_set_state (port,SRC_TRYWAIT ,0 ); +tcpm_set_state (port,SRC_TRYWAIT ,PD_T_PD_DEBOUNCE ); }break ;case SRC_TRY_WAIT :
Greg Kroah-Hartman
maintainerPATCH 125/184 usb: typec: ucsi: displayport: Fix NULL pointer access
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Kuchynski <[email protected]>
commit 312d79669e71283d05c05cc49a1a31e59e3d9e0e upstream.
This patch ensures that the UCSI driver waits for all pending tasks in the ucsi_displayport_work workqueue to finish executing before proceeding with the partner removal.
--- drivers/usb/typec/ucsi/displayport.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/typec/ucsi/displayport.c +2 -0
@@ -296,6 +296,8 @@ void ucsi_displayport_remove_partner(strif (!dp)return ; +cancel_work_sync (&dp->work); + dp->data.conf =0 ; dp->data.status =0 ; dp->initialized = false;
Greg Kroah-Hartman
maintainerPATCH 126/184 USB: usbtmc: use interruptible sleep in usbtmc_read
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 054c5145540e5ad5b80adf23a5e3e2fc281fb8aa upstream.
usbtmc_read() calls usbtmc_generic_read() which uses interruptible sleep, but usbtmc_read() itself uses uninterruptble sleep for mutual exclusion between threads. That makes no sense.
Both should use interruptible sleep.
--- drivers/usb/class/usbtmc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/class/usbtmc.c +5 -1
@@ -1380,7 +1380,10 @@ static ssize_t usbtmc_read(struct file *if (!buffer)return -ENOMEM ; -mutex_lock (&data->io_mutex); + retval =mutex_lock_interruptible (&data->io_mutex); +if (retval <0 ) + goto exit_nolock; +if (data->zombie) { retval = -ENODEV ; goto exit;
@@ -1503,6 +1506,7 @@ static ssize_t usbtmc_read(struct file * exit:mutex_unlock (&data->io_mutex); +exit_nolock:kfree (buffer);return retval; }
Greg Kroah-Hartman
maintainerPATCH 127/184 usb: usbtmc: Fix erroneous get_stb ioctl error returns
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Penkler <[email protected]>
commit cac01bd178d6a2a23727f138d647ce1a0e8a73a1 upstream.
wait_event_interruptible_timeout returns a long
The return was being assigned to an int causing an integer overflow when the remaining jiffies > INT_MAX resulting in random error returns.
Use a long return value and convert to int ioctl return only on error.
When the return value of wait_event_interruptible_timeout was <= INT_MAX the number of remaining jiffies was returned which has no meaning for the user. Return 0 on success.
--- drivers/usb/class/usbtmc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/usb/class/usbtmc.c +8 -4
@@ -482,6 +482,7 @@ static int usbtmc_get_stb(struct usbtmc_u8 *buffer;u8 tag;int rv; +long wait_rv;dev_dbg (dev,"Enter ioctl_read_stb iin_ep_present: %d\n" , data->iin_ep_present);
@@ -511,16 +512,17 @@ static int usbtmc_get_stb(struct usbtmc_ }if (data->iin_ep_present) { - rv =wait_event_interruptible_timeout ( + wait_rv =wait_event_interruptible_timeout ( data->waitq,atomic_read (&data->iin_data_valid) !=0 , file_data->timeout); -if (rv <0 ) { -dev_dbg (dev,"wait interrupted %d\n" , rv); +if (wait_rv <0 ) { +dev_dbg (dev,"wait interrupted %ld\n" , wait_rv); + rv = wait_rv; goto exit; } -if (rv ==0 ) { +if (wait_rv ==0 ) {dev_dbg (dev,"wait timed out\n" ); rv = -ETIMEDOUT ; goto exit;
@@ -539,6 +541,8 @@ static int usbtmc_get_stb(struct usbtmc_dev_dbg (dev,"stb:0x%02x received %d\n" , (unsigned int )*stb, rv); + rv =0 ; + exit:/* bump interrupt bTag */ data->iin_bTag +=1 ;
Greg Kroah-Hartman
maintainerPATCH 128/184 usb: usbtmc: Fix erroneous wait_srq ioctl return
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Penkler <[email protected]>
commit a9747c9b8b59ab4207effd20eb91a890acb44e16 upstream.
wait_event_interruptible_timeout returns a long
The return was being assigned to an int causing an integer overflow when the remaining jiffies > INT_MAX resulting in random error returns.
Use a long return value, converting to the int ioctl return only on error.
--- drivers/usb/class/usbtmc.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
drivers/usb/class/usbtmc.c +11 -12
@@ -606,9 +606,9 @@ static int usbtmc488_ioctl_wait_srq(stru {struct usbtmc_device_data *data = file_data->data;struct device *dev = &data->intf->dev; -int rv;u32 timeout;unsigned long expire; +long wait_rv;if (!data->iin_ep_present) {dev_dbg (dev,"no interrupt endpoint present\n" );
@@ -622,25 +622,24 @@ static int usbtmc488_ioctl_wait_srq(strumutex_unlock (&data->io_mutex); - rv =wait_event_interruptible_timeout ( - data->waitq, -atomic_read (&file_data->srq_asserted) !=0 || -atomic_read (&file_data->closing), - expire); + wait_rv =wait_event_interruptible_timeout ( + data->waitq, +atomic_read (&file_data->srq_asserted) !=0 || +atomic_read (&file_data->closing), + expire);mutex_lock (&data->io_mutex);/* Note! disconnect or close could be called in the meantime */ if (atomic_read (&file_data->closing) || data->zombie) - rv = -ENODEV ; +return -ENODEV ; -if (rv <0 ) { -/* dev can be invalid now! */ -pr_debug ("%s - wait interrupted %d\n" , __func__, rv); -return rv; +if (wait_rv <0 ) { +dev_dbg (dev,"%s - wait interrupted %ld\n" , __func__, wait_rv); +return wait_rv; } -if (rv ==0 ) { +if (wait_rv ==0 ) {dev_dbg (dev,"%s - wait timed out\n" , __func__);return -ETIMEDOUT ; }
Greg Kroah-Hartman
maintainerPATCH 129/184 usb: usbtmc: Fix erroneous generic_read ioctl return
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Penkler <[email protected]>
commit 4e77d3ec7c7c0d9535ccf1138827cb9bb5480b9b upstream.
wait_event_interruptible_timeout returns a long
The return value was being assigned to an int causing an integer overflow when the remaining jiffies > INT_MAX which resulted in random error returns.
Use a long return value, converting to the int ioctl return only on error.
--- drivers/usb/class/usbtmc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/usb/class/usbtmc.c +12 -6
@@ -833,6 +833,7 @@ static ssize_t usbtmc_generic_read(strucunsigned long expire;int bufcount =1 ;int again =0 ; +long wait_rv;/* mutex already locked */
@@ -945,19 +946,24 @@ static ssize_t usbtmc_generic_read(strucif (!(flags &USBTMC_FLAG_ASYNC )) {dev_dbg (dev,"%s: before wait time %lu\n" , __func__, expire); - retval =wait_event_interruptible_timeout ( + wait_rv =wait_event_interruptible_timeout ( file_data->wait_bulk_in,usbtmc_do_transfer (file_data), expire); -dev_dbg (dev,"%s: wait returned %d\n" , - __func__, retval); +dev_dbg (dev,"%s: wait returned %ld\n" , + __func__, wait_rv); -if (retval <=0 ) { -if (retval ==0 ) - retval = -ETIMEDOUT ; +if (wait_rv <0 ) { + retval = wait_rv; goto error; } + +if (wait_rv ==0 ) { + retval = -ETIMEDOUT ; + goto error; + } + } urb =usb_get_from_anchor (&file_data->in_anchor);
Greg Kroah-Hartman
maintainerPATCH 130/184 iio: accel: adxl367: fix setting odr for activity time update
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lothar Rubusch <[email protected]>
[ Upstream commit 38f67d0264929762e54ae5948703a21f841fe706 ]
Fix setting the odr value to update activity time based on frequency derrived by recent odr, and not by obsolete odr value.
The [small] bug: When _adxl367_set_odr() is called with a new odr value, it first writes the new odr value to the hardware register ADXL367_REG_FILTER_CTL.
Second, it calls _adxl367_set_act_time_ms(), which calls adxl367_time_ms_to_samples(). Here st->odr still holds the old odr value. This st->odr member is used to derrive a frequency value, which is applied to update ADXL367_REG_TIME_ACT. Hence, the idea is to update activity time, based on possibilities and power consumption by the current ODR rate.
Finally, when the function calls return, again in _adxl367_set_odr() the new ODR is assigned to st->odr.
The fix: When setting a new ODR value is set to ADXL367_REG_FILTER_CTL, also ADXL367_REG_TIME_ACT should probably be updated with a frequency based on the recent ODR value and not the old one. Changing the location of the assignment to st->odr fixes this.
--- drivers/iio/accel/adxl367.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/iio/accel/adxl367.c +3 -7
@@ -604,18 +604,14 @@ static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)if (ret)return ret; + st->odr = odr; +/* Activity timers depend on ODR */ ret =_adxl367_set_act_time_ms (st, st->act_time_ms);if (ret)return ret; - ret =_adxl367_set_inact_time_ms (st, st->inact_time_ms); -if (ret) -return ret; - - st->odr = odr; - -return 0 ; +return _adxl367_set_inact_time_ms (st, st->inact_time_ms); }static int adxl367_set_odr (struct iio_dev *indio_dev,enum adxl367_odr odr)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 131/184 iio: temp: maxim-thermocouple: Fix potential lack of DMA safe buffer.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit f79aeb6c631b57395f37acbfbe59727e355a714c ]
The trick of using __aligned(IIO_DMA_MINALIGN) ensures that there is no overlap between buffers used for DMA and those used for driver state storage that are before the marking. It doesn't ensure anything above state variables found after the marking. Hence move this particular bit of state earlier in the structure.
--- drivers/iio/temperature/maxim_thermocouple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/maxim_thermocouple.c +1 -1
@@ -121,9 +121,9 @@ static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {struct maxim_thermocouple_data {struct spi_device *spi;const struct maxim_thermocouple_chip *chip; +char tc_type;u8 buffer[16 ]__aligned(IIO_DMA_MINALIGN) ; -char tc_type; }; static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 132/184 types: Complement the aligned types with signed 64-bit one
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit e4ca0e59c39442546866f3dd514a3a5956577daf ]
Some user may want to use aligned signed 64-bit type. Provide it for them.
Stable-dep-of: 1bb942287e05 ("iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64")
--- include/linux/types.h | 3 ++- include/uapi/linux/types.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
include/linux/types.h +2 -1
@@ -115,8 +115,9 @@ typedef u64 u_int64_t;typedef s64 int64_t ;#endif -/* this is a special 64bit data type that is 8-byte aligned */ +/* These are the special 64-bit data types that are 8-byte aligned */ #define aligned_u64 __aligned_u64 +#define aligned_s64 __aligned_s64#define aligned_be64 __aligned_be64#define aligned_le64 __aligned_le64
include/uapi/linux/types.h +1 -0
@@ -53,6 +53,7 @@ typedef __u32 __bitwise __wsum;* No conversions are necessary between 32-bit user-space and a 64-bit kernel. */ #define __aligned_u64 __u64 __attribute__((aligned(8))) +#define __aligned_s64 __s64 __attribute__((aligned(8)))#define __aligned_be64 __be64 __attribute__((aligned(8)))#define __aligned_le64 __le64 __attribute__((aligned(8)))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 133/184 iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit 1bb942287e05dc4c304a003ea85e6dd9a5e7db39 ]
The IIO ABI requires 64-bit aligned timestamps. In this case insufficient padding would have been added on architectures where an s64 is only 32-bit aligned. Use aligned_s64 to enforce the correct alignment.
--- drivers/iio/accel/adxl355_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/accel/adxl355_core.c +1 -1
@@ -231,7 +231,7 @@ struct adxl355_data {u8 transf_buf[3 ];struct {u8 buf[14 ]; -s64 ts; +aligned_s64 ts; } buffer; }__aligned(IIO_DMA_MINALIGN) ; };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 134/184 iio: adc: dln2: Use aligned_s64 for timestamp
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit 5097eaae98e53f9ab9d35801c70da819b92ca907 ]
Here the lack of marking allows the overall structure to not be sufficiently aligned resulting in misplacement of the timestamp in iio_push_to_buffers_with_timestamp(). Use aligned_s64 to force the alignment on all architectures.
--- drivers/iio/adc/dln2-adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/dln2-adc.c +1 -1
@@ -481,7 +481,7 @@ static irqreturn_t dln2_adc_trigger_h(int irq, void *p)struct iio_dev *indio_dev = pf->indio_dev;struct {__le16 values[DLN2_ADC_MAX_CHANNELS ]; -int64_t timestamp_space; +aligned_s64 timestamp_space; } data;struct dln2_adc_get_all_vals dev_data;struct dln2_adc *dln2 =iio_priv (indio_dev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 135/184 MIPS: Fix idle VS timer enqueue
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marco Crivellari <[email protected]>
[ Upstream commit 56651128e2fbad80f632f388d6bf1f39c928267a ]
MIPS 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 'wait' instruction may set the TIF_NEED_RESCHED flag. In order to deal with this possible race, IRQs interrupting __r4k_wait() rollback their return address to the beginning of __r4k_wait() 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 __r4k_wait() 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 handles both TIF_NEED_RESCHED and pending timers.
CONFIG_CPU_MICROMIPS has been removed along with the nop instructions. There, NOPs are 2 byte in size, so change the code with 3 _ssnop which are always 4 byte and remove the ifdef. Added ehb to make sure the hazard is always cleared.
--- arch/mips/include/asm/idle.h | 3 +- arch/mips/kernel/genex.S | 62 +++++++++++++++++++++--------------- arch/mips/kernel/idle.c | 7 ---- 3 files changed, 37 insertions(+), 35 deletions(-)
arch/mips/include/asm/idle.h +1 -2
@@ -6,8 +6,7 @@#include <linux/linkage.h> extern void (*cpu_wait)(void ); -extern void r4k_wait (void ); -extern asmlinkage void __r4k_wait(void); +extern asmlinkage void r4k_wait(void);extern void r4k_wait_irqoff (void );static inline int using_rollback_handler (void )
arch/mips/kernel/genex.S +36 -26
78 lines not on this page · raw message
arch/mips/kernel/idle.c +0 -7
@@ -35,13 +35,6 @@ static void __cpuidle r3081_wait(void)write_c0_conf (cfg |R30XX_CONF_HALT ); } -void __cpuidle r4k_wait(void) -{ -raw_local_irq_enable (); -__r4k_wait (); -raw_local_irq_disable (); -} -/* * This variant is preferable as it allows testing need_resched and going to * sleep depending on the outcome atomically. Unfortunately the "It is
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 136/184 MIPS: Move r4k_wait() to .cpuidle.text section
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marco Crivellari <[email protected]>
[ Upstream commit b713f27e32d87c35737ec942dd6f5ed6b7475f48 ]
Fix missing .cpuidle.text section assignment for r4k_wait() to correct backtracing with nmi_backtrace().
--- arch/mips/kernel/genex.S | 1 + 1 file changed, 1 insertion(+)
arch/mips/kernel/genex.S +1 -0
@@ -104,6 +104,7 @@ handle_vcei: __FINIT + .section .cpuidle.text,"ax" /* Align to 32 bytes for the maximum idle interrupt region size. */ .align 5 LEAF(r4k_wait)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 137/184 MIPS: Fix MAX_REG_OFFSET
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit c44572e0cc13c9afff83fd333135a0aa9b27ba26 ]
Fix MAX_REG_OFFSET to point to the last register in 'pt_regs' and not to the marker itself, which could allow regs_get_register() to return an invalid offset.
--- arch/mips/include/asm/ptrace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/include/asm/ptrace.h +2 -1
@@ -65,7 +65,8 @@ static inline void instruction_pointer_set(struct pt_regs *regs,/* Query offset/name of register from its name/offset */ extern int regs_query_register_offset (const char *name); -#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last)) +#define MAX_REG_OFFSET \ + (offsetof(struct pt_regs, __last) - sizeof(unsigned long))/** * regs_get_register() - get register value from its offset
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 138/184 riscv: misaligned: Add handling for ZCB instructions
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nylon Chen <[email protected]>
[ Upstream commit eb16b3727c05ed36420c90eca1e8f0e279514c1c ]
Add support for the Zcb extension's compressed half-word instructions (C.LHU, C.LH, and C.SH) in the RISC-V misaligned access trap handler.
--- arch/riscv/kernel/traps_misaligned.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/riscv/kernel/traps_misaligned.c +17 -0
@@ -87,6 +87,13 @@#define INSN_MATCH_C_FSWSP 0xe002#define INSN_MASK_C_FSWSP 0xe003 +#define INSN_MATCH_C_LHU 0x8400 +#define INSN_MASK_C_LHU 0xfc43 +#define INSN_MATCH_C_LH 0x8440 +#define INSN_MASK_C_LH 0xfc43 +#define INSN_MATCH_C_SH 0x8c00 +#define INSN_MASK_C_SH 0xfc43 +#define INSN_LEN (insn) ((((insn) & 0x3) < 0x3) ? 2 : 4)#if defined(CONFIG_64BIT )
@@ -405,6 +412,13 @@ int handle_misaligned_load(struct pt_regs *regs) fp =1 ; len =4 ;#endif + }else if ((insn &INSN_MASK_C_LHU ) ==INSN_MATCH_C_LHU ) { + len =2 ; + insn =RVC_RS2S (insn) <<SH_RD ; + }else if ((insn &INSN_MASK_C_LH ) ==INSN_MATCH_C_LH ) { + len =2 ; + shift =8 * (sizeof (ulong) - len); + insn =RVC_RS2S (insn) <<SH_RD ; }else { regs->epc = epc;return -1 ;
@@ -504,6 +518,9 @@ int handle_misaligned_store(struct pt_regs *regs) len =4 ; val.data_ulong =GET_F32_RS2C (insn, regs);#endif + }else if ((insn &INSN_MASK_C_SH ) ==INSN_MATCH_C_SH ) { + len =2 ; + val.data_ulong =GET_RS2S (insn, regs); }else { regs->epc = epc;return -1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 139/184 loop: Use bdev limit helpers for configuring discard
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Garry <[email protected]>
[ Upstream commit 8d3fd059dd289e6c322e5741ad56794bcce699a2 ]
Instead of directly looking at the request_queue limits, use the bdev limits helpers, which is preferable.
Stable-dep-of: f5c84eff634b ("loop: Add sanity check for read/write_iter")
--- drivers/block/loop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/block/loop.c +4 -4
@@ -710,11 +710,11 @@ static void loop_config_discard(struct loop_device *lo,* file-backed loop devices: discarded regions read back as zero. */ if (S_ISBLK (inode->i_mode)) { -struct request_queue *backingq =bdev_get_queue (I_BDEV (inode)); +struct block_device *bdev =I_BDEV (inode); - max_discard_sectors = backingq->limits.max_write_zeroes_sectors; - granularity =bdev_discard_granularity (I_BDEV (inode)) ?: -queue_physical_block_size (backingq); + max_discard_sectors =bdev_write_zeroes_sectors (bdev); + granularity =bdev_discard_granularity (bdev) ?: +bdev_physical_block_size (bdev);/* * We use punch hole to reclaim the free space used by the
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 140/184 loop: Simplify discard granularity calc
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Garry <[email protected]>
[ Upstream commit d47de6ac8842327ae1c782670283450159c55d5b ]
A bdev discard granularity is always at least SECTOR_SIZE, so don't check for a zero value.
Stable-dep-of: f5c84eff634b ("loop: Add sanity check for read/write_iter")
--- drivers/block/loop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/block/loop.c +1 -2
@@ -713,8 +713,7 @@ static void loop_config_discard(struct loop_device *lo,struct block_device *bdev =I_BDEV (inode); max_discard_sectors =bdev_write_zeroes_sectors (bdev); - granularity =bdev_discard_granularity (bdev) ?: -bdev_physical_block_size (bdev); + granularity =bdev_discard_granularity (bdev);/* * We use punch hole to reclaim the free space used by the
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 141/184 loop: Fix ABBA locking race
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: OGAWA Hirofumi <[email protected]>
[ Upstream commit b49125574cae26458d4aa02ce8f4523ba9a2a328 ]
Current loop calls vfs_statfs() while holding the q->limits_lock. If FS takes some locking in vfs_statfs callback, this may lead to ABBA locking bug (at least, FAT fs has this issue actually).
So this patch calls vfs_statfs() outside q->limits_locks instead, because looks like no reason to hold q->limits_locks while getting discord configs.
Chain exists of: &sbi->fat_lock --> &q->q_usage_counter(io)#17 --> &q->limits_lock Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&q->limits_lock);
lock(&q->q_usage_counter(io)#17);
lock(&q->limits_lock); lock(&sbi->fat_lock);
*** DEADLOCK ***
Stable-dep-of: f5c84eff634b ("loop: Add sanity check for read/write_iter")
--- drivers/block/loop.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/block/loop.c +15 -15
@@ -694,12 +694,11 @@ static void loop_sysfs_exit(struct loop_device *lo) &loop_attribute_group); } -static void loop_config_discard (struct loop_device *lo, -struct queue_limits *lim) +static void loop_get_discard_config (struct loop_device *lo, +u32 *granularity,u32 *max_discard_sectors) {struct file *file = lo->lo_backing_file;struct inode *inode = file->f_mapping->host; -u32 granularity =0 , max_discard_sectors =0 ;struct kstatfs sbuf;/*
@@ -712,24 +711,17 @@ static void loop_config_discard(struct loop_device *lo,if (S_ISBLK (inode->i_mode)) {struct block_device *bdev =I_BDEV (inode); - max_discard_sectors =bdev_write_zeroes_sectors (bdev); - granularity =bdev_discard_granularity (bdev); + *max_discard_sectors =bdev_write_zeroes_sectors (bdev); + *granularity =bdev_discard_granularity (bdev);/* * We use punch hole to reclaim the free space used by the * image a.k.a. discard. */ }else if (file->f_op->fallocate && !vfs_statfs (&file->f_path, &sbuf)) { - max_discard_sectors =UINT_MAX >>9 ; - granularity = sbuf.f_bsize; + *max_discard_sectors =UINT_MAX >>9 ; + *granularity = sbuf.f_bsize; } - - lim->max_hw_discard_sectors = max_discard_sectors; - lim->max_write_zeroes_sectors = max_discard_sectors; -if (max_discard_sectors) - lim->discard_granularity = granularity; -else - lim->discard_granularity =0 ; }struct loop_worker {
@@ -915,6 +907,7 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize)struct inode *inode = file->f_mapping->host;struct block_device *backing_bdev =NULL ;struct queue_limits lim; +u32 granularity =0 , max_discard_sectors =0 ;if (S_ISBLK (inode->i_mode)) backing_bdev =I_BDEV (inode);
@@ -924,6 +917,8 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize)if (!bsize) bsize =loop_default_blocksize (lo, backing_bdev); +loop_get_discard_config (lo, &granularity, &max_discard_sectors); + lim =queue_limits_start_update (lo->lo_queue); lim.logical_block_size = bsize; lim.physical_block_size = bsize;
@@ -933,7 +928,12 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize) lim.features |=BLK_FEAT_WRITE_CACHE ;if (backing_bdev && !bdev_nonrot (backing_bdev)) lim.features |=BLK_FEAT_ROTATIONAL ; -loop_config_discard (lo, &lim); + lim.max_hw_discard_sectors = max_discard_sectors; + lim.max_write_zeroes_sectors = max_discard_sectors; +if (max_discard_sectors) + lim.discard_granularity = granularity; +else + lim.discard_granularity =0 ;return queue_limits_commit_update (lo->lo_queue, &lim); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 142/184 loop: refactor queue limits updates
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit b38c8be255e89ffcdeb817407222d2de0b573a41 ]
Replace loop_reconfigure_limits with a slightly less encompassing loop_update_limits that expects the caller to acquire and commit the queue limits to prepare for sorting out the freeze vs limits lock ordering.
Stable-dep-of: f5c84eff634b ("loop: Add sanity check for read/write_iter")
--- drivers/block/loop.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)
drivers/block/loop.c +20 -16
@@ -901,12 +901,12 @@ static unsigned int loop_default_blocksize(struct loop_device *lo,return SECTOR_SIZE ; } -static int loop_reconfigure_limits (struct loop_device *lo,unsigned int bsize) +static void loop_update_limits (struct loop_device *lo,struct queue_limits *lim, +unsigned int bsize) {struct file *file = lo->lo_backing_file;struct inode *inode = file->f_mapping->host;struct block_device *backing_bdev =NULL ; -struct queue_limits lim;u32 granularity =0 , max_discard_sectors =0 ;if (S_ISBLK (inode->i_mode))
@@ -919,22 +919,20 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize)loop_get_discard_config (lo, &granularity, &max_discard_sectors); - lim =queue_limits_start_update (lo->lo_queue); - lim.logical_block_size = bsize; - lim.physical_block_size = bsize; - lim.io_min = bsize; - lim.features &= ~(BLK_FEAT_WRITE_CACHE |BLK_FEAT_ROTATIONAL ); + lim->logical_block_size = bsize; + lim->physical_block_size = bsize; + lim->io_min = bsize; + lim->features &= ~(BLK_FEAT_WRITE_CACHE |BLK_FEAT_ROTATIONAL );if (file->f_op->fsync && !(lo->lo_flags &LO_FLAGS_READ_ONLY )) - lim.features |=BLK_FEAT_WRITE_CACHE ; + lim->features |=BLK_FEAT_WRITE_CACHE ;if (backing_bdev && !bdev_nonrot (backing_bdev)) - lim.features |=BLK_FEAT_ROTATIONAL ; - lim.max_hw_discard_sectors = max_discard_sectors; - lim.max_write_zeroes_sectors = max_discard_sectors; + lim->features |=BLK_FEAT_ROTATIONAL ; + lim->max_hw_discard_sectors = max_discard_sectors; + lim->max_write_zeroes_sectors = max_discard_sectors;if (max_discard_sectors) - lim.discard_granularity = granularity; + lim->discard_granularity = granularity;else - lim.discard_granularity =0 ; -return queue_limits_commit_update (lo->lo_queue, &lim); + lim->discard_granularity =0 ; } static int loop_configure(struct loop_device *lo, blk_mode_t mode,
@@ -943,6 +941,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, {struct file *file =fget (config->fd);struct address_space *mapping; +struct queue_limits lim;int error;loff_t size;bool partscan;
@@ -1014,7 +1013,9 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, lo->old_gfp_mask =mapping_gfp_mask (mapping);mapping_set_gfp_mask (mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); - error =loop_reconfigure_limits (lo, config->block_size); + lim =queue_limits_start_update (lo->lo_queue); +loop_update_limits (lo, &lim, config->block_size); + error =queue_limits_commit_update (lo->lo_queue, &lim);if (error) goto out_unlock;
@@ -1382,6 +1383,7 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)static int loop_set_block_size (struct loop_device *lo,unsigned long arg) { +struct queue_limits lim;int err =0 ;if (lo->lo_state != Lo_bound)
@@ -1394,7 +1396,9 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)invalidate_bdev (lo->lo_device);blk_mq_freeze_queue (lo->lo_queue); - err =loop_reconfigure_limits (lo, arg); + lim =queue_limits_start_update (lo->lo_queue); +loop_update_limits (lo, &lim, arg); + err =queue_limits_commit_update (lo->lo_queue, &lim);loop_update_dio (lo);blk_mq_unfreeze_queue (lo->lo_queue);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 143/184 loop: factor out a loop_assign_backing_file helper
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit d278164832618bf2775c6a89e6434e2633de1eed ]
Split the code for setting up a backing file into a helper in preparation of adding more code to this path.
Stable-dep-of: f5c84eff634b ("loop: Add sanity check for read/write_iter")
--- drivers/block/loop.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/block/loop.c +10 -10
@@ -493,6 +493,14 @@ static int loop_validate_file(struct file *file, struct block_device *bdev)return 0 ; } +static void loop_assign_backing_file (struct loop_device *lo,struct file *file) +{ + lo->lo_backing_file = file; + lo->old_gfp_mask =mapping_gfp_mask (file->f_mapping); +mapping_set_gfp_mask (file->f_mapping, + lo->old_gfp_mask & ~(__GFP_IO | __GFP_FS)); +} +/* * loop_change_fd switched the backing store of a loopback device to * a new file. This is useful for operating system installers to free up
@@ -545,10 +553,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,disk_force_media_change (lo->lo_disk);blk_mq_freeze_queue (lo->lo_queue);mapping_set_gfp_mask (old_file->f_mapping, lo->old_gfp_mask); - lo->lo_backing_file = file; - lo->old_gfp_mask =mapping_gfp_mask (file->f_mapping); -mapping_set_gfp_mask (file->f_mapping, - lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); +loop_assign_backing_file (lo, file);loop_update_dio (lo);blk_mq_unfreeze_queue (lo->lo_queue); partscan = lo->lo_flags &LO_FLAGS_PARTSCAN ;
@@ -940,7 +945,6 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, const struct loop_config *config) {struct file *file =fget (config->fd); -struct address_space *mapping;struct queue_limits lim;int error;loff_t size;
@@ -976,8 +980,6 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,if (error) goto out_unlock; - mapping = file->f_mapping; -if ((config->info.lo_flags & ~LOOP_CONFIGURE_SETTABLE_FLAGS ) !=0 ) { error = -EINVAL ; goto out_unlock;
@@ -1009,9 +1011,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, lo->use_dio = lo->lo_flags &LO_FLAGS_DIRECT_IO ; lo->lo_device = bdev; - lo->lo_backing_file = file; - lo->old_gfp_mask =mapping_gfp_mask (mapping); -mapping_set_gfp_mask (mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); +loop_assign_backing_file (lo, file); lim =queue_limits_start_update (lo->lo_queue);loop_update_limits (lo, &lim, config->block_size);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 144/184 loop: Add sanity check for read/write_iter
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
[ Upstream commit f5c84eff634ba003326aa034c414e2a9dcb7c6a7 ]
Some file systems do not support read_iter/write_iter, such as selinuxfs in this issue.
So before calling them, first confirm that the interface is supported and then call it.
It is releavant in that vfs_iter_read/write have the check, and removal of their used caused szybot to be able to hit this issue.
--- drivers/block/loop.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/block/loop.c +23 -0
@@ -501,6 +501,17 @@ static void loop_assign_backing_file(struct loop_device *lo, struct file *file) lo->old_gfp_mask & ~(__GFP_IO | __GFP_FS)); } +static int loop_check_backing_file (struct file *file) +{ +if (!file->f_op->read_iter) +return -EINVAL ; + +if ((file->f_mode &FMODE_WRITE ) && !file->f_op->write_iter) +return -EINVAL ; + +return 0 ; +} +/* * loop_change_fd switched the backing store of a loopback device to * a new file. This is useful for operating system installers to free up
@@ -521,6 +532,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,if (!file)return -EBADF ; + error =loop_check_backing_file (file); +if (error) +return error; +/* suppress uevents while reconfiguring the device */ dev_set_uevent_suppress (disk_to_dev (lo->lo_disk),1 );
@@ -953,6 +968,14 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,if (!file)return -EBADF ; + +if ((mode &BLK_OPEN_WRITE ) && !file->f_op->write_iter) +return -EINVAL ; + + error =loop_check_backing_file (file); +if (error) +return error; + is_loop =is_loop_device (file);/* This is safe, since we have a reference from open(). */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 145/184 drm/panel: simple: Update timings for AUO G101EVN010
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Baker <[email protected]>
[ Upstream commit 7c6fa1797a725732981f2d77711c867166737719 ]
Switch to panel timings based on datasheet for the AUO G101EVN01.0 LVDS panel. Default timings were tested on the panel.
Previous mode-based timings resulted in horizontal display shift.
--- drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/gpu/drm/panel/panel-simple.c +13 -12
@@ -1027,27 +1027,28 @@ static const struct panel_desc auo_g070vvn01 = { }, }; -static const struct drm_display_mode auo_g101evn010_mode = { - .clock =68930 , - .hdisplay =1280 , - .hsync_start =1280 +82 , - .hsync_end =1280 +82 +2 , - .htotal =1280 +82 +2 +84 , - .vdisplay =800 , - .vsync_start =800 +8 , - .vsync_end =800 +8 +2 , - .vtotal =800 +8 +2 +6 , +static const struct display_timing auo_g101evn010_timing = { + .pixelclock = {64000000 ,68930000 ,85000000 }, + .hactive = {1280 ,1280 ,1280 }, + .hfront_porch = {8 ,64 ,256 }, + .hback_porch = {8 ,64 ,256 }, + .hsync_len = {40 ,168 ,767 }, + .vactive = {800 ,800 ,800 }, + .vfront_porch = {4 ,8 ,100 }, + .vback_porch = {4 ,8 ,100 }, + .vsync_len = {8 ,16 ,223 }, };static const struct panel_desc auo_g101evn010 = { - .modes = &auo_g101evn010_mode, - .num_modes =1 , + .timings = &auo_g101evn010_timing, + .num_timings =1 , .bpc =6 , .size = { .width =216 , .height =135 , }, .bus_format =MEDIA_BUS_FMT_RGB666_1X7X3_SPWG , + .bus_flags =DRM_BUS_FLAG_DE_HIGH , .connector_type =DRM_MODE_CONNECTOR_LVDS , };
Signature · 1 line
2.39.5