6.1.42-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 6.1.42-rc1 review
This is the start of the stable review cycle for the 6.1.42 release. There are 183 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 Thu, 27 Jul 2023 10:44:26 +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.1.42-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.1.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.1.42-rc1
Wayne Lin <[email protected]>
drm/amd/display: Add polling method to handle MST reply packet
Hersen Wu <[email protected]>
drm/amd/display: fix linux dp link lost handled only one time
Srinivasan Shanmugam <[email protected]>
drm/amd/display: Clean up errors & warnings in amdgpu_dm.c
Qingqing Zhuo <[email protected]>
drm/amd/display: force connector state when bpc changes during compliance
Wayne Lin <[email protected]>
drm/dp_mst: Clear MSG_RDY flag before sending new message
Srinivasan Shanmugam <[email protected]>
drm/amd/display: fix some coding style issues
Hamza Mahfooz <[email protected]>
drm/amd/display: use max_dsc_bpp in amdgpu_dm
Ilya Leoshkevich <[email protected]>
selftests/bpf: Fix sk_assign on s390x
Yonghong Song <[email protected]>
selftests/bpf: Workaround verification failure for fexit_bpf2bpf/func_replace_return_code
Andrii Nakryiko <[email protected]>
selftests/bpf: make test_align selftest more robust
Andrii Nakryiko <[email protected]>
bpf: aggressively forget precise markings during state checkpointing
Andrii Nakryiko <[email protected]>
bpf: stop setting precise in current state
Andrii Nakryiko <[email protected]>
bpf: allow precision tracking for programs with subprogs
Masahiro Yamada <[email protected]>
scripts/kallsyms: update the usage in the comment block
Yuma Ueda <[email protected]>
scripts/kallsyms.c Make the comment up-to-date with current implementation
Arnd Bergmann <[email protected]>
kallsyms: add kallsyms_seqs_of_names to list of special symbols
Abe Kohandel <[email protected]>
spi: dw: Remove misleading comment for Mount Evans SoC
Yunxiang Li <[email protected]>
drm/ttm: fix bulk_move corruption when adding a entry
Mohamed Khalfella <[email protected]>
tracing/histograms: Return an error if we fail to add histogram to hist_vars list
Zhang Yi <[email protected]>
jbd2: recheck chechpointing non-dirty buffer
Vladimir Oltean <[email protected]>
net: phy: prevent stale pointer dereference in phy_init()
Eric Dumazet <[email protected]>
tcp: annotate data-races around fastopenq.max_qlen
Eric Dumazet <[email protected]>
tcp: annotate data-races around icsk->icsk_user_timeout
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->notsent_lowat
Eric Dumazet <[email protected]>
tcp: annotate data-races around rskq_defer_accept
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->linger2
Eric Dumazet <[email protected]>
tcp: annotate data-races around icsk->icsk_syn_retries
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->keepalive_probes
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->keepalive_intvl
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->keepalive_time
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->tsoffset
Eric Dumazet <[email protected]>
tcp: annotate data-races around tp->tcp_tx_delay
Douglas Anderson <[email protected]>
Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_remove_adv_monitor()
Pauli Virtanen <[email protected]>
Bluetooth: ISO: fix iso_conn related locking and validity issues
Pauli Virtanen <[email protected]>
Bluetooth: hci_event: call disconnect callback before deleting conn
Pauli Virtanen <[email protected]>
Bluetooth: use RCU for hci_conn_params and iterate safely in hci_sync
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: skip bound chain on rule flush
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: skip bound chain in netns release path
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: fix improper element removal
Florian Westphal <[email protected]>
netfilter: nf_tables: can't schedule in nft_chain_validate
Florian Westphal <[email protected]>
netfilter: nf_tables: fix spurious set element insertion failure
Vitaly Rodionov <[email protected]>
ALSA: hda/realtek: Fix generic fixup definition for cs35l41 amp
Kuniyuki Iwashima <[email protected]>
llc: Don't drop packet from non-root netns.
Zhang Shurong <[email protected]>
fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe
Kuniyuki Iwashima <[email protected]>
Revert "tcp: avoid the lookup process failing to get sk in ehash table"
Yuanjun Gong <[email protected]>
net:ipv6: check return value of pskb_trim()
Wang Ming <[email protected]>
net: ipv4: Use kfree_sensitive instead of kfree
Eric Dumazet <[email protected]>
tcp: annotate data-races around tcp_rsk(req)->ts_recent
Eric Dumazet <[email protected]>
tcp: annotate data-races around tcp_rsk(req)->txhash
Antoine Tenart <[email protected]>
net: ipv4: use consistent txhash in TIME_WAIT and SYN_RECV
Florian Kauer <[email protected]>
igc: Prevent garbled TX queue with XDP ZEROCOPY
Kurt Kanzenbach <[email protected]>
igc: Avoid transmit queue timeout for XDP
Alexander Duyck <[email protected]>
bpf, arm64: Fix BTI type used for freplace attached functions
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Repeat check_max_stack_depth for async callbacks
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Fix subprog idx logic in check_max_stack_depth
Geetha sowjanya <[email protected]>
octeontx2-pf: Dont allocate BPIDs for LBK interfaces
Jiapeng Chong <[email protected]>
security: keys: Modify mismatched function name
Ahmed Zaki <[email protected]>
iavf: fix reset task race with iavf_remove()
Ahmed Zaki <[email protected]>
iavf: fix a deadlock caused by rtnl and driver's lock circular dependencies
Marcin Szycik <[email protected]>
iavf: Wait for reset in callbacks which trigger it
Przemek Kitszel <[email protected]>
iavf: make functions static where possible
Ahmed Zaki <[email protected]>
iavf: send VLAN offloading caps once after VFR
Marcin Szycik <[email protected]>
iavf: Move netdev_update_features() into watchdog task
Ahmed Zaki <[email protected]>
iavf: use internal state to free traffic IRQs
Ding Hui <[email protected]>
iavf: Fix out-of-bounds when setting channels on remove
Ding Hui <[email protected]>
iavf: Fix use-after-free in free_netdev
Tristram Ha <[email protected]>
net: dsa: microchip: correct KSZ8795 static MAC table access
Oleksij Rempel <[email protected]>
net: dsa: microchip: ksz8_r_sta_mac_table(): Avoid using error code for empty entries
Oleksij Rempel <[email protected]>
net: dsa: microchip: ksz8: Make ksz8_r_sta_mac_table() static
Oleksij Rempel <[email protected]>
net: dsa: microchip: ksz8: Separate static MAC table operations for code reuse
Victor Nogueira <[email protected]>
net: sched: cls_bpf: Undo tcf_bind_filter in case of an error
Victor Nogueira <[email protected]>
net: sched: cls_u32: Undo refcount decrement in case update failed
Victor Nogueira <[email protected]>
net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode
Victor Nogueira <[email protected]>
net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms
Dan Carpenter <[email protected]>
ASoC: SOF: ipc3-dtrace: uninitialized data in dfsentry_trace_filter_write()
Shyam Prasad N <[email protected]>
cifs: fix mid leak during reconnection after timeout threshold
Daniel Golle <[email protected]>
net: ethernet: mtk_eth_soc: handle probe deferral
Kuniyuki Iwashima <[email protected]>
bridge: Add extack warning when enabling STP in netns.
Tanmay Patil <[email protected]>
net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()
Linus Walleij <[email protected]>
dsa: mv88e6xxx: Do a final check before timing out
Yonghong Song <[email protected]>
kallsyms: strip LTO-only suffixes from promoted global functions
Zhen Lei <[email protected]>
kallsyms: Correctly sequence symbols when CONFIG_LTO_CLANG=y
Zhen Lei <[email protected]>
kallsyms: Improve the performance of kallsyms_lookup_name()
Jaewon Kim <[email protected]>
spi: s3c64xx: clear loopback bit after loopback test
Christoph Hellwig <[email protected]>
btrfs: be a bit more careful when setting mirror_num_ret in btrfs_map_block
James Clark <[email protected]>
perf build: Fix library not found error when using CSLIBS
Yangtao Li <[email protected]>
fbdev: imxfb: Removed unneeded release_mem_region
Martin Kaiser <[email protected]>
fbdev: imxfb: warn about invalid left/right margin
Jonas Gorski <[email protected]>
spi: bcm63xx: fix max prepend length
Biju Das <[email protected]>
pinctrl: renesas: rzg2l: Handle non-unique subnode names
Geert Uytterhoeven <[email protected]>
pinctrl: renesas: rzv2m: Handle non-unique subnode names
Suren Baghdasaryan <[email protected]>
sched/psi: use kernfs polling functions for PSI trigger polling
Domenico Cerasuolo <[email protected]>
sched/psi: Allow unprivileged polling of N*2s period
Domenico Cerasuolo <[email protected]>
sched/psi: Extract update_triggers side effect
Domenico Cerasuolo <[email protected]>
sched/psi: Rename existing poll members in preparation
Domenico Cerasuolo <[email protected]>
sched/psi: Rearrange polling code in preparation
Chengming Zhou <[email protected]>
sched/psi: Fix avgs_work re-arm in psi_avgs_work()
Miaohe Lin <[email protected]>
sched/fair: Use recent_used_cpu to test p->cpus_ptr
Srinivas Kandagatla <[email protected]>
ASoC: qcom: q6apm: do not close GPR port before closing graph
Srinivas Kandagatla <[email protected]>
ASoC: codecs: wcd938x: fix dB range for HPHL and HPHR
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix mbhc impedance loglevel
Vijendar Mukunda <[email protected]>
ASoC: amd: acp: fix for invalid dai id handling in acp_get_byte_count()
Hao Chen <[email protected]>
net: hns3: fix strncpy() not using dest-buf length as length issue
Ying Hsu <[email protected]>
igb: Fix igb_down hung on surprise removal
Yi Kuo <[email protected]>
wifi: iwlwifi: pcie: add device id 51F1 for killer 1675
Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: avoid baid size integer overflow
Mukesh Sisodiya <[email protected]>
wifi: iwlwifi: Add support for new PCI Id
Gustavo A. R. Silva <[email protected]>
wifi: wext-core: Fix -Wstringop-overflow warning in ioctl_standard_iw_point()
Petr Oros <[email protected]>
devlink: report devlink_port_type_warn source device
Jisheng Zhang <[email protected]>
net: ethernet: litex: add support for 64 bit stats
P Praneesh <[email protected]>
wifi: ath11k: fix memory leak in WMI firmware stats
Abe Kohandel <[email protected]>
spi: dw: Add compatible for Intel Mount Evans SoC
Ilan Peer <[email protected]>
wifi: mac80211_hwsim: Fix possible NULL dereference
Wen Gong <[email protected]>
wifi: ath11k: add support default regdb while searching board-2.bin for WCN6855
Aditi Ghag <[email protected]>
bpf: tcp: Avoid taking fast sock lock in iterator
Martin KaFai Lau <[email protected]>
bpf: Address KCSAN report on bpf_lru_list
Kui-Feng Lee <[email protected]>
bpf: Print a warning only if writing to unprivileged_bpf_disabled.
Maxime Bizon <[email protected]>
wifi: ath11k: fix registration of 6Ghz-only phy without the full channel range
Yicong Yang <[email protected]>
sched/fair: Don't balance task to its current running CPU
Paul E. McKenney <[email protected]>
rcu: Mark additional concurrent load from ->cpu_no_qs.b.exp
Shigeru Yoshida <[email protected]>
rcu-tasks: Avoid pr_info() with spin lock in cblist_init_generic()
Hans de Goede <[email protected]>
ACPI: video: Add backlight=native DMI quirk for Dell Studio 1569
Immad Mir <[email protected]>
FS: JFS: Check for read-only mounted filesystem in txBegin
Immad Mir <[email protected]>
FS: JFS: Fix null-ptr-deref Read in txBegin
Gustavo A. R. Silva <[email protected]>
MIPS: dec: prom: Address -Warray-bounds warning
Yogesh <[email protected]>
fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev
Jan Kara <[email protected]>
udf: Fix uninitialized array access for some pathnames
Christian Brauner <[email protected]>
ovl: check type and offset of struct vfsmount in ovl_entry
Marco Morandini <[email protected]>
HID: add quirk for 03f0:464a HP Elite Presenter Mouse
Ye Bin <[email protected]>
quota: fix warning in dqgrab()
Jan Kara <[email protected]>
quota: Properly disable quotas when add_dquot_ref() fails
Oswald Buddenhagen <[email protected]>
ALSA: emu10k1: roll up loops in DSP setup code for Audigy
hackyzh002 <[email protected]>
drm/radeon: Fix integer overflow in radeon_cs_parser_init
Eric Whitney <[email protected]>
ext4: correct inline offset when handling xattrs in inode body
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix soundwire initialisation race
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix codec initialisation race
Johan Hovold <[email protected]>
ASoC: codecs: wcd934x: fix resource leaks on component remove
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix missing mbhc init error handling
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix resource leaks on component remove
Sheetal <[email protected]>
ASoC: tegra: Fix AMX byte map
Johan Hovold <[email protected]>
ASoC: qdsp6: audioreach: fix topology probe deferral
Johan Hovold <[email protected]>
ASoC: codecs: wcd-mbhc-v2: fix resource leaks on component remove
Johan Hovold <[email protected]>
ASoC: codecs: wcd938x: fix missing clsh ctrl error handling
Thomas Petazzoni <[email protected]>
ASoC: cs42l51: fix driver to properly autoload with automatic module loading
Sameer Pujar <[email protected]>
ASoC: rt5640: Fix sleep in atomic context
Sheetal <[email protected]>
ASoC: tegra: Fix ADX byte map
Fabio Estevam <[email protected]>
ASoC: fsl_sai: Revert "ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode"
Matus Gajdos <[email protected]>
ASoC: fsl_sai: Disable bit clock with transmitter
Nicholas Kazlauskas <[email protected]>
drm/amd/display: Keep PHY active for DP displays on DCN31
Taimur Hassan <[email protected]>
drm/amd/display: check TG is non-null before checking if enabled
Zhikai Zhai <[email protected]>
drm/amd/display: Disable MPC split by default on special asic
Simon Ser <[email protected]>
drm/amd/display: only accept async flips for fast updates
Jocelyn Falempe <[email protected]>
drm/client: Fix memory leak in drm_client_modeset_probe
Jocelyn Falempe <[email protected]>
drm/client: Fix memory leak in drm_client_target_cloned
Alex Deucher <[email protected]>
drm/amdgpu/pm: make mclk consistent for smu 13.0.7
Alex Deucher <[email protected]>
drm/amdgpu/pm: make gfxclock consistent for sienna cichlid
Guchun Chen <[email protected]>
drm/amdgpu/vkms: relax timer deactivation by hrtimer_try_to_cancel
Ville Syrjälä <[email protected]>
dma-buf/dma-resv: Stop leaking on krealloc() failure
Matthieu Baerts <[email protected]>
selftests: tc: add ConnTrack procfs kconfig
Marc Kleine-Budde <[email protected]>
can: gs_usb: gs_can_open(): improve error handling
YueHaibing <[email protected]>
can: bcm: Fix UAF in bcm_proc_show()
Fedor Ross <[email protected]>
can: mcp251xfd: __mcp251xfd_chip_set_mode(): increase poll timeout
Mark Brown <[email protected]>
arm64/fpsimd: Ensure SME storage is allocated after SVE VL changes
Mark Brown <[email protected]>
regmap: Account for register length in SMBus I/O limits
Rob Herring <[email protected]>
of: Preserve "of-display" device name for compatibility
Mark Brown <[email protected]>
regmap: Drop initial version of maximum transfer length fixes
Matthieu Baerts <[email protected]>
selftests: tc: add 'ct' action kconfig dep
Matthieu Baerts <[email protected]>
selftests: tc: set timeout to 15 minutes
Josef Bacik <[email protected]>
btrfs: fix race between balance and cancel/pause
Miklos Szeredi <[email protected]>
fuse: ioctl: translate ENOSYS in outarg
Filipe Manana <[email protected]>
btrfs: zoned: fix memory leak after finding block group with super blocks
Josef Bacik <[email protected]>
btrfs: set_page_extent_mapped after read_folio in btrfs_cont_expand
Bernd Schubert <[email protected]>
fuse: Apply flags2 only when userspace set the FUSE_INIT_EXT
Miklos Szeredi <[email protected]>
fuse: revalidate: don't invalidate if interrupted
Filipe Manana <[email protected]>
btrfs: fix warning when putting transaction with qgroups enabled after abort
Georg Müller <[email protected]>
perf probe: Add test for regression introduced by switch to die_get_decl_file()
Petr Pavlu <[email protected]>
keys: Fix linking a duplicate key to a keyring's assoc_array
Liam R. Howlett <[email protected]>
maple_tree: fix node allocation testing on 32 bit
Peng Zhang <[email protected]>
maple_tree: set the node limit when creating a new root node
Luka Guzenko <[email protected]>
ALSA: hda/realtek: Enable Mute LED on HP Laptop 15s-eq2xxx
Christoffer Sandberg <[email protected]>
ALSA: hda/realtek: Add quirk for Clevo NS70AU
Kailang Yang <[email protected]>
ALSA: hda/realtek - remove 3k pull low procedure
Jens Axboe <[email protected]>
io_uring: treat -EAGAIN for REQ_F_NOWAIT as final for io-wq
-------------
Diffstat:
Documentation/accounting/psi.rst | 4 + Makefile | 4 +- arch/arm64/kernel/fpsimd.c | 33 +- arch/arm64/net/bpf_jit_comp.c | 8 +- arch/mips/include/asm/dec/prom.h | 2 +- drivers/acpi/video_detect.c | 8 + drivers/base/regmap/regmap-i2c.c | 8 +- drivers/base/regmap/regmap-spi-avmm.c | 2 +- drivers/base/regmap/regmap.c | 6 +- drivers/dma-buf/dma-resv.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 5 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 415 ++++++++-------- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 12 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 125 +++++ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 121 ++++- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 11 + .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 5 + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 141 +----- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +- .../drm/amd/display/dc/dcn303/dcn303_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dm_helpers.h | 6 + drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h | 4 + .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 8 +- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 2 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 54 ++- drivers/gpu/drm/drm_client_modeset.c | 6 + drivers/gpu/drm/i915/display/intel_dp.c | 7 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 12 +- drivers/gpu/drm/radeon/radeon_cs.c | 3 +- drivers/gpu/drm/ttm/ttm_resource.c | 5 +- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-quirks.c | 1 + drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 10 +- drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 1 + drivers/net/can/usb/gs_usb.c | 31 +- drivers/net/dsa/microchip/ksz8.h | 2 - drivers/net/dsa/microchip/ksz8795.c | 121 +++-- drivers/net/dsa/microchip/ksz_common.c | 8 +- drivers/net/dsa/microchip/ksz_common.h | 7 + drivers/net/dsa/mv88e6xxx/chip.c | 7 + drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 33 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 29 +- drivers/net/ethernet/intel/iavf/iavf.h | 16 +- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 39 +- drivers/net/ethernet/intel/iavf/iavf_main.c | 232 ++++++--- drivers/net/ethernet/intel/iavf/iavf_txrx.c | 43 +- drivers/net/ethernet/intel/iavf/iavf_txrx.h | 4 - drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 8 +- drivers/net/ethernet/intel/igb/igb_main.c | 5 + drivers/net/ethernet/intel/igc/igc_main.c | 12 +- drivers/net/ethernet/litex/litex_liteeth.c | 19 +- .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 5 +- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 29 +- drivers/net/ethernet/ti/cpsw_ale.c | 24 +- drivers/net/phy/phy_device.c | 21 +- drivers/net/wireless/ath/ath11k/core.c | 53 +- drivers/net/wireless/ath/ath11k/mac.c | 3 +- drivers/net/wireless/ath/ath11k/wmi.c | 5 + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 4 + drivers/net/wireless/mac80211_hwsim.c | 4 +- drivers/of/platform.c | 2 +- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 28 +- drivers/pinctrl/renesas/pinctrl-rzv2m.c | 28 +- drivers/spi/spi-bcm63xx.c | 2 +- drivers/spi/spi-dw-mmio.c | 22 + drivers/spi/spi-s3c64xx.c | 2 + drivers/video/fbdev/au1200fb.c | 3 + drivers/video/fbdev/imxfb.c | 5 +- fs/btrfs/block-group.c | 1 + fs/btrfs/inode.c | 14 +- fs/btrfs/qgroup.c | 1 + fs/btrfs/volumes.c | 20 +- fs/ext4/xattr.c | 14 + fs/fuse/dir.c | 2 +- fs/fuse/inode.c | 5 +- fs/fuse/ioctl.c | 21 +- fs/jbd2/checkpoint.c | 102 ++-- fs/jfs/jfs_dmap.c | 3 + fs/jfs/jfs_txnmgr.c | 5 + fs/jfs/namei.c | 5 + fs/overlayfs/ovl_entry.h | 9 + fs/quota/dquot.c | 5 +- fs/smb/client/connect.c | 19 +- fs/udf/unicode.c | 2 +- include/drm/display/drm_dp_mst_helper.h | 7 +- include/linux/psi.h | 5 +- include/linux/psi_types.h | 45 +- include/linux/tcp.h | 2 +- include/net/bluetooth/hci_core.h | 5 + include/net/ip.h | 2 +- include/net/tcp.h | 31 +- io_uring/io_uring.c | 8 + kernel/bpf/bpf_lru_list.c | 21 +- kernel/bpf/bpf_lru_list.h | 7 +- kernel/bpf/syscall.c | 3 +- kernel/bpf/verifier.c | 234 ++++++++- kernel/cgroup/cgroup.c | 2 +- kernel/kallsyms.c | 91 +++- kernel/kallsyms_internal.h | 1 + kernel/rcu/tasks.h | 5 +- kernel/rcu/tree_exp.h | 2 +- kernel/rcu/tree_plugin.h | 4 +- kernel/sched/fair.c | 4 +- kernel/sched/psi.c | 540 ++++++++++++--------- kernel/trace/trace_events_hist.c | 3 +- lib/maple_tree.c | 3 +- net/bluetooth/hci_conn.c | 10 +- net/bluetooth/hci_core.c | 42 +- net/bluetooth/hci_event.c | 15 +- net/bluetooth/hci_sync.c | 121 ++++- net/bluetooth/iso.c | 55 ++- net/bluetooth/mgmt.c | 26 +- net/bridge/br_stp_if.c | 3 + net/can/bcm.c | 12 +- net/core/devlink.c | 5 +- net/ipv4/esp4.c | 2 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/inet_hashtables.c | 17 +- net/ipv4/inet_timewait_sock.c | 8 +- net/ipv4/ip_output.c | 4 +- net/ipv4/tcp.c | 57 +-- net/ipv4/tcp_fastopen.c | 6 +- net/ipv4/tcp_ipv4.c | 27 +- net/ipv4/tcp_minisocks.c | 11 +- net/ipv4/tcp_output.c | 6 +- net/ipv6/ip6_gre.c | 3 +- net/ipv6/tcp_ipv6.c | 4 +- net/llc/llc_input.c | 3 - net/netfilter/nf_tables_api.c | 12 +- net/netfilter/nft_set_pipapo.c | 6 +- net/sched/cls_bpf.c | 99 ++-- net/sched/cls_matchall.c | 35 +- net/sched/cls_u32.c | 48 +- net/wireless/wext-core.c | 6 + scripts/kallsyms.c | 75 ++- scripts/link-vmlinux.sh | 4 + security/keys/request_key.c | 35 +- security/keys/trusted-keys/trusted_tpm2.c | 2 +- sound/pci/emu10k1/emufx.c | 112 +---- sound/pci/hda/patch_realtek.c | 54 ++- sound/soc/amd/acp/amd.h | 7 +- sound/soc/codecs/cs42l51-i2c.c | 6 + sound/soc/codecs/cs42l51.c | 7 - sound/soc/codecs/cs42l51.h | 1 - sound/soc/codecs/rt5640.c | 12 +- sound/soc/codecs/wcd-mbhc-v2.c | 57 ++- sound/soc/codecs/wcd934x.c | 12 + sound/soc/codecs/wcd938x.c | 86 +++- sound/soc/fsl/fsl_sai.c | 8 +- sound/soc/fsl/fsl_sai.h | 1 + sound/soc/qcom/qdsp6/q6apm.c | 7 +- sound/soc/qcom/qdsp6/topology.c | 4 +- sound/soc/sof/ipc3-dtrace.c | 9 +- sound/soc/tegra/tegra210_adx.c | 34 +- sound/soc/tegra/tegra210_amx.c | 40 +- tools/perf/Makefile.config | 4 +- .../tests/shell/test_uprobe_from_different_cu.sh | 77 +++ tools/testing/radix-tree/maple.c | 6 +- tools/testing/selftests/bpf/prog_tests/align.c | 38 +- tools/testing/selftests/bpf/prog_tests/sk_assign.c | 25 +- tools/testing/selftests/bpf/progs/connect4_prog.c | 2 +- tools/testing/selftests/bpf/progs/test_sk_assign.c | 11 + .../selftests/bpf/progs/test_sk_assign_libbpf.c | 3 + tools/testing/selftests/tc-testing/config | 2 + tools/testing/selftests/tc-testing/settings | 1 + 167 files changed, 2997 insertions(+), 1561 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/183 io_uring: treat -EAGAIN for REQ_F_NOWAIT as final for io-wq
From: Jens Axboe <[email protected]>
commit a9be202269580ca611c6cebac90eaf1795497800 upstream.
io-wq assumes that an issue is blocking, but it may not be if the request type has asked for a non-blocking attempt. If we get -EAGAIN for that case, then we need to treat it as a final result and not retry or arm poll for it.
--- io_uring/io_uring.c | 8 ++++++++ 1 file changed, 8 insertions(+)
io_uring/io_uring.c +8 -0
@@ -1803,6 +1803,14 @@ fail: ret =io_issue_sqe (req, issue_flags);if (ret != -EAGAIN )break ; + +/* +* If REQ_F_NOWAIT is set, then don't wait or retry with +* poll. -EAGAIN is final for that case. +*/ +if (req->flags &REQ_F_NOWAIT ) +break ; +/* * We can get EAGAIN for iopolled IO even though we're * forcing a sync submission from here, since we can't
Greg Kroah-Hartman
maintainerPATCH 2/183 ALSA: hda/realtek - remove 3k pull low procedure
In reply to Greg Kroah-HartmanFrom: Kailang Yang <[email protected]>
commit 69ea4c9d02b7947cdd612335a61cc1a02e544ccd upstream.
This was the ALC283 depop procedure.
Maybe this procedure wasn't suitable with new codec.
So, let us remove it. But HP 15z-fc000 must do 3k pull low. If it reboot with plugged headset,
it will have errors show don't find codec error messages. Run 3k pull low will solve issues.
So, let AMD chipset will run this for workarround.
--- sound/pci/hda/patch_realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
sound/pci/hda/patch_realtek.c +5 -2
@@ -122,6 +122,7 @@ struct alc_spec { unsigned int ultra_low_power:1; unsigned int has_hs_key:1; unsigned int no_internal_mic_pin:1; + unsigned int en_3kpull_low:1;/* for PLL fix */ hda_nid_t pll_nid;
@@ -3622,6 +3623,7 @@ static void alc256_shutup(struct hda_codif (!hp_pin) hp_pin =0x21 ; +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ hp_pin_sense =snd_hda_jack_detect (codec, hp_pin);if (hp_pin_sense)
@@ -3638,8 +3640,7 @@ static void alc256_shutup(struct hda_cod/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly * when booting with headset plugged. So skip setting it for the codec alc257 */ -if (codec->core.vendor_id !=0x10ec0236 && - codec->core.vendor_id !=0x10ec0257 ) +if (spec->en_3kpull_low)alc_update_coef_idx (codec,0x46 ,0 ,3 <<12 );if (!spec->no_shutup_pins)
@@ -10599,6 +10600,8 @@ static int patch_alc269(struct hda_codec spec->shutup = alc256_shutup; spec->init_hook = alc256_init; spec->gen.mixer_nid =0 ;/* ALC256 does not have any loopback mixer path */ +if (codec->bus->pci->vendor ==PCI_VENDOR_ID_AMD ) + spec->en_3kpull_low = true;break ;case 0x10ec0257 : spec->codec_variant =ALC269_TYPE_ALC257 ;
Greg Kroah-Hartman
maintainerPATCH 3/183 ALSA: hda/realtek: Add quirk for Clevo NS70AU
In reply to Greg Kroah-HartmanFrom: Christoffer Sandberg <[email protected]>
commit c250ef8954eda2024c8861c36e9fc1b589481fe7 upstream.
Fixes headset detection on Clevo NS70AU.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9645,6 +9645,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1558 ,0x5157 ,"Clevo W517GU1" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x51a1 ,"Clevo NS50MU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x51b1 ,"Clevo NS50AU" ,ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1558 ,0x51b3 ,"Clevo NS70AU" ,ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x5630 ,"Clevo NP50RNJS" ,ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x70a1 ,"Clevo NB70T[HJK]" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 4/183 ALSA: hda/realtek: Enable Mute LED on HP Laptop 15s-eq2xxx
In reply to Greg Kroah-HartmanFrom: Luka Guzenko <[email protected]>
commit 0659400f18c0e6c0c69d74fe5d09e7f6fbbd52a2 upstream.
The HP Laptop 15s-eq2xxx uses ALC236 codec and controls the mute LED using COEF 0x07 index 1. No existing quirk covers this configuration. Adds a new quirk and enables it for the device.
--- sound/pci/hda/patch_realtek.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
sound/pci/hda/patch_realtek.c +21 -0
@@ -4624,6 +4624,21 @@ static void alc236_fixup_hp_mute_led_coe } } +static void alc236_fixup_hp_mute_led_coefbit2 (struct hda_codec *codec, +const struct hda_fixup *fix,int action) +{ +struct alc_spec *spec = codec->spec; + +if (action ==HDA_FIXUP_ACT_PRE_PROBE ) { + spec->mute_led_polarity =0 ; + spec->mute_led_coef.idx =0x07 ; + spec->mute_led_coef.mask =1 ; + spec->mute_led_coef.on =1 ; + spec->mute_led_coef.off =0 ; +snd_hda_gen_add_mute_led_cdev (codec, coef_mute_led_set); + } +} +/* turn on/off mic-mute LED per capture hook by coef bit */ static int coef_micmute_led_set (struct led_classdev *led_cdev,enum led_brightness brightness)
@@ -7134,6 +7149,7 @@ enum {ALC285_FIXUP_HP_GPIO_LED ,ALC285_FIXUP_HP_MUTE_LED ,ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED , +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ,ALC236_FIXUP_HP_GPIO_LED ,ALC236_FIXUP_HP_MUTE_LED , ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
@@ -8557,6 +8573,10 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_spectre_x360_mute_led, }, + [ALC236_FIXUP_HP_MUTE_LED_COEFBIT2] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_coefbit2, + }, [ALC236_FIXUP_HP_GPIO_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_gpio_led,
@@ -9441,6 +9461,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x886d ,"HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC" ,ALC285_FIXUP_HP_GPIO_AMP_INIT ),SND_PCI_QUIRK (0x103c ,0x8870 ,"HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC" ,ALC285_FIXUP_HP_GPIO_AMP_INIT ),SND_PCI_QUIRK (0x103c ,0x8873 ,"HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC" ,ALC285_FIXUP_HP_GPIO_AMP_INIT ), +SND_PCI_QUIRK (0x103c ,0x887a ,"HP Laptop 15s-eq2xxx" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x888d ,"HP ZBook Power 15.6 inch G8 Mobile Workstation PC" ,ALC236_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8895 ,"HP EliteBook 855 G8 Notebook PC" ,ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED ), SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
Greg Kroah-Hartman
maintainerPATCH 5/183 maple_tree: set the node limit when creating a new root node
In reply to Greg Kroah-HartmanFrom: Peng Zhang <[email protected]>
commit 3c769fd88b9742954763a968e84de09f7ad78cfe upstream.
Set the node limit of the root node so that the last pivot of all nodes is the node limit (if the node is not full).
This patch also fixes a bug in mas_rev_awalk(). Effectively, always setting a maximum makes mas_logical_pivot() behave as mas_safe_pivot(). Without this fix, it is possible that very small tasks would fail to find the correct gap. Although this has not been observed with real tasks, it has been reported to happen in m68k nommu running the maple tree tests.
--- lib/maple_tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/maple_tree.c +2 -1
@@ -3711,7 +3711,8 @@ static inline int mas_root_expand(struct mas->offset = slot; pivots[slot] = mas->last;if (mas->last !=ULONG_MAX ) - slot++; + pivots[++slot] =ULONG_MAX ; + mas->depth =1 ;mas_set_height (mas);ma_set_meta (node, maple_leaf_64,0 , slot);
Greg Kroah-Hartman
maintainerPATCH 6/183 maple_tree: fix node allocation testing on 32 bit
In reply to Greg Kroah-HartmanFrom: Liam R. Howlett <[email protected]>
commit ef5c3de5211b5a3a8102b25aa83eb4cde65ac2fd upstream.
Internal node counting was altered and the 64 bit test was updated, however the 32bit test was missed.
Restore the 32bit test to a functional state.
--- tools/testing/radix-tree/maple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/radix-tree/maple.c +3 -3
@@ -181,9 +181,9 @@ static noinline void check_new_node(stru e = i -1 ; }else {if (i >=4 ) - e = i -4 ; -else if (i ==3 ) - e = i -2 ; + e = i -3 ; +else if (i >=1 ) + e = i -1 ;else e =0 ; }
Greg Kroah-Hartman
maintainerPATCH 7/183 keys: Fix linking a duplicate key to a keyrings assoc_array
In reply to Greg Kroah-HartmanFrom: Petr Pavlu <[email protected]>
commit d55901522f96082a43b9842d34867363c0cdbac5 upstream.
When making a DNS query inside the kernel using dns_query(), the request code can in rare cases end up creating a duplicate index key in the assoc_array of the destination keyring. It is eventually found by a BUG_ON() check in the assoc_array implementation and results in a crash.
Example report:
[2158499.700025] kernel BUG at ../lib/assoc_array.c:652! [2158499.700039] invalid opcode: 0000 [#1] SMP PTI [2158499.700065] CPU: 3 PID: 31985 Comm: kworker/3:1 Kdump: loaded Not tainted 5.3.18-150300.59.90-default #1 SLE15-SP3 [2158499.700096] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 [2158499.700351] Workqueue: cifsiod cifs_resolve_server [cifs] [2158499.700380] RIP: 0010:assoc_array_insert+0x85f/0xa40 [2158499.700401] Code: ff 74 2b 48 8b 3b 49 8b 45 18 4c 89 e6 48 83 e7 fe e8 95 ec 74 00 3b 45 88 7d db 85 c0 79 d4 0f 0b 0f 0b 0f 0b e8 41 f2 be ff <0f> 0b 0f 0b 81 7d 88 ff ff ff 7f 4c 89 eb 4c 8b ad 58 ff ff ff 0f [2158499.700448] RSP: 0018:ffffc0bd6187faf0 EFLAGS: 00010282 [2158499.700470] RAX: ffff9f1ea7da2fe8 RBX: ffff9f1ea7da2fc1 RCX: 0000000000000005 [2158499.700492] RDX: 0000000000000000 RSI: 0000000000000005 RDI: 0000000000000000 [2158499.700515] RBP: ffffc0bd6187fbb0 R08: ffff9f185faf1100 R09: 0000000000000000 [2158499.700538] R10: ffff9f1ea7da2cc0 R11: 000000005ed8cec8 R12: ffffc0bd6187fc28 [2158499.700561] R13: ffff9f15feb8d000 R14: ffff9f1ea7da2fc0 R15: ffff9f168dc0d740 [2158499.700585] FS: 0000000000000000(0000) GS:ffff9f185fac0000(0000) knlGS:0000000000000000 [2158499.700610] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [2158499.700630] CR2: 00007fdd94fca238 CR3: 0000000809d8c006 CR4: 00000000003706e0 [2158499.700702] Call Trace: [2158499.700741] ? key_alloc+0x447/0x4b0 [2158499.700768] ? __key_link_begin+0x43/0xa0 [2158499.700790] __key_link_begin+0x43/0xa0 [2158499.700814] request_key_and_link+0x2c7/0x730 [2158499.700847] ? dns_resolver_read+0x20/0x20 [dns_resolver] [2158499.700873] ? key_default_cmp+0x20/0x20 [2158499.700898] request_key_tag+0x43/0xa0 [2158499.700926] dns_query+0x114/0x2ca [dns_resolver] [2158499.701127] dns_resolve_server_name_to_ip+0x194/0x310 [cifs] [2158499.701164] ? scnprintf+0x49/0x90 [2158499.701190] ? __switch_to_asm+0x40/0x70 [2158499.701211] ? __switch_to_asm+0x34/0x70 [2158499.701405] reconn_set_ipaddr_from_hostname+0x81/0x2a0 [cifs] [2158499.701603] cifs_resolve_server+0x4b/0xd0 [cifs] [2158499.701632] process_one_work+0x1f8/0x3e0 [2158499.701658] worker_thread+0x2d/0x3f0 [2158499.701682] ? process_one_work+0x3e0/0x3e0 [2158499.701703] kthread+0x10d/0x130 [2158499.701723] ? kthread_park+0xb0/0xb0 [2158499.701746] ret_from_fork+0x1f/0x40
The situation occurs as follows:
* Some kernel facility invokes dns_query() to resolve a hostname, for example, "abcdef". The function registers its global DNS resolver cache as current->cred.thread_keyring and passes the query to request_key_net() -> request_key_tag() -> request_key_and_link().
* Function request_key_and_link() creates a keyring_search_context object. Its match_data.cmp method gets set via a call to type->match_preparse() (resolves to dns_resolver_match_preparse()) to dns_resolver_cmp().
* Function request_key_and_link() continues and invokes search_process_keyrings_rcu() which returns that a given key was not found. The control is then passed to request_key_and_link() -> construct_alloc_key().
* Concurrently to that, a second task similarly makes a DNS query for "abcdef." and its result gets inserted into the DNS resolver cache.
* Back on the first task, function construct_alloc_key() first runs __key_link_begin() to determine an assoc_array_edit operation to insert a new key. Index keys in the array are compared exactly as-is, using keyring_compare_object(). The operation finds that "abcdef" is not yet present in the destination keyring.
* Function construct_alloc_key() continues and checks if a given key is already present on some keyring by again calling search_process_keyrings_rcu(). This search is done using dns_resolver_cmp() and "abcdef" gets matched with now present key "abcdef.".
* The found key is linked on the destination keyring by calling __key_link() and using the previously calculated assoc_array_edit operation. This inserts the "abcdef." key in the array but creates a duplicity because the same index key is already present.
Fix the problem by postponing __key_link_begin() in construct_alloc_key() until an actual key which should be linked into the destination keyring is determined.
--- security/keys/request_key.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-)
security/keys/request_key.c +24 -11
@@ -401,17 +401,21 @@ static int construct_alloc_key(struct keset_bit (KEY_FLAG_USER_CONSTRUCT , &key->flags);if (dest_keyring) { - ret =__key_link_lock (dest_keyring, &ctx->index_key); + ret =__key_link_lock (dest_keyring, &key->index_key);if (ret <0 ) goto link_lock_failed; - ret =__key_link_begin (dest_keyring, &ctx->index_key, &edit); -if (ret <0 ) - goto link_prealloc_failed; } -/* attach the key to the destination keyring under lock, but we do need +/* +* Attach the key to the destination keyring under lock, but we do need * to do another check just in case someone beat us to it whilst we -* waited for locks */ +* waited for locks. +* +* The caller might specify a comparison function which looks for keys +* that do not exactly match but are still equivalent from the caller's +* perspective. The __key_link_begin() operation must be done only after +* an actual key is determined. +*/ mutex_lock (&key_construction_mutex);rcu_read_lock ();
@@ -420,12 +424,16 @@ static int construct_alloc_key(struct keif (!IS_ERR (key_ref)) goto key_already_present; -if (dest_keyring) +if (dest_keyring) { + ret =__key_link_begin (dest_keyring, &key->index_key, &edit); +if (ret <0 ) + goto link_alloc_failed;__key_link (dest_keyring, key, &edit); + }mutex_unlock (&key_construction_mutex);if (dest_keyring) -__key_link_end (dest_keyring, &ctx->index_key, edit); +__key_link_end (dest_keyring, &key->index_key, edit);mutex_unlock (&user->cons_lock); *_key = key;kleave (" = 0 [%d]" ,key_serial (key));
@@ -438,10 +446,13 @@ key_already_present:mutex_unlock (&key_construction_mutex); key =key_ref_to_ptr (key_ref);if (dest_keyring) { + ret =__key_link_begin (dest_keyring, &key->index_key, &edit); +if (ret <0 ) + goto link_alloc_failed_unlocked; ret =__key_link_check_live_key (dest_keyring, key);if (ret ==0 )__key_link (dest_keyring, key, &edit); -__key_link_end (dest_keyring, &ctx->index_key, edit); +__key_link_end (dest_keyring, &key->index_key, edit);if (ret <0 ) goto link_check_failed; }
@@ -456,8 +467,10 @@ link_check_failed:kleave (" = %d [linkcheck]" , ret);return ret; -link_prealloc_failed: -__key_link_end (dest_keyring, &ctx->index_key, edit); +link_alloc_failed: +mutex_unlock (&key_construction_mutex); +link_alloc_failed_unlocked: +__key_link_end (dest_keyring, &key->index_key, edit); link_lock_failed:mutex_unlock (&user->cons_lock);key_put (key);
Greg Kroah-Hartman
maintainerPATCH 8/183 perf probe: Add test for regression introduced by switch to die_get_decl_file()
In reply to Greg Kroah-HartmanFrom: Georg Müller <[email protected]>
commit 56cbeacf143530576905623ac72ae0964f3293a6 upstream.
This patch adds a test to validate that 'perf probe' works for binaries where DWARF info is split into multiple CUs
--- tools/perf/tests/shell/test_uprobe_from_different_cu.sh | 77 ++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 tools/perf/tests/shell/test_uprobe_from_different_cu.sh
tools/perf/tests/shell/test_uprobe_from_different_cu.sh new file +77 -0
@@ -0,0 +1,77 @@ +#!/bin/bash +# test perf probe of function from different CU +# SPDX-License-Identifier: GPL-2.0 + +set -e + +temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX) + +cleanup() +{ + trap - EXIT TERM INT + if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then + echo "--- Cleaning up ---" + perf probe -x ${temp_dir}/testfile -d foo + rm -f "${temp_dir}/"* + rmdir "${temp_dir}" + fi +} + +trap_cleanup() +{ + cleanup + exit 1 +} + +trap trap_cleanup EXIT TERM INT + +cat > ${temp_dir}/testfile-foo.h << EOF +struct t +{ + int *p; + int c; +}; + +extern int foo (int i, struct t *t); +EOF + +cat > ${temp_dir}/testfile-foo.c << EOF +#include "testfile-foo.h" + +int +foo (int i, struct t *t) +{ + int j, res = 0; + for (j = 0; j < i && j < t->c; j++) + res += t->p[j]; + + return res; +} +EOF + +cat > ${temp_dir}/testfile-main.c << EOF +#include "testfile-foo.h" + +static struct t g; + +int +main (int argc, char **argv) +{ + int i; + int j[argc]; + g.c = argc; + g.p = j; + for (i = 0; i < argc; i++) + j[i] = (int) argv[i][0]; + return foo (3, &g); +} +EOF + +gcc -g -Og -flto -c ${temp_dir}/testfile-foo.c -o ${temp_dir}/testfile-foo.o +gcc -g -Og -c ${temp_dir}/testfile-main.c -o ${temp_dir}/testfile-main.o +gcc -g -Og -o ${temp_dir}/testfile ${temp_dir}/testfile-foo.o ${temp_dir}/testfile-main.o + +perf probe -x ${temp_dir}/testfile --funcs foo +perf probe -x ${temp_dir}/testfile foo + +cleanup
Greg Kroah-Hartman
maintainerPATCH 9/183 btrfs: fix warning when putting transaction with qgroups enabled after abort
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit aa84ce8a78a1a5c10cdf9c7a5fb0c999fbc2c8d6 upstream.
If we have a transaction abort with qgroups enabled we get a warning triggered when doing the final put on the transaction, like this:
[552.6789] ------------[ cut here ]------------ [552.6815] WARNING: CPU: 4 PID: 81745 at fs/btrfs/transaction.c:144 btrfs_put_transaction+0x123/0x130 [btrfs] [552.6817] Modules linked in: btrfs blake2b_generic xor (...) [552.6819] CPU: 4 PID: 81745 Comm: btrfs-transacti Tainted: G W 6.4.0-rc6-btrfs-next-134+ #1 [552.6819] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [552.6819] RIP: 0010:btrfs_put_transaction+0x123/0x130 [btrfs] [552.6821] Code: bd a0 01 00 (...) [552.6821] RSP: 0018:ffffa168c0527e28 EFLAGS: 00010286 [552.6821] RAX: ffff936042caed00 RBX: ffff93604a3eb448 RCX: 0000000000000000 [552.6821] RDX: ffff93606421b028 RSI: ffffffff92ff0878 RDI: ffff93606421b010 [552.6821] RBP: ffff93606421b000 R08: 0000000000000000 R09: ffffa168c0d07c20 [552.6821] R10: 0000000000000000 R11: ffff93608dc52950 R12: ffffa168c0527e70 [552.6821] R13: ffff93606421b000 R14: ffff93604a3eb420 R15: ffff93606421b028 [552.6821] FS: 0000000000000000(0000) GS:ffff93675fb00000(0000) knlGS:0000000000000000 [552.6821] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [552.6821] CR2: 0000558ad262b000 CR3: 000000014feda005 CR4: 0000000000370ee0 [552.6822] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [552.6822] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [552.6822] Call Trace: [552.6822] <TASK> [552.6822] ? __warn+0x80/0x130 [552.6822] ? btrfs_put_transaction+0x123/0x130 [btrfs] [552.6824] ? report_bug+0x1f4/0x200 [552.6824] ? handle_bug+0x42/0x70 [552.6824] ? exc_invalid_op+0x14/0x70 [552.6824] ? asm_exc_invalid_op+0x16/0x20 [552.6824] ? btrfs_put_transaction+0x123/0x130 [btrfs] [552.6826] btrfs_cleanup_transaction+0xe7/0x5e0 [btrfs] [552.6828] ? _raw_spin_unlock_irqrestore+0x23/0x40 [552.6828] ? try_to_wake_up+0x94/0x5e0 [552.6828] ? __pfx_process_timeout+0x10/0x10 [552.6828] transaction_kthread+0x103/0x1d0 [btrfs] [552.6830] ? __pfx_transaction_kthread+0x10/0x10 [btrfs] [552.6832] kthread+0xee/0x120 [552.6832] ? __pfx_kthread+0x10/0x10 [552.6832] ret_from_fork+0x29/0x50 [552.6832] </TASK> [552.6832] ---[ end trace 0000000000000000 ]---
This corresponds to this line of code:
void btrfs_put_transaction(struct btrfs_transaction *transaction)
{
(...)
WARN_ON(!RB_EMPTY_ROOT(
&transaction->delayed_refs.dirty_extent_root));
(...)
}The warning happens because btrfs_qgroup_destroy_extent_records(), called in the transaction abort path, we free all entries from the rbtree "dirty_extent_root" with rbtree_postorder_for_each_entry_safe(), but we don't actually empty the rbtree - it's still pointing to nodes that were freed.
So set the rbtree's root node to NULL to avoid this warning (assign RB_ROOT).
--- fs/btrfs/qgroup.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/qgroup.c +1 -0
@@ -4410,4 +4410,5 @@ void btrfs_qgroup_destroy_extent_recordsulist_free (entry->old_roots);kfree (entry); } + *root =RB_ROOT ; }
Greg Kroah-Hartman
maintainerPATCH 10/183 fuse: revalidate: dont invalidate if interrupted
In reply to Greg Kroah-HartmanFrom: Miklos Szeredi <[email protected]>
commit a9d1c4c6df0e568207907c04aed9e7beb1294c42 upstream.
If the LOOKUP request triggered from fuse_dentry_revalidate() is interrupted, then the dentry will be invalidated, possibly resulting in submounts being unmounted.
--- fs/fuse/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/fuse/dir.c +1 -1
@@ -258,7 +258,7 @@ static int fuse_dentry_revalidate(structspin_unlock (&fi->lock); }kfree (forget); -if (ret == -ENOMEM ) +if (ret == -ENOMEM || ret == -EINTR ) goto out;if (ret ||fuse_invalid_attr (&outarg.attr) ||fuse_stale_inode (inode, outarg.generation, &outarg.attr))
Greg Kroah-Hartman
maintainerPATCH 11/183 fuse: Apply flags2 only when userspace set the FUSE_INIT_EXT
In reply to Greg Kroah-HartmanFrom: Bernd Schubert <[email protected]>
commit 3066ff93476c35679cb07a97cce37d9bb07632ff upstream.
This is just a safety precaution to avoid checking flags on memory that was initialized on the user space side. libfuse zeroes struct fuse_init_out outarg, but this is not guranteed to be done in all implementations. Better is to act on flags and to only apply flags2 when FUSE_INIT_EXT is set.
There is a risk with this change, though - it might break existing user space libraries, which are already using flags2 without setting FUSE_INIT_EXT.
The corresponding libfuse patch is here
https://github.com/libfuse/libfuse/pull/662
--- fs/fuse/inode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/fuse/inode.c +4 -1
@@ -1127,7 +1127,10 @@ static void process_init_reply(struct fuprocess_init_limits (fc, arg);if (arg->minor >=6 ) { -u64 flags = arg->flags | (u64 ) arg->flags2 <<32 ; +u64 flags = arg->flags; + +if (flags &FUSE_INIT_EXT ) + flags |= (u64 ) arg->flags2 <<32 ; ra_pages = arg->max_readahead /PAGE_SIZE ;if (flags &FUSE_ASYNC_READ )
Greg Kroah-Hartman
maintainerPATCH 12/183 btrfs: set_page_extent_mapped after read_folio in btrfs_cont_expand
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 17b17fcd6d446b95904a6929c40012ee7f0afc0c upstream.
While trying to get the subpage blocksize tests running, I hit the following panic on generic/476
assertion failed: PagePrivate(page) && page->private, in fs/btrfs/subpage.c:229 kernel BUG at fs/btrfs/subpage.c:229!
Internal error: Oops - BUG: 00000000f2000800 [#1] SMP CPU: 1 PID: 1453 Comm: fsstress Not tainted 6.4.0-rc7+ #12 Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20230301gitf80f052277c8-26.fc38 03/01/2023 pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) pc : btrfs_subpage_assert+0xbc/0xf0 lr : btrfs_subpage_assert+0xbc/0xf0 Call trace: btrfs_subpage_assert+0xbc/0xf0 btrfs_subpage_clear_checked+0x38/0xc0 btrfs_page_clear_checked+0x48/0x98 btrfs_truncate_block+0x5d0/0x6a8 btrfs_cont_expand+0x5c/0x528 btrfs_write_check.isra.0+0xf8/0x150 btrfs_buffered_write+0xb4/0x760 btrfs_do_write_iter+0x2f8/0x4b0 btrfs_file_write_iter+0x1c/0x30 do_iter_readv_writev+0xc8/0x158 do_iter_write+0x9c/0x210 vfs_iter_write+0x24/0x40 iter_file_splice_write+0x224/0x390 direct_splice_actor+0x38/0x68 splice_direct_to_actor+0x12c/0x260 do_splice_direct+0x90/0xe8 generic_copy_file_range+0x50/0x90 vfs_copy_file_range+0x29c/0x470 __arm64_sys_copy_file_range+0xcc/0x498 invoke_syscall.constprop.0+0x80/0xd8 do_el0_svc+0x6c/0x168 el0_svc+0x50/0x1b0 el0t_64_sync_handler+0x114/0x120 el0t_64_sync+0x194/0x198
This happens because during btrfs_cont_expand we'll get a page, set it as mapped, and if it's not Uptodate we'll read it. However between the read and re-locking the page we could have called release_folio() on the page, but left the page in the file mapping. release_folio() can clear the page private, and thus further down we blow up when we go to modify the subpage bits.
Fix this by putting the set_page_extent_mapped() after the read. This is safe because read_folio() will call set_page_extent_mapped() before it does the read, and then if we clear page private but leave it on the mapping we're completely safe re-setting set_page_extent_mapped(). With this patch I can now run generic/476 without panicing.
--- fs/btrfs/inode.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +11 -3
@@ -4913,9 +4913,6 @@ again: ret = -ENOMEM ; goto out; } - ret =set_page_extent_mapped (page); -if (ret <0 ) - goto out_unlock;if (!PageUptodate (page)) { ret =btrfs_read_folio (NULL ,page_folio (page));
@@ -4930,6 +4927,17 @@ again: goto out_unlock; } } + +/* +* We unlock the page after the io is completed and then re-lock it +* above. release_folio() could have come in between that and cleared +* PagePrivate(), but left the page in the mapping. Set the page mapped +* here to make sure it's properly set for the subpage stuff. +*/ + ret =set_page_extent_mapped (page); +if (ret <0 ) + goto out_unlock; +wait_on_page_writeback (page);lock_extent (io_tree, block_start, block_end, &cached_state);
Greg Kroah-Hartman
maintainerPATCH 13/183 btrfs: zoned: fix memory leak after finding block group with super blocks
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit f1a07c2b4e2c473ec322b8b9ece071b8c88a3512 upstream.
At exclude_super_stripes(), if we happen to find a block group that has super blocks mapped to it and we are on a zoned filesystem, we error out as this is not supposed to happen, indicating either a bug or maybe some memory corruption for example. However we are exiting the function without freeing the memory allocated for the logical address of the super blocks. Fix this by freeing the logical address.
--- fs/btrfs/block-group.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/block-group.c +1 -0
@@ -1894,6 +1894,7 @@ static int exclude_super_stripes(struct/* Shouldn't have super stripes in sequential zones */ if (zoned && nr) { +kfree (logical);btrfs_err (fs_info,"zoned: block group %llu must not contain super block" , cache->start);
Greg Kroah-Hartman
maintainerPATCH 14/183 fuse: ioctl: translate ENOSYS in outarg
In reply to Greg Kroah-HartmanFrom: Miklos Szeredi <[email protected]>
commit 6a567e920fd0451bf29abc418df96c3365925770 upstream.
Fuse shouldn't return ENOSYS from its ioctl implementation. If userspace responds with ENOSYS it should be translated to ENOTTY.
There are two ways to return an error from the IOCTL request:
- fuse_out_header.error
- fuse_ioctl_out.result
Commit 02c0cab8e734 ("fuse: ioctl: translate ENOSYS") already fixed this issue for the first case, but missed the second case. This patch fixes the second case.
--- fs/fuse/ioctl.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
fs/fuse/ioctl.c +13 -8
@@ -9,14 +9,23 @@#include <linux/compat.h> #include <linux/fileattr.h> -static ssize_t fuse_send_ioctl (struct fuse_mount *fm,struct fuse_args *args) +static ssize_t fuse_send_ioctl (struct fuse_mount *fm,struct fuse_args *args, +struct fuse_ioctl_out *outarg) { -ssize_t ret =fuse_simple_request (fm, args); +ssize_t ret; + + args->out_args[0 ].size =sizeof (*outarg); + args->out_args[0 ].value = outarg; + + ret =fuse_simple_request (fm, args);/* Translate ENOSYS, which shouldn't be returned from fs */ if (ret == -ENOSYS ) ret = -ENOTTY ; +if (ret >=0 && outarg->result == -ENOSYS ) + outarg->result = -ENOTTY ; +return ret; }
@@ -264,13 +273,11 @@ long fuse_do_ioctl(struct file *file, un } ap.args.out_numargs =2 ; - ap.args.out_args[0 ].size =sizeof (outarg); - ap.args.out_args[0 ].value = &outarg; ap.args.out_args[1 ].size = out_size; ap.args.out_pages = true; ap.args.out_argvar = true; - transferred =fuse_send_ioctl (fm, &ap.args); + transferred =fuse_send_ioctl (fm, &ap.args, &outarg); err = transferred;if (transferred <0 ) goto out;
@@ -399,12 +406,10 @@ static int fuse_priv_ioctl(struct inode args.in_args[1 ].size = inarg.in_size; args.in_args[1 ].value = ptr; args.out_numargs =2 ; - args.out_args[0 ].size =sizeof (outarg); - args.out_args[0 ].value = &outarg; args.out_args[1 ].size = inarg.out_size; args.out_args[1 ].value = ptr; - err =fuse_send_ioctl (fm, &args); + err =fuse_send_ioctl (fm, &args, &outarg);if (!err) {if (outarg.result <0 ) err = outarg.result;
Greg Kroah-Hartman
maintainerPATCH 15/183 btrfs: fix race between balance and cancel/pause
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit b19c98f237cd76981aaded52c258ce93f7daa8cb upstream.
Syzbot reported a panic that looks like this:
assertion failed: fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED, in fs/btrfs/ioctl.c:465
------------[ cut here ]------------ kernel BUG at fs/btrfs/messages.c:259! RIP: 0010:btrfs_assertfail+0x2c/0x30 fs/btrfs/messages.c:259 Call Trace: <TASK> btrfs_exclop_balance fs/btrfs/ioctl.c:465 [inline] btrfs_ioctl_balance fs/btrfs/ioctl.c:3564 [inline] btrfs_ioctl+0x531e/0x5b30 fs/btrfs/ioctl.c:4632 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+0x197/0x210 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
The reproducer is running a balance and a cancel or pause in parallel. The way balance finishes is a bit wonky, if we were paused we need to save the balance_ctl in the fs_info, but clear it otherwise and cleanup. However we rely on the return values being specific errors, or having a cancel request or no pause request. If balance completes and returns 0, but we have a pause or cancel request we won't do the appropriate cleanup, and then the next time we try to start a balance we'll trip this ASSERT.
The error handling is just wrong here, we always want to clean up, unless we got -ECANCELLED and we set the appropriate pause flag in the exclusive op. With this patch the reproducer ran for an hour without tripping, previously it would trip in less than a few minutes.
--- fs/btrfs/volumes.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
fs/btrfs/volumes.c +4 -10
@@ -4092,14 +4092,6 @@ static int alloc_profile_is_valid(u64 flreturn has_single_bit_set (flags); } -static inline int balance_need_close (struct btrfs_fs_info *fs_info) -{ -/* cancel requested || normal exit path */ -return atomic_read (&fs_info->balance_cancel_req) || - (atomic_read (&fs_info->balance_pause_req) ==0 && -atomic_read (&fs_info->balance_cancel_req) ==0 ); -} -/* * Validate target profile against allowed profiles and return true if it's OK. * Otherwise print the error message and return false.
@@ -4289,6 +4281,7 @@ int btrfs_balance(struct btrfs_fs_info *u64 num_devices;unsigned seq;bool reducing_redundancy; +bool paused = false;int i; if (btrfs_fs_closing(fs_info) ||
@@ -4419,6 +4412,7 @@ int btrfs_balance(struct btrfs_fs_info *if (ret == -ECANCELED &&atomic_read (&fs_info->balance_pause_req)) {btrfs_info (fs_info,"balance: paused" );btrfs_exclop_balance (fs_info,BTRFS_EXCLOP_BALANCE_PAUSED ); + paused = true; }/* * Balance can be canceled by:
@@ -4447,8 +4441,8 @@ int btrfs_balance(struct btrfs_fs_info *btrfs_update_ioctl_balance_args (fs_info, bargs); } -if ((ret && ret != -ECANCELED && ret != -ENOSPC ) || -balance_need_close (fs_info)) { +/* We didn't pause, we can clean everything up. */ +if (!paused) {reset_balance_state (fs_info);btrfs_exclop_finish (fs_info); }
Greg Kroah-Hartman
maintainerPATCH 16/183 selftests: tc: set timeout to 15 minutes
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit fda05798c22a354efde09a76bdfc276b2d591829 upstream.
When looking for something else in LKFT reports [1], I noticed that the TC selftest ended with a timeout error:
not ok 1 selftests: tc-testing: tdc.sh # TIMEOUT 45 seconds
The timeout had been introduced 3 years ago, see the Fixes commit below.
This timeout is only in place when executing the selftests via the kselftests runner scripts. I guess this is not what most TC devs are using and nobody noticed the issue before.
The new timeout is set to 15 minutes as suggested by Pedro [2]. It looks like it is plenty more time than what it takes in "normal" conditions.
--- tools/testing/selftests/tc-testing/settings | 1 + 1 file changed, 1 insertion(+) create mode 100644 tools/testing/selftests/tc-testing/settings
tools/testing/selftests/tc-testing/settings new file +1 -0
@@ -0,0 +1 @@ +timeout=900
Greg Kroah-Hartman
maintainerPATCH 17/183 selftests: tc: add ct action kconfig dep
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 719b4774a8cb1a501e2d22a5a4a3a0a870e427d5 upstream.
When looking for something else in LKFT reports [1], I noticed most of the tests were skipped because the "teardown stage" did not complete successfully.
Pedro found out this is due to the fact CONFIG_NF_FLOW_TABLE is required but not listed in the 'config' file. Adding it to the list fixes the issues on LKFT side. CONFIG_NET_ACT_CT is now set to 'm' in the final kconfig.
--- tools/testing/selftests/tc-testing/config | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/tc-testing/config +1 -0
@@ -5,6 +5,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_FLOW_TABLE=m CONFIG_NF_NAT=m CONFIG_NETFILTER_XT_TARGET_LOG=m
Greg Kroah-Hartman
maintainerPATCH 18/183 regmap: Drop initial version of maximum transfer length fixes
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit bc64734825c59e18a27ac266b07e14944c111fd8 upstream.
When problems were noticed with the register address not being taken into account when limiting raw transfers with I2C devices we fixed this in the core. Unfortunately it has subsequently been realised that a lot of buses were relying on the prior behaviour, partly due to unclear documentation not making it obvious what was intended in the core. This is all more involved to fix than is sensible for a fix commit so let's just drop the original fixes, a separate commit will fix the originally observed problem in an I2C specific way
--- drivers/base/regmap/regmap-spi-avmm.c | 2 +- drivers/base/regmap/regmap.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-)
drivers/base/regmap/regmap-spi-avmm.c +1 -1
@@ -660,7 +660,7 @@ static const struct regmap_bus regmap_sp .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, .val_format_endian_default = REGMAP_ENDIAN_NATIVE, .max_raw_read = SPI_AVMM_VAL_SIZE * MAX_READ_CNT, - .max_raw_write = SPI_AVMM_REG_SIZE + SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT, + .max_raw_write = SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT, .free_context = spi_avmm_bridge_ctx_free, };
drivers/base/regmap/regmap.c +2 -4
@@ -2064,8 +2064,6 @@ int _regmap_raw_write(struct regmap *mapsize_t val_count = val_len / val_bytes;size_t chunk_count, chunk_bytes;size_t chunk_regs = val_count; -size_t max_data = map->max_raw_write - map->format.reg_bytes - - map->format.pad_bytes;int ret, i;if (!val_count)
@@ -2073,8 +2071,8 @@ int _regmap_raw_write(struct regmap *mapif (map->use_single_write) chunk_regs =1 ; -else if (map->max_raw_write && val_len > max_data) - chunk_regs = max_data / val_bytes; +else if (map->max_raw_write && val_len > map->max_raw_write) + chunk_regs = map->max_raw_write / val_bytes; chunk_count = val_count / chunk_regs; chunk_bytes = chunk_regs * val_bytes;
Greg Kroah-Hartman
maintainerPATCH 19/183 of: Preserve "of-display" device name for compatibility
In reply to Greg Kroah-HartmanFrom: Rob Herring <[email protected]>
commit 0bb8f49cd2cc8cb32ac51189ff9fcbe7ec3d9d65 upstream.
Since commit 241d2fb56a18 ("of: Make OF framebuffer device names unique"), as spotted by Frédéric Bonnard, the historical "of-display" device is
gone: the updated logic creates "of-display.0" instead, then as many "of-display.N" as required.
This means that offb no longer finds the expected device, which prevents the Debian Installer from setting up its interface, at least on ppc64el.
Fix this by keeping "of-display" for the first device and "of-display.N" for subsequent devices.
--- drivers/of/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/of/platform.c +1 -1
@@ -557,7 +557,7 @@ static int __init of_platform_default_poif (!of_get_property (node,"linux,opened" ,NULL ) || !of_get_property (node,"linux,boot-display" ,NULL ))continue ; - dev =of_platform_device_create (node,"of-display.0" ,NULL ); + dev =of_platform_device_create (node,"of-display" ,NULL );of_node_put (node);if (WARN_ON (!dev))return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 20/183 regmap: Account for register length in SMBus I/O limits
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit 0c9d2eb5e94792fe64019008a04d4df5e57625af upstream.
The SMBus I2C buses have limits on the size of transfers they can do but do not factor in the register length meaning we may try to do a transfer longer than our length limit, the core will not take care of this. Future changes will factor this out into the core but there are a number of users that assume current behaviour so let's just do something conservative here.
This does not take account padding bits but practically speaking these are very rarely if ever used on I2C buses given that they generally run slowly enough to mean there's no issue.
--- drivers/base/regmap/regmap-i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/base/regmap/regmap-i2c.c +4 -4
@@ -242,8 +242,8 @@ static int regmap_i2c_smbus_i2c_read(voistatic const struct regmap_bus regmap_i2c_smbus_i2c_block = { .write = regmap_i2c_smbus_i2c_write, .read = regmap_i2c_smbus_i2c_read, - .max_raw_read =I2C_SMBUS_BLOCK_MAX , - .max_raw_write =I2C_SMBUS_BLOCK_MAX , + .max_raw_read =I2C_SMBUS_BLOCK_MAX -1 , + .max_raw_write =I2C_SMBUS_BLOCK_MAX -1 , }; static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
@@ -299,8 +299,8 @@ static int regmap_i2c_smbus_i2c_read_regstatic const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = { .write = regmap_i2c_smbus_i2c_write_reg16, .read = regmap_i2c_smbus_i2c_read_reg16, - .max_raw_read =I2C_SMBUS_BLOCK_MAX , - .max_raw_write =I2C_SMBUS_BLOCK_MAX , + .max_raw_read =I2C_SMBUS_BLOCK_MAX -2 , + .max_raw_write =I2C_SMBUS_BLOCK_MAX -2 , }; static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
Greg Kroah-Hartman
maintainerPATCH 21/183 arm64/fpsimd: Ensure SME storage is allocated after SVE VL changes
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit d4d5be94a87872421ea2569044092535aff0b886 upstream.
When we reconfigure the SVE vector length we discard the backing storage for the SVE vectors and then reallocate on next SVE use, leaving the SME specific state alone. This means that we do not enable SME traps if they were already disabled. That means that userspace code can enter streaming mode without trapping, putting the task in a state where if we try to save the state of the task we will fault.
Since the ABI does not specify that changing the SVE vector length disturbs SME state, and since SVE code may not be aware of SME code in the process, we shouldn't simply discard any ZA state. Instead immediately reallocate the storage for SVE, and disable SME if we change the SVE vector length while there is no SME state active.
Disabling SME traps on SVE vector length changes would make the overall code more complex since we would have a state where we have valid SME state stored but might get a SME trap.
--- arch/arm64/kernel/fpsimd.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
arch/arm64/kernel/fpsimd.c +25 -8
@@ -803,6 +803,8 @@ void sve_sync_from_fpsimd_zeropad(structint vec_set_vector_length (struct task_struct *task,enum vec_type type,unsigned long vl,unsigned long flags) { +bool free_sme = false; +if (flags & ~(unsigned long )(PR_SVE_VL_INHERIT |PR_SVE_SET_VL_ONEXEC ))return -EINVAL ;
@@ -851,21 +853,36 @@ int vec_set_vector_length(struct task_st thread_sm_enabled(&task->thread))sve_to_fpsimd (task); -if (system_supports_sme () && type ==ARM64_VEC_SME ) { - task->thread.svcr &= ~(SVCR_SM_MASK | -SVCR_ZA_MASK ); -clear_thread_flag (TIF_SME ); +if (system_supports_sme ()) { +if (type ==ARM64_VEC_SME || + !(task->thread.svcr & (SVCR_SM_MASK |SVCR_ZA_MASK ))) { +/* +* We are changing the SME VL or weren't using +* SME anyway, discard the state and force a +* reallocation. +*/ + task->thread.svcr &= ~(SVCR_SM_MASK | +SVCR_ZA_MASK ); +clear_thread_flag (TIF_SME ); + free_sme = true; + } }if (task == current)put_cpu_fpsimd_context ();/* -* Force reallocation of task SVE and SME state to the correct -* size on next use: +* Free the changed states if they are not in use, SME will be +* reallocated to the correct size on next use and we just +* allocate SVE now in case it is needed for use in streaming +* mode. */ -sve_free (task); -if (system_supports_sme () && type ==ARM64_VEC_SME ) +if (system_supports_sve ()) { +sve_free (task); +sve_alloc (task, true); + } + +if (free_sme)sme_free (task);task_set_vl (task, type, vl);
Greg Kroah-Hartman
maintainerPATCH 22/183 can: mcp251xfd: __mcp251xfd_chip_set_mode(): increase poll timeout
In reply to Greg Kroah-HartmanFrom: Fedor Ross <[email protected]>
commit 9efa1a5407e81265ea502cab83be4de503decc49 upstream.
The mcp251xfd controller needs an idle bus to enter 'Normal CAN 2.0 mode' or . The maximum length of a CAN frame is 736 bits (64 data bytes, CAN-FD, EFF mode, worst case bit stuffing and interframe spacing). For low bit rates like 10 kbit/s the arbitrarily chosen MCP251XFD_POLL_TIMEOUT_US of 1 ms is too small.
Otherwise during polling for the CAN controller to enter 'Normal CAN 2.0 mode' the timeout limit is exceeded and the configuration fails with:
| $ ip link set dev can1 up type can bitrate 10000 | [ 731.911072] mcp251xfd spi2.1 can1: Controller failed to enter mode CAN 2.0 Mode (6) and stays in Configuration Mode (4) (con=0x068b0760, osc=0x00000468). | [ 731.927192] mcp251xfd spi2.1 can1: CRC read error at address 0x0e0c (length=4, data=00 00 00 00, CRC=0x0000) retrying. | [ 731.938101] A link change request failed with some changes committed already. Interface can1 may have been left with an inconsistent configuration, please check. | RTNETLINK answers: Connection timed out
Make MCP251XFD_POLL_TIMEOUT_US timeout calculation dynamic. Use maximum of 1ms and bit time of 1 full 64 data bytes CAN-FD frame in EFF mode, worst case bit stuffing and interframe spacing at the current bit rate.
For easier backporting define the macro MCP251XFD_FRAME_LEN_MAX_BITS that holds the max frame length in bits, which is 736. This can be replaced by can_frame_bits(true, true, true, true, CANFD_MAX_DLEN) in a cleanup patch later.
--- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 10 ++++++++-- drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +8 -2
@@ -227,6 +227,8 @@ static int __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, const u8 mode_req, bool nowait) { + const struct can_bittiming *bt = &priv->can.bittiming; +unsigned long timeout_us =MCP251XFD_POLL_TIMEOUT_US ;u32 con =0 , con_reqop, osc =0 ;u8 mode;int err;
@@ -246,12 +248,16 @@ __mcp251xfd_chip_set_mode(const struct mif (mode_req ==MCP251XFD_REG_CON_MODE_SLEEP || nowait)return 0 ; +if (bt->bitrate) + timeout_us = max_t(unsigned long, timeout_us, +MCP251XFD_FRAME_LEN_MAX_BITS *USEC_PER_SEC / + bt->bitrate); + err =regmap_read_poll_timeout (priv->map_reg,MCP251XFD_REG_CON , con, !mcp251xfd_reg_invalid (con) &&FIELD_GET (MCP251XFD_REG_CON_OPMOD_MASK , con) == mode_req, -MCP251XFD_POLL_SLEEP_US , -MCP251XFD_POLL_TIMEOUT_US ); +MCP251XFD_POLL_SLEEP_US , timeout_us);if (err != -ETIMEDOUT && err != -EBADMSG )return err;
drivers/net/can/spi/mcp251xfd/mcp251xfd.h +1 -0
@@ -387,6 +387,7 @@ static_assert(MCP251XFD_TIMESTAMP_WORK_D#define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US)#define MCP251XFD_POLL_SLEEP_US (10)#define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) +#define MCP251XFD_FRAME_LEN_MAX_BITS (736)/* Misc */ #define MCP251XFD_NAPI_WEIGHT 32
Greg Kroah-Hartman
maintainerPATCH 23/183 can: bcm: Fix UAF in bcm_proc_show()
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
commit 55c3b96074f3f9b0aee19bf93cd71af7516582bb upstream.
BUG: KASAN: slab-use-after-free in bcm_proc_show+0x969/0xa80 Read of size 8 at addr ffff888155846230 by task cat/7862 CPU: 1 PID: 7862 Comm: cat Not tainted 6.5.0-rc1-00153-gc8746099c197 #230 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0xd5/0x150 print_report+0xc1/0x5e0 kasan_report+0xba/0xf0 bcm_proc_show+0x969/0xa80 seq_read_iter+0x4f6/0x1260 seq_read+0x165/0x210 proc_reg_read+0x227/0x300 vfs_read+0x1d5/0x8d0 ksys_read+0x11e/0x240 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd Allocated by task 7846: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_kmalloc+0x9e/0xa0 bcm_sendmsg+0x264b/0x44e0 sock_sendmsg+0xda/0x180 ____sys_sendmsg+0x735/0x920 ___sys_sendmsg+0x11d/0x1b0 __sys_sendmsg+0xfa/0x1d0 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 7846: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x27/0x40 ____kasan_slab_free+0x161/0x1c0 slab_free_freelist_hook+0x119/0x220 __kmem_cache_free+0xb4/0x2e0 rcu_core+0x809/0x1bd0
bcm_op is freed before procfs entry be removed in bcm_release(), this lead to bcm_proc_show() may read the freed bcm_op.
--- net/can/bcm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/can/bcm.c +6 -6
@@ -1526,6 +1526,12 @@ static int bcm_release(struct socket *solock_sock (sk); +#if IS_ENABLED (CONFIG_PROC_FS ) +/* remove procfs entry */ +if (net->can.bcmproc_dir && bo->bcm_proc_read) +remove_proc_entry (bo->procname, net->can.bcmproc_dir); +#endif /* CONFIG_PROC_FS */ +list_for_each_entry_safe (op, next, &bo->tx_ops, list)bcm_remove_op (op);
@@ -1561,12 +1567,6 @@ static int bcm_release(struct socket *solist_for_each_entry_safe (op, next, &bo->rx_ops, list)bcm_remove_op (op); -#if IS_ENABLED (CONFIG_PROC_FS ) -/* remove procfs entry */ -if (net->can.bcmproc_dir && bo->bcm_proc_read) -remove_proc_entry (bo->procname, net->can.bcmproc_dir); -#endif /* CONFIG_PROC_FS */ -/* remove device reference */ if (bo->bound) { bo->bound =0 ;
Greg Kroah-Hartman
maintainerPATCH 24/183 can: gs_usb: gs_can_open(): improve error handling
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
commit 2603be9e8167ddc7bea95dcfab9ffc33414215aa upstream.
The gs_usb driver handles USB devices with more than 1 CAN channel. The RX path for all channels share the same bulk endpoint (the transmitted bulk data encodes the channel number). These per-device resources are allocated and submitted by the first opened channel.
During this allocation, the resources are either released immediately in case of a failure or the URBs are anchored. All anchored URBs are finally killed with gs_usb_disconnect().
Currently, gs_can_open() returns with an error if the allocation of a URB or a buffer fails. However, if usb_submit_urb() fails, the driver continues with the URBs submitted so far, even if no URBs were successfully submitted.
Treat every error as fatal and free all allocated resources immediately.
Switch to goto-style error handling, to prepare the driver for more per-device resource allocation.
--- drivers/net/can/usb/gs_usb.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
drivers/net/can/usb/gs_usb.c +22 -9
@@ -833,6 +833,7 @@ static int gs_can_open(struct net_device .mode = cpu_to_le32(GS_CAN_MODE_START), };struct gs_host_frame *hf; +struct urb *urb =NULL ;u32 ctrlmode;u32 flags =0 ;int rc, i;
@@ -858,13 +859,14 @@ static int gs_can_open(struct net_deviceif (!parent->active_channels) {for (i =0 ; i <GS_MAX_RX_URBS ; i++) { -struct urb *urb;u8 *buf;/* alloc rx urb */ urb =usb_alloc_urb (0 ,GFP_KERNEL ); -if (!urb) -return -ENOMEM ; +if (!urb) { + rc = -ENOMEM ; + goto out_usb_kill_anchored_urbs; + }/* alloc rx buffer */ buf = kmalloc(dev->parent->hf_size_rx,
@@ -872,8 +874,8 @@ static int gs_can_open(struct net_deviceif (!buf) {netdev_err (netdev,"No memory left for USB buffer\n" ); -usb_free_urb (urb); -return -ENOMEM ; + rc = -ENOMEM ; + goto out_usb_free_urb; }/* fill, anchor, and submit rx urb */
@@ -896,9 +898,7 @@ static int gs_can_open(struct net_devicenetdev_err (netdev,"usb_submit failed (err=%d)\n" , rc); -usb_unanchor_urb (urb); -usb_free_urb (urb); -break ; + goto out_usb_unanchor_urb; }/* Drop reference,
@@ -944,7 +944,8 @@ static int gs_can_open(struct net_deviceif (dev->feature &GS_CAN_FEATURE_HW_TIMESTAMP )gs_usb_timestamp_stop (dev); dev->can.state =CAN_STATE_STOPPED ; -return rc; + + goto out_usb_kill_anchored_urbs; } parent->active_channels++;
@@ -952,6 +953,18 @@ static int gs_can_open(struct net_devicenetif_start_queue (netdev);return 0 ; + +out_usb_unanchor_urb: +usb_unanchor_urb (urb); +out_usb_free_urb: +usb_free_urb (urb); +out_usb_kill_anchored_urbs: +if (!parent->active_channels) +usb_kill_anchored_urbs (&dev->tx_submitted); + +close_candev (netdev); + +return rc; }static int gs_can_close (struct net_device *netdev)
Greg Kroah-Hartman
maintainerPATCH 25/183 selftests: tc: add ConnTrack procfs kconfig
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 031c99e71fedcce93b6785d38b7d287bf59e3952 upstream.
When looking at the TC selftest reports, I noticed one test was failing because /proc/net/nf_conntrack was not available.
not ok 373 3992 - Add ct action triggering DNAT tuple conflict
Could not match regex pattern. Verify command output:
cat: /proc/net/nf_conntrack: No such file or directory
It is only available if NF_CONNTRACK_PROCFS kconfig is set. So the issue can be fixed simply by adding it to the list of required kconfig.
--- tools/testing/selftests/tc-testing/config | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/tc-testing/config +1 -0
@@ -5,6 +5,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_FLOW_TABLE=m CONFIG_NF_NAT=m CONFIG_NETFILTER_XT_TARGET_LOG=m
Greg Kroah-Hartman
maintainerPATCH 26/183 dma-buf/dma-resv: Stop leaking on krealloc() failure
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
Currently dma_resv_get_fences() will leak the previously allocated array if the fence iteration got restarted and the krealloc_array() fails.
Free the old array by hand, and make sure we still clear the returned *fences so the caller won't end up accessing freed memory. Some (but not all) of the callers of dma_resv_get_fences() seem to still trawl through the array even when dma_resv_get_fences() failed. And let's zero out *num_fences as well for good measure.
--- drivers/dma-buf/dma-resv.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/dma-buf/dma-resv.c +9 -4
@@ -566,6 +566,7 @@ int dma_resv_get_fences(struct dma_resvdma_resv_for_each_fence_unlocked (&cursor, fence) {if (dma_resv_iter_is_restarted (&cursor)) { +struct dma_fence **new_fences;unsigned int count;while (*num_fences)
@@ -574,13 +575,17 @@ int dma_resv_get_fences(struct dma_resv count = cursor.num_fences +1 ;/* Eventually re-allocate the array */ - *fences =krealloc_array (*fences, count, -sizeof (void *), -GFP_KERNEL ); -if (count && !*fences) { + new_fences =krealloc_array (*fences, count, +sizeof (void *), +GFP_KERNEL ); +if (count && !new_fences) { +kfree (*fences); + *fences =NULL ; + *num_fences =0 ;dma_resv_iter_end (&cursor);return -ENOMEM ; } + *fences = new_fences; } (*fences)[(*num_fences)++] =dma_fence_get (fence);
Greg Kroah-Hartman
maintainerPATCH 27/183 drm/amdgpu/vkms: relax timer deactivation by hrtimer_try_to_cancel
In reply to Greg Kroah-HartmanFrom: Guchun Chen <[email protected]>
commit b42ae87a7b3878afaf4c3852ca66c025a5b996e0 upstream.
In below thousands of screen rotation loop tests with virtual display enabled, a CPU hard lockup issue may happen, leading system to unresponsive and crash.
do {
xrandr --output Virtual --rotate inverted
xrandr --output Virtual --rotate right
xrandr --output Virtual --rotate left
xrandr --output Virtual --rotate normal
} while (1);NMI watchdog: Watchdog detected hard LOCKUP on cpu 1
? hrtimer_run_softirq+0x140/0x140 ? store_vblank+0xe0/0xe0 [drm] hrtimer_cancel+0x15/0x30 amdgpu_vkms_disable_vblank+0x15/0x30 [amdgpu] drm_vblank_disable_and_save+0x185/0x1f0 [drm] drm_crtc_vblank_off+0x159/0x4c0 [drm] ? record_print_text.cold+0x11/0x11 ? wait_for_completion_timeout+0x232/0x280 ? drm_crtc_wait_one_vblank+0x40/0x40 [drm] ? bit_wait_io_timeout+0xe0/0xe0 ? wait_for_completion_interruptible+0x1d7/0x320 ? mutex_unlock+0x81/0xd0
amdgpu_vkms_crtc_atomic_disable
It's caused by a stuck in lock dependency in such scenario on different CPUs.
CPU1 CPU2drm_crtc_vblank_off hrtimer_interrupt
grab event_lock (irq disabled) __hrtimer_run_queues
grab vbl_lock/vblank_time_block amdgpu_vkms_vblank_simulate
amdgpu_vkms_disable_vblank drm_handle_vblank
hrtimer_cancel grab dev->event_lock
So CPU1 stucks in hrtimer_cancel as timer callback is running endless on current clock base, as that timer queue on CPU2 has no chance to finish it because of failing to hold the lock. So NMI watchdog will throw the errors after its threshold, and all later CPUs are impacted/blocked.
So use hrtimer_try_to_cancel to fix this, as disable_vblank callback does not need to wait the handler to finish. And also it's not necessary to check the return value of hrtimer_try_to_cancel, because even if it's -1 which means current timer callback is running, it will be reprogrammed in hrtimer_start with calling enable_vblank to make it works.
v2: only re-arm timer when vblank is enabled (Christian) and add a Fixes tag as well
v3: drop warn printing (Christian)
v4: drop superfluous check of blank->enabled in timer function, as it's guaranteed in drm_handle_vblank (Christian)
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +3 -2
@@ -55,8 +55,9 @@ static enum hrtimer_restart amdgpu_vkms_DRM_WARN ("%s: vblank timer overrun\n" , __func__); ret =drm_crtc_handle_vblank (crtc); +/* Don't queue timer again when vblank is disabled. */ if (!ret) -DRM_ERROR ("amdgpu_vkms failure on handling vblank" ); +return HRTIMER_NORESTART ;return HRTIMER_RESTART ; }
@@ -81,7 +82,7 @@ static void amdgpu_vkms_disable_vblank(s {struct amdgpu_crtc *amdgpu_crtc =to_amdgpu_crtc (crtc); -hrtimer_cancel (&amdgpu_crtc->vblank_timer); +hrtimer_try_to_cancel (&amdgpu_crtc->vblank_timer); } static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
Greg Kroah-Hartman
maintainerPATCH 28/183 drm/amdgpu/pm: make gfxclock consistent for sienna cichlid
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit a4eb11824170d742531998f4ebd1c6a18b63db47 upstream.
Use average gfxclock for consistency with other dGPUs.
--- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +6 -2
@@ -1927,12 +1927,16 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, *size =4 ;break ;case AMDGPU_PP_SENSOR_GFX_MCLK : - ret =sienna_cichlid_get_current_clk_freq_by_table (smu,SMU_UCLK , (uint32_t *)data); + ret =sienna_cichlid_get_smu_metrics_data (smu, +METRICS_CURR_UCLK , + (uint32_t *)data); *(uint32_t *)data *=100 ; *size =4 ;break ;case AMDGPU_PP_SENSOR_GFX_SCLK : - ret =sienna_cichlid_get_current_clk_freq_by_table (smu,SMU_GFXCLK , (uint32_t *)data); + ret =sienna_cichlid_get_smu_metrics_data (smu, +METRICS_AVERAGE_GFXCLK , + (uint32_t *)data); *(uint32_t *)data *=100 ; *size =4 ;break ;
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 29/183 drm/amdgpu/pm: make mclk consistent for smu 13.0.7
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit 068c8bb10f37bb84824625dbbda053a3a3e0d6e1 upstream.
Use current uclk to be consistent with other dGPUs.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +1 -1
@@ -940,7 +940,7 @@ static int smu_v13_0_7_read_sensor(strucbreak ;case AMDGPU_PP_SENSOR_GFX_MCLK : ret =smu_v13_0_7_get_smu_metrics_data (smu, -METRICS_AVERAGE_UCLK , +METRICS_CURR_UCLK , (uint32_t *)data); *(uint32_t *)data *=100 ; *size =4 ;
Greg Kroah-Hartman
maintainerPATCH 30/183 drm/client: Fix memory leak in drm_client_target_cloned
In reply to Greg Kroah-HartmanFrom: Jocelyn Falempe <[email protected]>
commit c2a88e8bdf5f6239948d75283d0ae7e0c7945b03 upstream.
dmt_mode is allocated and never freed in this function.
It was found with the ast driver, but most drivers using generic fbdev setup are probably affected.
This fixes the following kmemleak report:
backtrace:
[<00000000b391296d>] drm_mode_duplicate+0x45/0x220 [drm]
[<00000000e45bb5b3>] drm_client_target_cloned.constprop.0+0x27b/0x480 [drm]
[<00000000ed2d3a37>] drm_client_modeset_probe+0x6bd/0xf50 [drm]
[<0000000010e5cc9d>] __drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper]
[<00000000909f82ca>] drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper]
[<00000000063a69aa>] drm_client_register+0x169/0x240 [drm]
[<00000000a8c61525>] ast_pci_probe+0x142/0x190 [ast]
[<00000000987f19bb>] local_pci_probe+0xdc/0x180
[<000000004fca231b>] work_for_cpu_fn+0x4e/0xa0
[<0000000000b85301>] process_one_work+0x8b7/0x1540
[<000000003375b17c>] worker_thread+0x70a/0xed0
[<00000000b0d43cd9>] kthread+0x29f/0x340
[<000000008d770833>] ret_from_fork+0x1f/0x30unreferenced object 0xff11000333089a00 (size 128):
--- drivers/gpu/drm/drm_client_modeset.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/drm_client_modeset.c +5 -0
@@ -315,6 +315,9 @@ static bool drm_client_target_cloned(str can_clone = true; dmt_mode =drm_mode_find_dmt (dev,1024 ,768 ,60 , false); +if (!dmt_mode) + goto fail; +for (i =0 ; i < connector_count; i++) {if (!enabled[i])continue ;
@@ -330,11 +333,13 @@ static bool drm_client_target_cloned(strif (!modes[i]) can_clone = false; } +kfree (dmt_mode);if (can_clone) {DRM_DEBUG_KMS ("can clone using 1024x768\n" );return true; } +fail:DRM_INFO ("kms: can't enable cloning when we probably wanted to.\n" );return false; }
Greg Kroah-Hartman
maintainerPATCH 31/183 drm/client: Fix memory leak in drm_client_modeset_probe
In reply to Greg Kroah-HartmanFrom: Jocelyn Falempe <[email protected]>
commit 2329cc7a101af1a844fbf706c0724c0baea38365 upstream.
When a new mode is set to modeset->mode, the previous mode should be freed. This fixes the following kmemleak report:
drm_mode_duplicate+0x45/0x220 [drm] drm_client_modeset_probe+0x944/0xf50 [drm] __drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper] drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper] drm_client_register+0x169/0x240 [drm] ast_pci_probe+0x142/0x190 [ast] local_pci_probe+0xdc/0x180 work_for_cpu_fn+0x4e/0xa0 process_one_work+0x8b7/0x1540 worker_thread+0x70a/0xed0 kthread+0x29f/0x340 ret_from_fork+0x1f/0x30
--- drivers/gpu/drm/drm_client_modeset.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_client_modeset.c +1 -0
@@ -871,6 +871,7 @@ int drm_client_modeset_probe(struct drm_break ; } +kfree (modeset->mode); modeset->mode =drm_mode_duplicate (dev, mode);drm_connector_get (connector); modeset->connectors[modeset->num_connectors++] = connector;
Greg Kroah-Hartman
maintainerPATCH 32/183 drm/amd/display: only accept async flips for fast updates
In reply to Greg Kroah-HartmanFrom: Simon Ser <[email protected]>
commit 1ca67aba8d11c2849d395013e1fdce02918d5657 upstream.
Up until now, amdgpu was silently degrading to vsync when user-space requested an async flip but the hardware didn't support it.
The hardware doesn't support immediate flips when the update changes the FB pitch, the DCC state, the rotation, enables or disables CRTCs or planes, etc. This is reflected in the dm_crtc_state.update_type
field: UPDATE_TYPE_FAST means that immediate flip is supported.
Silently degrading async flips to vsync is not the expected behavior from a uAPI point-of-view. Xorg expects async flips to fail if unsupported, to be able to fall back to a blit. i915 already behaves this way.
This patch aligns amdgpu with uAPI expectations and returns a failure when an async flip is not possible.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++++++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 12 ++++++++++++ 2 files changed, 20 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +8 -0
@@ -7757,7 +7757,15 @@ static void amdgpu_dm_commit_planes(stru* Only allow immediate flips for fast updates that don't * change memory domain, FB pitch, DCC state, rotation or * mirroring. +* +* dm_crtc_helper_atomic_check() only accepts async flips with +* fast updates. */ +if (crtc->state->async_flip && + acrtc_state->update_type !=UPDATE_TYPE_FAST ) +drm_warn_once (state->dev, +"[PLANE:%d:%s] async flip with non-fast update\n" , + plane->base.id, plane->name); bundle->flip_addrs[planes_count].flip_immediate = crtc->state->async_flip && acrtc_state->update_type == UPDATE_TYPE_FAST &&
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +12 -0
@@ -406,6 +406,18 @@ static int dm_crtc_helper_atomic_check(sreturn -EINVAL ; } +/* +* Only allow async flips for fast updates that don't change the FB +* pitch, the DCC state, rotation, etc. +*/ +if (crtc_state->async_flip && + dm_crtc_state->update_type !=UPDATE_TYPE_FAST ) { +drm_dbg_atomic (crtc->dev, +"[CRTC:%d:%s] async flips are only supported for fast updates\n" , + crtc->base.id, crtc->name); +return -EINVAL ; + } +/* In some use cases, like reset, no stream is attached */ if (!dm_crtc_state->stream)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 33/183 drm/amd/display: Disable MPC split by default on special asic
In reply to Greg Kroah-HartmanFrom: Zhikai Zhai <[email protected]>
commit a460beefe77d780ac48f19d39333852a7f93ffc1 upstream.
[WHY]
All of pipes will be used when the MPC split enable on the dcn which just has 2 pipes. Then MPO enter will trigger the minimal transition which need programe dcn from 2 pipes MPC split to 2 pipes MPO. This action will cause lag if happen frequently.
[HOW]
Disable the MPC split for the platform which dcn resource is limited
--- drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +1 -1
@@ -65,7 +65,7 @@ static const struct dc_debug_options deb .timing_trace = false, .clock_trace = true, .disable_pplib_clock_request = true, - .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .pipe_split_policy = MPC_SPLIT_AVOID, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true,
Greg Kroah-Hartman
maintainerPATCH 34/183 drm/amd/display: check TG is non-null before checking if enabled
In reply to Greg Kroah-HartmanFrom: Taimur Hassan <[email protected]>
commit 5a25cefc0920088bb9afafeb80ad3dcd84fe278b upstream.
[Why & How]
If there is no TG allocation we can dereference a NULL pointer when checking if the TG is enabled.
--- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +2 -1
@@ -3293,7 +3293,8 @@ void dcn10_wait_for_mpcc_disconnect(if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {struct hubp *hubp =get_hubp_by_inst (res_pool, mpcc_inst); -if (pipe_ctx->stream_res.tg->funcs->is_tg_enabled (pipe_ctx->stream_res.tg)) +if (pipe_ctx->stream_res.tg && + pipe_ctx->stream_res.tg->funcs->is_tg_enabled (pipe_ctx->stream_res.tg)) res_pool->mpc->funcs->wait_for_idle (res_pool->mpc, mpcc_inst); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false; hubp->funcs->set_blank (hubp, true);
Greg Kroah-Hartman
maintainerPATCH 35/183 drm/amd/display: Keep PHY active for DP displays on DCN31
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
commit 2387ccf43e3c6cb5dbd757c5ef410cca9f14b971 upstream.
[Why & How]
Port of a change that went into DCN314 to keep the PHY enabled when we have a connected and active DP display.
The PHY can hang if PHY refclk is disabled inadvertently.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +5 -0
@@ -86,6 +86,11 @@ static int dcn31_get_active_display_cnt_ stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) tmds_present = true; + +/* Checking stream / link detection ensuring that PHY is active*/ +if (dc_is_dp_signal (stream->signal) && !stream->dpms_off) + display_count++; + }for (i =0 ; i < dc->link_count; i++) {
Greg Kroah-Hartman
maintainerPATCH 36/183 ASoC: fsl_sai: Disable bit clock with transmitter
In reply to Greg Kroah-HartmanFrom: Matus Gajdos <[email protected]>
commit 269f399dc19f0e5c51711c3ba3bd06e0ef6ef403 upstream.
Otherwise bit clock remains running writing invalid data to the DAC.
--- sound/soc/fsl/fsl_sai.c | 2 +- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_sai.c +1 -1
@@ -719,7 +719,7 @@ static void fsl_sai_config_disable(strucu32 xcsr, count =100 ;regmap_update_bits (sai->regmap,FSL_SAI_xCSR (tx, ofs), -FSL_SAI_CSR_TERE ,0 ); +FSL_SAI_CSR_TERE |FSL_SAI_CSR_BCE ,0 );/* TERE will remain set till the end of current frame */ do {
sound/soc/fsl/fsl_sai.h +1 -0
@@ -91,6 +91,7 @@/* SAI Transmit/Receive Control Register */ #define FSL_SAI_CSR_TERE BIT(31)#define FSL_SAI_CSR_SE BIT(30) +#define FSL_SAI_CSR_BCE BIT(28)#define FSL_SAI_CSR_FR BIT(25)#define FSL_SAI_CSR_SR BIT(24)#define FSL_SAI_CSR_xF_SHIFT 16
Greg Kroah-Hartman
maintainerPATCH 37/183 ASoC: fsl_sai: Revert "ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode"
In reply to Greg Kroah-HartmanFrom: Fabio Estevam <[email protected]>
commit 86867aca7330e4fbcfa2a117e20b48bbb6c758a9 upstream.
This reverts commit ff87d619ac180444db297f043962a5c325ded47b.
Andreas reports that on an i.MX8MP-based system where MCLK needs to be used as an input, the MCLK pin is actually an output, despite not having the 'fsl,sai-mclk-direction-output' property present in the devicetree.
This is caused by commit ff87d619ac18 ("ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode") that sets FSL_SAI_MCTL_MCLK_EN unconditionally for imx8mm/8mn/8mp/93, causing the MCLK to always be configured as output.
FSL_SAI_MCTL_MCLK_EN corresponds to the MOE (MCLK Output Enable) bit of register MCR and the drivers sets it when the 'fsl,sai-mclk-direction-output' devicetree property is present.
Revert the commit to allow SAI to use MCLK as input as well.
--- sound/soc/fsl/fsl_sai.c | 6 ------ 1 file changed, 6 deletions(-)
sound/soc/fsl/fsl_sai.c +0 -6
@@ -507,12 +507,6 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) savediv / 2 - 1); } -if (sai->soc_data->max_register >=FSL_SAI_MCTL ) { -/* SAI is in master mode at this point, so enable MCLK */ -regmap_update_bits (sai->regmap,FSL_SAI_MCTL , -FSL_SAI_MCTL_MCLK_EN ,FSL_SAI_MCTL_MCLK_EN ); - } -return 0 ; }
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 38/183 ASoC: tegra: Fix ADX byte map
In reply to Greg Kroah-HartmanFrom: Sheetal <[email protected]>
commit 6dfe70be0b0dec0f9297811501bec26c05fd96ad upstream.
Byte mask for channel-1 of stream-1 is not getting enabled and this causes failures during ADX use cases. This happens because the byte map value 0 matches the byte map array and put() callback returns without enabling the corresponding bits in the byte mask.
ADX supports 4 output streams and each stream can have a maximum of 16 channels. Each byte in the input frame is uniquely mapped to a byte in one of these 4 outputs. This mapping is done with the help of byte map array via user space control setting. The byte map array size in the driver is 16 and each array element is of size 4 bytes. This corresponds to 64 byte map values.
Each byte in the byte map array can have any value between 0 to 255 to enable the corresponding bits in the byte mask. The value 256 is used as a way to disable the byte map. However the byte map array element cannot store this value. The put() callback disables the byte mask for 256 value and byte map value is reset to 0 for this case. This causes problems during subsequent runs since put() callback, for value of 0, just returns without enabling the byte mask. In short, the problem is coming because 0 and 256 control values are stored as 0 in the byte map array.
Right now fix the put() callback by actually looking at the byte mask array state to identify if any change is needed and update the fields accordingly. The get() callback needs an update as well to return the correct control value that user has set before. Note that when user set 256, the value is stored as 0 and byte mask is disabled. So byte mask state is used to either return 256 or the value from byte map array.
Given above, this looks bit complicated and all this happens because the byte map array is tightly packed and cannot actually store the 256 value. Right now the priority is to fix the existing failure and a TODO item is put to improve this logic.
--- sound/soc/tegra/tegra210_adx.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)
sound/soc/tegra/tegra210_adx.c +22 -12
@@ -2,7 +2,7 @@// // tegra210_adx.c - Tegra210 ADX driver // -// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. #include <linux/clk.h> #include <linux/device.h>
@@ -175,10 +175,20 @@ static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol, mc = (struct soc_mixer_control *)kcontrol->private_value; enabled = adx->byte_mask[mc->reg /32 ] & (1 << (mc->reg %32 )); +/* +* TODO: Simplify this logic to just return from bytes_map[] +* +* Presently below is required since bytes_map[] is +* tightly packed and cannot store the control value of 256. +* Byte mask state is used to know if 256 needs to be returned. +* Note that for control value of 256, the put() call stores 0 +* in the bytes_map[] and disables the corresponding bit in +* byte_mask[]. +*/ if (enabled) ucontrol->value.integer.value[0 ] = bytes_map[mc->reg];else - ucontrol->value.integer.value[0 ] =0 ; + ucontrol->value.integer.value[0 ] =256 ;return 0 ; }
@@ -192,19 +202,19 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol,int value = ucontrol->value.integer.value[0 ];struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; +unsigned int mask_val = adx->byte_mask[mc->reg /32 ]; -if (value == bytes_map[mc->reg]) +if (value >=0 && value <=255 ) + mask_val |= (1 << (mc->reg %32 )); +else + mask_val &= ~(1 << (mc->reg %32 )); + +if (mask_val == adx->byte_mask[mc->reg /32 ])return 0 ; -if (value >=0 && value <=255 ) { -/* update byte map and enable slot */ - bytes_map[mc->reg] = value; - adx->byte_mask[mc->reg /32 ] |= (1 << (mc->reg %32 )); - }else { -/* reset byte map and disable slot */ - bytes_map[mc->reg] =0 ; - adx->byte_mask[mc->reg /32 ] &= ~(1 << (mc->reg %32 )); - } +/* Update byte map and slot */ + bytes_map[mc->reg] = value %256 ; + adx->byte_mask[mc->reg /32 ] = mask_val;return 1 ; }
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 39/183 ASoC: rt5640: Fix sleep in atomic context
In reply to Greg Kroah-HartmanFrom: Sameer Pujar <[email protected]>
commit 70a6404ff610aa4889d98977da131c37f9ff9d1f upstream.
Following prints are observed while testing audio on Jetson AGX Orin which has onboard RT5640 audio codec:
BUG: sleeping function called from invalid context at kernel/workqueue.c:3027 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/0 preempt_count: 10001, expected: 0 RCU nest depth: 0, expected: 0 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:159 __handle_irq_event_percpu+0x1e0/0x270 ---[ end trace ad1c64905aac14a6 ]-
The IRQ handler rt5640_irq() runs in interrupt context and can sleep during cancel_delayed_work_sync().
Fix this by running IRQ handler, rt5640_irq(), in thread context. Hence replace request_irq() calls with devm_request_threaded_irq().
--- sound/soc/codecs/rt5640.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/soc/codecs/rt5640.c +7 -5
@@ -2562,9 +2562,10 @@ static void rt5640_enable_jack_detect(stif (jack_data && jack_data->use_platform_clock) rt5640->use_platform_clock = jack_data->use_platform_clock; - ret =request_irq (rt5640->irq, rt5640_irq, -IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT , -"rt5640" , rt5640); + ret =devm_request_threaded_irq (component->dev, rt5640->irq, +NULL , rt5640_irq, +IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT , +"rt5640" , rt5640);if (ret) {dev_warn (component->dev,"Failed to reguest IRQ %d: %d\n" , rt5640->irq, ret);rt5640_disable_jack_detect (component);
@@ -2617,8 +2618,9 @@ static void rt5640_enable_hda_jack_detec rt5640->jack = jack; - ret =request_irq (rt5640->irq, rt5640_irq, -IRQF_TRIGGER_RISING |IRQF_ONESHOT ,"rt5640" , rt5640); + ret =devm_request_threaded_irq (component->dev, rt5640->irq, +NULL , rt5640_irq,IRQF_TRIGGER_RISING |IRQF_ONESHOT , +"rt5640" , rt5640);if (ret) {dev_warn (component->dev,"Failed to reguest IRQ %d: %d\n" , rt5640->irq, ret); rt5640->irq = -ENXIO ;
Greg Kroah-Hartman
maintainerPATCH 40/183 ASoC: cs42l51: fix driver to properly autoload with automatic module loading
In reply to Greg Kroah-HartmanFrom: Thomas Petazzoni <[email protected]>
commit e51df4f81b02bcdd828a04de7c1eb6a92988b61e upstream.
In commit 2cb1e0259f50 ("ASoC: cs42l51: re-hook of_match_table pointer"), 9 years ago, some random guy fixed the cs42l51 after it was split into a core part and an I2C part to properly match based on a Device Tree compatible string.
However, the fix in this commit is wrong: the MODULE_DEVICE_TABLE(of, ....) is in the core part of the driver, not the I2C part. Therefore, automatic module loading based on module.alias, based on matching with the DT compatible string, loads the core part of the driver, but not the I2C part. And threfore, the i2c_driver is not registered, and the codec is not known to the system, nor matched with a DT node with the corresponding compatible string.
In order to fix that, we move the MODULE_DEVICE_TABLE(of, ...) into the I2C part of the driver. The cs42l51_of_match[] array is also moved as well, as it is not possible to have this definition in one file, and the MODULE_DEVICE_TABLE(of, ...) invocation in another file, due to how MODULE_DEVICE_TABLE works.
Thanks to this commit, the I2C part of the driver now properly autoloads, and thanks to its dependency on the core part, the core part gets autoloaded as well, resulting in a functional sound card without having to manually load kernel modules.
--- sound/soc/codecs/cs42l51-i2c.c | 6 ++++++ sound/soc/codecs/cs42l51.c | 7 ------- sound/soc/codecs/cs42l51.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-)
sound/soc/codecs/cs42l51-i2c.c +6 -0
@@ -19,6 +19,12 @@ static struct i2c_device_id cs42l51_i2c_ };MODULE_DEVICE_TABLE (i2c, cs42l51_i2c_id); +const struct of_device_id cs42l51_of_match[] = { + { .compatible ="cirrus,cs42l51" , }, + { } +}; +MODULE_DEVICE_TABLE (of, cs42l51_of_match); +static int cs42l51_i2c_probe (struct i2c_client *i2c) {struct regmap_config config;
sound/soc/codecs/cs42l51.c +0 -7
@@ -826,13 +826,6 @@ int __maybe_unused cs42l51_resume(struct }EXPORT_SYMBOL_GPL (cs42l51_resume); -const struct of_device_id cs42l51_of_match[] = { - { .compatible ="cirrus,cs42l51" , }, - { } -}; -MODULE_DEVICE_TABLE (of, cs42l51_of_match); -EXPORT_SYMBOL_GPL (cs42l51_of_match); -MODULE_AUTHOR ("Arnaud Patard <[email protected]>" );MODULE_DESCRIPTION ("Cirrus Logic CS42L51 ALSA SoC Codec Driver" );MODULE_LICENSE ("GPL" );
sound/soc/codecs/cs42l51.h +0 -1
@@ -16,7 +16,6 @@ int cs42l51_probe(struct device *dev, stvoid cs42l51_remove (struct device *dev);int __maybe_unused cs42l51_suspend (struct device *dev);int __maybe_unused cs42l51_resume (struct device *dev); -extern const struct of_device_id cs42l51_of_match[];#define CS42L51_CHIP_ID 0x1B#define CS42L51_CHIP_REV_A 0x00
Greg Kroah-Hartman
maintainerPATCH 41/183 ASoC: codecs: wcd938x: fix missing clsh ctrl error handling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit ed0dd9205bf69593edb495cb4b086dbae96a3f05 upstream.
Allocation of the clash control structure may fail so add the missing error handling to avoid dereferencing an error pointer.
--- sound/soc/codecs/wcd938x.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/soc/codecs/wcd938x.c +4 -0
@@ -3090,6 +3090,10 @@ static int wcd938x_soc_codec_probe(struc WCD938X_ID_MASK); wcd938x->clsh_info =wcd_clsh_ctrl_alloc (component,WCD938X ); +if (IS_ERR (wcd938x->clsh_info)) { +pm_runtime_put (dev); +return PTR_ERR (wcd938x->clsh_info); + }wcd938x_io_init (wcd938x);/* Set all interrupts as edge triggered */
Greg Kroah-Hartman
maintainerPATCH 42/183 ASoC: codecs: wcd-mbhc-v2: fix resource leaks on component remove
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit a5475829adcc600bc69ee9ff7c9e3e43fb4f8d30 upstream.
The MBHC resources must be released on component probe failure and removal so can not be tied to the lifetime of the component device.
This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component:
snd-sc8280xp sound: ASoC: failed to instantiate card -517
genirq: Flags mismatch irq 299. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr) wcd938x_codec audio-codec: Failed to request mbhc interrupts -16 wcd938x_codec audio-codec: mbhc initialization failed
wcd938x_codec audio-codec: ASoC: error at snd_soc_component_probe on audio-codec: -16 snd-sc8280xp sound: ASoC: failed to instantiate card -16
--- sound/soc/codecs/wcd-mbhc-v2.c | 57 +++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 16 deletions(-)
sound/soc/codecs/wcd-mbhc-v2.c +41 -16
@@ -1454,7 +1454,7 @@ struct wcd_mbhc *wcd_mbhc_init(struct snreturn ERR_PTR (-EINVAL ); } - mbhc =devm_kzalloc (dev,sizeof (*mbhc),GFP_KERNEL ); + mbhc =kzalloc (sizeof (*mbhc),GFP_KERNEL );if (!mbhc)return ERR_PTR (-ENOMEM );
@@ -1474,61 +1474,76 @@ struct wcd_mbhc *wcd_mbhc_init(struct snINIT_WORK (&mbhc->correct_plug_swch, wcd_correct_swch_plug); - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->mbhc_sw_intr,NULL , + ret =request_threaded_irq (mbhc->intr_ids->mbhc_sw_intr,NULL , wcd_mbhc_mech_plug_detect_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"mbhc sw intr" , mbhc);if (ret) - goto err; + goto err_free_mbhc; - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->mbhc_btn_press_intr,NULL , + ret =request_threaded_irq (mbhc->intr_ids->mbhc_btn_press_intr,NULL , wcd_mbhc_btn_press_handler,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"Button Press detect" , mbhc);if (ret) - goto err; + goto err_free_sw_intr; - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->mbhc_btn_release_intr,NULL , + ret =request_threaded_irq (mbhc->intr_ids->mbhc_btn_release_intr,NULL , wcd_mbhc_btn_release_handler,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"Button Release detect" , mbhc);if (ret) - goto err; + goto err_free_btn_press_intr; - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->mbhc_hs_ins_intr,NULL , + ret =request_threaded_irq (mbhc->intr_ids->mbhc_hs_ins_intr,NULL , wcd_mbhc_adc_hs_ins_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"Elect Insert" , mbhc);if (ret) - goto err; + goto err_free_btn_release_intr;disable_irq_nosync (mbhc->intr_ids->mbhc_hs_ins_intr); - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->mbhc_hs_rem_intr,NULL , + ret =request_threaded_irq (mbhc->intr_ids->mbhc_hs_rem_intr,NULL , wcd_mbhc_adc_hs_rem_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"Elect Remove" , mbhc);if (ret) - goto err; + goto err_free_hs_ins_intr;disable_irq_nosync (mbhc->intr_ids->mbhc_hs_rem_intr); - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->hph_left_ocp,NULL , + ret =request_threaded_irq (mbhc->intr_ids->hph_left_ocp,NULL , wcd_mbhc_hphl_ocp_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"HPH_L OCP detect" , mbhc);if (ret) - goto err; + goto err_free_hs_rem_intr; - ret =devm_request_threaded_irq (dev, mbhc->intr_ids->hph_right_ocp,NULL , + ret =request_threaded_irq (mbhc->intr_ids->hph_right_ocp,NULL , wcd_mbhc_hphr_ocp_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"HPH_R OCP detect" , mbhc);if (ret) - goto err; + goto err_free_hph_left_ocp;return mbhc; -err: + +err_free_hph_left_ocp: +free_irq (mbhc->intr_ids->hph_left_ocp, mbhc); +err_free_hs_rem_intr: +free_irq (mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); +err_free_hs_ins_intr: +free_irq (mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); +err_free_btn_release_intr: +free_irq (mbhc->intr_ids->mbhc_btn_release_intr, mbhc); +err_free_btn_press_intr: +free_irq (mbhc->intr_ids->mbhc_btn_press_intr, mbhc); +err_free_sw_intr: +free_irq (mbhc->intr_ids->mbhc_sw_intr, mbhc); +err_free_mbhc: +kfree (mbhc); +dev_err (dev,"Failed to request mbhc interrupts %d\n" , ret);return ERR_PTR (ret);
@@ -1537,9 +1552,19 @@ EXPORT_SYMBOL(wcd_mbhc_init);void wcd_mbhc_deinit (struct wcd_mbhc *mbhc) { +free_irq (mbhc->intr_ids->hph_right_ocp, mbhc); +free_irq (mbhc->intr_ids->hph_left_ocp, mbhc); +free_irq (mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); +free_irq (mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); +free_irq (mbhc->intr_ids->mbhc_btn_release_intr, mbhc); +free_irq (mbhc->intr_ids->mbhc_btn_press_intr, mbhc); +free_irq (mbhc->intr_ids->mbhc_sw_intr, mbhc); +mutex_lock (&mbhc->lock);wcd_cancel_hs_detect_plug (mbhc, &mbhc->correct_plug_swch);mutex_unlock (&mbhc->lock); + +kfree (mbhc); }EXPORT_SYMBOL (wcd_mbhc_deinit);
Greg Kroah-Hartman
maintainerPATCH 1/11 drm/radeon: Fix integer overflow in radeon_cs_parser_init
In reply to Greg Kroah-Hartman[ Upstream commit f828b681d0cd566f86351c0b913e6cb6ed8c7b9c ]
The type of size is unsigned, if size is 0x40000000, there will be an integer overflow, size will be zero after size *= sizeof(uint32_t), will cause uninitialized memory to be referenced later
--- drivers/gpu/drm/radeon/radeon_cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_cs.c +2 -1
@@ -270,7 +270,8 @@ int radeon_cs_parser_init(struct radeon_ {struct drm_radeon_cs *cs = data;uint64_t *chunk_array_ptr; -unsigned size, i; +u64 size; +unsigned i;u32 ring =RADEON_CS_RING_GFX ;s32 priority =0 ;
Greg Kroah-Hartman
maintainerPATCH 2/11 ALSA: emu10k1: roll up loops in DSP setup code for Audigy
In reply to Greg Kroah-Hartman[ Upstream commit 8cabf83c7aa54530e699be56249fb44f9505c4f3 ]
There is no apparent reason for the massive code duplication.
--- sound/pci/emu10k1/emufx.c | 112 +++------------------------------------------- 1 file changed, 9 insertions(+), 103 deletions(-)
sound/pci/emu10k1/emufx.c +9 -103
@@ -1563,14 +1563,8 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G gpr +=2 ;/* Master volume (will be renamed later) */ -A_OP (icode, &ptr, iMAC0,A_GPR (playback+0 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+0 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+1 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+1 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+2 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+2 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+3 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+3 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+4 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+4 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+5 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+5 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+6 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+6 +SND_EMU10K1_PLAYBACK_CHANNELS )); -A_OP (icode, &ptr, iMAC0,A_GPR (playback+7 +SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+7 +SND_EMU10K1_PLAYBACK_CHANNELS )); +for (z =0 ; z <8 ; z++) +A_OP (icode, &ptr, iMAC0,A_GPR (playback+z+SND_EMU10K1_PLAYBACK_CHANNELS ),A_C_00000000 ,A_GPR (gpr),A_GPR (playback+z+SND_EMU10K1_PLAYBACK_CHANNELS ));snd_emu10k1_init_mono_control (&controls[nctl++],"Wave Master Playback Volume" , gpr,0 ); gpr +=2 ;
@@ -1654,102 +1648,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_Gdev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n", gpr, tmp); */ -/* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ -/* A_P16VIN(0) is delayed by one sample, -* so all other A_P16VIN channels will need to also be delayed -*/ -/* Left ADC in. 1 of 2 */ snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_P16VIN (0x0 ),A_FXBUS2 (0 ) ); -/* Right ADC in 1 of 2 */ - gpr_map[gpr++] =0x00000000 ; -/* Delaying by one sample: instead of copying the input -* value A_P16VIN to output A_FXBUS2 as in the first channel, -* we use an auxiliary register, delaying the value by one -* sample -*/ -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (2 ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x1 ),A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (4 ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x2 ),A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (6 ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x3 ),A_C_00000000 ,A_C_00000000 ); -/* For 96kHz mode */ -/* Left ADC in. 2 of 2 */ - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (0x8 ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x4 ),A_C_00000000 ,A_C_00000000 ); -/* Right ADC in 2 of 2 */ - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (0xa ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x5 ),A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (0xc ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x6 ),A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr -1 ),A_FXBUS2 (0xe ) ); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x7 ),A_C_00000000 ,A_C_00000000 ); -/* Pavel Hofman - we still have voices, A_FXBUS2s, and -* A_P16VINs available - -* let's add 8 more capture channels - total of 16 -*/ - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x10 )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x8 ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x12 )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0x9 ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x14 )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xa ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x16 )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xb ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x18 )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xc ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x1a )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xd ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x1c )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xe ), -A_C_00000000 ,A_C_00000000 ); - gpr_map[gpr++] =0x00000000 ; -snd_emu10k1_audigy_dsp_convert_32_to_2x16 (icode, &ptr, tmp, - bit_shifter16, -A_GPR (gpr -1 ), -A_FXBUS2 (0x1e )); -A_OP (icode, &ptr, iACC3,A_GPR (gpr -1 ),A_P16VIN (0xf ), -A_C_00000000 ,A_C_00000000 ); +/* A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels +* will need to also be delayed; we use an auxiliary register for that. */ +for (z =1 ; z <0x10 ; z++) { +snd_emu10k1_audigy_dsp_convert_32_to_2x16 ( icode, &ptr, tmp, bit_shifter16,A_GPR (gpr),A_FXBUS2 (z *2 ) ); +A_OP (icode, &ptr, iACC3,A_GPR (gpr),A_P16VIN (z),A_C_00000000 ,A_C_00000000 ); + gpr_map[gpr++] =0x00000000 ; + } }#if 0
Greg Kroah-Hartman
maintainerPATCH 3/11 quota: Properly disable quotas when add_dquot_ref() fails
In reply to Greg Kroah-Hartman[ Upstream commit 6a4e3363792e30177cc3965697e34ddcea8b900b ]
When add_dquot_ref() fails (usually due to IO error or ENOMEM), we want to disable quotas we are trying to enable. However dquot_disable() call was passed just the flags we are enabling so in case flags == DQUOT_USAGE_ENABLED dquot_disable() call will just fail with EINVAL instead of properly disabling quotas. Fix the problem by always passing DQUOT_LIMITS_ENABLED | DQUOT_USAGE_ENABLED to dquot_disable() in this case.
Message-Id: <[email protected]>
--- fs/quota/dquot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/quota/dquot.c +2 -1
@@ -2420,7 +2420,8 @@ int dquot_load_quota_sb(struct super_blo error =add_dquot_ref (sb, type);if (error) -dquot_disable (sb, type, flags); +dquot_disable (sb, type, +DQUOT_USAGE_ENABLED |DQUOT_LIMITS_ENABLED );return error; out_fmt:
Greg Kroah-Hartman
maintainerPATCH 4/11 quota: fix warning in dqgrab()
In reply to Greg Kroah-Hartman[ Upstream commit d6a95db3c7ad160bc16b89e36449705309b52bcb ]
There's issue as follows when do fault injection:
WARNING: CPU: 1 PID: 14870 at include/linux/quotaops.h:51 dquot_disable+0x13b7/0x18c0 Modules linked in: CPU: 1 PID: 14870 Comm: fsconfig Not tainted 6.3.0-next-20230505-00006-g5107a9c821af-dirty #541 RIP: 0010:dquot_disable+0x13b7/0x18c0 RSP: 0018:ffffc9000acc79e0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88825e41b980 RDX: 0000000000000000 RSI: ffff88825e41b980 RDI: 0000000000000002 RBP: ffff888179f68000 R08: ffffffff82087ca7 R09: 0000000000000000 R10: 0000000000000001 R11: ffffed102f3ed026 R12: ffff888179f68130 R13: ffff888179f68110 R14: dffffc0000000000 R15: ffff888179f68118 FS: 00007f450a073740(0000) GS:ffff88882fc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffe96f2efd8 CR3: 000000025c8ad000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> dquot_load_quota_sb+0xd53/0x1060 dquot_resume+0x172/0x230 ext4_reconfigure+0x1dc6/0x27b0 reconfigure_super+0x515/0xa90 __x64_sys_fsconfig+0xb19/0xd20 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Above issue may happens as follows:
ProcessA ProcessB ProcessCsys_fsconfig
vfs_fsconfig_locked
reconfigure_super
ext4_remount
dquot_suspend -> suspend all type quota
sys_fsconfig
vfs_fsconfig_locked
reconfigure_super
ext4_remount
dquot_resume
ret = dquot_load_quota_sb
add_dquot_ref
do_open -> open file O_RDWR
vfs_open
do_dentry_open
get_write_access
atomic_inc_unless_negative(&inode->i_writecount)
ext4_file_open
dquot_file_open
dquot_initialize
__dquot_initialize
dqget
atomic_inc(&dquot->dq_count);
__dquot_initialize
__dquot_initialize
dqget
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
ext4_acquire_dquot
-> Return error DQ_ACTIVE_B flag isn't set
dquot_disable
invalidate_dquots
if (atomic_read(&dquot->dq_count))
dqgrab
WARN_ON_ONCE(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
-> Trigger warningIn the above scenario, 'dquot->dq_flags' has no DQ_ACTIVE_B is normal when dqgrab().
To solve above issue just replace the dqgrab() use in invalidate_dquots() with atomic_inc(&dquot->dq_count).
Message-Id: <[email protected]>
--- fs/quota/dquot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/quota/dquot.c +1 -1
@@ -555,7 +555,7 @@ restart:continue ;/* Wait for dquot users */ if (atomic_read (&dquot->dq_count)) { -dqgrab (dquot); +atomic_inc (&dquot->dq_count);spin_unlock (&dq_list_lock);/* * Once dqput() wakes us up, we know it's time to free
Greg Kroah-Hartman
maintainerPATCH 5/11 HID: add quirk for 03f0:464a HP Elite Presenter Mouse
In reply to Greg Kroah-Hartman[ Upstream commit 0db117359e47750d8bd310d19f13e1c4ef7fc26a ]
HP Elite Presenter Mouse HID Record Descriptor shows two mouses (Repord ID 0x1 and 0x2), one keypad (Report ID 0x5), two Consumer Controls (Report IDs 0x6 and 0x3). Previous to this commit it registers one mouse, one keypad and one Consumer Control, and it was usable only as a digitl laser pointer (one of the two mouses). This patch defines the 464a USB device ID and enables the HID_QUIRK_MULTI_INPUT quirk for it, allowing to use the device both as a mouse and a digital laser pointer.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -614,6 +614,7 @@#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030#define USB_VENDOR_ID_HP 0x03f0 +#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
drivers/hid/hid-quirks.c +1 -0
@@ -96,6 +96,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
Greg Kroah-Hartman
maintainerPATCH 6/11 ovl: check type and offset of struct vfsmount in ovl_entry
In reply to Greg Kroah-Hartman[ Upstream commit f723edb8a532cd26e1ff0a2b271d73762d48f762 ]
Porting overlayfs to the new amount api I started experiencing random crashes that couldn't be explained easily. So after much debugging and reasoning it became clear that struct ovl_entry requires the point to struct vfsmount to be the first member and of type struct vfsmount.
During the port I added a new member at the beginning of struct ovl_entry which broke all over the place in the form of random crashes and cache corruptions. While there's a comment in ovl_free_fs() to the effect of "Hack! Reuse ofs->layers as a vfsmount array before freeing it" there's no such comment on struct ovl_entry which makes this easy to trip over.
Add a comment and two static asserts for both the offset and the type of pointer in struct ovl_entry.
--- fs/overlayfs/ovl_entry.h | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/overlayfs/ovl_entry.h +9 -0
@@ -32,6 +32,7 @@ struct ovl_sb { };struct ovl_layer { +/* ovl_free_fs() relies on @mnt being the first member! */ struct vfsmount *mnt;/* Trap in ovl inode cache */ struct inode *trap;
@@ -42,6 +43,14 @@ struct ovl_layer {int fsid; }; +/* +* ovl_free_fs() relies on @mnt being the first member when unmounting +* the private mounts created for each layer. Let's check both the +* offset and type. +*/ +static_assert (offsetof(struct ovl_layer , mnt) ==0 ); +static_assert (__same_type(typeof_member (struct ovl_layer ,mnt ),struct vfsmount *)); +struct ovl_path {const struct ovl_layer *layer;struct dentry *dentry;
Greg Kroah-Hartman
maintainerPATCH 7/11 udf: Fix uninitialized array access for some pathnames
In reply to Greg Kroah-Hartman[ Upstream commit 028f6055c912588e6f72722d89c30b401bbcf013 ]
For filenames that begin with . and are between 2 and 5 characters long, UDF charset conversion code would read uninitialized memory in the output buffer. The only practical impact is that the name may be prepended a "unification hash" when it is not actually needed but still it is good to fix this.
--- fs/udf/unicode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/udf/unicode.c +1 -1
@@ -247,7 +247,7 @@ static int udf_name_from_CS0(struct super_block *sb, }if (translate) { -if (str_o_len <=2 && str_o[0 ] =='.' && +if (str_o_len >0 && str_o_len <=2 && str_o[0 ] =='.' && (str_o_len ==1 || str_o[1 ] =='.' )) needsCRC =1 ;if (needsCRC) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 8/11 fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev
In reply to Greg Kroah-Hartman[ Upstream commit 4e302336d5ca1767a06beee7596a72d3bdc8d983 ]
Syzkaller reported the following issue:
UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:1965:6 index -84 is out of range for type 's8[341]' (aka 'signed char[341]') CPU: 1 PID: 4995 Comm: syz-executor146 Not tainted 6.4.0-rc6-syzkaller-00037-gb6dad5178cea #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:217 [inline] __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 dbAllocDmapLev+0x3e5/0x430 fs/jfs/jfs_dmap.c:1965 dbAllocCtl+0x113/0x920 fs/jfs/jfs_dmap.c:1809 dbAllocAG+0x28f/0x10b0 fs/jfs/jfs_dmap.c:1350 dbAlloc+0x658/0xca0 fs/jfs/jfs_dmap.c:874 dtSplitUp fs/jfs/jfs_dtree.c:974 [inline] dtInsert+0xda7/0x6b00 fs/jfs/jfs_dtree.c:863 jfs_create+0x7b6/0xbb0 fs/jfs/namei.c:137 lookup_open fs/namei.c:3492 [inline] open_last_lookups fs/namei.c:3560 [inline] path_openat+0x13df/0x3170 fs/namei.c:3788 do_filp_open+0x234/0x490 fs/namei.c:3818 do_sys_openat2+0x13f/0x500 fs/open.c:1356 do_sys_open fs/open.c:1372 [inline] __do_sys_openat fs/open.c:1388 [inline] __se_sys_openat fs/open.c:1383 [inline] __x64_sys_openat+0x247/0x290 fs/open.c:1383 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f1f4e33f7e9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc21129578 EFLAGS: 00000246 ORIG_RAX: 0000000000000101 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1f4e33f7e9 RDX: 000000000000275a RSI: 0000000020000040 RDI: 00000000ffffff9c RBP: 00007f1f4e2ff080 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f1f4e2ff110 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK>
The bug occurs when the dbAllocDmapLev()function attempts to access dp->tree.stree[leafidx + LEAFIND] while the leafidx value is negative.
To rectify this, the patch introduces a safeguard within the dbAllocDmapLev() function. A check has been added to verify if leafidx is negative. If it is, the function immediately returns an I/O error, preventing any further execution that could potentially cause harm.
Tested via syzbot.
--- fs/jfs/jfs_dmap.c | 3 +++ 1 file changed, 3 insertions(+)
fs/jfs/jfs_dmap.c +3 -0
@@ -1959,6 +1959,9 @@ dbAllocDmapLev(struct bmap * bmp,if (dbFindLeaf ((dmtree_t *) & dp->tree, l2nb, &leafidx))return -ENOSPC ; +if (leafidx <0 ) +return -EIO ; +/* determine the block number within the file system corresponding * to the leaf at which free space was found. */
Greg Kroah-Hartman
maintainerPATCH 9/11 MIPS: dec: prom: Address -Warray-bounds warning
In reply to Greg Kroah-Hartman[ Upstream commit 7b191b9b55df2a844bd32d1d380f47a7df1c2896 ]
Zero-length arrays are deprecated, and we are replacing them with flexible array members instead. So, replace zero-length array with flexible-array member in struct memmap.
Address the following warning found after building (with GCC-13) mips64
with decstation_64_defconfig:
In function 'rex_setup_memory_region',
inlined from 'prom_meminit' at arch/mips/dec/prom/memory.c:91:3:arch/mips/dec/prom/memory.c:72:31: error: array subscript i is outside array bounds of 'unsigned char[0]' [-Werror=array-bounds=]
72 | if (bm->bitmap[i] == 0xff)
| ~~~~~~~~~~^~~
In file included from arch/mips/dec/prom/memory.c:16:./arch/mips/include/asm/dec/prom.h: In function 'prom_meminit':./arch/mips/include/asm/dec/prom.h:73:23: note: while referencing 'bitmap'
73 | unsigned char bitmap[0];
This helps with the ongoing efforts to globally enable -Warray-bounds.
This results in no differences in binary output.
--- arch/mips/include/asm/dec/prom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/dec/prom.h +1 -1
@@ -70,7 +70,7 @@ static inline bool prom_is_rex(u32 magic*/ typedef struct {int pagesize; -unsigned char bitmap[0 ]; +unsigned char bitmap[]; }memmap ;
Greg Kroah-Hartman
maintainerPATCH 43/183 ASoC: qdsp6: audioreach: fix topology probe deferral
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 46ec420573cefa1fc98025e7e6841bdafd6f1e20 upstream.
Propagate errors when failing to load the topology component so that probe deferrals can be handled.
--- sound/soc/qcom/qdsp6/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/qcom/qdsp6/topology.c +2 -2
@@ -1100,8 +1100,8 @@ int audioreach_tplg_init(struct snd_soc_ ret =snd_soc_tplg_component_load (component, &audioreach_tplg_ops, fw);if (ret <0 ) { -dev_err (dev,"tplg component load failed%d\n" , ret); - ret = -EINVAL ; +if (ret != -EPROBE_DEFER ) +dev_err (dev,"tplg component load failed: %d\n" , ret); }release_firmware (fw);
Greg Kroah-Hartman
maintainerPATCH 10/11 FS: JFS: Fix null-ptr-deref Read in txBegin
In reply to Greg Kroah-Hartman[ Upstream commit 47cfdc338d674d38f4b2f22b7612cc6a2763ba27 ]
Syzkaller reported an issue where txBegin may be called on a superblock in a read-only mounted filesystem which leads to NULL pointer deref. This could be solved by checking if the filesystem is read-only before calling txBegin, and returning with appropiate error code.
--- fs/jfs/namei.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/jfs/namei.c +5 -0
@@ -799,6 +799,11 @@ static int jfs_link(struct dentry *old_dif (rc) goto out; +if (isReadOnly (ip)) { +jfs_error (ip->i_sb,"read-only filesystem\n" ); +return -EROFS ; + } + tid =txBegin (ip->i_sb,0 );mutex_lock_nested (&JFS_IP (dir)->commit_mutex,COMMIT_MUTEX_PARENT );
Greg Kroah-Hartman
maintainerPATCH 44/183 ASoC: tegra: Fix AMX byte map
In reply to Greg Kroah-HartmanFrom: Sheetal <[email protected]>
commit 49bd7b08149417a30aa7d92c8c85b3518de44a76 upstream.
Byte mask for channel-1 of stream-1 is not getting enabled and this causes failures during AMX use cases. This happens because the byte map value 0 matches the byte map array and put() callback returns without enabling the corresponding bits in the byte mask.
AMX supports 4 input streams and each stream can take a maximum of 16 channels. Each byte in the output frame is uniquely mapped to a byte in one of these 4 inputs. This mapping is done with the help of byte map array via user space control setting. The byte map array size in the driver is 16 and each array element is of size 4 bytes. This corresponds to 64 byte map values.
Each byte in the byte map array can have any value between 0 to 255 to enable the corresponding bits in the byte mask. The value 256 is used as a way to disable the byte map. However the byte map array element cannot store this value. The put() callback disables the byte mask for 256 value and byte map value is reset to 0 for this case. This causes problems during subsequent runs since put() callback, for value of 0, just returns without enabling the byte mask. In short, the problem is coming because 0 and 256 control values are stored as 0 in the byte map array.
Right now fix the put() callback by actually looking at the byte mask array state to identify if any change is needed and update the fields accordingly. The get() callback needs an update as well to return the correct control value that user has set before. Note that when user sets 256, the value is stored as 0 and byte mask is disabled. So byte mask state is used to either return 256 or the value from byte map array.
Given above, this looks bit complicated and all this happens because the byte map array is tightly packed and cannot actually store the 256 value. Right now the priority is to fix the existing failure and a TODO item is put to improve this logic.
--- sound/soc/tegra/tegra210_amx.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-)
sound/soc/tegra/tegra210_amx.c +22 -18
@@ -2,7 +2,7 @@// // tegra210_amx.c - Tegra210 AMX driver // -// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. #include <linux/clk.h> #include <linux/device.h>
@@ -203,10 +203,20 @@ static int tegra210_amx_get_byte_map(strelse enabled = amx->byte_mask[0 ] & (1 << reg); +/* +* TODO: Simplify this logic to just return from bytes_map[] +* +* Presently below is required since bytes_map[] is +* tightly packed and cannot store the control value of 256. +* Byte mask state is used to know if 256 needs to be returned. +* Note that for control value of 256, the put() call stores 0 +* in the bytes_map[] and disables the corresponding bit in +* byte_mask[]. +*/ if (enabled) ucontrol->value.integer.value[0 ] = bytes_map[reg];else - ucontrol->value.integer.value[0 ] =0 ; + ucontrol->value.integer.value[0 ] =256 ;return 0 ; }
@@ -221,25 +231,19 @@ static int tegra210_amx_put_byte_map(strunsigned char *bytes_map = (unsigned char *)&amx->map;int reg = mc->reg;int value = ucontrol->value.integer.value[0 ]; +unsigned int mask_val = amx->byte_mask[reg /32 ]; -if (value == bytes_map[reg]) +if (value >=0 && value <=255 ) + mask_val |= (1 << (reg %32 )); +else + mask_val &= ~(1 << (reg %32 )); + +if (mask_val == amx->byte_mask[reg /32 ])return 0 ; -if (value >=0 && value <=255 ) { -/* Update byte map and enable slot */ - bytes_map[reg] = value; -if (reg >31 ) - amx->byte_mask[1 ] |= (1 << (reg -32 )); -else - amx->byte_mask[0 ] |= (1 << reg); - }else { -/* Reset byte map and disable slot */ - bytes_map[reg] =0 ; -if (reg >31 ) - amx->byte_mask[1 ] &= ~(1 << (reg -32 )); -else - amx->byte_mask[0 ] &= ~(1 << reg); - } +/* Update byte map and slot */ + bytes_map[reg] = value %256 ; + amx->byte_mask[reg /32 ] = mask_val;return 1 ; }
Greg Kroah-Hartman
maintainerPATCH 45/183 ASoC: codecs: wcd938x: fix resource leaks on component remove
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit a3406f87775fee986876e03f93a84385f54d5999 upstream.
Make sure to release allocated resources on component probe failure and on remove.
This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component:
snd-sc8280xp sound: ASoC: failed to instantiate card -517
genirq: Flags mismatch irq 289. 00002001 (HPHR PDM WD INT) vs. 00002001 (HPHR PDM WD INT)
wcd938x_codec audio-codec: Failed to request HPHR WD interrupt (-16)
genirq: Flags mismatch irq 290. 00002001 (HPHL PDM WD INT) vs. 00002001 (HPHL PDM WD INT)
wcd938x_codec audio-codec: Failed to request HPHL WD interrupt (-16)
genirq: Flags mismatch irq 291. 00002001 (AUX PDM WD INT) vs. 00002001 (AUX PDM WD INT)
wcd938x_codec audio-codec: Failed to request Aux WD interrupt (-16)
genirq: Flags mismatch irq 292. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr)
wcd938x_codec audio-codec: Failed to request mbhc interrupts -16--- sound/soc/codecs/wcd938x.c | 55 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-)
sound/soc/codecs/wcd938x.c +48 -7
@@ -2633,6 +2633,14 @@ static int wcd938x_mbhc_init(struct snd_return 0 ; } + +static void wcd938x_mbhc_deinit (struct snd_soc_component *component) +{ +struct wcd938x_priv *wcd938x =snd_soc_component_get_drvdata (component); + +wcd_mbhc_deinit (wcd938x->wcd_mbhc); +} +/* END MBHC */ static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
@@ -3113,20 +3121,26 @@ static int wcd938x_soc_codec_probe(struc ret =request_threaded_irq (wcd938x->hphr_pdm_wd_int,NULL , wcd938x_wd_handle_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"HPHR PDM WD INT" , wcd938x); -if (ret) +if (ret) {dev_err (dev,"Failed to request HPHR WD interrupt (%d)\n" , ret); + goto err_free_clsh_ctrl; + } ret =request_threaded_irq (wcd938x->hphl_pdm_wd_int,NULL , wcd938x_wd_handle_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"HPHL PDM WD INT" , wcd938x); -if (ret) +if (ret) {dev_err (dev,"Failed to request HPHL WD interrupt (%d)\n" , ret); + goto err_free_hphr_pdm_wd_int; + } ret =request_threaded_irq (wcd938x->aux_pdm_wd_int,NULL , wcd938x_wd_handle_irq,IRQF_ONESHOT |IRQF_TRIGGER_RISING ,"AUX PDM WD INT" , wcd938x); -if (ret) +if (ret) {dev_err (dev,"Failed to request Aux WD interrupt (%d)\n" , ret); + goto err_free_hphl_pdm_wd_int; + }/* Disable watchdog interrupt for HPH and AUX */ disable_irq_nosync (wcd938x->hphr_pdm_wd_int);
@@ -3141,7 +3155,7 @@ static int wcd938x_soc_codec_probe(strucdev_err (component->dev,"%s: Failed to add snd ctrls for variant: %d\n" , __func__, wcd938x->variant); - goto err; + goto err_free_aux_pdm_wd_int; }break ;case WCD9385 :
@@ -3151,7 +3165,7 @@ static int wcd938x_soc_codec_probe(strucdev_err (component->dev,"%s: Failed to add snd ctrls for variant: %d\n" , __func__, wcd938x->variant); - goto err; + goto err_free_aux_pdm_wd_int; }break ;default :
@@ -3159,12 +3173,38 @@ static int wcd938x_soc_codec_probe(struc } ret =wcd938x_mbhc_init (component); -if (ret) +if (ret) {dev_err (component->dev,"mbhc initialization failed\n" ); -err: + goto err_free_aux_pdm_wd_int; + } + +return 0 ; + +err_free_aux_pdm_wd_int: +free_irq (wcd938x->aux_pdm_wd_int, wcd938x); +err_free_hphl_pdm_wd_int: +free_irq (wcd938x->hphl_pdm_wd_int, wcd938x); +err_free_hphr_pdm_wd_int: +free_irq (wcd938x->hphr_pdm_wd_int, wcd938x); +err_free_clsh_ctrl: +wcd_clsh_ctrl_free (wcd938x->clsh_info); +return ret; } +static void wcd938x_soc_codec_remove (struct snd_soc_component *component) +{ +struct wcd938x_priv *wcd938x =snd_soc_component_get_drvdata (component); + +wcd938x_mbhc_deinit (component); + +free_irq (wcd938x->aux_pdm_wd_int, wcd938x); +free_irq (wcd938x->hphl_pdm_wd_int, wcd938x); +free_irq (wcd938x->hphr_pdm_wd_int, wcd938x); + +wcd_clsh_ctrl_free (wcd938x->clsh_info); +} +static int wcd938x_codec_set_jack (struct snd_soc_component *comp,struct snd_soc_jack *jack,void *data) {
@@ -3181,6 +3221,7 @@ static int wcd938x_codec_set_jack(structstatic const struct snd_soc_component_driver soc_codec_dev_wcd938x = { .name ="wcd938x_codec" , .probe = wcd938x_soc_codec_probe, + .remove = wcd938x_soc_codec_remove, .controls = wcd938x_snd_controls, .num_controls =ARRAY_SIZE (wcd938x_snd_controls), .dapm_widgets = wcd938x_dapm_widgets,
Greg Kroah-Hartman
maintainerPATCH 46/183 ASoC: codecs: wcd938x: fix missing mbhc init error handling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 7dfae2631bfbdebecd35fe7b472ab3cc95c9ed66 upstream.
MBHC initialisation can fail so add the missing error handling to avoid dereferencing an error pointer when later configuring the jack:
Unable to handle kernel paging request at virtual address fffffffffffffff8
pc : wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc]
lr : wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x]
Call trace:
wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc]
wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x]
snd_soc_component_set_jack+0x28/0x8c [snd_soc_core]
qcom_snd_wcd_jack_setup+0x7c/0x19c [snd_soc_qcom_common]
sc8280xp_snd_init+0x20/0x2c [snd_soc_sc8280xp]
snd_soc_link_init+0x28/0x90 [snd_soc_core]
snd_soc_bind_card+0x628/0xbfc [snd_soc_core]
snd_soc_register_card+0xec/0x104 [snd_soc_core]
devm_snd_soc_register_card+0x4c/0xa4 [snd_soc_core]
sc8280xp_platform_probe+0xf0/0x108 [snd_soc_sc8280xp]--- sound/soc/codecs/wcd938x.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/codecs/wcd938x.c +2 -0
@@ -2625,6 +2625,8 @@ static int wcd938x_mbhc_init(struct snd_ WCD938X_IRQ_HPHR_OCP_INT); wcd938x->wcd_mbhc =wcd_mbhc_init (component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true); +if (IS_ERR (wcd938x->wcd_mbhc)) +return PTR_ERR (wcd938x->wcd_mbhc);snd_soc_add_component_controls (component, impedance_detect_controls,ARRAY_SIZE (impedance_detect_controls));
Greg Kroah-Hartman
maintainerPATCH 47/183 ASoC: codecs: wcd934x: fix resource leaks on component remove
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 798590cc7d3c2b5f3a7548d96dd4d8a081c1bc39 upstream.
Make sure to release allocated MBHC resources also on component remove.
This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component.
--- sound/soc/codecs/wcd934x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
sound/soc/codecs/wcd934x.c +12 -0
@@ -3044,6 +3044,17 @@ static int wcd934x_mbhc_init(struct snd_return 0 ; } + +static void wcd934x_mbhc_deinit (struct snd_soc_component *component) +{ +struct wcd934x_codec *wcd =snd_soc_component_get_drvdata (component); + +if (!wcd->mbhc) +return ; + +wcd_mbhc_deinit (wcd->mbhc); +} +static int wcd934x_comp_probe (struct snd_soc_component *component) {struct wcd934x_codec *wcd =dev_get_drvdata (component->dev);
@@ -3077,6 +3088,7 @@ static void wcd934x_comp_remove(struct s {struct wcd934x_codec *wcd =dev_get_drvdata (comp->dev); +wcd934x_mbhc_deinit (comp);wcd_clsh_ctrl_free (wcd->clsh_ctrl); }
Greg Kroah-Hartman
maintainerPATCH 48/183 ASoC: codecs: wcd938x: fix codec initialisation race
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 85a61b1ce461a3f62f1019e5e6423c393c542bff upstream.
Make sure to resume the codec and soundwire device before trying to read the codec variant and configure the device during component probe.
This specifically avoids interpreting (a masked and shifted) -EBUSY errno as the variant:
wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16
when the soundwire device happens to be suspended, which in turn prevents some headphone controls from being registered.
--- sound/soc/codecs/wcd938x.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/soc/codecs/wcd938x.c +6 -0
@@ -3095,6 +3095,10 @@ static int wcd938x_soc_codec_probe(strucsnd_soc_component_init_regmap (component, wcd938x->regmap); + ret =pm_runtime_resume_and_get (dev); +if (ret <0 ) +return ret; + wcd938x->variant =snd_soc_component_read_field (component,WCD938X_DIGITAL_EFUSE_REG_0 ,WCD938X_ID_MASK );
@@ -3112,6 +3116,8 @@ static int wcd938x_soc_codec_probe(struc (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0); } +pm_runtime_put (dev); + wcd938x->hphr_pdm_wd_int =regmap_irq_get_virq (wcd938x->irq_chip,WCD938X_IRQ_HPHR_PDM_WD_INT ); wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
Greg Kroah-Hartman
maintainerPATCH 49/183 ASoC: codecs: wcd938x: fix soundwire initialisation race
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 6f49256897083848ce9a59651f6b53fc80462397 upstream.
Make sure that the soundwire device used for register accesses has been enumerated and initialised before trying to read the codec variant during component probe.
This specifically avoids interpreting (a masked and shifted) -EBUSY errno as the variant:
wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16
in case the soundwire device has not yet been initialised, which in turn prevents some headphone controls from being registered.
--- sound/soc/codecs/wcd938x.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/codecs/wcd938x.c +9 -0
@@ -3090,9 +3090,18 @@ static int wcd938x_irq_init(struct wcd93static int wcd938x_soc_codec_probe (struct snd_soc_component *component) {struct wcd938x_priv *wcd938x =snd_soc_component_get_drvdata (component); +struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev;struct device *dev = component->dev; +unsigned long time_left;int ret, i; + time_left =wait_for_completion_timeout (&tx_sdw_dev->initialization_complete, +msecs_to_jiffies (2000 )); +if (!time_left) { +dev_err (dev,"soundwire device init timeout\n" ); +return -ETIMEDOUT ; + } +snd_soc_component_init_regmap (component, wcd938x->regmap); ret =pm_runtime_resume_and_get (dev);
Greg Kroah-Hartman
maintainerPATCH 50/183 ext4: correct inline offset when handling xattrs in inode body
In reply to Greg Kroah-HartmanFrom: Eric Whitney <[email protected]>
commit 6909cf5c4101214f4305a62d582a5b93c7e1eb9a upstream.
When run on a file system where the inline_data feature has been enabled, xfstests generic/269, generic/270, and generic/476 cause ext4 to emit error messages indicating that inline directory entries are corrupted. This occurs because the inline offset used to locate inline directory entries in the inode body is not updated when an xattr in that shared region is deleted and the region is shifted in memory to recover the space it occupied. If the deleted xattr precedes the system.data attribute, which points to the inline directory entries, that attribute will be moved further up in the region. The inline offset continues to point to whatever is located in system.data's former location, with unfortunate effects when used to access directory entries or (presumably) inline data in the inode body.
--- fs/ext4/xattr.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/ext4/xattr.c +14 -0
@@ -1732,6 +1732,20 @@ static int ext4_xattr_set_entry(struct ememmove (here, (void *)here + size, (void *)last - (void *)here +sizeof (__u32));memset (last,0 , size); + +/* +* Update i_inline_off - moved ibody region might contain +* system.data attribute. Handling a failure here won't +* cause other complications for setting an xattr. +*/ +if (!is_block &&ext4_has_inline_data (inode)) { + ret =ext4_find_inline_data_nolock (inode); +if (ret) { +ext4_warning_inode (inode, +"unable to update i_inline_off" ); + goto out; + } + } }else if (s->not_found) {/* Insert new name. */ size_t size =EXT4_XATTR_LEN (name_len);
Greg Kroah-Hartman
maintainerPATCH 62/183 ACPI: video: Add backlight=native DMI quirk for Dell Studio 1569
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 23d28cc0444be3f694eb986cd653b6888b78431d ]
The Dell Studio 1569 predates Windows 8, so it defaults to using acpi_video# for backlight control, but this is non functional on this model.
Add a DMI quirk to use the native intel_backlight interface which does work properly.
--- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/acpi/video_detect.c +8 -0
@@ -512,6 +512,14 @@ static const struct dmi_system_id video_ }, { .callback = video_detect_force_native, + /* Dell Studio 1569 */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), + DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1569"), + }, + }, + { + .callback = video_detect_force_native,/* Acer Aspire 3830TG */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
Greg Kroah-Hartman
maintainerPATCH 63/183 rcu-tasks: Avoid pr_info() with spin lock in cblist_init_generic()
In reply to Greg Kroah-HartmanFrom: Shigeru Yoshida <[email protected]>
[ Upstream commit 5fc8cbe4cf0fd34ded8045c385790c3bf04f6785 ]
pr_info() is called with rtp->cbs_gbl_lock spin lock locked. Because pr_info() calls printk() that might sleep, this will result in BUG like below:
[ 0.206455] cblist_init_generic: Setting adjustable number of callback queues.
[ 0.206463]
[ 0.206464] =============================
[ 0.206464] [ BUG: Invalid wait context ]
[ 0.206465] 5.19.0-00428-g9de1f9c8ca51 #5 Not tainted
[ 0.206466] -----------------------------
[ 0.206466] swapper/0/1 is trying to lock:
[ 0.206467] ffffffffa0167a58 (&port_lock_key){....}-{3:3}, at: serial8250_console_write+0x327/0x4a0
[ 0.206473] other info that might help us debug this:
[ 0.206473] context-{5:5}
[ 0.206474] 3 locks held by swapper/0/1:
[ 0.206474] #0: ffffffff9eb597e0 (rcu_tasks.cbs_gbl_lock){....}-{2:2}, at: cblist_init_generic.constprop.0+0x14/0x1f0
[ 0.206478] #1: ffffffff9eb579c0 (console_lock){+.+.}-{0:0}, at: _printk+0x63/0x7e
[ 0.206482] #2: ffffffff9ea77780 (console_owner){....}-{0:0}, at: console_emit_next_record.constprop.0+0x111/0x330
[ 0.206485] stack backtrace:
[ 0.206486] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.19.0-00428-g9de1f9c8ca51 #5
[ 0.206488] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-1.fc36 04/01/2014
[ 0.206489] Call Trace:
[ 0.206490] <TASK>
[ 0.206491] dump_stack_lvl+0x6a/0x9f
[ 0.206493] __lock_acquire.cold+0x2d7/0x2fe
[ 0.206496] ? stack_trace_save+0x46/0x70
[ 0.206497] lock_acquire+0xd1/0x2f0
[ 0.206499] ? serial8250_console_write+0x327/0x4a0
[ 0.206500] ? __lock_acquire+0x5c7/0x2720
[ 0.206502] _raw_spin_lock_irqsave+0x3d/0x90
[ 0.206504] ? serial8250_console_write+0x327/0x4a0
[ 0.206506] serial8250_console_write+0x327/0x4a0
[ 0.206508] console_emit_next_record.constprop.0+0x180/0x330
[ 0.206511] console_unlock+0xf7/0x1f0
[ 0.206512] vprintk_emit+0xf7/0x330
[ 0.206514] _printk+0x63/0x7e
[ 0.206516] cblist_init_generic.constprop.0.cold+0x24/0x32
[ 0.206518] rcu_init_tasks_generic+0x5/0xd9
[ 0.206522] kernel_init_freeable+0x15b/0x2a2
[ 0.206523] ? rest_init+0x160/0x160
[ 0.206526] kernel_init+0x11/0x120
[ 0.206527] ret_from_fork+0x1f/0x30
[ 0.206530] </TASK>
[ 0.207018] cblist_init_generic: Setting shift to 1 and lim to 1.This patch moves pr_info() so that it is called without rtp->cbs_gbl_lock locked.
--- kernel/rcu/tasks.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/rcu/tasks.h +4 -1
@@ -233,7 +233,6 @@ static void cblist_init_generic(struct rcu_tasks *rtp)if (rcu_task_enqueue_lim <0 ) { rcu_task_enqueue_lim =1 ; rcu_task_cb_adjust = true; -pr_info ("%s: Setting adjustable number of callback queues.\n" , __func__); }else if (rcu_task_enqueue_lim ==0 ) { rcu_task_enqueue_lim =1 ; }
@@ -264,6 +263,10 @@ static void cblist_init_generic(struct rcu_tasks *rtp)raw_spin_unlock_rcu_node (rtpcp);// irqs remain disabled. }raw_spin_unlock_irqrestore (&rtp->cbs_gbl_lock, flags); + +if (rcu_task_cb_adjust) +pr_info ("%s: Setting adjustable number of callback queues.\n" , __func__); +pr_info ("%s: Setting shift to %d and lim to %d.\n" , __func__,data_race (rtp->percpu_enqueue_shift),data_race (rtp->percpu_enqueue_lim)); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 64/183 rcu: Mark additional concurrent load from ->cpu_no_qs.b.exp
In reply to Greg Kroah-HartmanFrom: Paul E. McKenney <[email protected]>
[ Upstream commit 9146eb25495ea8bfb5010192e61e3ed5805ce9ef ]
The per-CPU rcu_data structure's ->cpu_no_qs.b.exp field is updated only on the instance corresponding to the current CPU, but can be read more widely. Unmarked accesses are OK from the corresponding CPU, but only if interrupts are disabled, given that interrupt handlers can and do modify this field.
Unfortunately, although the load from rcu_preempt_deferred_qs() is always carried out from the corresponding CPU, interrupts are not necessarily disabled. This commit therefore upgrades this load to READ_ONCE.
Similarly, the diagnostic access from synchronize_rcu_expedited_wait() might run with interrupts disabled and from some other CPU. This commit therefore marks this load with data_race().
Finally, the C-language access in rcu_preempt_ctxt_queue() is OK as is because interrupts are disabled and this load is always from the corresponding CPU. This commit adds a comment giving the rationale for this access being safe.
This data race was reported by KCSAN. Not appropriate for backporting due to failure being unlikely.
--- kernel/rcu/tree_exp.h | 2 +- kernel/rcu/tree_plugin.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
kernel/rcu/tree_exp.h +1 -1
@@ -641,7 +641,7 @@ static void synchronize_rcu_expedited_wait(void)"O." [!!cpu_online (cpu)],"o." [!!(rdp->grpmask & rnp->expmaskinit)],"N." [!!(rdp->grpmask & rnp->expmaskinitnext)], - "D."[!!(rdp->cpu_no_qs.b.exp)]); + "D."[!!data_race(rdp->cpu_no_qs.b.exp)]); } } pr_cont(" } %lu jiffies s: %lu root: %#lx/%c\n",
kernel/rcu/tree_plugin.h +3 -1
@@ -257,6 +257,8 @@ static void rcu_preempt_ctxt_queue(struct rcu_node *rnp, struct rcu_data *rdp)* GP should not be able to end until we report, so there should be * no need to check for a subsequent expedited GP. (Though we are * still in a quiescent state in any case.) +* +* Interrupts are disabled, so ->cpu_no_qs.b.exp cannot change. */ if (blkd_state &RCU_EXP_BLKD && rdp->cpu_no_qs.b.exp)rcu_report_exp_rdp (rdp);
@@ -941,7 +943,7 @@ notrace void rcu_preempt_deferred_qs(struct task_struct *t) {struct rcu_data *rdp =this_cpu_ptr (&rcu_data); -if (rdp->cpu_no_qs.b.exp) +if (READ_ONCE (rdp->cpu_no_qs.b.exp))rcu_report_exp_rdp (rdp); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 65/183 sched/fair: Dont balance task to its current running CPU
In reply to Greg Kroah-HartmanFrom: Yicong Yang <[email protected]>
[ Upstream commit 0dd37d6dd33a9c23351e6115ae8cdac7863bc7de ]
We've run into the case that the balancer tries to balance a migration disabled task and trigger the warning in set_task_cpu() like below:
------------[ cut here ]------------ WARNING: CPU: 7 PID: 0 at kernel/sched/core.c:3115 set_task_cpu+0x188/0x240 Modules linked in: hclgevf xt_CHECKSUM ipt_REJECT nf_reject_ipv4 <...snip> CPU: 7 PID: 0 Comm: swapper/7 Kdump: loaded Tainted: G O 6.1.0-rc4+ #1 Hardware name: Huawei TaiShan 2280 V2/BC82AMDC, BIOS 2280-V2 CS V5.B221.01 12/09/2021 pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : set_task_cpu+0x188/0x240 lr : load_balance+0x5d0/0xc60 sp : ffff80000803bc70 x29: ffff80000803bc70 x28: ffff004089e190e8 x27: ffff004089e19040 x26: ffff007effcabc38 x25: 0000000000000000 x24: 0000000000000001 x23: ffff80000803be84 x22: 000000000000000c x21: ffffb093e79e2a78 x20: 000000000000000c x19: ffff004089e19040 x18: 0000000000000000 x17: 0000000000001fad x16: 0000000000000030 x15: 0000000000000000 x14: 0000000000000003 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000001 x10: 0000000000000400 x9 : ffffb093e4cee530 x8 : 00000000fffffffe x7 : 0000000000ce168a x6 : 000000000000013e x5 : 00000000ffffffe1 x4 : 0000000000000001 x3 : 0000000000000b2a x2 : 0000000000000b2a x1 : ffffb093e6d6c510 x0 : 0000000000000001 Call trace: set_task_cpu+0x188/0x240 load_balance+0x5d0/0xc60 rebalance_domains+0x26c/0x380 _nohz_idle_balance.isra.0+0x1e0/0x370 run_rebalance_domains+0x6c/0x80 __do_softirq+0x128/0x3d8 ____do_softirq+0x18/0x24 call_on_irq_stack+0x2c/0x38 do_softirq_own_stack+0x24/0x3c __irq_exit_rcu+0xcc/0xf4 irq_exit_rcu+0x18/0x24 el1_interrupt+0x4c/0xe4 el1h_64_irq_handler+0x18/0x2c el1h_64_irq+0x74/0x78 arch_cpu_idle+0x18/0x4c default_idle_call+0x58/0x194 do_idle+0x244/0x2b0 cpu_startup_entry+0x30/0x3c secondary_start_kernel+0x14c/0x190 __secondary_switched+0xb0/0xb4 ---[ end trace 0000000000000000 ]---
Further investigation shows that the warning is superfluous, the migration disabled task is just going to be migrated to its current running CPU. This is because that on load balance if the dst_cpu is not allowed by the task, we'll re-select a new_dst_cpu as a candidate. If no task can be balanced to dst_cpu we'll try to balance the task to the new_dst_cpu instead. In this case when the migration disabled task is not on CPU it only allows to run on its current CPU, load balance will select its current CPU as new_dst_cpu and later triggers the warning above.
The new_dst_cpu is chosen from the env->dst_grpmask. Currently it contains CPUs in sched_group_span() and if we have overlapped groups it's possible to run into this case. This patch makes env->dst_grpmask of group_balance_mask() which exclude any CPUs from the busiest group and solve the issue. For balancing in a domain with no overlapped groups the behaviour keeps same as before.
--- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/fair.c +1 -1
@@ -10556,7 +10556,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, .sd = sd, .dst_cpu = this_cpu, .dst_rq = this_rq, - .dst_grpmask = sched_group_span(sd->groups), + .dst_grpmask = group_balance_mask(sd->groups), .idle = idle, .loop_break = SCHED_NR_MIGRATE_BREAK, .cpus = cpus,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 66/183 wifi: ath11k: fix registration of 6Ghz-only phy without the full channel range
In reply to Greg Kroah-HartmanFrom: Maxime Bizon <[email protected]>
[ Upstream commit e2ceb1de2f83aafd8003f0b72dfd4b7441e97d14 ]
Because of what seems to be a typo, a 6Ghz-only phy for which the BDF does not allow the 7115Mhz channel will fail to register:
WARNING: CPU: 2 PID: 106 at net/wireless/core.c:907 wiphy_register+0x914/0x954 Modules linked in: ath11k_pci sbsa_gwdt CPU: 2 PID: 106 Comm: kworker/u8:5 Not tainted 6.3.0-rc7-next-20230418-00549-g1e096a17625a-dirty #9 Hardware name: Freebox V7R Board (DT) Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : wiphy_register+0x914/0x954 lr : ieee80211_register_hw+0x67c/0xc10 sp : ffffff800b123aa0 x29: ffffff800b123aa0 x28: 0000000000000000 x27: 0000000000000000 x26: 0000000000000000 x25: 0000000000000006 x24: ffffffc008d51418 x23: ffffffc008cb0838 x22: ffffff80176c2460 x21: 0000000000000168 x20: ffffff80176c0000 x19: ffffff80176c03e0 x18: 0000000000000014 x17: 00000000cbef338c x16: 00000000d2a26f21 x15: 00000000ad6bb85f x14: 0000000000000020 x13: 0000000000000020 x12: 00000000ffffffbd x11: 0000000000000208 x10: 00000000fffffdf7 x9 : ffffffc009394718 x8 : ffffff80176c0528 x7 : 000000007fffffff x6 : 0000000000000006 x5 : 0000000000000005 x4 : ffffff800b304284 x3 : ffffff800b304284 x2 : ffffff800b304d98 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: wiphy_register+0x914/0x954 ieee80211_register_hw+0x67c/0xc10 ath11k_mac_register+0x7c4/0xe10 ath11k_core_qmi_firmware_ready+0x1f4/0x570 ath11k_qmi_driver_event_work+0x198/0x590 process_one_work+0x1b8/0x328 worker_thread+0x6c/0x414 kthread+0x100/0x104 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- ath11k_pci 0002:01:00.0: ieee80211 registration failed: -22 ath11k_pci 0002:01:00.0: failed register the radio with mac80211: -22 ath11k_pci 0002:01:00.0: failed to create pdev core: -22
--- drivers/net/wireless/ath/ath11k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/mac.c +1 -1
@@ -8715,7 +8715,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, }if (supported_bands &WMI_HOST_WLAN_5G_CAP ) { -if (reg_cap->high_5ghz_chan >=ATH11K_MAX_6G_FREQ ) { +if (reg_cap->high_5ghz_chan >=ATH11K_MIN_6G_FREQ ) { channels =kmemdup (ath11k_6ghz_channels,sizeof (ath11k_6ghz_channels),GFP_KERNEL );if (!channels) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 67/183 bpf: Print a warning only if writing to unprivileged_bpf_disabled.
In reply to Greg Kroah-HartmanFrom: Kui-Feng Lee <[email protected]>
[ Upstream commit fedf99200ab086c42a572fca1d7266b06cdc3e3f ]
Only print the warning message if you are writing to "/proc/sys/kernel/unprivileged_bpf_disabled".
The kernel may print an annoying warning when you read "/proc/sys/kernel/unprivileged_bpf_disabled" saying
WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!
However, this message is only meaningful when the feature is disabled or enabled.
--- kernel/bpf/syscall.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/bpf/syscall.c +2 -1
@@ -5289,7 +5289,8 @@ static int bpf_unpriv_handler(struct ctl_table *table, int write, *(int *)table->data = unpriv_enable; } -unpriv_ebpf_notify (unpriv_enable); +if (write) +unpriv_ebpf_notify (unpriv_enable);return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 68/183 bpf: Address KCSAN report on bpf_lru_list
In reply to Greg Kroah-HartmanFrom: Martin KaFai Lau <[email protected]>
[ Upstream commit ee9fd0ac3017c4313be91a220a9ac4c99dde7ad4 ]
KCSAN reported a data-race when accessing node->ref. Although node->ref does not have to be accurate,
take this chance to use a more common READ_ONCE() and WRITE_ONCE() pattern instead of data_race().
There is an existing bpf_lru_node_is_ref() and bpf_lru_node_set_ref(). This patch also adds bpf_lru_node_clear_ref() to do the WRITE_ONCE(node->ref, 0) also.
==================================================================
BUG: KCSAN: data-race in __bpf_lru_list_rotate / __htab_lru_percpu_map_update_elem
write to 0xffff888137038deb of 1 bytes by task 11240 on cpu 1:
__bpf_lru_node_move kernel/bpf/bpf_lru_list.c:113 [inline] __bpf_lru_list_rotate_active kernel/bpf/bpf_lru_list.c:149 [inline] __bpf_lru_list_rotate+0x1bf/0x750 kernel/bpf/bpf_lru_list.c:240 bpf_lru_list_pop_free_to_local kernel/bpf/bpf_lru_list.c:329 [inline] bpf_common_lru_pop_free kernel/bpf/bpf_lru_list.c:447 [inline] bpf_lru_pop_free+0x638/0xe20 kernel/bpf/bpf_lru_list.c:499 prealloc_lru_pop kernel/bpf/hashtab.c:290 [inline] __htab_lru_percpu_map_update_elem+0xe7/0x820 kernel/bpf/hashtab.c:1316 bpf_percpu_hash_update+0x5e/0x90 kernel/bpf/hashtab.c:2313 bpf_map_update_value+0x2a9/0x370 kernel/bpf/syscall.c:200 generic_map_update_batch+0x3ae/0x4f0 kernel/bpf/syscall.c:1687 bpf_map_do_batch+0x2d9/0x3d0 kernel/bpf/syscall.c:4534 __sys_bpf+0x338/0x810 __do_sys_bpf kernel/bpf/syscall.c:5096 [inline] __se_sys_bpf kernel/bpf/syscall.c:5094 [inline] __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5094 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
read to 0xffff888137038deb of 1 bytes by task 11241 on cpu 0:
bpf_lru_node_set_ref kernel/bpf/bpf_lru_list.h:70 [inline] __htab_lru_percpu_map_update_elem+0x2f1/0x820 kernel/bpf/hashtab.c:1332 bpf_percpu_hash_update+0x5e/0x90 kernel/bpf/hashtab.c:2313 bpf_map_update_value+0x2a9/0x370 kernel/bpf/syscall.c:200 generic_map_update_batch+0x3ae/0x4f0 kernel/bpf/syscall.c:1687 bpf_map_do_batch+0x2d9/0x3d0 kernel/bpf/syscall.c:4534 __sys_bpf+0x338/0x810 __do_sys_bpf kernel/bpf/syscall.c:5096 [inline] __se_sys_bpf kernel/bpf/syscall.c:5094 [inline] __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5094 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x01 -> 0x00
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 11241 Comm: syz-executor.3 Not tainted 6.3.0-rc7-syzkaller-00136-g6a66fdd29ea1 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/30/2023 ==================================================================
--- kernel/bpf/bpf_lru_list.c | 21 +++++++++++++-------- kernel/bpf/bpf_lru_list.h | 7 ++----- 2 files changed, 15 insertions(+), 13 deletions(-)
kernel/bpf/bpf_lru_list.c +13 -8
@@ -41,7 +41,12 @@ static struct list_head *local_pending_list(struct bpf_lru_locallist *loc_l)/* bpf_lru_node helpers */ static bool bpf_lru_node_is_ref (const struct bpf_lru_node *node) { -return node->ref; +return READ_ONCE (node->ref); +} + +static void bpf_lru_node_clear_ref (struct bpf_lru_node *node) +{ +WRITE_ONCE (node->ref,0 ); } static void bpf_lru_list_count_inc(struct bpf_lru_list *l,
@@ -89,7 +94,7 @@ static void __bpf_lru_node_move_in(struct bpf_lru_list *l,bpf_lru_list_count_inc (l, tgt_type); node->type = tgt_type; - node->ref =0 ; +bpf_lru_node_clear_ref (node);list_move (&node->list, &l->lists[tgt_type]); }
@@ -110,7 +115,7 @@ static void __bpf_lru_node_move(struct bpf_lru_list *l,bpf_lru_list_count_inc (l, tgt_type); node->type = tgt_type; } - node->ref =0 ; +bpf_lru_node_clear_ref (node);/* If the moving node is the next_inactive_rotation candidate, * move the next_inactive_rotation pointer also.
@@ -353,7 +358,7 @@ static void __local_list_add_pending(struct bpf_lru *lru, *(u32 *)((void *)node + lru->hash_offset) = hash; node->cpu = cpu; node->type =BPF_LRU_LOCAL_LIST_T_PENDING ; - node->ref =0 ; +bpf_lru_node_clear_ref (node);list_add (&node->list,local_pending_list (loc_l)); }
@@ -419,7 +424,7 @@ static struct bpf_lru_node *bpf_percpu_lru_pop_free(struct bpf_lru *lru,if (!list_empty (free_list)) { node = list_first_entry(free_list, struct bpf_lru_node, list); *(u32 *)((void *)node + lru->hash_offset) = hash; - node->ref =0 ; +bpf_lru_node_clear_ref (node);__bpf_lru_node_move (l, node,BPF_LRU_LIST_T_INACTIVE ); }
@@ -522,7 +527,7 @@ static void bpf_common_lru_push_free(struct bpf_lru *lru, } node->type =BPF_LRU_LOCAL_LIST_T_FREE ; - node->ref =0 ; +bpf_lru_node_clear_ref (node);list_move (&node->list,local_free_list (loc_l));raw_spin_unlock_irqrestore (&loc_l->lock, flags);
@@ -568,7 +573,7 @@ static void bpf_common_lru_populate(struct bpf_lru *lru, void *buf, node = (struct bpf_lru_node *)(buf + node_offset); node->type =BPF_LRU_LIST_T_FREE ; - node->ref =0 ; +bpf_lru_node_clear_ref (node);list_add (&node->list, &l->lists[BPF_LRU_LIST_T_FREE ]); buf += elem_size; }
@@ -594,7 +599,7 @@ static void bpf_percpu_lru_populate(struct bpf_lru *lru, void *buf, node = (struct bpf_lru_node *)(buf + node_offset); node->cpu = cpu; node->type =BPF_LRU_LIST_T_FREE ; - node->ref =0 ; +bpf_lru_node_clear_ref (node);list_add (&node->list, &l->lists[BPF_LRU_LIST_T_FREE ]); i++; buf += elem_size;
kernel/bpf/bpf_lru_list.h +2 -5
@@ -64,11 +64,8 @@ struct bpf_lru {static inline void bpf_lru_node_set_ref (struct bpf_lru_node *node) { -/* ref is an approximation on access frequency. It does not -* have to be very accurate. Hence, no protection is used. -*/ -if (!node->ref) - node->ref =1 ; +if (!READ_ONCE (node->ref)) +WRITE_ONCE (node->ref,1 ); } int bpf_lru_init(struct bpf_lru *lru, bool percpu, u32 hash_offset,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 69/183 bpf: tcp: Avoid taking fast sock lock in iterator
In reply to Greg Kroah-HartmanFrom: Aditi Ghag <[email protected]>
[ Upstream commit 9378096e8a656fb5c4099b26b1370c56f056eab9 ]
This is a preparatory commit to replace lock_sock_fast with lock_sock,and facilitate BPF programs executed from the TCP sockets iterator to be able to destroy TCP sockets using the bpf_sock_destroy kfunc (implemented in follow-up commits).
Previously, BPF TCP iterator was acquiring the sock lock with BH disabled. This led to scenarios where the sockets hash table bucket lock can be acquired with BH enabled in some path versus disabled in other. In such situation, kernel issued a warning since it thinks that in the BH enabled path the same bucket lock *might* be acquired again in the softirq context (BH disabled), which will lead to a potential dead lock. Since bpf_sock_destroy also happens in a process context, the potential deadlock warning is likely a false alarm.
Here is a snippet of annotated stack trace that motivated this change:
```
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&h->lhash2[i].lock);
local_bh_disable();
lock(&h->lhash2[i].lock);
kernel imagined possible scenario:
local_bh_disable(); /* Possible softirq */
lock(&h->lhash2[i].lock);
*** Potential Deadlock ***
process context:
lock_acquire+0xcd/0x330
_raw_spin_lock+0x33/0x40
------> Acquire (bucket) lhash2.lock with BH enabled
__inet_hash+0x4b/0x210
inet_csk_listen_start+0xe6/0x100
inet_listen+0x95/0x1d0
__sys_listen+0x69/0xb0
__x64_sys_listen+0x14/0x20
do_syscall_64+0x3c/0x90
entry_SYSCALL_64_after_hwframe+0x72/0xdc
bpf_sock_destroy run from iterator:
lock_acquire+0xcd/0x330
_raw_spin_lock+0x33/0x40
------> Acquire (bucket) lhash2.lock with BH disabled
inet_unhash+0x9a/0x110
tcp_set_state+0x6a/0x210
tcp_abort+0x10d/0x200
bpf_prog_6793c5ca50c43c0d_iter_tcp6_server+0xa4/0xa9
bpf_iter_run_prog+0x1ff/0x340
------> lock_sock_fast that acquires sock lock with BH disabled
bpf_iter_tcp_seq_show+0xca/0x190
bpf_seq_read+0x177/0x450
```Also, Yonghong reported a deadlock for non-listening TCP sockets that this change resolves. Previously, lock_sock_fast held the sock spin lock with BH which was again being acquired in tcp_abort:
```
watchdog: BUG: soft lockup - CPU#0 stuck for 86s! [test_progs:2331]
RIP: 0010:queued_spin_lock_slowpath+0xd8/0x500
Call Trace:
<TASK>
_raw_spin_lock+0x84/0x90
tcp_abort+0x13c/0x1f0
bpf_prog_88539c5453a9dd47_iter_tcp6_client+0x82/0x89
bpf_iter_run_prog+0x1aa/0x2c0
? preempt_count_sub+0x1c/0xd0
? from_kuid_munged+0x1c8/0x210
bpf_iter_tcp_seq_show+0x14e/0x1b0
bpf_seq_read+0x36c/0x6a0
bpf_iter_tcp_seq_show
lock_sock_fast
__lock_sock_fast
spin_lock_bh(&sk->sk_lock.slock);
/* * Fast path return with bottom halves disabled and * sock::sk_lock.slock held.* */
...
tcp_abort
local_bh_disable();
spin_lock(&((sk)->sk_lock.slock)); // from bh_lock_sock(sk)
```With the switch to lock_sock, it calls spin_unlock_bh before returning:
```
lock_sock
lock_sock_nested
spin_lock_bh(&sk->sk_lock.slock);
:
spin_unlock_bh(&sk->sk_lock.slock);
```--- net/ipv4/tcp_ipv4.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/ipv4/tcp_ipv4.c +2 -3
@@ -2911,7 +2911,6 @@ static int bpf_iter_tcp_seq_show(struct seq_file *seq, void *v)struct bpf_iter_meta meta;struct bpf_prog *prog;struct sock *sk = v; -bool slow;uid_t uid;int ret;
@@ -2919,7 +2918,7 @@ static int bpf_iter_tcp_seq_show(struct seq_file *seq, void *v)return 0 ;if (sk_fullsock (sk)) - slow =lock_sock_fast (sk); +lock_sock (sk);if (unlikely (sk_unhashed (sk))) { ret =SEQ_SKIP ;
@@ -2943,7 +2942,7 @@ static int bpf_iter_tcp_seq_show(struct seq_file *seq, void *v) unlock:if (sk_fullsock (sk)) -unlock_sock_fast (sk, slow); +release_sock (sk);return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 70/183 wifi: ath11k: add support default regdb while searching board-2.bin for WCN6855
In reply to Greg Kroah-HartmanFrom: Wen Gong <[email protected]>
[ Upstream commit 88ca89202f8e8afb5225eb5244d79cd67c15d744 ]
Sometimes board-2.bin does not have the regdb data which matched the parameters such as vendor, device, subsystem-vendor, subsystem-device and etc. Add default regdb data with 'bus=%s' into board-2.bin for WCN6855, then ath11k use 'bus=pci' to search regdb data in board-2.bin for WCN6855.
kernel: [ 122.515808] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262'
kernel: [ 122.517240] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564
kernel: [ 122.517280] ath11k_pci 0000:03:00.0: failed to fetch regdb data for bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262 from ath11k/WCN6855/hw2.0/board-2.bin
kernel: [ 122.517464] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci'
kernel: [ 122.518901] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564
kernel: [ 122.518915] ath11k_pci 0000:03:00.0: board name
kernel: [ 122.518917] ath11k_pci 0000:03:00.0: 00000000: 62 75 73 3d 70 63 69 bus=pci
kernel: [ 122.518918] ath11k_pci 0000:03:00.0: boot found match regdb data for name 'bus=pci'
kernel: [ 122.518920] ath11k_pci 0000:03:00.0: boot found regdb data for 'bus=pci'
kernel: [ 122.518921] ath11k_pci 0000:03:00.0: fetched regdb
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
--- drivers/net/wireless/ath/ath11k/core.c | 53 +++++++++++++++++++------- 1 file changed, 40 insertions(+), 13 deletions(-)
drivers/net/wireless/ath/ath11k/core.c +40 -13
@@ -870,7 +870,8 @@ int ath11k_core_check_dt(struct ath11k_base *ab) }static int __ath11k_core_create_board_name (struct ath11k_base *ab,char *name, -size_t name_len,bool with_variant) +size_t name_len,bool with_variant, +bool bus_type_mode) {/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ char variant[9 +ATH11K_QMI_BDF_EXT_STR_LENGTH ] = {0 };
@@ -881,15 +882,20 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,switch (ab->id.bdf_search) {case ATH11K_BDF_SEARCH_BUS_AND_BOARD : -scnprintf (name, name_len, -"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s" , -ath11k_bus_str (ab->hif.bus), - ab->id.vendor, ab->id.device, - ab->id.subsystem_vendor, - ab->id.subsystem_device, - ab->qmi.target.chip_id, - ab->qmi.target.board_id, - variant); +if (bus_type_mode) +scnprintf (name, name_len, +"bus=%s" , +ath11k_bus_str (ab->hif.bus)); +else +scnprintf (name, name_len, +"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s" , +ath11k_bus_str (ab->hif.bus), + ab->id.vendor, ab->id.device, + ab->id.subsystem_vendor, + ab->id.subsystem_device, + ab->qmi.target.chip_id, + ab->qmi.target.board_id, + variant);break ;default : scnprintf(name, name_len,
@@ -908,13 +914,19 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,static int ath11k_core_create_board_name (struct ath11k_base *ab,char *name,size_t name_len) { -return __ath11k_core_create_board_name (ab, name, name_len, true); +return __ath11k_core_create_board_name (ab, name, name_len, true, false); }static int ath11k_core_create_fallback_board_name (struct ath11k_base *ab,char *name,size_t name_len) { -return __ath11k_core_create_board_name (ab, name, name_len, false); +return __ath11k_core_create_board_name (ab, name, name_len, false, false); +} + +static int ath11k_core_create_bus_type_board_name (struct ath11k_base *ab,char *name, +size_t name_len) +{ +return __ath11k_core_create_board_name (ab, name, name_len, false, true); } const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
@@ -1218,7 +1230,7 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)int ath11k_core_fetch_regdb (struct ath11k_base *ab,struct ath11k_board_data *bd) { -char boardname[BOARD_NAME_SIZE ]; +char boardname[BOARD_NAME_SIZE ], default_boardname[BOARD_NAME_SIZE ];int ret; ret =ath11k_core_create_board_name (ab, boardname,BOARD_NAME_SIZE );
@@ -1235,6 +1247,21 @@ int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bdif (!ret) goto exit; + ret =ath11k_core_create_bus_type_board_name (ab, default_boardname, +BOARD_NAME_SIZE ); +if (ret) { +ath11k_dbg (ab,ATH11K_DBG_BOOT , +"failed to create default board name for regdb: %d" , ret); + goto exit; + } + + ret =ath11k_core_fetch_board_data_api_n (ab, bd, default_boardname, +ATH11K_BD_IE_REGDB , +ATH11K_BD_IE_REGDB_NAME , +ATH11K_BD_IE_REGDB_DATA ); +if (!ret) + goto exit; + ret =ath11k_core_fetch_board_data_api_1 (ab, bd,ATH11K_REGDB_FILE_NAME );if (ret) ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 71/183 wifi: mac80211_hwsim: Fix possible NULL dereference
In reply to Greg Kroah-HartmanFrom: Ilan Peer <[email protected]>
[ Upstream commit 0cc80943ef518a1c51a1111e9346d1daf11dd545 ]
In a call to mac80211_hwsim_select_tx_link() the sta pointer might be NULL, thus need to check that it is not NULL before accessing it.
--- drivers/net/wireless/mac80211_hwsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mac80211_hwsim.c +2 -2
@@ -4,7 +4,7 @@* Copyright (c) 2008, Jouni Malinen <[email protected]> * Copyright (c) 2011, Javier Lopez <[email protected]> * Copyright (c) 2016 - 2017 Intel Deutschland GmbH -* Copyright (C) 2018 - 2022 Intel Corporation +* Copyright (C) 2018 - 2023 Intel Corporation */ /*
@@ -1753,7 +1753,7 @@ mac80211_hwsim_select_tx_link(struct mac80211_hwsim_data *data,WARN_ON (is_multicast_ether_addr (hdr->addr1)); -if (WARN_ON_ONCE (!sta->valid_links)) +if (WARN_ON_ONCE (!sta || !sta->valid_links))return &vif->bss_conf;for (i =0 ; i <ARRAY_SIZE (vif->link_conf); i++) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 72/183 spi: dw: Add compatible for Intel Mount Evans SoC
In reply to Greg Kroah-HartmanFrom: Abe Kohandel <[email protected]>
[ Upstream commit 0760d5d0e9f0c0e2200a0323a61d1995bb745dee ]
The Intel Mount Evans SoC's Integrated Management Complex uses the SPI controller for access to a NOR SPI FLASH. However, the SoC doesn't provide a mechanism to override the native chip select signal.
This driver doesn't use DMA for memory operations when a chip select override is not provided due to the native chip select timing behavior. As a result no DMA configuration is done for the controller and this configuration is not tested.
The controller also has an errata where a full TX FIFO can result in data corruption. The suggested workaround is to never completely fill the FIFO. The TX FIFO has a size of 32 so the fifo_len is set to 31.
--- drivers/spi/spi-dw-mmio.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/spi/spi-dw-mmio.c +29 -0
@@ -222,6 +222,31 @@ static int dw_spi_intel_init(struct platform_device *pdev,return 0 ; } +/* +* The Intel Mount Evans SoC's Integrated Management Complex uses the +* SPI controller for access to a NOR SPI FLASH. However, the SoC doesn't +* provide a mechanism to override the native chip select signal. +* +* This driver doesn't use DMA for memory operations when a chip select +* override is not provided due to the native chip select timing behavior. +* As a result no DMA configuration is done for the controller and this +* configuration is not tested. +*/ +static int dw_spi_mountevans_imc_init (struct platform_device *pdev, +struct dw_spi_mmio *dwsmmio) +{ +/* +* The Intel Mount Evans SoC's Integrated Management Complex DW +* apb_ssi_v4.02a controller has an errata where a full TX FIFO can +* result in data corruption. The suggested workaround is to never +* completely fill the FIFO. The TX FIFO has a size of 32 so the +* fifo_len is set to 31. +*/ + dwsmmio->dws.fifo_len =31 ; + +return 0 ; +} +static int dw_spi_canaan_k210_init (struct platform_device *pdev,struct dw_spi_mmio *dwsmmio) {
@@ -350,6 +375,10 @@ static const struct of_device_id dw_spi_mmio_of_match[] = { { .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_hssi_init}, { .compatible = "intel,keembay-ssi", .data = dw_spi_intel_init}, { .compatible = "intel,thunderbay-ssi", .data = dw_spi_intel_init}, + { + .compatible = "intel,mountevans-imc-ssi", + .data = dw_spi_mountevans_imc_init, + }, { .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init}, { .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init}, { /* end of table */}
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 73/183 wifi: ath11k: fix memory leak in WMI firmware stats
In reply to Greg Kroah-HartmanFrom: P Praneesh <[email protected]>
[ Upstream commit 6aafa1c2d3e3fea2ebe84c018003f2a91722e607 ]
Memory allocated for firmware pdev, vdev and beacon statistics are not released during rmmod.
Fix it by calling ath11k_fw_stats_free() function before hardware unregister.
While at it, avoid calling ath11k_fw_stats_free() while processing the firmware stats received in the WMI event because the local list is getting spliced and reinitialised and hence there are no elements in the list after splicing.
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/mac.c | 1 + drivers/net/wireless/ath/ath11k/wmi.c | 5 +++++ 2 files changed, 6 insertions(+)
drivers/net/wireless/ath/ath11k/mac.c +1 -0
@@ -9279,6 +9279,7 @@ void ath11k_mac_destroy(struct ath11k_base *ab)if (!ar)continue ; +ath11k_fw_stats_free (&ar->fw_stats);ieee80211_free_hw (ar->hw); pdev->ar =NULL ; }
drivers/net/wireless/ath/ath11k/wmi.c +5 -0
@@ -7590,6 +7590,11 @@ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skrcu_read_unlock ();spin_unlock_bh (&ar->data_lock); +/* Since the stats's pdev, vdev and beacon list are spliced and reinitialised +* at this point, no need to free the individual list. +*/ +return ; + free:ath11k_fw_stats_free (&stats); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 74/183 net: ethernet: litex: add support for 64 bit stats
In reply to Greg Kroah-HartmanFrom: Jisheng Zhang <[email protected]>
[ Upstream commit 18da174d865a87d47d2f33f5b0a322efcf067728 ]
Implement 64 bit per cpu stats to fix the overflow of netdev->stats on 32 bit platforms. To simplify the code, we use net core pcpu_sw_netstats infrastructure. One small drawback is some memory overhead because litex uses just one queue, but we allocate the counters per cpu.
--- drivers/net/ethernet/litex/litex_liteeth.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/net/ethernet/litex/litex_liteeth.c +15 -4
@@ -78,8 +78,7 @@ static int liteeth_rx(struct net_device *netdev)memcpy_fromio (data, priv->rx_base + rx_slot * priv->slot_size, len); skb->protocol =eth_type_trans (skb, netdev); - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += len; +dev_sw_netstats_rx_add (netdev, len);return netif_rx (skb);
@@ -185,8 +184,7 @@ static netdev_tx_t liteeth_start_xmit(struct sk_buff *skb,litex_write16 (priv->base +LITEETH_READER_LENGTH , skb->len);litex_write8 (priv->base +LITEETH_READER_START ,1 ); - netdev->stats.tx_bytes += skb->len; - netdev->stats.tx_packets++; +dev_sw_netstats_tx_add (netdev,1 , skb->len); priv->tx_slot = (priv->tx_slot +1 ) % priv->num_tx_slots;dev_kfree_skb_any (skb);
@@ -194,9 +192,17 @@ static netdev_tx_t liteeth_start_xmit(struct sk_buff *skb,return NETDEV_TX_OK ; } +static void +liteeth_get_stats64 (struct net_device *netdev,struct rtnl_link_stats64 *stats) +{ +netdev_stats_to_stats64 (stats, &netdev->stats); +dev_fetch_sw_netstats (stats, netdev->tstats); +} +static const struct net_device_ops liteeth_netdev_ops = { .ndo_open = liteeth_open, .ndo_stop = liteeth_stop, + .ndo_get_stats64 = liteeth_get_stats64, .ndo_start_xmit = liteeth_start_xmit, };
@@ -242,6 +248,11 @@ static int liteeth_probe(struct platform_device *pdev) priv->netdev = netdev; priv->dev = &pdev->dev; + netdev->tstats =devm_netdev_alloc_pcpu_stats (&pdev->dev, + struct pcpu_sw_netstats); +if (!netdev->tstats) +return -ENOMEM ; + irq =platform_get_irq (pdev,0 );if (irq <0 )return irq;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 75/183 devlink: report devlink_port_type_warn source device
In reply to Greg Kroah-HartmanFrom: Petr Oros <[email protected]>
[ Upstream commit a52305a81d6bb74b90b400dfa56455d37872fe4b ]
devlink_port_type_warn is scheduled for port devlink and warning when the port type is not set. But from this warning it is not easy found out which device (driver) has no devlink port set.
[ 3709.975552] Type was not set for devlink port. [ 3709.975579] WARNING: CPU: 1 PID: 13092 at net/devlink/leftover.c:6775 devlink_port_type_warn+0x11/0x20 [ 3709.993967] Modules linked in: openvswitch nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nfnetlink bluetooth rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs vhost_net vhost vhost_iotlb tap tun bridge stp llc qrtr intel_rapl_msr intel_rapl_common i10nm_edac nfit libnvdimm x86_pkg_temp_thermal mlx5_ib intel_powerclamp coretemp dell_wmi ledtrig_audio sparse_keymap ipmi_ssif kvm_intel ib_uverbs rfkill ib_core video kvm iTCO_wdt acpi_ipmi intel_vsec irqbypass ipmi_si iTCO_vendor_support dcdbas ipmi_devintf mei_me ipmi_msghandler rapl mei intel_cstate isst_if_mmio isst_if_mbox_pci dell_smbios intel_uncore isst_if_common i2c_i801 dell_wmi_descriptor wmi_bmof i2c_smbus intel_pch_thermal pcspkr acpi_power_meter xfs libcrc32c sd_mod sg nvme_tcp mgag200 i2c_algo_bit nvme_fabrics drm_shmem_helper drm_kms_helper nvme syscopyarea ahci sysfillrect sysimgblt nvme_core fb_sys_fops crct10dif_pclmul libahci mlx5_core sfc crc32_pclmul nvme_common drm [ 3709.994030] crc32c_intel mtd t10_pi mlxfw libata tg3 mdio megaraid_sas psample ghash_clmulni_intel pci_hyperv_intf wmi dm_multipath sunrpc dm_mirror dm_region_hash dm_log dm_mod be2iscsi bnx2i cnic uio cxgb4i cxgb4 tls libcxgbi libcxgb qla4xxx iscsi_boot_sysfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi fuse [ 3710.108431] CPU: 1 PID: 13092 Comm: kworker/1:1 Kdump: loaded Not tainted 5.14.0-319.el9.x86_64 #1 [ 3710.108435] Hardware name: Dell Inc. PowerEdge R750/0PJ80M, BIOS 1.8.2 09/14/2022 [ 3710.108437] Workqueue: events devlink_port_type_warn [ 3710.108440] RIP: 0010:devlink_port_type_warn+0x11/0x20 [ 3710.108443] Code: 84 76 fe ff ff 48 c7 03 20 0e 1a ad 31 c0 e9 96 fd ff ff 66 0f 1f 44 00 00 0f 1f 44 00 00 48 c7 c7 18 24 4e ad e8 ef 71 62 ff <0f> 0b c3 cc cc cc cc 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 f6 87 [ 3710.108445] RSP: 0018:ff3b6d2e8b3c7e90 EFLAGS: 00010282 [ 3710.108447] RAX: 0000000000000000 RBX: ff366d6580127080 RCX: 0000000000000027 [ 3710.108448] RDX: 0000000000000027 RSI: 00000000ffff86de RDI: ff366d753f41f8c8 [ 3710.108449] RBP: ff366d658ff5a0c0 R08: ff366d753f41f8c0 R09: ff3b6d2e8b3c7e18 [ 3710.108450] R10: 0000000000000001 R11: 0000000000000023 R12: ff366d753f430600 [ 3710.108451] R13: ff366d753f436900 R14: 0000000000000000 R15: ff366d753f436905 [ 3710.108452] FS: 0000000000000000(0000) GS:ff366d753f400000(0000) knlGS:0000000000000000 [ 3710.108453] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3710.108454] CR2: 00007f1c57bc74e0 CR3: 000000111d26a001 CR4: 0000000000773ee0 [ 3710.108456] PKRU: 55555554 [ 3710.108457] Call Trace: [ 3710.108458] <TASK> [ 3710.108459] process_one_work+0x1e2/0x3b0 [ 3710.108466] ? rescuer_thread+0x390/0x390 [ 3710.108468] worker_thread+0x50/0x3a0 [ 3710.108471] ? rescuer_thread+0x390/0x390 [ 3710.108473] kthread+0xdd/0x100 [ 3710.108477] ? kthread_complete_and_exit+0x20/0x20 [ 3710.108479] ret_from_fork+0x1f/0x30 [ 3710.108485] </TASK> [ 3710.108486] ---[ end trace 1b4b23cd0c65d6a0 ]---
After patch:
[ 402.473064] ice 0000:41:00.0: Type was not set for devlink port. [ 402.473064] ice 0000:41:00.1: Type was not set for devlink port.
--- net/core/devlink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/core/devlink.c +4 -1
@@ -9826,7 +9826,10 @@ EXPORT_SYMBOL_GPL(devlink_free);static void devlink_port_type_warn (struct work_struct *work) { -WARN (true,"Type was not set for devlink port." ); +struct devlink_port *port =container_of (to_delayed_work (work), + struct devlink_port, + type_warn_dw); +dev_warn (port->devlink->dev,"Type was not set for devlink port." ); }static bool devlink_port_type_should_warn (struct devlink_port *devlink_port)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 76/183 wifi: wext-core: Fix -Wstringop-overflow warning in ioctl_standard_iw_point()
In reply to Greg Kroah-HartmanFrom: Gustavo A. R. Silva <[email protected]>
[ Upstream commit 71e7552c90db2a2767f5c17c7ec72296b0d92061 ]
-Wstringop-overflow is legitimately warning us about extra_size pontentially being zero at some point, hence potenially ending up _allocating_ zero bytes of memory for extra pointer and then trying to access such object in a call to copy_from_user().
Fix this by adding a sanity check to ensure we never end up trying to allocate zero bytes of data for extra pointer, before continue executing the rest of the code in the function.
Address the following -Wstringop-overflow warning seen when built
m68k architecture with allyesconfig configuration:
from net/wireless/wext-core.c:11:
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:183:7,
inlined from 'ioctl_standard_iw_point' at net/wireless/wext-core.c:825:7:arch/m68k/include/asm/string.h:48:25: warning: '__builtin_memset' writing 1 or more bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
48 | #define memset(d, c, n) __builtin_memset(d, c, n)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/uaccess.h:153:17: note: in expansion of macro 'memset'
153 | memset(to + (n - res), 0, res);
| ^~~~~~In function 'kmalloc',
inlined from 'kzalloc' at include/linux/slab.h:694:9,
inlined from 'ioctl_standard_iw_point' at net/wireless/wext-core.c:819:10:include/linux/slab.h:577:16: note: at offset 1 into destination object of size 0 allocated by '__kmalloc'
577 | return __kmalloc(size, flags);
| ^~~~~~~~~~~~~~~~~~~~~~This help with the ongoing efforts to globally enable -Wstringop-overflow.
--- net/wireless/wext-core.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/wireless/wext-core.c +6 -0
@@ -799,6 +799,12 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, } } +/* Sanity-check to ensure we never end up _allocating_ zero +* bytes of data for extra. +*/ +if (extra_size <=0 ) +return -EFAULT ; +/* kzalloc() ensures NULL-termination for essid_compat. */ extra =kzalloc (extra_size,GFP_KERNEL );if (!extra)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 77/183 wifi: iwlwifi: Add support for new PCI Id
In reply to Greg Kroah-HartmanFrom: Mukesh Sisodiya <[email protected]>
[ Upstream commit 35bd6f1d043d089fcb60450e1287cc65f0095787 ]
Add support for the PCI Id 51F1 without IMR support.
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +2 -0
@@ -495,6 +495,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_trans_cfg)}, {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, + {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_trans_cfg)},
@@ -543,6 +544,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {IWL_DEV_INFO (0x51F0 ,0x1551 , iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name),IWL_DEV_INFO (0x51F0 ,0x1691 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),IWL_DEV_INFO (0x51F0 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), +IWL_DEV_INFO (0x51F1 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),IWL_DEV_INFO (0x54F0 ,0x1691 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),IWL_DEV_INFO (0x54F0 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), IWL_DEV_INFO(0x7A70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 78/183 wifi: iwlwifi: mvm: avoid baid size integer overflow
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 1a528ab1da324d078ec60283c34c17848580df24 ]
Roee reported various hard-to-debug crashes with pings in EHT aggregation scenarios. Enabling KASAN showed that we access the BAID allocation out of bounds, and looking at the code a bit shows that since the reorder buffer entry (struct iwl_mvm_reorder_buf_entry) is 128 bytes if debug such as lockdep is enabled, then staring from an agg size 512 we overflow the size calculation, and allocate a much smaller structure than we should, causing slab corruption once we initialize this.
Fix this by simply using u32 instead of u16.
--- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/sta.c +1 -1
@@ -2738,7 +2738,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, }if (iwl_mvm_has_new_rx_api (mvm) && start) { -u16 reorder_buf_size = buf_size *sizeof (baid_data->entries[0 ]); +u32 reorder_buf_size = buf_size *sizeof (baid_data->entries[0 ]);/* sparse doesn't like the __align() so don't check */ #ifndef __CHECKER__
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 79/183 wifi: iwlwifi: pcie: add device id 51F1 for killer 1675
In reply to Greg Kroah-HartmanFrom: Yi Kuo <[email protected]>
[ Upstream commit f4daceae4087bbb3e9a56044b44601d520d009d2 ]
Intel Killer AX1675i/s with device id 51f1 would show
"No config found for PCI dev 51f1/1672" in dmesg and refuse to work. Add the new device id 51F1 for 1675i/s to fix the issue.
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +2 -0
@@ -683,6 +683,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {IWL_DEV_INFO (0x2726 ,0x1672 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name),IWL_DEV_INFO (0x51F0 ,0x1671 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name),IWL_DEV_INFO (0x51F0 ,0x1672 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), +IWL_DEV_INFO (0x51F1 ,0x1671 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), +IWL_DEV_INFO (0x51F1 ,0x1672 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name),IWL_DEV_INFO (0x54F0 ,0x1671 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name),IWL_DEV_INFO (0x54F0 ,0x1672 , iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), IWL_DEV_INFO(0x7A70, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name),
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 80/183 igb: Fix igb_down hung on surprise removal
In reply to Greg Kroah-HartmanFrom: Ying Hsu <[email protected]>
[ Upstream commit 004d25060c78fc31f66da0fa439c544dda1ac9d5 ]
In a setup where a Thunderbolt hub connects to Ethernet and a display through USB Type-C, users may experience a hung task timeout when they remove the cable between the PC and the Thunderbolt hub. This is because the igb_down function is called multiple times when the Thunderbolt hub is unplugged. For example, the igb_io_error_detected triggers the first call, and the igb_remove triggers the second call. The second call to igb_down will block at napi_synchronize. Here's the call trace:
__schedule+0x3b0/0xddb
? __mod_timer+0x164/0x5d3
schedule+0x44/0xa8
schedule_timeout+0xb2/0x2a4
? run_local_timers+0x4e/0x4e
msleep+0x31/0x38
igb_down+0x12c/0x22a [igb 6615058754948bfde0bf01429257eb59f13030d4]
__igb_close+0x6f/0x9c [igb 6615058754948bfde0bf01429257eb59f13030d4]
igb_close+0x23/0x2b [igb 6615058754948bfde0bf01429257eb59f13030d4]
__dev_close_many+0x95/0xec
dev_close_many+0x6e/0x103
unregister_netdevice_many+0x105/0x5b1
unregister_netdevice_queue+0xc2/0x10d
unregister_netdev+0x1c/0x23
igb_remove+0xa7/0x11c [igb 6615058754948bfde0bf01429257eb59f13030d4]
pci_device_remove+0x3f/0x9c
device_release_driver_internal+0xfe/0x1b4
pci_stop_bus_device+0x5b/0x7f
pci_stop_bus_device+0x30/0x7f
pci_stop_bus_device+0x30/0x7f
pci_stop_and_remove_bus_device+0x12/0x19
pciehp_unconfigure_device+0x76/0xe9
pciehp_disable_slot+0x6e/0x131
pciehp_handle_presence_or_link_change+0x7a/0x3f7
pciehp_ist+0xbe/0x194
irq_thread_fn+0x22/0x4d
? irq_thread+0x1fd/0x1fd
irq_thread+0x17b/0x1fd
? irq_forced_thread_fn+0x5f/0x5f
kthread+0x142/0x153
? __irq_get_irqchip_state+0x46/0x46
? kthread_associate_blkcg+0x71/0x71
ret_from_fork+0x1f/0x30In this case, igb_io_error_detected detaches the network interface and requests a PCIE slot reset, however, the PCIE reset callback is not being invoked and thus the Ethernet connection breaks down. As the PCIE error in this case is a non-fatal one, requesting a slot reset can be avoided.
This patch fixes the task hung issue and preserves Ethernet connection by ignoring non-fatal PCIE errors.
--- drivers/net/ethernet/intel/igb/igb_main.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/intel/igb/igb_main.c +5 -0
@@ -9585,6 +9585,11 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev,struct net_device *netdev =pci_get_drvdata (pdev);struct igb_adapter *adapter =netdev_priv (netdev); +if (state == pci_channel_io_normal) { +dev_warn (&pdev->dev,"Non-correctable non-fatal error reported.\n" ); +return PCI_ERS_RESULT_CAN_RECOVER ; + } +netif_device_detach (netdev);if (state == pci_channel_io_perm_failure)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 81/183 net: hns3: fix strncpy() not using dest-buf length as length issue
In reply to Greg Kroah-HartmanFrom: Hao Chen <[email protected]>
[ Upstream commit 1cf3d5567f273a8746d1bade00633a93204f80f0 ]
Now, strncpy() in hns3_dbg_fill_content() use src-length as copy-length, it may result in dest-buf overflow.
This patch is to fix intel compile warning for csky-linux-gcc (GCC) 12.1.0 compiler.
The warning reports as below:
hclge_debugfs.c:92:25: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-truncation]
strncpy(pos, items[i].name, strlen(items[i].name));
hclge_debugfs.c:90:25: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(pos, result[i], strlen(result[i]));
strncpy() use src-length as copy-length, it may result in dest-buf overflow.
So,this patch add some values check to avoid this issue.
--- .../ethernet/hisilicon/hns3/hns3_debugfs.c | 31 ++++++++++++++----- .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 29 ++++++++++++++--- 2 files changed, 48 insertions(+), 12 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +24 -7
@@ -435,19 +435,36 @@ static void hns3_dbg_fill_content(char *content, u16 len,const struct hns3_dbg_item *items, const char **result, u16 size) { +#define HNS3_DBG_LINE_END_LEN 2 char *pos = content; +u16 item_len;u16 i; +if (!len) { +return ; + }else if (len <=HNS3_DBG_LINE_END_LEN ) { + *pos++ ='\0' ; +return ; + } +memset (content,' ' , len); -for (i =0 ; i < size; i++) { -if (result) -strncpy (pos, result[i],strlen (result[i])); -else -strncpy (pos, items[i].name,strlen (items[i].name)); + len -=HNS3_DBG_LINE_END_LEN ; - pos +=strlen (items[i].name) + items[i].interval; +for (i =0 ; i < size; i++) { + item_len =strlen (items[i].name) + items[i].interval; +if (len < item_len) +break ; + +if (result) { +if (item_len <strlen (result[i])) +break ; +strscpy (pos, result[i],strlen (result[i])); + }else { +strscpy (pos, items[i].name,strlen (items[i].name)); + } + pos += item_len; + len -= item_len; } - *pos++ ='\n' ; *pos++ ='\0' ; }
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +24 -5
@@ -87,16 +87,35 @@ static void hclge_dbg_fill_content(char *content, u16 len,const struct hclge_dbg_item *items, const char **result, u16 size) { +#define HCLGE_DBG_LINE_END_LEN 2 char *pos = content; +u16 item_len;u16 i; +if (!len) { +return ; + }else if (len <=HCLGE_DBG_LINE_END_LEN ) { + *pos++ ='\0' ; +return ; + } +memset (content,' ' , len); + len -=HCLGE_DBG_LINE_END_LEN ; +for (i =0 ; i < size; i++) { -if (result) -strncpy (pos, result[i],strlen (result[i])); -else -strncpy (pos, items[i].name,strlen (items[i].name)); - pos +=strlen (items[i].name) + items[i].interval; + item_len =strlen (items[i].name) + items[i].interval; +if (len < item_len) +break ; + +if (result) { +if (item_len <strlen (result[i])) +break ; +strscpy (pos, result[i],strlen (result[i])); + }else { +strscpy (pos, items[i].name,strlen (items[i].name)); + } + pos += item_len; + len -= item_len; } *pos++ ='\n' ; *pos++ ='\0' ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 82/183 ASoC: amd: acp: fix for invalid dai id handling in acp_get_byte_count()
In reply to Greg Kroah-HartmanFrom: Vijendar Mukunda <[email protected]>
[ Upstream commit 85aeab362201cf52c34cd429e4f6c75a0b42f9a3 ]
For invalid dai id, instead of returning -EINVAL return bytes count as zero in acp_get_byte_count() function.
--- sound/soc/amd/acp/amd.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
sound/soc/amd/acp/amd.h +4 -3
@@ -173,7 +173,7 @@ int snd_amd_acp_find_config(struct pci_dev *pci);static inline u64 acp_get_byte_count (struct acp_dev_data *adata,int dai_id,int direction) { -u64 byte_count, low =0 , high =0 ; +u64 byte_count =0 , low =0 , high =0 ;if (direction ==SNDRV_PCM_STREAM_PLAYBACK ) {switch (dai_id) {
@@ -191,7 +191,7 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, intbreak ;default :dev_err (adata->dev,"Invalid dai id %x\n" , dai_id); -return -EINVAL ; + goto POINTER_RETURN_BYTES; } }else {switch (dai_id) {
@@ -213,12 +213,13 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, intbreak ;default :dev_err (adata->dev,"Invalid dai id %x\n" , dai_id); -return -EINVAL ; + goto POINTER_RETURN_BYTES; } }/* Get 64 bit value from two 32 bit registers */ byte_count = (high <<32 ) | low; +POINTER_RETURN_BYTES:return byte_count; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 83/183 ASoC: codecs: wcd938x: fix mbhc impedance loglevel
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit e5ce198bd5c6923b6a51e1493b1401f84c24b26d ]
Demote the MBHC impedance measurement printk, which is not an error message, from error to debug level.
While at it, fix the capitalisation of "ohm" and add the missing space before the opening parenthesis.
--- sound/soc/codecs/wcd938x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wcd938x.c +2 -2
@@ -2165,8 +2165,8 @@ static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x,else if (x1 < minCode_param[noff]) *zdet =WCD938X_ZDET_FLOATING_IMPEDANCE ; -pr_err ("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n" , - __func__, d1, c1, x1, *zdet); +pr_debug ("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n" , + __func__, d1, c1, x1, *zdet); ramp_down: i =0 ;while (x1) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 84/183 ASoC: codecs: wcd938x: fix dB range for HPHL and HPHR
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c03226ba15fe3c42d13907ec7d8536396602557b ]
dB range for HPHL and HPHR gains are from +6dB to -30dB in steps of 1.5dB with register values range from 0 to 24.
Current code maps these dB ranges incorrectly, fix them to allow proper volume setting.
--- sound/soc/codecs/wcd938x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wcd938x.c +3 -3
@@ -210,7 +210,7 @@ struct wcd938x_priv { }; static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); -static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(line_gain, 600, -3000); +static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, -3000); static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);struct wcd938x_mbhc_zdet_param {
@@ -2662,8 +2662,8 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { wcd938x_get_swr_port, wcd938x_set_swr_port),SOC_SINGLE_EXT ("DSD_R Switch" ,WCD938X_DSD_R ,0 ,1 ,0 , wcd938x_get_swr_port, wcd938x_set_swr_port), -SOC_SINGLE_TLV ("HPHL Volume" ,WCD938X_HPH_L_EN ,0 ,0x18 ,0 , line_gain), -SOC_SINGLE_TLV ("HPHR Volume" ,WCD938X_HPH_R_EN ,0 ,0x18 ,0 , line_gain), +SOC_SINGLE_TLV ("HPHL Volume" ,WCD938X_HPH_L_EN ,0 ,0x18 ,1 , line_gain), +SOC_SINGLE_TLV ("HPHR Volume" ,WCD938X_HPH_R_EN ,0 ,0x18 ,1 , line_gain),WCD938X_EAR_PA_GAIN_TLV ("EAR_PA Volume" ,WCD938X_ANA_EAR_COMPANDER_CTL ,2 ,0x10 ,0 , ear_pa_gain), SOC_SINGLE_EXT("ADC1 Switch", WCD938X_ADC1, 1, 1, 0,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 85/183 ASoC: qcom: q6apm: do not close GPR port before closing graph
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c1be62923d4d86e7c06b1224626e27eb8d9ab32e ]
Closing GPR port before graph close can result in un handled notifications from DSP, this results in spam of errors from GPR driver as there is no one to handle these notification at that point in time.
Fix this by closing GPR port after graph close is finished.
--- sound/soc/qcom/qdsp6/q6apm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
sound/soc/qcom/qdsp6/q6apm.c +6 -1
@@ -515,6 +515,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)switch (hdr->opcode) {case DATA_CMD_RSP_WR_SH_MEM_EP_DATA_BUFFER_DONE_V2 : +if (!graph->ar_graph) +break ; client_event =APM_CLIENT_EVENT_DATA_WRITE_DONE ;mutex_lock (&graph->lock); token = hdr->token &APM_WRITE_TOKEN_MASK ;
@@ -548,6 +550,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)wake_up (&graph->cmd_wait);break ;case DATA_CMD_RSP_RD_SH_MEM_EP_DATA_BUFFER_V2 : +if (!graph->ar_graph) +break ; client_event =APM_CLIENT_EVENT_DATA_READ_DONE ;mutex_lock (&graph->lock); rd_done = data->payload;
@@ -650,8 +654,9 @@ int q6apm_graph_close(struct q6apm_graph *graph) {struct audioreach_graph *ar_graph = graph->ar_graph; -gpr_free_port (graph->port); + graph->ar_graph =NULL ;kref_put (&ar_graph->refcount, q6apm_put_audioreach_graph); +gpr_free_port (graph->port);kfree (graph);return 0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 86/183 sched/fair: Use recent_used_cpu to test p->cpus_ptr
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit ae2ad293d6be143ad223f5f947cca07bcbe42595 ]
When checking whether a recently used CPU can be a potential idle candidate, recent_used_cpu should be used to test p->cpus_ptr as p->recent_used_cpu is not equal to recent_used_cpu and candidate decision is made based on recent_used_cpu here.
--- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/fair.c +1 -1
@@ -6935,7 +6935,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) recent_used_cpu != target && cpus_share_cache(recent_used_cpu, target) && (available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) && - cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) && + cpumask_test_cpu(recent_used_cpu, p->cpus_ptr) && asym_fits_cpu(task_util, util_min, util_max, recent_used_cpu)) {return recent_used_cpu; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 87/183 sched/psi: Fix avgs_work re-arm in psi_avgs_work()
In reply to Greg Kroah-HartmanFrom: Chengming Zhou <[email protected]>
[ Upstream commit 2fcd7bbae90a6d844da8660a9d27079281dfbba2 ]
Pavan reported a problem that PSI avgs_work idle shutoff is not working at all. Because PSI_NONIDLE condition would be observed in psi_avgs_work()->collect_percpu_times()->get_recent_times() even if only the kworker running avgs_work on the CPU.
Although commit 1b69ac6b40eb ("psi: fix aggregation idle shut-off") avoided the ping-pong wake problem when the worker sleep, psi_avgs_work() still will always re-arm the avgs_work, so shutoff is not working.
This patch changes to use PSI_STATE_RESCHEDULE to flag whether to re-arm avgs_work in get_recent_times(). For the current CPU, we re-arm avgs_work only when (NR_RUNNING > 1 || NR_IOWAIT > 0 || NR_MEMSTALL > 0), for other CPUs we can just check PSI_NONIDLE delta. The new flag is only used in psi_avgs_work(), so we check in get_recent_times() that current_work() is avgs_work.
One potential problem is that the brief period of non-idle time incurred between the aggregation run and the kworker's dequeue will be stranded in the per-cpu buckets until avgs_work run next time. The buckets can hold 4s worth of time, and future activity will wake the avgs_work with a 2s delay, giving us 2s worth of data we can leave behind when shut off the avgs_work. If the kworker run other works after avgs_work shut off and doesn't have any scheduler activities for 2s, this maybe a problem.
Stable-dep-of: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
--- include/linux/psi_types.h | 3 +++ kernel/sched/psi.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-)
include/linux/psi_types.h +3 -0
@@ -72,6 +72,9 @@ enum psi_states {/* Use one bit in the state mask to track TSK_ONCPU */ #define PSI_ONCPU (1 << NR_PSI_STATES) +/* Flag whether to re-arm avgs_work, see details in get_recent_times() */ +#define PSI_STATE_RESCHEDULE (1 << (NR_PSI_STATES + 1)) +enum psi_aggregators {PSI_AVGS =0 ,PSI_POLL ,
kernel/sched/psi.c +27 -3
@@ -243,6 +243,8 @@ static void get_recent_times(struct psi_group *group, int cpu, u32 *pchanged_states) {struct psi_group_cpu *groupc =per_cpu_ptr (group->pcpu, cpu); +int current_cpu =raw_smp_processor_id (); +unsigned int tasks[NR_PSI_TASK_COUNTS ];u64 now, state_start;enum psi_states s;unsigned int seq;
@@ -257,6 +259,8 @@ static void get_recent_times(struct psi_group *group, int cpu,memcpy (times, groupc->times,sizeof (groupc->times)); state_mask = groupc->state_mask; state_start = groupc->state_start; +if (cpu == current_cpu) +memcpy (tasks, groupc->tasks,sizeof (groupc->tasks)); }while (read_seqcount_retry (&groupc->seq, seq));/* Calculate state time deltas against the previous snapshot */
@@ -281,6 +285,28 @@ static void get_recent_times(struct psi_group *group, int cpu,if (delta) *pchanged_states |= (1 << s); } + +/* +* When collect_percpu_times() from the avgs_work, we don't want to +* re-arm avgs_work when all CPUs are IDLE. But the current CPU running +* this avgs_work is never IDLE, cause avgs_work can't be shut off. +* So for the current CPU, we need to re-arm avgs_work only when +* (NR_RUNNING > 1 || NR_IOWAIT > 0 || NR_MEMSTALL > 0), for other CPUs +* we can just check PSI_NONIDLE delta. +*/ +if (current_work () == &group->avgs_work.work) { +bool reschedule; + +if (cpu == current_cpu) + reschedule = tasks[NR_RUNNING ] + + tasks[NR_IOWAIT ] + + tasks[NR_MEMSTALL ] >1 ; +else + reschedule = *pchanged_states & (1 <<PSI_NONIDLE ); + +if (reschedule) + *pchanged_states |=PSI_STATE_RESCHEDULE ; + } } static void calc_avgs(unsigned long avg[3], int missed_periods,
@@ -416,7 +442,6 @@ static void psi_avgs_work(struct work_struct *work)struct delayed_work *dwork;struct psi_group *group;u32 changed_states; -bool nonidle;u64 now; dwork =to_delayed_work (work);
@@ -427,7 +452,6 @@ static void psi_avgs_work(struct work_struct *work) now =sched_clock ();collect_percpu_times (group,PSI_AVGS , &changed_states); - nonidle = changed_states & (1 <<PSI_NONIDLE );/* * If there is task activity, periodically fold the per-cpu * times and feed samples into the running averages. If things
@@ -438,7 +462,7 @@ static void psi_avgs_work(struct work_struct *work)if (now >= group->avg_next_update) group->avg_next_update =update_averages (group, now); -if (nonidle) { +if (changed_states &PSI_STATE_RESCHEDULE ) {schedule_delayed_work (dwork,nsecs_to_jiffies ( group->avg_next_update - now) +1 ); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 88/183 sched/psi: Rearrange polling code in preparation
In reply to Greg Kroah-HartmanFrom: Domenico Cerasuolo <[email protected]>
[ Upstream commit 7fab21fa0d000a0ea32d73ce8eec68557c6c268b ]
Move a few functions up in the file to avoid forward declaration needed in the patch implementing unprivileged PSI triggers.
Stable-dep-of: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
--- kernel/sched/psi.c | 196 ++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 98 deletions(-)
kernel/sched/psi.c +98 -98
@@ -384,92 +384,6 @@ static void collect_percpu_times(struct psi_group *group, *pchanged_states = changed_states; } -static u64 update_averages (struct psi_group *group,u64 now) -{ -unsigned long missed_periods =0 ; -u64 expires, period; -u64 avg_next_update; -int s; - -/* avgX= */ - expires = group->avg_next_update; -if (now - expires >= psi_period) - missed_periods =div_u64 (now - expires, psi_period); - -/* -* The periodic clock tick can get delayed for various -* reasons, especially on loaded systems. To avoid clock -* drift, we schedule the clock in fixed psi_period intervals. -* But the deltas we sample out of the per-cpu buckets above -* are based on the actual time elapsing between clock ticks. -*/ - avg_next_update = expires + ((1 + missed_periods) * psi_period); - period = now - (group->avg_last_update + (missed_periods * psi_period)); - group->avg_last_update = now; - -for (s =0 ; s <NR_PSI_STATES -1 ; s++) { -u32 sample; - - sample = group->total[PSI_AVGS ][s] - group->avg_total[s]; -/* -* Due to the lockless sampling of the time buckets, -* recorded time deltas can slip into the next period, -* which under full pressure can result in samples in -* excess of the period length. -* -* We don't want to report non-sensical pressures in -* excess of 100%, nor do we want to drop such events -* on the floor. Instead we punt any overage into the -* future until pressure subsides. By doing this we -* don't underreport the occurring pressure curve, we -* just report it delayed by one period length. -* -* The error isn't cumulative. As soon as another -* delta slips from a period P to P+1, by definition -* it frees up its time T in P. -*/ -if (sample > period) - sample = period; - group->avg_total[s] += sample; -calc_avgs (group->avg[s], missed_periods, sample, period); - } - -return avg_next_update; -} - -static void psi_avgs_work (struct work_struct *work) -{ -struct delayed_work *dwork; -struct psi_group *group; -u32 changed_states; -u64 now; - - dwork =to_delayed_work (work); - group = container_of(dwork, struct psi_group, avgs_work); - -mutex_lock (&group->avgs_lock); - - now =sched_clock (); - -collect_percpu_times (group,PSI_AVGS , &changed_states); -/* -* If there is task activity, periodically fold the per-cpu -* times and feed samples into the running averages. If things -* are idle and there is no data to process, stop the clock. -* Once restarted, we'll catch up the running averages in one -* go - see calc_avgs() and missed_periods. -*/ -if (now >= group->avg_next_update) - group->avg_next_update =update_averages (group, now); - -if (changed_states &PSI_STATE_RESCHEDULE ) { -schedule_delayed_work (dwork,nsecs_to_jiffies ( - group->avg_next_update - now) +1 ); - } - -mutex_unlock (&group->avgs_lock); -} -/* Trigger tracking window manipulations */ static void window_reset (struct psi_window *win,u64 now,u64 value,u64 prev_growth)
@@ -516,18 +430,6 @@ static u64 window_update(struct psi_window *win, u64 now, u64 value)return growth; } -static void init_triggers (struct psi_group *group,u64 now) -{ -struct psi_trigger *t; - -list_for_each_entry (t, &group->triggers, node) -window_reset (&t->win, now, - group->total[PSI_POLL ][t->state],0 ); -memcpy (group->polling_total, group->total[PSI_POLL ], -sizeof (group->polling_total)); - group->polling_next_update = now + group->poll_min_period; -} -static u64 update_triggers (struct psi_group *group,u64 now) {struct psi_trigger *t;
@@ -590,6 +492,104 @@ static u64 update_triggers(struct psi_group *group, u64 now)return now + group->poll_min_period; } +static u64 update_averages (struct psi_group *group,u64 now) +{ +unsigned long missed_periods =0 ; +u64 expires, period; +u64 avg_next_update; +int s; + +/* avgX= */ + expires = group->avg_next_update; +if (now - expires >= psi_period) + missed_periods =div_u64 (now - expires, psi_period); + +/* +* The periodic clock tick can get delayed for various +* reasons, especially on loaded systems. To avoid clock +* drift, we schedule the clock in fixed psi_period intervals. +* But the deltas we sample out of the per-cpu buckets above +* are based on the actual time elapsing between clock ticks. +*/ + avg_next_update = expires + ((1 + missed_periods) * psi_period); + period = now - (group->avg_last_update + (missed_periods * psi_period)); + group->avg_last_update = now; + +for (s =0 ; s <NR_PSI_STATES -1 ; s++) { +u32 sample; + + sample = group->total[PSI_AVGS ][s] - group->avg_total[s]; +/* +* Due to the lockless sampling of the time buckets, +* recorded time deltas can slip into the next period, +* which under full pressure can result in samples in +* excess of the period length. +* +* We don't want to report non-sensical pressures in +* excess of 100%, nor do we want to drop such events +* on the floor. Instead we punt any overage into the +* future until pressure subsides. By doing this we +* don't underreport the occurring pressure curve, we +* just report it delayed by one period length. +* +* The error isn't cumulative. As soon as another +* delta slips from a period P to P+1, by definition +* it frees up its time T in P. +*/ +if (sample > period) + sample = period; + group->avg_total[s] += sample; +calc_avgs (group->avg[s], missed_periods, sample, period); + } + +return avg_next_update; +} + +static void psi_avgs_work (struct work_struct *work) +{ +struct delayed_work *dwork; +struct psi_group *group; +u32 changed_states; +u64 now; + + dwork =to_delayed_work (work); + group = container_of(dwork, struct psi_group, avgs_work); + +mutex_lock (&group->avgs_lock); + + now =sched_clock (); + +collect_percpu_times (group,PSI_AVGS , &changed_states); +/* +* If there is task activity, periodically fold the per-cpu +* times and feed samples into the running averages. If things +* are idle and there is no data to process, stop the clock. +* Once restarted, we'll catch up the running averages in one +* go - see calc_avgs() and missed_periods. +*/ +if (now >= group->avg_next_update) + group->avg_next_update =update_averages (group, now); + +if (changed_states &PSI_STATE_RESCHEDULE ) { +schedule_delayed_work (dwork,nsecs_to_jiffies ( + group->avg_next_update - now) +1 ); + } + +mutex_unlock (&group->avgs_lock); +} + +static void init_triggers (struct psi_group *group,u64 now) +{ +struct psi_trigger *t; + +list_for_each_entry (t, &group->triggers, node) +window_reset (&t->win, now, + group->total[PSI_POLL ][t->state],0 ); +memcpy (group->polling_total, group->total[PSI_POLL ], +sizeof (group->polling_total)); + group->polling_next_update = now + group->poll_min_period; +} +/* Schedule polling if it's not already scheduled or forced. */ static void psi_schedule_poll_work (struct psi_group *group,unsigned long delay,bool force)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 89/183 sched/psi: Rename existing poll members in preparation
In reply to Greg Kroah-HartmanFrom: Domenico Cerasuolo <[email protected]>
[ Upstream commit 65457b74aa9437418e552e8d52d7112d4f9901a6 ]
Renaming in PSI implementation to make a clear distinction between privileged and unprivileged triggers code to be implemented in the next patch.
Stable-dep-of: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
--- include/linux/psi_types.h | 36 ++++----- kernel/sched/psi.c | 163 +++++++++++++++++++------------------- 2 files changed, 100 insertions(+), 99 deletions(-)
include/linux/psi_types.h +18 -18
@@ -175,26 +175,26 @@ struct psi_group {u64 total[NR_PSI_AGGREGATORS ][NR_PSI_STATES -1 ];unsigned long avg[NR_PSI_STATES -1 ][3 ]; -/* Monitor work control */ -struct task_struct __rcu *poll_task; -struct timer_list poll_timer; -wait_queue_head_t poll_wait; -atomic_t poll_wakeup; -atomic_t poll_scheduled; +/* Monitor RT polling work control */ +struct task_struct __rcu *rtpoll_task; +struct timer_list rtpoll_timer; +wait_queue_head_t rtpoll_wait; +atomic_t rtpoll_wakeup; +atomic_t rtpoll_scheduled;/* Protects data used by the monitor */ -struct mutex trigger_lock; - -/* Configured polling triggers */ -struct list_head triggers; -u32 nr_triggers[NR_PSI_STATES -1 ]; -u32 poll_states; -u64 poll_min_period; - -/* Total stall times at the start of monitor activation */ -u64 polling_total[NR_PSI_STATES -1 ]; -u64 polling_next_update; - u64 polling_until; +struct mutex rtpoll_trigger_lock; + +/* Configured RT polling triggers */ +struct list_head rtpoll_triggers; +u32 rtpoll_nr_triggers[NR_PSI_STATES -1 ]; +u32 rtpoll_states; +u64 rtpoll_min_period; + +/* Total stall times at the start of RT polling monitor activation */ +u64 rtpoll_total[NR_PSI_STATES -1 ]; +u64 rtpoll_next_update; + u64 rtpoll_until; };#else /* CONFIG_PSI */
kernel/sched/psi.c +82 -81
339 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 90/183 sched/psi: Extract update_triggers side effect
In reply to Greg Kroah-HartmanFrom: Domenico Cerasuolo <[email protected]>
[ Upstream commit 4468fcae49f08e88fbbffe05b29496192df89991 ]
This change moves update_total flag out of update_triggers function, currently called only in psi_poll_work.
In the next patch, update_triggers will be called also in psi_avgs_work, but the total update information is specific to psi_poll_work. Returning update_total value to the caller let us avoid differentiating the implementation of update_triggers for different aggregators.
Stable-dep-of: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
--- kernel/sched/psi.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
kernel/sched/psi.c +10 -9
@@ -430,11 +430,11 @@ static u64 window_update(struct psi_window *win, u64 now, u64 value)return growth; } -static u64 update_triggers (struct psi_group *group,u64 now) +static u64 update_triggers (struct psi_group *group,u64 now,bool *update_total) {struct psi_trigger *t; -bool update_total = false;u64 *total = group->total[PSI_POLL ]; + *update_total = false;/* * On subsequent updates, calculate growth deltas and let
@@ -462,7 +462,7 @@ static u64 update_triggers(struct psi_group *group, u64 now)* been through all of them. Also remember to extend the * polling time if we see new stall activity. */ - update_total = true; + *update_total = true;/* Calculate growth since last update */ growth =window_update (&t->win, now, total[t->state]);
@@ -485,10 +485,6 @@ static u64 update_triggers(struct psi_group *group, u64 now) t->pending_event = false; } -if (update_total) -memcpy (group->rtpoll_total, total, -sizeof (group->rtpoll_total)); -return now + group->rtpoll_min_period; }
@@ -622,6 +618,7 @@ static void psi_rtpoll_work(struct psi_group *group) {bool force_reschedule = false;u32 changed_states; +bool update_total;u64 now;mutex_lock (&group->rtpoll_trigger_lock);
@@ -686,8 +683,12 @@ static void psi_rtpoll_work(struct psi_group *group) goto out; } -if (now >= group->rtpoll_next_update) - group->rtpoll_next_update =update_triggers (group, now); +if (now >= group->rtpoll_next_update) { + group->rtpoll_next_update =update_triggers (group, now, &update_total); +if (update_total) +memcpy (group->rtpoll_total, group->total[PSI_POLL ], +sizeof (group->rtpoll_total)); + } psi_schedule_rtpoll_work(group, nsecs_to_jiffies(group->rtpoll_next_update - now) + 1,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 91/183 sched/psi: Allow unprivileged polling of N*2s period
In reply to Greg Kroah-HartmanFrom: Domenico Cerasuolo <[email protected]>
[ Upstream commit d82caa273565b45fcf103148950549af76c314b0 ]
PSI offers 2 mechanisms to get information about a specific resource pressure. One is reading from /proc/pressure/<resource>, which gives average pressures aggregated every 2s. The other is creating a pollable fd for a specific resource and cgroup.
The trigger creation requires CAP_SYS_RESOURCE, and gives the possibility to pick specific time window and threshold, spawing an RT thread to aggregate the data.
Systemd would like to provide containers the option to monitor pressure on their own cgroup and sub-cgroups. For example, if systemd launches a container that itself then launches services, the container should have the ability to poll() for pressure in individual services. But neither the container nor the services are privileged.
This patch implements a mechanism to allow unprivileged users to create pressure triggers. The difference with privileged triggers creation is that unprivileged ones must have a time window that's a multiple of 2s. This is so that we can avoid unrestricted spawning of rt threads, and use instead the same aggregation mechanism done for the averages, which runs independently of any triggers.
Stable-dep-of: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
--- Documentation/accounting/psi.rst | 4 + include/linux/psi.h | 2 +- include/linux/psi_types.h | 7 ++ kernel/cgroup/cgroup.c | 2 +- kernel/sched/psi.c | 175 +++++++++++++++++++------------ 5 files changed, 121 insertions(+), 69 deletions(-)
Documentation/accounting/psi.rst +4 -0
@@ -105,6 +105,10 @@ prevent overly frequent polling. Max limit is chosen as a high enough number after which monitors are most likely not needed and psi averages can be used instead. +Unprivileged users can also create monitors, with the only limitation that the +window size must be a multiple of 2s, in order to prevent excessive resource +usage. + When activated, psi monitor stays active for at least the duration of one tracking window to avoid repeated activations/deactivations when system is bouncing in and out of the stall state.
include/linux/psi.h +1 -1
@@ -24,7 +24,7 @@ void psi_memstall_leave(unsigned long *flags);int psi_show (struct seq_file *s,struct psi_group *group,enum psi_res res);struct psi_trigger *psi_trigger_create (struct psi_group *group, -char *buf,enum psi_res res); +char *buf,enum psi_res res,struct file *file);void psi_trigger_destroy (struct psi_trigger *t); __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file,
include/linux/psi_types.h +7 -0
@@ -151,6 +151,9 @@ struct psi_trigger {/* Deferred event(s) from previous ratelimit window */ bool pending_event; + +/* Trigger type - PSI_AVGS for unprivileged, PSI_POLL for RT */ +enum psi_aggregators aggregator; };struct psi_group {
@@ -171,6 +174,10 @@ struct psi_group {/* Aggregator work control */ struct delayed_work avgs_work; +/* Unprivileged triggers against N*PSI_FREQ windows */ +struct list_head avg_triggers; +u32 avg_nr_triggers[NR_PSI_STATES -1 ]; +/* Total stall times and sampled pressure averages */ u64 total[NR_PSI_AGGREGATORS ][NR_PSI_STATES -1 ];unsigned long avg[NR_PSI_STATES -1 ][3 ];
kernel/cgroup/cgroup.c +1 -1
@@ -3771,7 +3771,7 @@ static ssize_t pressure_write(struct kernfs_open_file *of, char *buf, } psi =cgroup_psi (cgrp); - new =psi_trigger_create (psi, buf, res); + new =psi_trigger_create (psi, buf, res, of->file);if (IS_ERR (new)) {cgroup_put (cgrp);return PTR_ERR (new);
kernel/sched/psi.c +108 -67
301 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 11/11 FS: JFS: Check for read-only mounted filesystem in txBegin
In reply to Greg Kroah-Hartman[ Upstream commit 95e2b352c03b0a86c5717ba1d24ea20969abcacc ]
This patch adds a check for read-only mounted filesystem in txBegin before starting a transaction potentially saving from NULL pointer deref.
--- fs/jfs/jfs_txnmgr.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/jfs/jfs_txnmgr.c +5 -0
@@ -354,6 +354,11 @@ tid_t txBegin(struct super_block *sb, injfs_info ("txBegin: flag = 0x%x" , flag); log =JFS_SBI (sb)->log; +if (!log) { +jfs_error (sb,"read-only filesystem\n" ); +return 0 ; + } +TXN_LOCK ();INCREMENT (TxStat.txBegin);
Greg Kroah-Hartman
maintainerPATCH 92/183 sched/psi: use kernfs polling functions for PSI trigger polling
In reply to Greg Kroah-HartmanFrom: Suren Baghdasaryan <[email protected]>
[ Upstream commit aff037078ecaecf34a7c2afab1341815f90fba5e ]
Destroying psi trigger in cgroup_file_release causes UAF issues when a cgroup is removed from under a polling process. This is happening because cgroup removal causes a call to cgroup_file_release while the actual file is still alive. Destroying the trigger at this point would also destroy its waitqueue head and if there is still a polling process on that file accessing the waitqueue, it will step on the freed pointer:
do_select
vfs_poll
do_rmdir
cgroup_rmdir
kernfs_drain_open_files
cgroup_file_release
cgroup_pressure_release
psi_trigger_destroy
wake_up_pollfree(&t->event_wait)// vfs_poll is unblocked
synchronize_rcu kfree(t)
poll_freewait -> UAF access to the trigger's waitqueue head
Patch [1] fixed this issue for epoll() case using wake_up_pollfree(), however the same issue exists for synchronous poll() case.
The root cause of this issue is that the lifecycles of the psi trigger's waitqueue and of the file associated with the trigger are different. Fix this by using kernfs_generic_poll function when polling on cgroup-specific psi triggers. It internally uses kernfs_open_node->poll waitqueue head with its lifecycle tied to the file's lifecycle. This also renders the fix in [1] obsolete, so revert it.
[1] commit c2dbe32d5db5 ("sched/psi: Fix use-after-free in ep_remove_wait_queue()")
--- include/linux/psi.h | 5 +++-- include/linux/psi_types.h | 3 +++ kernel/cgroup/cgroup.c | 2 +- kernel/sched/psi.c | 29 +++++++++++++++++++++-------- 4 files changed, 28 insertions(+), 11 deletions(-)
include/linux/psi.h +3 -2
@@ -23,8 +23,9 @@ void psi_memstall_enter(unsigned long *flags);void psi_memstall_leave (unsigned long *flags);int psi_show (struct seq_file *s,struct psi_group *group,enum psi_res res); -struct psi_trigger *psi_trigger_create (struct psi_group *group, -char *buf,enum psi_res res,struct file *file); +struct psi_trigger *psi_trigger_create (struct psi_group *group,char *buf, +enum psi_res res,struct file *file, +struct kernfs_open_file *of);void psi_trigger_destroy (struct psi_trigger *t); __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file,
include/linux/psi_types.h +3 -0
@@ -137,6 +137,9 @@ struct psi_trigger {/* Wait queue for polling */ wait_queue_head_t event_wait; +/* Kernfs file for cgroup triggers */ +struct kernfs_open_file *of; +/* Pending event flag */ int event;
kernel/cgroup/cgroup.c +1 -1
@@ -3771,7 +3771,7 @@ static ssize_t pressure_write(struct kernfs_open_file *of, char *buf, } psi =cgroup_psi (cgrp); - new =psi_trigger_create (psi, buf, res, of->file); + new =psi_trigger_create (psi, buf, res, of->file, of);if (IS_ERR (new)) {cgroup_put (cgrp);return PTR_ERR (new);
kernel/sched/psi.c +21 -8
@@ -494,8 +494,12 @@ static u64 update_triggers(struct psi_group *group, u64 now, bool *update_total,continue ;/* Generate an event */ -if (cmpxchg (&t->event,0 ,1 ) ==0 ) -wake_up_interruptible (&t->event_wait); +if (cmpxchg (&t->event,0 ,1 ) ==0 ) { +if (t->of) +kernfs_notify (t->of->kn); +else +wake_up_interruptible (&t->event_wait); + } t->last_event_time = now;/* Reset threshold breach flag once event got generated */ t->pending_event = false;
@@ -1272,8 +1276,9 @@ int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res)return 0 ; } -struct psi_trigger *psi_trigger_create (struct psi_group *group, -char *buf,enum psi_res res,struct file *file) +struct psi_trigger *psi_trigger_create (struct psi_group *group,char *buf, +enum psi_res res,struct file *file, +struct kernfs_open_file *of) {struct psi_trigger *t;enum psi_states state;
@@ -1333,7 +1338,9 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, t->event =0 ; t->last_event_time =0 ; -init_waitqueue_head (&t->event_wait); + t->of = of; +if (!of) +init_waitqueue_head (&t->event_wait); t->pending_event = false; t->aggregator = privileged ?PSI_POLL :PSI_AVGS ;
@@ -1390,7 +1397,10 @@ void psi_trigger_destroy(struct psi_trigger *t)* being accessed later. Can happen if cgroup is deleted from under a * polling process. */ -wake_up_pollfree (&t->event_wait); +if (t->of) +kernfs_notify (t->of->kn); +else +wake_up_interruptible (&t->event_wait);if (t->aggregator ==PSI_AVGS ) {mutex_lock (&group->avgs_lock);
@@ -1462,7 +1472,10 @@ __poll_t psi_trigger_poll(void **trigger_ptr,if (!t)return DEFAULT_POLLMASK |EPOLLERR |EPOLLPRI ; -poll_wait (file, &t->event_wait, wait); +if (t->of) +kernfs_generic_poll (t->of, wait); +else +poll_wait (file, &t->event_wait, wait);if (cmpxchg (&t->event,1 ,0 ) ==1 ) ret |=EPOLLPRI ;
@@ -1532,7 +1545,7 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf,return -EBUSY ; } - new =psi_trigger_create (&psi_system, buf, res, file); + new =psi_trigger_create (&psi_system, buf, res, file,NULL );if (IS_ERR (new)) {mutex_unlock (&seq->lock);return PTR_ERR (new);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 93/183 pinctrl: renesas: rzv2m: Handle non-unique subnode names
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit f46a0b47cc0829acd050213194c5a77351e619b2 ]
The eMMC and SDHI pin control configuration nodes in DT have subnodes with the same names ("data" and "ctrl"). As the RZ/V2M pin control driver considers only the names of the subnodes, this leads to conflicts:
pinctrl-rzv2m b6250000.pinctrl: pin P8_2 already requested by 85000000.mmc; cannot claim for 85020000.mmc
pinctrl-rzv2m b6250000.pinctrl: pin-130 (85020000.mmc) status -22
renesas_sdhi_internal_dmac 85020000.mmc: Error applying setting, reverse things backFix this by constructing unique names from the node names of both the pin control configuration node and its child node, where appropriate.
Reported by: Fabrizio Castro <[email protected]>
--- drivers/pinctrl/renesas/pinctrl-rzv2m.c | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-)
drivers/pinctrl/renesas/pinctrl-rzv2m.c +20 -8
@@ -207,6 +207,7 @@ static int rzv2m_map_add_config(struct pinctrl_map *map,static int rzv2m_dt_subnode_to_map (struct pinctrl_dev *pctldev,struct device_node *np, +struct device_node *parent,struct pinctrl_map **map,unsigned int *num_maps,unsigned int *index)
@@ -224,6 +225,7 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,struct property *prop;int ret, gsel, fsel;const char **pin_fn; +const char *name;const char *pin; pinmux =of_find_property (np,"pinmux" ,NULL );
@@ -307,8 +309,19 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, psel_val[i] =MUX_FUNC (value); } +if (parent) { + name =devm_kasprintf (pctrl->dev,GFP_KERNEL ,"%pOFn.%pOFn" , + parent, np); +if (!name) { + ret = -ENOMEM ; + goto done; + } + }else { + name = np->name; + } +/* Register a single pin group listing all the pins we read from DT */ - gsel =pinctrl_generic_add_group (pctldev, np->name, pins, num_pinmux,NULL ); + gsel =pinctrl_generic_add_group (pctldev, name, pins, num_pinmux,NULL );if (gsel <0 ) { ret = gsel; goto done;
@@ -318,17 +331,16 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,* Register a single group function where the 'data' is an array PSEL * register values read from DT. */ - pin_fn[0 ] = np->name; - fsel =pinmux_generic_add_function (pctldev, np->name, pin_fn,1 , - psel_val); + pin_fn[0 ] = name; + fsel =pinmux_generic_add_function (pctldev, name, pin_fn,1 , psel_val);if (fsel <0 ) { ret = fsel; goto remove_group; } maps[idx].type =PIN_MAP_TYPE_MUX_GROUP ; - maps[idx].data.mux.group = np->name; - maps[idx].data.mux.function = np->name; + maps[idx].data.mux.group = name; + maps[idx].data.mux.function = name; idx++;dev_dbg (pctrl->dev,"Parsed %pOF with %d pins\n" , np, num_pinmux);
@@ -375,7 +387,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev, index =0 ;for_each_child_of_node (np, child) { - ret =rzv2m_dt_subnode_to_map (pctldev, child, map, + ret =rzv2m_dt_subnode_to_map (pctldev, child, np, map, num_maps, &index);if (ret <0 ) {of_node_put (child);
@@ -384,7 +396,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev, }if (*num_maps ==0 ) { - ret =rzv2m_dt_subnode_to_map (pctldev, np, map, + ret =rzv2m_dt_subnode_to_map (pctldev, np,NULL , map, num_maps, &index);if (ret <0 ) goto done;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 94/183 pinctrl: renesas: rzg2l: Handle non-unique subnode names
In reply to Greg Kroah-HartmanFrom: Biju Das <[email protected]>
[ Upstream commit bfc374a145ae133613e05b9b89be561f169cb58d ]
Currently, sd1 and sd0 have unique subnode names 'sd1_mux' and 'sd0_mux'. If we change these to non-unique subnode names such as 'mux' this can lead to the below conflict as the RZ/G2L pin control driver considers only the names of the subnodes.
pinctrl-rzg2l 11030000.pinctrl: pin P47_0 already requested by 11c00000.mmc; cannot claim for 11c10000.mmc pinctrl-rzg2l 11030000.pinctrl: pin-376 (11c10000.mmc) status -22
pinctrl-rzg2l 11030000.pinctrl: could not request pin 376 (P47_0) from group mux on device pinctrl-rzg2l renesas_sdhi_internal_dmac 11c10000.mmc: Error applying setting, reverse things back
Fix this by constructing unique names from the node names of both the pin control configuration node and its child node, where appropriate.
Based on the work done by Geert for the RZ/V2M pinctrl driver.
--- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-)
drivers/pinctrl/renesas/pinctrl-rzg2l.c +20 -8
@@ -246,6 +246,7 @@ static int rzg2l_map_add_config(struct pinctrl_map *map,static int rzg2l_dt_subnode_to_map (struct pinctrl_dev *pctldev,struct device_node *np, +struct device_node *parent,struct pinctrl_map **map,unsigned int *num_maps,unsigned int *index)
@@ -263,6 +264,7 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,struct property *prop;int ret, gsel, fsel;const char **pin_fn; +const char *name;const char *pin; pinmux =of_find_property (np,"pinmux" ,NULL );
@@ -346,8 +348,19 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, psel_val[i] =MUX_FUNC (value); } +if (parent) { + name =devm_kasprintf (pctrl->dev,GFP_KERNEL ,"%pOFn.%pOFn" , + parent, np); +if (!name) { + ret = -ENOMEM ; + goto done; + } + }else { + name = np->name; + } +/* Register a single pin group listing all the pins we read from DT */ - gsel =pinctrl_generic_add_group (pctldev, np->name, pins, num_pinmux,NULL ); + gsel =pinctrl_generic_add_group (pctldev, name, pins, num_pinmux,NULL );if (gsel <0 ) { ret = gsel; goto done;
@@ -357,17 +370,16 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,* Register a single group function where the 'data' is an array PSEL * register values read from DT. */ - pin_fn[0 ] = np->name; - fsel =pinmux_generic_add_function (pctldev, np->name, pin_fn,1 , - psel_val); + pin_fn[0 ] = name; + fsel =pinmux_generic_add_function (pctldev, name, pin_fn,1 , psel_val);if (fsel <0 ) { ret = fsel; goto remove_group; } maps[idx].type =PIN_MAP_TYPE_MUX_GROUP ; - maps[idx].data.mux.group = np->name; - maps[idx].data.mux.function = np->name; + maps[idx].data.mux.group = name; + maps[idx].data.mux.function = name; idx++;dev_dbg (pctrl->dev,"Parsed %pOF with %d pins\n" , np, num_pinmux);
@@ -414,7 +426,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev, index =0 ;for_each_child_of_node (np, child) { - ret =rzg2l_dt_subnode_to_map (pctldev, child, map, + ret =rzg2l_dt_subnode_to_map (pctldev, child, np, map, num_maps, &index);if (ret <0 ) {of_node_put (child);
@@ -423,7 +435,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev, }if (*num_maps ==0 ) { - ret =rzg2l_dt_subnode_to_map (pctldev, np, map, + ret =rzg2l_dt_subnode_to_map (pctldev, np,NULL , map, num_maps, &index);if (ret <0 ) goto done;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 95/183 spi: bcm63xx: fix max prepend length
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
[ Upstream commit 5158814cbb37bbb38344b3ecddc24ba2ed0365f2 ]
The command word is defined as following:
/* Command */
#define SPI_CMD_COMMAND_SHIFT 0
#define SPI_CMD_DEVICE_ID_SHIFT 4
#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8
#define SPI_CMD_ONE_BYTE_SHIFT 11
#define SPI_CMD_ONE_WIRE_SHIFT 12If the prepend byte count field starts at bit 8, and the next defined bit is SPI_CMD_ONE_BYTE at bit 11, it can be at most 3 bits wide, and thus the max value is 7, not 15.
--- drivers/spi/spi-bcm63xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-bcm63xx.c +1 -1
@@ -126,7 +126,7 @@ enum bcm63xx_regs_spi { SPI_MSG_DATA_SIZE, }; -#define BCM63XX_SPI_MAX_PREPEND 15 +#define BCM63XX_SPI_MAX_PREPEND 7#define BCM63XX_SPI_MAX_CS 8#define BCM63XX_SPI_BUS_NUM 0
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 96/183 fbdev: imxfb: warn about invalid left/right margin
In reply to Greg Kroah-HartmanFrom: Martin Kaiser <[email protected]>
[ Upstream commit 4e47382fbca916d7db95cbf9e2d7ca2e9d1ca3fe ]
Warn about invalid var->left_margin or var->right_margin. Their values are read from the device tree.
We store var->left_margin-3 and var->right_margin-1 in register fields. These fields should be >= 0.
--- drivers/video/fbdev/imxfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/fbdev/imxfb.c +2 -2
@@ -613,10 +613,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *infif (var->hsync_len <1 || var->hsync_len >64 )printk (KERN_ERR "%s: invalid hsync_len %d\n" , info->fix.id, var->hsync_len); -if (var->left_margin >255 ) +if (var->left_margin <3 || var->left_margin >255 )printk (KERN_ERR "%s: invalid left_margin %d\n" , info->fix.id, var->left_margin); -if (var->right_margin >255 ) +if (var->right_margin <1 || var->right_margin >255 )printk (KERN_ERR "%s: invalid right_margin %d\n" , info->fix.id, var->right_margin);if (var->yres <1 || var->yres > ymax_mask)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 97/183 fbdev: imxfb: Removed unneeded release_mem_region
In reply to Greg Kroah-HartmanFrom: Yangtao Li <[email protected]>
[ Upstream commit 45fcc058a75bf5d65cf4c32da44a252fbe873cd4 ]
Remove unnecessary release_mem_region from the error path to prevent mem region from being released twice, which could avoid resource leak or other unexpected issues.
--- drivers/video/fbdev/imxfb.c | 1 - 1 file changed, 1 deletion(-)
drivers/video/fbdev/imxfb.c +0 -1
@@ -1043,7 +1043,6 @@ static int imxfb_probe(struct platform_device *pdev) failed_map: failed_ioremap: failed_getclock: -release_mem_region (res->start,resource_size (res)); failed_of_parse:kfree (info->pseudo_palette); failed_init:
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 98/183 perf build: Fix library not found error when using CSLIBS
In reply to Greg Kroah-HartmanFrom: James Clark <[email protected]>
[ Upstream commit 1feece2780ac2f8de45177fe53979726cee4b3d1 ]
-L only specifies the search path for libraries directly provided in the link line with -l. Because -lopencsd isn't specified, it's only linked because it's a dependency of -lopencsd_c_api. Dependencies like this are resolved using the default system search paths or -rpath-link=... rather than -L. This means that compilation only works if OpenCSD is installed to the system rather than provided with the CSLIBS (-L) option.
This could be fixed by adding -Wl,-rpath-link=$(CSLIBS) but that is less conventional than just adding -lopencsd to the link line so that it uses -L. -lopencsd seems to have been removed in commit ed17b1914978eddb ("perf tools: Drop requirement for libstdc++.so for libopencsd check") because it was thought that there was a chance compilation would work even if it didn't exist, but I think that only applies to libstdc++ so there is no harm to add it back. libopencsd.so and libopencsd_c_api.so would always exist together.
Testing
=======
The following scenarios now all work:
* Cross build with OpenCSD installed
* Cross build using CSLIBS=...
* Native build with OpenCSD installed
* Native build using CSLIBS=...
* Static cross build with OpenCSD installed
* Static cross build with CSLIBS=...
Committer testing:
⬢[acme@toolbox perf-tools]$ alias m alias m='make -k BUILD_BPF_SKEL=1 CORESIGHT=1 O=/tmp/build/perf-tools -C tools/perf install-bin && git status && perf test python ; perf record -o /dev/null sleep 0.01 ; perf stat --null sleep 0.01' ⬢[acme@toolbox perf-tools]$ ldd ~/bin/perf | grep csd libopencsd_c_api.so.1 => /lib64/libopencsd_c_api.so.1 (0x00007fd49c44e000) libopencsd.so.1 => /lib64/libopencsd.so.1 (0x00007fd49bd56000) ⬢[acme@toolbox perf-tools]$ cat /etc/redhat-release Fedora release 36 (Thirty Six) ⬢[acme@toolbox perf-tools]$
--- tools/perf/Makefile.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/Makefile.config +2 -2
@@ -149,9 +149,9 @@ FEATURE_CHECK_LDFLAGS-libcrypto = -lcrypto ifdef CSINCLUDES LIBOPENCSD_CFLAGS := -I$(CSINCLUDES) endif -OPENCSDLIBS := -lopencsd_c_api +OPENCSDLIBS := -lopencsd_c_api -lopencsd ifeq ($(findstring -static,${LDFLAGS}),-static) - OPENCSDLIBS += -lopencsd -lstdc++ + OPENCSDLIBS += -lstdc++ endif ifdef CSLIBS LIBOPENCSD_LDFLAGS := -L$(CSLIBS)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 99/183 btrfs: be a bit more careful when setting mirror_num_ret in btrfs_map_block
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 4e7de35eb7d1a1d4f2dda15f39fbedd4798a0b8d ]
The mirror_num_ret is allowed to be NULL, although it has to be set when smap is set. Unfortunately that is not a well enough specifiable invariant for static type checkers, so add a NULL check to make sure they are fine.
--- fs/btrfs/volumes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/volumes.c +4 -2
@@ -6595,11 +6595,13 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,if (patch_the_first_stripe_for_dev_replace) { smap->dev = dev_replace->tgtdev; smap->physical = physical_to_patch_in_first_stripe; - *mirror_num_ret = map->num_stripes +1 ; +if (mirror_num_ret) + *mirror_num_ret = map->num_stripes +1 ; }else {set_io_stripe (smap, map, stripe_index, stripe_offset, stripe_nr); - *mirror_num_ret = mirror_num; +if (mirror_num_ret) + *mirror_num_ret = mirror_num; } *bioc_ret =NULL ; ret =0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 100/183 spi: s3c64xx: clear loopback bit after loopback test
In reply to Greg Kroah-HartmanFrom: Jaewon Kim <[email protected]>
[ Upstream commit 9ec3c5517e22a12d2ff1b71e844f7913641460c6 ]
When SPI loopback transfer is performed, S3C64XX_SPI_MODE_SELF_LOOPBACK bit still remained. It works as loopback even if the next transfer is not spi loopback mode.
If not SPI_LOOP, needs to clear S3C64XX_SPI_MODE_SELF_LOOPBACK bit.
--- drivers/spi/spi-s3c64xx.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/spi/spi-s3c64xx.c +2 -0
@@ -668,6 +668,8 @@ static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)if ((sdd->cur_mode &SPI_LOOP ) && sdd->port_conf->has_loopback) val |=S3C64XX_SPI_MODE_SELF_LOOPBACK ; +else + val &= ~S3C64XX_SPI_MODE_SELF_LOOPBACK ;writel (val, regs +S3C64XX_SPI_MODE_CFG );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 101/183 kallsyms: Improve the performance of kallsyms_lookup_name()
In reply to Greg Kroah-HartmanFrom: Zhen Lei <[email protected]>
[ Upstream commit 60443c88f3a89fd303a9e8c0e84895910675c316 ]
Currently, to search for a symbol, we need to expand the symbols in 'kallsyms_names' one by one, and then use the expanded string for comparison. It's O(n).
If we sort names in ascending order like addresses, we can also use binary search. It's O(log(n)).
In order not to change the implementation of "/proc/kallsyms", the table kallsyms_names[] is still stored in a one-to-one correspondence with the address in ascending order.
Add array kallsyms_seqs_of_names[], it's indexed by the sequence number of the sorted names, and the corresponding content is the sequence number of the sorted addresses. For example:
Assume that the index of NameX in array kallsyms_seqs_of_names[] is 'i', the content of kallsyms_seqs_of_names[i] is 'k', then the corresponding address of NameX is kallsyms_addresses[k]. The offset in kallsyms_names[] is get_symbol_offset(k).
Note that the memory usage will increase by (4 * kallsyms_num_syms) bytes, the next two patches will reduce (1 * kallsyms_num_syms) bytes and properly handle the case CONFIG_LTO_CLANG=y.
Performance test results: (x86)
Before:
min=234, max=10364402, avg=5206926
min=267, max=11168517, avg=5207587
After:
min=1016, max=90894, avg=7272
min=1014, max=93470, avg=7293
The average lookup performance of kallsyms_lookup_name() improved 715x.
Stable-dep-of: 8cc32a9bbf29 ("kallsyms: strip LTO-only suffixes from promoted global functions")
--- kernel/kallsyms.c | 86 +++++++++++++++++++++++++++++++++----- kernel/kallsyms_internal.h | 1 + scripts/kallsyms.c | 37 ++++++++++++++++ 3 files changed, 113 insertions(+), 11 deletions(-)
kernel/kallsyms.c +75 -11
@@ -187,26 +187,90 @@ static bool cleanup_symbol_name(char *s)return false; } +static int compare_symbol_name (const char *name,char *namebuf) +{ +int ret; + + ret =strcmp (name, namebuf); +if (!ret) +return ret; + +if (cleanup_symbol_name (namebuf) && !strcmp (name, namebuf)) +return 0 ; + +return ret; +} + +static int kallsyms_lookup_names (const char *name, +unsigned int *start, +unsigned int *end) +{ +int ret; +int low, mid, high; +unsigned int seq, off; +char namebuf[KSYM_NAME_LEN ]; + + low =0 ; + high = kallsyms_num_syms -1 ; + +while (low <= high) { + mid = low + (high - low) /2 ; + seq = kallsyms_seqs_of_names[mid]; + off =get_symbol_offset (seq); +kallsyms_expand_symbol (off, namebuf,ARRAY_SIZE (namebuf)); + ret =compare_symbol_name (name, namebuf); +if (ret >0 ) + low = mid +1 ; +else if (ret <0 ) + high = mid -1 ; +else +break ; + } + +if (low > high) +return -ESRCH ; + + low = mid; +while (low) { + seq = kallsyms_seqs_of_names[low -1 ]; + off =get_symbol_offset (seq); +kallsyms_expand_symbol (off, namebuf,ARRAY_SIZE (namebuf)); +if (compare_symbol_name (name, namebuf)) +break ; + low--; + } + *start = low; + +if (end) { + high = mid; +while (high < kallsyms_num_syms -1 ) { + seq = kallsyms_seqs_of_names[high +1 ]; + off =get_symbol_offset (seq); +kallsyms_expand_symbol (off, namebuf,ARRAY_SIZE (namebuf)); +if (compare_symbol_name (name, namebuf)) +break ; + high++; + } + *end = high; + } + +return 0 ; +} +/* Lookup the address for this symbol. Returns 0 if not found. */ unsigned long kallsyms_lookup_name (const char *name) { -char namebuf[KSYM_NAME_LEN ]; -unsigned long i; -unsigned int off; +int ret; +unsigned int i;/* Skip the search for empty string. */ if (!*name)return 0 ; -for (i =0 , off =0 ; i < kallsyms_num_syms; i++) { - off =kallsyms_expand_symbol (off, namebuf,ARRAY_SIZE (namebuf)); - -if (strcmp (namebuf, name) ==0 ) -return kallsyms_sym_address (i); + ret =kallsyms_lookup_names (name, &i,NULL ); +if (!ret) +return kallsyms_sym_address (kallsyms_seqs_of_names[i]); -if (cleanup_symbol_name (namebuf) &&strcmp (namebuf, name) ==0 ) -return kallsyms_sym_address (i); - }return module_kallsyms_lookup_name (name); }
kernel/kallsyms_internal.h +1 -0
@@ -26,5 +26,6 @@ extern const char kallsyms_token_table[] __weak;extern const u16 kallsyms_token_index[]__weak ;extern const unsigned int kallsyms_markers[]__weak ; +extern const unsigned int kallsyms_seqs_of_names[]__weak ;#endif // LINUX_KALLSYMS_INTERNAL_H_
scripts/kallsyms.c +37 -0
@@ -49,6 +49,7 @@ _Static_assert(struct sym_entry {unsigned long long addr;unsigned int len; +unsigned int seq;unsigned int start_pos;unsigned int percpu_absolute;unsigned char sym[];
@@ -410,6 +411,35 @@ static int symbol_absolute(const struct sym_entry *s)return s->percpu_absolute; } +static int compare_names (const void *a,const void *b) +{ +int ret; +char sa_namebuf[KSYM_NAME_LEN ]; +char sb_namebuf[KSYM_NAME_LEN ]; +const struct sym_entry *sa = *(const struct sym_entry **)a; +const struct sym_entry *sb = *(const struct sym_entry **)b; + +expand_symbol (sa->sym, sa->len, sa_namebuf); +expand_symbol (sb->sym, sb->len, sb_namebuf); + ret =strcmp (&sa_namebuf[1 ], &sb_namebuf[1 ]); +if (!ret) { +if (sa->addr > sb->addr) +return 1 ; +else if (sa->addr < sb->addr) +return -1 ; + +/* keep old order */ +return (int )(sa->seq - sb->seq); + } + +return ret; +} + +static void sort_symbols_by_name (void ) +{ +qsort (table, table_cnt,sizeof (table[0 ]), compare_names); +} +static void write_src (void ) {unsigned int i, k, off;
@@ -495,6 +525,7 @@ static void write_src(void)for (i =0 ; i < table_cnt; i++) {if ((i &0xFF ) ==0 ) markers[i >>8 ] = off; + table[i]->seq = i;/* There cannot be any symbol of length zero. */ if (table[i]->len ==0 ) {
@@ -535,6 +566,12 @@ static void write_src(void)free (markers); +sort_symbols_by_name (); +output_label ("kallsyms_seqs_of_names" ); +for (i =0 ; i < table_cnt; i++) +printf ("\t.long\t%u\n" , table[i]->seq); +printf ("\n" ); +output_label ("kallsyms_token_table" ); off =0 ;for (i =0 ; i <256 ; i++) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 102/183 kallsyms: Correctly sequence symbols when CONFIG_LTO_CLANG=y
In reply to Greg Kroah-HartmanFrom: Zhen Lei <[email protected]>
[ Upstream commit 010a0aad39fccceba4a07d30d163158a39c704f3 ]
LLVM appends various suffixes for local functions and variables, suffixes observed:
- foo.llvm.[0-9a-f]+
- foo.[0-9a-f]+
Therefore, when CONFIG_LTO_CLANG=y, kallsyms_lookup_name() needs to truncate the suffix of the symbol name before comparing the local function or variable name.
Old implementation code:
- if (strcmp(namebuf, name) == 0)
- return kallsyms_sym_address(i);
- if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0)
- return kallsyms_sym_address(i);
The preceding process is traversed by address from low to high. That is, for those with the same name after the suffix is removed, the one with the smallest address is returned first. Therefore, when sorting in the tool, if the raw names are the same, they should be sorted by address in ascending order.
ASCII[.] = 2e
ASCII[0-9] = 30,39
ASCII[A-Z] = 41,5a
ASCII[_] = 5f
ASCII[a-z] = 61,7a
According to the preceding ASCII code values, the following sorting result is strictly followed.
---------------------------------
| main-key | sub-key | |---------------------------------| | | addr_lowest | | <name> | ... | | <name>.<suffix> | ... | | | addr_highest | |---------------------------------| | <name>?<others> | | //? is [_A-Za-z0-9]
---------------------------------
Stable-dep-of: 8cc32a9bbf29 ("kallsyms: strip LTO-only suffixes from promoted global functions")
--- scripts/kallsyms.c | 36 ++++++++++++++++++++++++++++++++++-- scripts/link-vmlinux.sh | 4 ++++ 2 files changed, 38 insertions(+), 2 deletions(-)
scripts/kallsyms.c +34 -2
@@ -78,6 +78,7 @@ static unsigned int table_size, table_cnt;static int all_symbols;static int absolute_percpu;static int base_relative; +static int lto_clang;static int token_profit[0x10000 ];
@@ -89,7 +90,7 @@ static unsigned char best_table_len[256];static void usage (void ) {fprintf (stderr,"Usage: kallsyms [--all-symbols] [--absolute-percpu] " -"[--base-relative] in.map > out.S\n" ); +"[--base-relative] [--lto-clang] in.map > out.S\n" );exit (1 ); }
@@ -411,6 +412,34 @@ static int symbol_absolute(const struct sym_entry *s)return s->percpu_absolute; } +static char *s_name (char *buf) +{ +/* Skip the symbol type */ +return buf +1 ; +} + +static void cleanup_symbol_name (char *s) +{ +char *p; + +if (!lto_clang) +return ; + +/* +* ASCII[.] = 2e +* ASCII[0-9] = 30,39 +* ASCII[A-Z] = 41,5a +* ASCII[_] = 5f +* ASCII[a-z] = 61,7a +* +* As above, replacing '.' with '\0' does not affect the main sorting, +* but it helps us with subsorting. +*/ + p =strchr (s,'.' ); +if (p) + *p ='\0' ; +} +static int compare_names (const void *a,const void *b) {int ret;
@@ -421,7 +450,9 @@ static int compare_names(const void *a, const void *b)expand_symbol (sa->sym, sa->len, sa_namebuf);expand_symbol (sb->sym, sb->len, sb_namebuf); - ret =strcmp (&sa_namebuf[1 ], &sb_namebuf[1 ]); +cleanup_symbol_name (s_name (sa_namebuf)); +cleanup_symbol_name (s_name (sb_namebuf)); + ret =strcmp (s_name (sa_namebuf),s_name (sb_namebuf));if (!ret) {if (sa->addr > sb->addr)return 1 ;
@@ -855,6 +886,7 @@ int main(int argc, char **argv) {"all-symbols", no_argument, &all_symbols, 1}, {"absolute-percpu", no_argument, &absolute_percpu, 1}, {"base-relative", no_argument, &base_relative, 1}, + {"lto-clang", no_argument, <o_clang, 1}, {}, };
scripts/link-vmlinux.sh +4 -0
@@ -156,6 +156,10 @@ kallsyms() kallsymopt="${kallsymopt} --base-relative" fi + if is_enabled CONFIG_LTO_CLANG; then + kallsymopt="${kallsymopt} --lto-clang" + fi + info KSYMS ${2} scripts/kallsyms ${kallsymopt} ${1} > ${2} }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 103/183 kallsyms: strip LTO-only suffixes from promoted global functions
In reply to Greg Kroah-HartmanFrom: Yonghong Song <[email protected]>
[ Upstream commit 8cc32a9bbf2934d90762d9de0187adcb5ad46a11 ]
Commit 6eb4bd92c1ce ("kallsyms: strip LTO suffixes from static functions") stripped all function/variable suffixes started with '.' regardless of whether those suffixes are generated at LTO mode or not. In fact, as far as I know, in LTO mode, when a static function/variable is promoted to the global scope, '.llvm.<...>' suffix is added.
The existing mechanism breaks live patch for a LTO kernel even if no <symbol>.llvm.<...> symbols are involved. For example, for the following kernel symbols:
$ grep bpf_verifier_vlog /proc/kallsyms ffffffff81549f60 t bpf_verifier_vlog ffffffff8268b430 d bpf_verifier_vlog._entry ffffffff8282a958 d bpf_verifier_vlog._entry_ptr ffffffff82e12a1f d bpf_verifier_vlog.__already_done 'bpf_verifier_vlog' is a static function. '_entry', '_entry_ptr' and '__already_done' are static variables used inside 'bpf_verifier_vlog', so llvm promotes them to file-level static with prefix 'bpf_verifier_vlog.'. Note that the func-level to file-level static function promotion also happens without LTO.
Given a symbol name 'bpf_verifier_vlog', with LTO kernel, current mechanism will return 4 symbols to live patch subsystem which current live patching subsystem cannot handle it. With non-LTO kernel, only one symbol
is returned.
In [1], we have a lengthy discussion, the suggestion is to separate two cases:
(1). new symbols with suffix which are generated regardless of whether
LTO is enabled or not, and
(2). new symbols with suffix generated only when LTO is enabled.
The cleanup_symbol_name() should only remove suffixes for case (2). Case (1) should not be changed so it can work uniformly with or without LTO.
This patch removed LTO-only suffix '.llvm.<...>' so live patching and tracing should work the same way for non-LTO kernel.
The cleanup_symbol_name() in scripts/kallsyms.c is also changed to have the same filtering pattern so both kernel and kallsyms tool have the same expectation on the order of symbols.
[1] https://lore.kernel.org/live-patching/[email protected]/T/#u
--- kernel/kallsyms.c | 5 ++--- scripts/kallsyms.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-)
kernel/kallsyms.c +2 -3
@@ -174,11 +174,10 @@ static bool cleanup_symbol_name(char *s)* LLVM appends various suffixes for local functions and variables that * must be promoted to global scope as part of LTO. This can break * hooking of static functions with kprobes. '.' is not a valid -* character in an identifier in C. Suffixes observed: +* character in an identifier in C. Suffixes only in LLVM LTO observed: * - foo.llvm.[0-9a-f]+ -* - foo.[0-9a-f]+ */ - res =strchr (s,'.' ); + res =strstr (s,".llvm." );if (res) { *res ='\0' ;return true;
scripts/kallsyms.c +3 -3
@@ -432,10 +432,10 @@ static void cleanup_symbol_name(char *s)* ASCII[_] = 5f * ASCII[a-z] = 61,7a * -* As above, replacing '.' with '\0' does not affect the main sorting, -* but it helps us with subsorting. +* As above, replacing the first '.' in ".llvm." with '\0' does not +* affect the main sorting, but it helps us with subsorting. */ - p =strchr (s,'.' ); + p =strstr (s,".llvm." );if (p) *p ='\0' ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 104/183 dsa: mv88e6xxx: Do a final check before timing out
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit 95ce158b6c93b28842b54b42ad1cb221b9844062 ]
I get sporadic timeouts from the driver when using the MV88E6352. Reading the status again after the loop fixes the
problem: the operation is successful but goes undetected.
Some added prints show things like this:
[ 58.356209] mv88e6085 mdio_mux-0.1:00: Timeout while waiting
for switch, addr 1b reg 0b, mask 8000, val 0000, data c000
[ 58.367487] mv88e6085 mdio_mux-0.1:00: Timeout waiting for
ATU op 4000, fid 0001
(...)
[ 61.826293] mv88e6085 mdio_mux-0.1:00: Timeout while waiting
for switch, addr 1c reg 18, mask 8000, val 0000, data 9860
[ 61.837560] mv88e6085 mdio_mux-0.1:00: Timeout waiting
for PHY command 1860 to completeThe reason is probably not the commands: I think those are mostly fine with the 50+50ms timeout, but the problem appears when OpenWrt brings up several interfaces in parallel on a system with 7 populated ports: if one of them take more than 50 ms and waits one or more of the others can get stuck on the mutex for the switch and then this can easily multiply.
As we sleep and wait, the function loop needs a final check after exiting the loop if we were successful.
--- drivers/net/dsa/mv88e6xxx/chip.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/dsa/mv88e6xxx/chip.c +7 -0
@@ -109,6 +109,13 @@ int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,usleep_range (1000 ,2000 ); } + err =mv88e6xxx_read (chip, addr, reg, &data); +if (err) +return err; + +if ((data & mask) == val) +return 0 ; +dev_err (chip->dev,"Timeout while waiting for switch\n" );return -ETIMEDOUT ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 105/183 net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()
In reply to Greg Kroah-HartmanFrom: Tanmay Patil <[email protected]>
[ Upstream commit b685f1a58956fa36cc01123f253351b25bfacfda ]
CPSW ALE has 75 bit ALE entries which are stored within three 32 bit words. The cpsw_ale_get_field() and cpsw_ale_set_field() functions assume that the field will be strictly contained within one word. However, this is not guaranteed to be the case and it is possible for ALE field entries to span across up to two words at the most.
Fix the methods to handle getting/setting fields spanning up to two words.
--- drivers/net/ethernet/ti/cpsw_ale.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/net/ethernet/ti/cpsw_ale.c +19 -5
@@ -106,23 +106,37 @@ struct cpsw_ale_dev_id {static inline int cpsw_ale_get_field (u32 *ale_entry,u32 start,u32 bits) { -int idx; +int idx, idx2; +u32 hi_val =0 ; idx = start /32 ; + idx2 = (start + bits -1 ) /32 ; +/* Check if bits to be fetched exceed a word */ +if (idx != idx2) { + idx2 =2 - idx2;/* flip */ + hi_val = ale_entry[idx2] << ((idx2 *32 ) - start); + } start -= idx *32 ; idx =2 - idx;/* flip */ -return (ale_entry[idx] >> start) &BITMASK (bits); +return (hi_val + (ale_entry[idx] >> start)) &BITMASK (bits); }static inline void cpsw_ale_set_field (u32 *ale_entry,u32 start,u32 bits,u32 value) { -int idx; +int idx, idx2; value &=BITMASK (bits); - idx = start /32 ; + idx = start /32 ; + idx2 = (start + bits -1 ) /32 ; +/* Check if bits to be set exceed a word */ +if (idx != idx2) { + idx2 =2 - idx2;/* flip */ + ale_entry[idx2] &= ~(BITMASK (bits + start - (idx2 *32 ))); + ale_entry[idx2] |= (value >> ((idx2 *32 ) - start)); + } start -= idx *32 ; - idx =2 - idx;/* flip */ + idx =2 - idx;/* flip */ ale_entry[idx] &= ~(BITMASK (bits) << start); ale_entry[idx] |= (value << start); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 106/183 bridge: Add extack warning when enabling STP in netns.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 56a16035bb6effb37177867cea94c13a8382f745 ]
When we create an L2 loop on a bridge in netns, we will see packets storm even if STP is enabled.
# unshare -n
# ip link add br0 type bridge
# ip link add veth0 type veth peer name veth1
# ip link set veth0 master br0 up
# ip link set veth1 master br0 up
# ip link set br0 type bridge stp_state 1
# ip link set br0 up
# sleep 30
# ip -s link show br0
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether b6:61:98:1c:1c:b5 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
956553768 12861249 0 0 0 12861249 <-. Keep
TX: bytes packets errors dropped carrier collsns | increasing
1027834 11951 0 0 0 0 <-' rapidlyThis is because llc_rcv() drops all packets in non-root netns and BPDU is dropped.
Let's add extack warning when enabling STP in netns.
# unshare -n # ip link add br0 type bridge # ip link set br0 type bridge stp_state 1 Warning: bridge: STP does not work in non-root netns.
Note this commit will be reverted later when we namespacify the whole LLC infra.
--- net/bridge/br_stp_if.c | 3 +++ 1 file changed, 3 insertions(+)
net/bridge/br_stp_if.c +3 -0
@@ -201,6 +201,9 @@ int br_stp_set_enabled(struct net_bridge *br, unsigned long val, {ASSERT_RTNL (); +if (!net_eq (dev_net (br->dev), &init_net)) +NL_SET_ERR_MSG_MOD (extack,"STP does not work in non-root netns" ); +if (br_mrp_enabled (br)) {NL_SET_ERR_MSG_MOD (extack,"STP can't be enabled if MRP is already enabled" );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 107/183 net: ethernet: mtk_eth_soc: handle probe deferral
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit 1d6d537dc55d1f42d16290f00157ac387985b95b ]
Move the call to of_get_ethdev_address to mtk_add_mac which is part of the probe function and can hence itself return -EPROBE_DEFER should of_get_ethdev_address return -EPROBE_DEFER. This allows us to entirely get rid of the mtk_init function.
The problem of of_get_ethdev_address returning -EPROBE_DEFER surfaced in situations in which the NVMEM provider holding the MAC address has not yet be loaded at the time mtk_eth_soc is initially probed. In this case probing of mtk_eth_soc should be deferred instead of falling back to use a random MAC address, so once the NVMEM provider becomes available probing can be repeated.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 29 ++++++++------------- 1 file changed, 11 insertions(+), 18 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +11 -18
@@ -3425,23 +3425,6 @@ static int mtk_hw_deinit(struct mtk_eth *eth)return 0 ; } -static int __init mtk_init (struct net_device *dev) -{ -struct mtk_mac *mac =netdev_priv (dev); -struct mtk_eth *eth = mac->hw; -int ret; - - ret =of_get_ethdev_address (mac->of_node, dev); -if (ret) { -/* If the mac address is invalid, use random mac address */ -eth_hw_addr_random (dev); -dev_err (eth->dev,"generated random MAC address %pM\n" , - dev->dev_addr); - } - -return 0 ; -} -static void mtk_uninit (struct net_device *dev) {struct mtk_mac *mac =netdev_priv (dev);
@@ -3789,7 +3772,6 @@ static const struct ethtool_ops mtk_ethtool_ops = { };static const struct net_device_ops mtk_netdev_ops = { - .ndo_init = mtk_init, .ndo_uninit = mtk_uninit, .ndo_open = mtk_open, .ndo_stop = mtk_stop,
@@ -3845,6 +3827,17 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) mac->hw = eth; mac->of_node = np; + err =of_get_ethdev_address (mac->of_node, eth->netdev[id]); +if (err == -EPROBE_DEFER ) +return err; + +if (err) { +/* If the mac address is invalid, use random mac address */ +eth_hw_addr_random (eth->netdev[id]); +dev_err (eth->dev,"generated random MAC address %pM\n" , + eth->netdev[id]->dev_addr); + } +memset (mac->hwlro_ip,0 ,sizeof (mac->hwlro_ip)); mac->hwlro_ip_cnt =0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 108/183 cifs: fix mid leak during reconnection after timeout threshold
In reply to Greg Kroah-HartmanFrom: Shyam Prasad N <[email protected]>
[ Upstream commit 69cba9d3c1284e0838ae408830a02c4a063104bc ]
When the number of responses with status of STATUS_IO_TIMEOUT exceeds a specified threshold (NUM_STATUS_IO_TIMEOUT), we reconnect the connection. But we do not return the mid, or the credits returned for the mid, or reduce the number of in-flight requests.
This bug could result in the server->in_flight count to go bad, and also cause a leak in the mids.
This change moves the check to a few lines below where the response is decrypted, even of the response is read from the transform header. This way, the code for returning the mids can be reused.
Also, the cifs_reconnect was reconnecting just the transport connection before. In case of multi-channel, this may not be what we want to do after several timeouts. Changed that to reconnect the session and the tree too.
Also renamed NUM_STATUS_IO_TIMEOUT to a more appropriate name MAX_STATUS_IO_TIMEOUT.
--- fs/smb/client/connect.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
fs/smb/client/connect.c +15 -4
@@ -59,7 +59,7 @@ extern bool disable_legacy_dialects;#define TLINK_IDLE_EXPIRE (600 * HZ)/* Drop the connection to not overload the server */ -#define NUM_STATUS_IO_TIMEOUT 5 +#define MAX_STATUS_IO_TIMEOUT 5struct mount_ctx {struct cifs_sb_info *cifs_sb;
@@ -1162,6 +1162,7 @@ cifs_demultiplex_thread(void *p)struct mid_q_entry *mids[MAX_COMPOUND ];char *bufs[MAX_COMPOUND ];unsigned int noreclaim_flag, num_io_timeout =0 ; +bool pending_reconnect = false; noreclaim_flag =memalloc_noreclaim_save ();cifs_dbg (FYI ,"Demultiplex PID: %d\n" ,task_pid_nr (current));
@@ -1201,6 +1202,8 @@ cifs_demultiplex_thread(void *p)cifs_dbg (FYI ,"RFC1002 header 0x%x\n" , pdu_length);if (!is_smb_response (server, buf[0 ]))continue ; + + pending_reconnect = false; next_pdu: server->pdu_size = pdu_length;
@@ -1258,10 +1261,13 @@ cifs_demultiplex_thread(void *p)if (server->ops->is_status_io_timeout && server->ops->is_status_io_timeout (buf)) { num_io_timeout++; -if (num_io_timeout >NUM_STATUS_IO_TIMEOUT ) { -cifs_reconnect (server, false); +if (num_io_timeout >MAX_STATUS_IO_TIMEOUT ) { +cifs_server_dbg (VFS , +"Number of request timeouts exceeded %d. Reconnecting" , +MAX_STATUS_IO_TIMEOUT ); + + pending_reconnect = true; num_io_timeout =0 ; -continue ; } }
@@ -1308,6 +1314,11 @@ cifs_demultiplex_thread(void *p) buf = server->smallbuf; goto next_pdu; } + +/* do this reconnect at the very end after processing all MIDs */ +if (pending_reconnect) +cifs_reconnect (server, true); + }/* end while !EXITING */ /* buffer usually freed in free_mid - need to free it here on exit */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 109/183 ASoC: SOF: ipc3-dtrace: uninitialized data in dfsentry_trace_filter_write()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 469e2f28c2cbee2430058c1c9bb6d1675d7195fb ]
This doesn't check how many bytes the simple_write_to_buffer() writes to the buffer. The only thing that we know is that the first byte is initialized and the last byte of the buffer is set to NUL. However the middle bytes could be uninitialized.
There is no need to use simple_write_to_buffer(). This code does not support partial writes but instead passes "pos = 0" as the starting offset regardless of what the user passed as "*ppos". Just use the copy_from_user() function and initialize the whole buffer.
--- sound/soc/sof/ipc3-dtrace.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
sound/soc/sof/ipc3-dtrace.c +4 -5
@@ -187,7 +187,6 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __userstruct snd_sof_dfsentry *dfse = file->private_data;struct sof_ipc_trace_filter_elem *elems =NULL ;struct snd_sof_dev *sdev = dfse->sdev; -loff_t pos =0 ;int num_elems;char *string;int ret;
@@ -202,11 +201,11 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __userif (!string)return -ENOMEM ; -/* assert null termination */ - string[count] =0 ; - ret =simple_write_to_buffer (string, count, &pos, from, count); -if (ret <0 ) +if (copy_from_user (string, from, count)) { + ret = -EFAULT ; goto error; + } + string[count] ='\0' ; ret =trace_filter_parse (sdev, string, &num_elems, &elems);if (ret <0 )
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 110/183 net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms
In reply to Greg Kroah-HartmanFrom: Victor Nogueira <[email protected]>
[ Upstream commit b3d0e0489430735e2e7626aa37e6462cdd136e9d ]
In case an error occurred after mall_set_parms executed successfully, we must undo the tcf_bind_filter call it issues.
Fix that by calling tcf_unbind_filter in err_replace_hw_filter label.
--- net/sched/cls_matchall.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-)
net/sched/cls_matchall.c +12 -23
@@ -157,26 +157,6 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 }, }; -static int mall_set_parms (struct net *net,struct tcf_proto *tp, -struct cls_mall_head *head, -unsigned long base,struct nlattr **tb, -struct nlattr *est,u32 flags,u32 fl_flags, -struct netlink_ext_ack *extack) -{ -int err; - - err =tcf_exts_validate_ex (net, tp, tb, est, &head->exts, flags, - fl_flags, extack); -if (err <0 ) -return err; - -if (tb[TCA_MATCHALL_CLASSID ]) { - head->res.classid =nla_get_u32 (tb[TCA_MATCHALL_CLASSID ]); -tcf_bind_filter (tp, &head->res, base); - } -return 0 ; -} - static int mall_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca,
@@ -185,6 +165,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, {struct cls_mall_head *head =rtnl_dereference (tp->root);struct nlattr *tb[TCA_MATCHALL_MAX +1 ]; +bool bound_to_filter = false;struct cls_mall_head *new;u32 userflags =0 ;int err;
@@ -224,11 +205,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, goto err_alloc_percpu; } - err =mall_set_parms (net, tp, new, base, tb, tca[TCA_RATE ], - flags, new->flags, extack); -if (err) + err =tcf_exts_validate_ex (net, tp, tb, tca[TCA_RATE ], + &new->exts, flags, new->flags, extack); +if (err <0 ) goto err_set_parms; +if (tb[TCA_MATCHALL_CLASSID ]) { + new->res.classid =nla_get_u32 (tb[TCA_MATCHALL_CLASSID ]); +tcf_bind_filter (tp, &new->res, base); + bound_to_filter = true; + } +if (!tc_skip_hw (new->flags)) { err =mall_replace_hw_filter (tp, new, (unsigned long )new, extack);
@@ -244,6 +231,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,return 0 ; err_replace_hw_filter: +if (bound_to_filter) +tcf_unbind_filter (tp, &new->res); err_set_parms:free_percpu (new->pf); err_alloc_percpu:
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 111/183 net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode
In reply to Greg Kroah-HartmanFrom: Victor Nogueira <[email protected]>
[ Upstream commit 9cb36faedeafb9720ac236aeae2ea57091d90a09 ]
When u32_replace_hw_knode fails, we need to undo the tcf_bind_filter operation done at u32_set_parms.
--- net/sched/cls_u32.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
net/sched/cls_u32.c +30 -11
@@ -710,8 +710,23 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { [TCA_U32_FLAGS] = { .type = NLA_U32 }, }; +static void u32_unbind_filter (struct tcf_proto *tp,struct tc_u_knode *n, +struct nlattr **tb) +{ +if (tb[TCA_U32_CLASSID ]) +tcf_unbind_filter (tp, &n->res); +} + +static void u32_bind_filter (struct tcf_proto *tp,struct tc_u_knode *n, +unsigned long base,struct nlattr **tb) +{ +if (tb[TCA_U32_CLASSID ]) { + n->res.classid =nla_get_u32 (tb[TCA_U32_CLASSID ]); +tcf_bind_filter (tp, &n->res, base); + } +} +static int u32_set_parms (struct net *net,struct tcf_proto *tp, -unsigned long base,struct tc_u_knode *n,struct nlattr **tb,struct nlattr *est,u32 flags,u32 fl_flags,struct netlink_ext_ack *extack)
@@ -758,10 +773,6 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,if (ht_old) ht_old->refcnt--; } -if (tb[TCA_U32_CLASSID ]) { - n->res.classid =nla_get_u32 (tb[TCA_U32_CLASSID ]); -tcf_bind_filter (tp, &n->res, base); - }if (ifindex >=0 ) n->ifindex = ifindex;
@@ -901,17 +912,20 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,if (!new)return -ENOMEM ; - err =u32_set_parms (net, tp, base, new, tb, - tca[TCA_RATE ], flags, new->flags, - extack); + err =u32_set_parms (net, tp, new, tb, tca[TCA_RATE ], + flags, new->flags, extack);if (err) {__u32_destroy_key (new);return err; } +u32_bind_filter (tp, new, base, tb); + err =u32_replace_hw_knode (tp, new, flags, extack);if (err) { +u32_unbind_filter (tp, new, tb); +__u32_destroy_key (new);return err; }
@@ -1072,15 +1086,18 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, }#endif - err =u32_set_parms (net, tp, base, n, tb, tca[TCA_RATE ], + err =u32_set_parms (net, tp, n, tb, tca[TCA_RATE ], flags, n->flags, extack); + +u32_bind_filter (tp, n, base, tb); +if (err ==0 ) {struct tc_u_knode __rcu **ins;struct tc_u_knode *pins; err =u32_replace_hw_knode (tp, n, flags, extack);if (err) - goto errhw; + goto errunbind;if (!tc_in_hw (n->flags)) n->flags |=TCA_CLS_FLAGS_NOT_IN_HW ;
@@ -1098,7 +1115,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,return 0 ; } -errhw: +errunbind: +u32_unbind_filter (tp, n, tb); +#ifdef CONFIG_CLS_U32_MARK free_percpu (n->pcpu_success);#endif
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 112/183 net: sched: cls_u32: Undo refcount decrement in case update failed
In reply to Greg Kroah-HartmanFrom: Victor Nogueira <[email protected]>
[ Upstream commit e8d3d78c19be0264a5692bed477c303523aead31 ]
In the case of an update, when TCA_U32_LINK is set, u32_set_parms will decrement the refcount of the ht_down (struct tc_u_hnode) pointer present in the older u32 filter which we are replacing. However, if u32_replace_hw_knode errors out, the update command fails and that ht_down pointer continues decremented. To fix that, when u32_replace_hw_knode fails, check if ht_down's refcount was decremented and undo the decrement.
--- net/sched/cls_u32.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/sched/cls_u32.c +7 -0
@@ -926,6 +926,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,if (err) {u32_unbind_filter (tp, new, tb); +if (tb[TCA_U32_LINK ]) { +struct tc_u_hnode *ht_old; + + ht_old =rtnl_dereference (n->ht_down); +if (ht_old) + ht_old->refcnt++; + }__u32_destroy_key (new);return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 113/183 net: sched: cls_bpf: Undo tcf_bind_filter in case of an error
In reply to Greg Kroah-HartmanFrom: Victor Nogueira <[email protected]>
[ Upstream commit 26a22194927e8521e304ed75c2f38d8068d55fc7 ]
If cls_bpf_offload errors out, we must also undo tcf_bind_filter that was done before the error.
Fix that by calling tcf_unbind_filter in errout_parms.
--- net/sched/cls_bpf.c | 99 +++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 52 deletions(-)
net/sched/cls_bpf.c +47 -52
@@ -404,56 +404,6 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,return 0 ; } -static int cls_bpf_set_parms (struct net *net,struct tcf_proto *tp, -struct cls_bpf_prog *prog,unsigned long base, -struct nlattr **tb,struct nlattr *est,u32 flags, -struct netlink_ext_ack *extack) -{ -bool is_bpf, is_ebpf, have_exts = false; -u32 gen_flags =0 ; -int ret; - - is_bpf = tb[TCA_BPF_OPS_LEN ] && tb[TCA_BPF_OPS ]; - is_ebpf = tb[TCA_BPF_FD ]; -if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) -return -EINVAL ; - - ret =tcf_exts_validate (net, tp, tb, est, &prog->exts, flags, - extack); -if (ret <0 ) -return ret; - -if (tb[TCA_BPF_FLAGS ]) { -u32 bpf_flags =nla_get_u32 (tb[TCA_BPF_FLAGS ]); - -if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT ) -return -EINVAL ; - - have_exts = bpf_flags &TCA_BPF_FLAG_ACT_DIRECT ; - } -if (tb[TCA_BPF_FLAGS_GEN ]) { - gen_flags =nla_get_u32 (tb[TCA_BPF_FLAGS_GEN ]); -if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || - !tc_flags_valid (gen_flags)) -return -EINVAL ; - } - - prog->exts_integrated = have_exts; - prog->gen_flags = gen_flags; - - ret = is_bpf ?cls_bpf_prog_from_ops (tb, prog) : -cls_bpf_prog_from_efd (tb, prog, gen_flags, tp); -if (ret <0 ) -return ret; - -if (tb[TCA_BPF_CLASSID ]) { - prog->res.classid =nla_get_u32 (tb[TCA_BPF_CLASSID ]); -tcf_bind_filter (tp, &prog->res, base); - } - -return 0 ; -} - static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca,
@@ -461,9 +411,12 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, struct netlink_ext_ack *extack) {struct cls_bpf_head *head =rtnl_dereference (tp->root); +bool is_bpf, is_ebpf, have_exts = false;struct cls_bpf_prog *oldprog = *arg;struct nlattr *tb[TCA_BPF_MAX +1 ]; +bool bound_to_filter = false;struct cls_bpf_prog *prog; +u32 gen_flags =0 ;int ret;if (tca[TCA_OPTIONS ] ==NULL )
@@ -502,11 +455,51 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, goto errout; prog->handle = handle; - ret =cls_bpf_set_parms (net, tp, prog, base, tb, tca[TCA_RATE ], flags, - extack); + is_bpf = tb[TCA_BPF_OPS_LEN ] && tb[TCA_BPF_OPS ]; + is_ebpf = tb[TCA_BPF_FD ]; +if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) { + ret = -EINVAL ; + goto errout_idr; + } + + ret =tcf_exts_validate (net, tp, tb, tca[TCA_RATE ], &prog->exts, + flags, extack); +if (ret <0 ) + goto errout_idr; + +if (tb[TCA_BPF_FLAGS ]) { +u32 bpf_flags =nla_get_u32 (tb[TCA_BPF_FLAGS ]); + +if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT ) { + ret = -EINVAL ; + goto errout_idr; + } + + have_exts = bpf_flags &TCA_BPF_FLAG_ACT_DIRECT ; + } +if (tb[TCA_BPF_FLAGS_GEN ]) { + gen_flags =nla_get_u32 (tb[TCA_BPF_FLAGS_GEN ]); +if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || + !tc_flags_valid (gen_flags)) { + ret = -EINVAL ; + goto errout_idr; + } + } + + prog->exts_integrated = have_exts; + prog->gen_flags = gen_flags; + + ret = is_bpf ?cls_bpf_prog_from_ops (tb, prog) : +cls_bpf_prog_from_efd (tb, prog, gen_flags, tp);if (ret <0 ) goto errout_idr; +if (tb[TCA_BPF_CLASSID ]) { + prog->res.classid =nla_get_u32 (tb[TCA_BPF_CLASSID ]); +tcf_bind_filter (tp, &prog->res, base); + bound_to_filter = true; + } + ret =cls_bpf_offload (tp, prog, oldprog, extack);if (ret) goto errout_parms;
@@ -528,6 +521,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,return 0 ; errout_parms: +if (bound_to_filter) +tcf_unbind_filter (tp, &prog->res);cls_bpf_free_parms (prog); errout_idr:if (!oldprog)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 114/183 net: dsa: microchip: ksz8: Separate static MAC table operations for code reuse
In reply to Greg Kroah-HartmanFrom: Oleksij Rempel <[email protected]>
[ Upstream commit f6636ff69ec4f2c94a5ee1d032b21cfe1e0a5678 ]
Move static MAC table operations to separate functions in order to reuse the code for add/del_fdb. This is needed to address kernel warnings caused by the lack of fdb add function support in the current driver.
Stable-dep-of: 4bdf79d686b4 ("net: dsa: microchip: correct KSZ8795 static MAC table access")
--- drivers/net/dsa/microchip/ksz8795.c | 34 +++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-)
drivers/net/dsa/microchip/ksz8795.c +23 -11
@@ -926,8 +926,8 @@ int ksz8_fdb_dump(struct ksz_device *dev, int port,return ret; } -int ksz8_mdb_add (struct ksz_device *dev,int port, -const struct switchdev_obj_port_mdb *mdb,struct dsa_db db) +static int ksz8_add_sta_mac (struct ksz_device *dev,int port, +const unsigned char *addr,u16 vid) {struct alu_struct alu;int index;
@@ -937,8 +937,8 @@ int ksz8_mdb_add(struct ksz_device *dev, int port,for (index =0 ; index < dev->info->num_statics; index++) {if (!ksz8_r_sta_mac_table (dev, index, &alu)) {/* Found one already in static MAC table. */ -if (!memcmp (alu.mac, mdb->addr,ETH_ALEN ) && - alu.fid == mdb->vid) +if (!memcmp (alu.mac, addr,ETH_ALEN ) && + alu.fid == vid)break ;/* Remember the first empty entry. */ }else if (!empty) {
@@ -954,23 +954,23 @@ int ksz8_mdb_add(struct ksz_device *dev, int port,if (index == dev->info->num_statics) { index = empty -1 ;memset (&alu,0 ,sizeof (alu)); -memcpy (alu.mac, mdb->addr,ETH_ALEN ); +memcpy (alu.mac, addr,ETH_ALEN ); alu.is_static = true; } alu.port_forward |=BIT (port); -if (mdb->vid) { +if (vid) { alu.is_use_fid = true;/* Need a way to map VID to FID. */ - alu.fid = mdb->vid; + alu.fid = vid; }ksz8_w_sta_mac_table (dev, index, &alu);return 0 ; } -int ksz8_mdb_del (struct ksz_device *dev,int port, -const struct switchdev_obj_port_mdb *mdb,struct dsa_db db) +static int ksz8_del_sta_mac (struct ksz_device *dev,int port, +const unsigned char *addr,u16 vid) {struct alu_struct alu;int index;
@@ -978,8 +978,8 @@ int ksz8_mdb_del(struct ksz_device *dev, int port,for (index =0 ; index < dev->info->num_statics; index++) {if (!ksz8_r_sta_mac_table (dev, index, &alu)) {/* Found one already in static MAC table. */ -if (!memcmp (alu.mac, mdb->addr,ETH_ALEN ) && - alu.fid == mdb->vid) +if (!memcmp (alu.mac, addr,ETH_ALEN ) && + alu.fid == vid)break ; } }
@@ -998,6 +998,18 @@ int ksz8_mdb_del(struct ksz_device *dev, int port,return 0 ; } +int ksz8_mdb_add (struct ksz_device *dev,int port, +const struct switchdev_obj_port_mdb *mdb,struct dsa_db db) +{ +return ksz8_add_sta_mac (dev, port, mdb->addr, mdb->vid); +} + +int ksz8_mdb_del (struct ksz_device *dev,int port, +const struct switchdev_obj_port_mdb *mdb,struct dsa_db db) +{ +return ksz8_del_sta_mac (dev, port, mdb->addr, mdb->vid); +} +int ksz8_port_vlan_filtering (struct ksz_device *dev,int port,bool flag,struct netlink_ext_ack *extack) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 115/183 net: dsa: microchip: ksz8: Make ksz8_r_sta_mac_table() static
In reply to Greg Kroah-HartmanFrom: Oleksij Rempel <[email protected]>
[ Upstream commit b5751cdd7dbe618a03951bdd4c982a71ba448b1b ]
As ksz8_r_sta_mac_table() is only used within ksz8795.c, there is no need to export it. Make the function static for better encapsulation.
Stable-dep-of: 4bdf79d686b4 ("net: dsa: microchip: correct KSZ8795 static MAC table access")
--- drivers/net/dsa/microchip/ksz8.h | 2 -- drivers/net/dsa/microchip/ksz8795.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-)
drivers/net/dsa/microchip/ksz8.h +0 -2
@@ -21,8 +21,6 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);int ksz8_w_phy (struct ksz_device *dev,u16 phy,u16 reg,u16 val);int ksz8_r_dyn_mac_table (struct ksz_device *dev,u16 addr,u8 *mac_addr,u8 *fid,u8 *src_port,u8 *timestamp,u16 *entries); -int ksz8_r_sta_mac_table (struct ksz_device *dev,u16 addr, -struct alu_struct *alu);void ksz8_w_sta_mac_table (struct ksz_device *dev,u16 addr,struct alu_struct *alu);void ksz8_r_mib_cnt (struct ksz_device *dev,int port,u16 addr,u64 *cnt);
drivers/net/dsa/microchip/ksz8795.c +2 -2
@@ -406,8 +406,8 @@ int ksz8_r_dyn_mac_table(struct ksz_device *dev, u16 addr, u8 *mac_addr,return rc; } -int ksz8_r_sta_mac_table (struct ksz_device *dev,u16 addr, -struct alu_struct *alu) +static int ksz8_r_sta_mac_table (struct ksz_device *dev,u16 addr, +struct alu_struct *alu) {u32 data_hi, data_lo;const u8 *shifts;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 116/183 net: dsa: microchip: ksz8_r_sta_mac_table(): Avoid using error code for empty entries
In reply to Greg Kroah-HartmanFrom: Oleksij Rempel <[email protected]>
[ Upstream commit 559901b46810e82ba5321a5e789f994b65d3bc3d ]
Prepare for the next patch by ensuring that ksz8_r_sta_mac_table() does not use error codes for empty entries. This change will enable better handling of read/write errors in the upcoming patch.
Stable-dep-of: 4bdf79d686b4 ("net: dsa: microchip: correct KSZ8795 static MAC table access")
--- drivers/net/dsa/microchip/ksz8795.c | 87 +++++++++++++++++------------ 1 file changed, 50 insertions(+), 37 deletions(-)
drivers/net/dsa/microchip/ksz8795.c +50 -37
@@ -407,7 +407,7 @@ int ksz8_r_dyn_mac_table(struct ksz_device *dev, u16 addr, u8 *mac_addr, }static int ksz8_r_sta_mac_table (struct ksz_device *dev,u16 addr, -struct alu_struct *alu) +struct alu_struct *alu,bool *valid) {u32 data_hi, data_lo;const u8 *shifts;
@@ -420,28 +420,32 @@ static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr,ksz8_r_table (dev,TABLE_STATIC_MAC , addr, &data); data_hi = data >>32 ; data_lo = (u32 )data; -if (data_hi & (masks[STATIC_MAC_TABLE_VALID ] | - masks[STATIC_MAC_TABLE_OVERRIDE ])) { - alu->mac[5 ] = (u8 )data_lo; - alu->mac[4 ] = (u8)(data_lo >>8 ); - alu->mac[3 ] = (u8)(data_lo >>16 ); - alu->mac[2 ] = (u8)(data_lo >>24 ); - alu->mac[1 ] = (u8 )data_hi; - alu->mac[0 ] = (u8)(data_hi >>8 ); - alu->port_forward = - (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS ]) >> - shifts[STATIC_MAC_FWD_PORTS ]; - alu->is_override = - (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE ]) ?1 :0 ; - data_hi >>=1 ; - alu->is_static = true; - alu->is_use_fid = - (data_hi & masks[STATIC_MAC_TABLE_USE_FID ]) ?1 :0 ; - alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID ]) >> - shifts[STATIC_MAC_FID ]; + +if (!(data_hi & (masks[STATIC_MAC_TABLE_VALID ] | + masks[STATIC_MAC_TABLE_OVERRIDE ]))) { + *valid = false;return 0 ; } -return -ENXIO ; + + alu->mac[5 ] = (u8 )data_lo; + alu->mac[4 ] = (u8)(data_lo >>8 ); + alu->mac[3 ] = (u8)(data_lo >>16 ); + alu->mac[2 ] = (u8)(data_lo >>24 ); + alu->mac[1 ] = (u8 )data_hi; + alu->mac[0 ] = (u8)(data_hi >>8 ); + alu->port_forward = + (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS ]) >> + shifts[STATIC_MAC_FWD_PORTS ]; + alu->is_override = (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE ]) ?1 :0 ; + data_hi >>=1 ; + alu->is_static = true; + alu->is_use_fid = (data_hi & masks[STATIC_MAC_TABLE_USE_FID ]) ?1 :0 ; + alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID ]) >> + shifts[STATIC_MAC_FID ]; + + *valid = true; + +return 0 ; } void ksz8_w_sta_mac_table(struct ksz_device *dev, u16 addr,
@@ -930,20 +934,25 @@ static int ksz8_add_sta_mac(struct ksz_device *dev, int port, const unsigned char *addr, u16 vid) {struct alu_struct alu; -int index; +int index, ret;int empty =0 ; alu.port_forward =0 ;for (index =0 ; index < dev->info->num_statics; index++) { -if (!ksz8_r_sta_mac_table (dev, index, &alu)) { -/* Found one already in static MAC table. */ -if (!memcmp (alu.mac, addr,ETH_ALEN ) && - alu.fid == vid) -break ; -/* Remember the first empty entry. */ - }else if (!empty) { - empty = index +1 ; +bool valid; + + ret =ksz8_r_sta_mac_table (dev, index, &alu, &valid); +if (ret) +return ret; +if (!valid) { +/* Remember the first empty entry. */ +if (!empty) + empty = index +1 ; +continue ; } + +if (!memcmp (alu.mac, addr,ETH_ALEN ) && alu.fid == vid) +break ; }/* no available entry */
@@ -973,15 +982,19 @@ static int ksz8_del_sta_mac(struct ksz_device *dev, int port, const unsigned char *addr, u16 vid) {struct alu_struct alu; -int index; +int index, ret;for (index =0 ; index < dev->info->num_statics; index++) { -if (!ksz8_r_sta_mac_table (dev, index, &alu)) { -/* Found one already in static MAC table. */ -if (!memcmp (alu.mac, addr,ETH_ALEN ) && - alu.fid == vid) -break ; - } +bool valid; + + ret =ksz8_r_sta_mac_table (dev, index, &alu, &valid); +if (ret) +return ret; +if (!valid) +continue ; + +if (!memcmp (alu.mac, addr,ETH_ALEN ) && alu.fid == vid) +break ; }/* no available entry */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 117/183 net: dsa: microchip: correct KSZ8795 static MAC table access
In reply to Greg Kroah-HartmanFrom: Tristram Ha <[email protected]>
[ Upstream commit 4bdf79d686b49ac49373b36466acfb93972c7d7c ]
The KSZ8795 driver code was modified to use on KSZ8863/73, which has different register definitions. Some of the new KSZ8795 register information are wrong compared to previous code.
KSZ8795 also behaves differently in that the STATIC_MAC_TABLE_USE_FID and STATIC_MAC_TABLE_FID bits are off by 1 when doing MAC table reading than writing. To compensate that a special code was added to shift the register value by 1 before applying those bits. This is wrong when the code is running on KSZ8863, so this special code is only executed when KSZ8795 is detected.
--- drivers/net/dsa/microchip/ksz8795.c | 8 +++++++- drivers/net/dsa/microchip/ksz_common.c | 8 ++++---- drivers/net/dsa/microchip/ksz_common.h | 7 +++++++ 3 files changed, 18 insertions(+), 5 deletions(-)
drivers/net/dsa/microchip/ksz8795.c +7 -1
@@ -437,7 +437,13 @@ static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr, (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS ]) >> shifts[STATIC_MAC_FWD_PORTS ]; alu->is_override = (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE ]) ?1 :0 ; - data_hi >>=1 ; + +/* KSZ8795 family switches have STATIC_MAC_TABLE_USE_FID and +* STATIC_MAC_TABLE_FID definitions off by 1 when doing read on the +* static MAC table compared to doing write. +*/ +if (ksz_is_ksz87xx (dev)) + data_hi >>=1 ; alu->is_static = true; alu->is_use_fid = (data_hi & masks[STATIC_MAC_TABLE_USE_FID ]) ?1 :0 ; alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID]) >>
drivers/net/dsa/microchip/ksz_common.c +4 -4
@@ -286,13 +286,13 @@ static const u32 ksz8795_masks[] = { [STATIC_MAC_TABLE_VALID] = BIT(21), [STATIC_MAC_TABLE_USE_FID] = BIT(23), [STATIC_MAC_TABLE_FID] = GENMASK(30, 24), - [STATIC_MAC_TABLE_OVERRIDE] = BIT(26), - [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(24, 20), + [STATIC_MAC_TABLE_OVERRIDE] = BIT(22), + [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(20, 16), [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0), - [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(8), + [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7), [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7), [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29), - [DYNAMIC_MAC_TABLE_FID] = GENMASK(26, 20), + [DYNAMIC_MAC_TABLE_FID] = GENMASK(22, 16), [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24), [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27), [P_MII_TX_FLOW_CTRL] = BIT(5),
drivers/net/dsa/microchip/ksz_common.h +7 -0
@@ -512,6 +512,13 @@ static inline void ksz_regmap_unlock(void *__mtx)mutex_unlock (mtx); } +static inline bool ksz_is_ksz87xx (struct ksz_device *dev) +{ +return dev->chip_id ==KSZ8795_CHIP_ID || + dev->chip_id ==KSZ8794_CHIP_ID || + dev->chip_id ==KSZ8765_CHIP_ID ; +} +static inline bool ksz_is_ksz88x3 (struct ksz_device *dev) {return dev->chip_id ==KSZ8830_CHIP_ID ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 118/183 iavf: Fix use-after-free in free_netdev
In reply to Greg Kroah-HartmanFrom: Ding Hui <[email protected]>
[ Upstream commit 5f4fa1672d98fe99d2297b03add35346f1685d6b ]
We do netif_napi_add() for all allocated q_vectors[], but potentially do netif_napi_del() for part of them, then kfree q_vectors and leave invalid pointers at dev->napi_list.
Reproducer:
[root@host ~]# cat repro.sh
#!/bin/bash
pf_dbsf="0000:41:00.0"
vf0_dbsf="0000:41:02.0"
g_pids=()
function do_set_numvf()
{
echo 2 >/sys/bus/pci/devices/${pf_dbsf}/sriov_numvfs
sleep $((RANDOM%3+1))
echo 0 >/sys/bus/pci/devices/${pf_dbsf}/sriov_numvfs
sleep $((RANDOM%3+1))
}
function do_set_channel()
{
local nic=$(ls -1 --indicator-style=none /sys/bus/pci/devices/${vf0_dbsf}/net/)
[ -z "$nic" ] && { sleep $((RANDOM%3)) ; return 1; }
ifconfig $nic 192.168.18.5 netmask 255.255.255.0
ifconfig $nic up
ethtool -L $nic combined 1
ethtool -L $nic combined 4
sleep $((RANDOM%3))
}
function on_exit()
{
local pid
for pid in "${g_pids[@]}"; do
kill -0 "$pid" &>/dev/null && kill "$pid" &>/dev/null
done
g_pids=()
} trap "on_exit; exit" EXIT
while :; do do_set_numvf ; done &
g_pids+=($!)
while :; do do_set_channel ; done &
g_pids+=($!)
wait
Result:
[ 4093.900222] ==================================================================
[ 4093.900230] BUG: KASAN: use-after-free in free_netdev+0x308/0x390
[ 4093.900232] Read of size 8 at addr ffff88b4dc145640 by task repro.sh/6699
[ 4093.900233]
[ 4093.900236] CPU: 10 PID: 6699 Comm: repro.sh Kdump: loaded Tainted: G O --------- -t - 4.18.0 #1
[ 4093.900238] Hardware name: Powerleader PR2008AL/H12DSi-N6, BIOS 2.0 04/09/2021
[ 4093.900239] Call Trace:
[ 4093.900244] dump_stack+0x71/0xab
[ 4093.900249] print_address_description+0x6b/0x290
[ 4093.900251] ? free_netdev+0x308/0x390
[ 4093.900252] kasan_report+0x14a/0x2b0
[ 4093.900254] free_netdev+0x308/0x390
[ 4093.900261] iavf_remove+0x825/0xd20 [iavf]
[ 4093.900265] pci_device_remove+0xa8/0x1f0
[ 4093.900268] device_release_driver_internal+0x1c6/0x460
[ 4093.900271] pci_stop_bus_device+0x101/0x150
[ 4093.900273] pci_stop_and_remove_bus_device+0xe/0x20
[ 4093.900275] pci_iov_remove_virtfn+0x187/0x420
[ 4093.900277] ? pci_iov_add_virtfn+0xe10/0xe10
[ 4093.900278] ? pci_get_subsys+0x90/0x90
[ 4093.900280] sriov_disable+0xed/0x3e0
[ 4093.900282] ? bus_find_device+0x12d/0x1a0
[ 4093.900290] i40e_free_vfs+0x754/0x1210 [i40e]
[ 4093.900298] ? i40e_reset_all_vfs+0x880/0x880 [i40e]
[ 4093.900299] ? pci_get_device+0x7c/0x90
[ 4093.900300] ? pci_get_subsys+0x90/0x90
[ 4093.900306] ? pci_vfs_assigned.part.7+0x144/0x210
[ 4093.900309] ? __mutex_lock_slowpath+0x10/0x10
[ 4093.900315] i40e_pci_sriov_configure+0x1fa/0x2e0 [i40e]
[ 4093.900318] sriov_numvfs_store+0x214/0x290
[ 4093.900320] ? sriov_totalvfs_show+0x30/0x30
[ 4093.900321] ? __mutex_lock_slowpath+0x10/0x10
[ 4093.900323] ? __check_object_size+0x15a/0x350
[ 4093.900326] kernfs_fop_write+0x280/0x3f0
[ 4093.900329] vfs_write+0x145/0x440
[ 4093.900330] ksys_write+0xab/0x160
[ 4093.900332] ? __ia32_sys_read+0xb0/0xb0
[ 4093.900334] ? fput_many+0x1a/0x120
[ 4093.900335] ? filp_close+0xf0/0x130
[ 4093.900338] do_syscall_64+0xa0/0x370
[ 4093.900339] ? page_fault+0x8/0x30
[ 4093.900341] entry_SYSCALL_64_after_hwframe+0x65/0xca
[ 4093.900357] RIP: 0033:0x7f16ad4d22c0
[ 4093.900359] Code: 73 01 c3 48 8b 0d d8 cb 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 89 24 2d 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 fe dd 01 00 48 89 04 24
[ 4093.900360] RSP: 002b:00007ffd6491b7f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 4093.900362] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f16ad4d22c0
[ 4093.900363] RDX: 0000000000000002 RSI: 0000000001a41408 RDI: 0000000000000001
[ 4093.900364] RBP: 0000000001a41408 R08: 00007f16ad7a1780 R09: 00007f16ae1f2700
[ 4093.900364] R10: 0000000000000001 R11: 0000000000000246 R12: 0000000000000002
[ 4093.900365] R13: 0000000000000001 R14: 00007f16ad7a0620 R15: 0000000000000001
[ 4093.900367]
[ 4093.900368] Allocated by task 820:
[ 4093.900371] kasan_kmalloc+0xa6/0xd0
[ 4093.900373] __kmalloc+0xfb/0x200
[ 4093.900376] iavf_init_interrupt_scheme+0x63b/0x1320 [iavf]
[ 4093.900380] iavf_watchdog_task+0x3d51/0x52c0 [iavf]
[ 4093.900382] process_one_work+0x56a/0x11f0
[ 4093.900383] worker_thread+0x8f/0xf40
[ 4093.900384] kthread+0x2a0/0x390
[ 4093.900385] ret_from_fork+0x1f/0x40
[ 4093.900387] 0xffffffffffffffff
[ 4093.900387]
[ 4093.900388] Freed by task 6699:
[ 4093.900390] __kasan_slab_free+0x137/0x190
[ 4093.900391] kfree+0x8b/0x1b0
[ 4093.900394] iavf_free_q_vectors+0x11d/0x1a0 [iavf]
[ 4093.900397] iavf_remove+0x35a/0xd20 [iavf]
[ 4093.900399] pci_device_remove+0xa8/0x1f0
[ 4093.900400] device_release_driver_internal+0x1c6/0x460
[ 4093.900401] pci_stop_bus_device+0x101/0x150
[ 4093.900402] pci_stop_and_remove_bus_device+0xe/0x20
[ 4093.900403] pci_iov_remove_virtfn+0x187/0x420
[ 4093.900404] sriov_disable+0xed/0x3e0
[ 4093.900409] i40e_free_vfs+0x754/0x1210 [i40e]
[ 4093.900415] i40e_pci_sriov_configure+0x1fa/0x2e0 [i40e]
[ 4093.900416] sriov_numvfs_store+0x214/0x290
[ 4093.900417] kernfs_fop_write+0x280/0x3f0
[ 4093.900418] vfs_write+0x145/0x440
[ 4093.900419] ksys_write+0xab/0x160
[ 4093.900420] do_syscall_64+0xa0/0x370
[ 4093.900421] entry_SYSCALL_64_after_hwframe+0x65/0xca
[ 4093.900422] 0xffffffffffffffff
[ 4093.900422]
[ 4093.900424] The buggy address belongs to the object at ffff88b4dc144200
which belongs to the cache kmalloc-8k of size 8192
[ 4093.900425] The buggy address is located 5184 bytes inside of
8192-byte region [ffff88b4dc144200, ffff88b4dc146200)
[ 4093.900425] The buggy address belongs to the page:
[ 4093.900427] page:ffffea00d3705000 refcount:1 mapcount:0 mapping:ffff88bf04415c80 index:0x0 compound_mapcount: 0
[ 4093.900430] flags: 0x10000000008100(slab|head)
[ 4093.900433] raw: 0010000000008100 dead000000000100 dead000000000200 ffff88bf04415c80
[ 4093.900434] raw: 0000000000000000 0000000000030003 00000001ffffffff 0000000000000000
[ 4093.900434] page dumped because: kasan: bad access detected
[ 4093.900435]
[ 4093.900435] Memory state around the buggy address:
[ 4093.900436] ffff88b4dc145500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 4093.900437] ffff88b4dc145580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 4093.900438] >ffff88b4dc145600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 4093.900438] ^
[ 4093.900439] ffff88b4dc145680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 4093.900440] ffff88b4dc145700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 4093.900440] ==================================================================Although the patch #2 (of 2) can avoid the issue triggered by this repro.sh, there still are other potential risks that if num_active_queues is changed to less than allocated q_vectors[] by unexpected, the mismatched netif_napi_add/del() can also cause UAF.
Since we actually call netif_napi_add() for all allocated q_vectors unconditionally in iavf_alloc_q_vectors(), so we should fix it by letting netif_napi_del() match to netif_napi_add().
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +1 -4
@@ -1840,19 +1840,16 @@ static int iavf_alloc_q_vectors(struct iavf_adapter *adapter)static void iavf_free_q_vectors (struct iavf_adapter *adapter) {int q_idx, num_q_vectors; -int napi_vectors;if (!adapter->q_vectors)return ; num_q_vectors = adapter->num_msix_vectors -NONQ_VECS ; - napi_vectors = adapter->num_active_queues;for (q_idx =0 ; q_idx < num_q_vectors; q_idx++) {struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx]; -if (q_idx < napi_vectors) -netif_napi_del (&q_vector->napi); +netif_napi_del (&q_vector->napi); }kfree (adapter->q_vectors); adapter->q_vectors =NULL ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 119/183 iavf: Fix out-of-bounds when setting channels on remove
In reply to Greg Kroah-HartmanFrom: Ding Hui <[email protected]>
[ Upstream commit 7c4bced3caa749ce468b0c5de711c98476b23a52 ]
If we set channels greater during iavf_remove(), and waiting reset done would be timeout, then returned with error but changed num_active_queues directly, that will lead to OOB like the following logs. Because the num_active_queues is greater than tx/rx_rings[] allocated actually.
Reproducer:
[root@host ~]# cat repro.sh
#!/bin/bash
pf_dbsf="0000:41:00.0"
vf0_dbsf="0000:41:02.0"
g_pids=()
function do_set_numvf()
{
echo 2 >/sys/bus/pci/devices/${pf_dbsf}/sriov_numvfs
sleep $((RANDOM%3+1))
echo 0 >/sys/bus/pci/devices/${pf_dbsf}/sriov_numvfs
sleep $((RANDOM%3+1))
}
function do_set_channel()
{
local nic=$(ls -1 --indicator-style=none /sys/bus/pci/devices/${vf0_dbsf}/net/)
[ -z "$nic" ] && { sleep $((RANDOM%3)) ; return 1; }
ifconfig $nic 192.168.18.5 netmask 255.255.255.0
ifconfig $nic up
ethtool -L $nic combined 1
ethtool -L $nic combined 4
sleep $((RANDOM%3))
}
function on_exit()
{
local pid
for pid in "${g_pids[@]}"; do
kill -0 "$pid" &>/dev/null && kill "$pid" &>/dev/null
done
g_pids=()
} trap "on_exit; exit" EXIT
while :; do do_set_numvf ; done &
g_pids+=($!)
while :; do do_set_channel ; done &
g_pids+=($!)
wait
Result:
[ 3506.152887] iavf 0000:41:02.0: Removing device [ 3510.400799] ================================================================== [ 3510.400820] BUG: KASAN: slab-out-of-bounds in iavf_free_all_tx_resources+0x156/0x160 [iavf] [ 3510.400823] Read of size 8 at addr ffff88b6f9311008 by task repro.sh/55536 [ 3510.400823] [ 3510.400830] CPU: 101 PID: 55536 Comm: repro.sh Kdump: loaded Tainted: G O --------- -t - 4.18.0 #1 [ 3510.400832] Hardware name: Powerleader PR2008AL/H12DSi-N6, BIOS 2.0 04/09/2021 [ 3510.400835] Call Trace: [ 3510.400851] dump_stack+0x71/0xab [ 3510.400860] print_address_description+0x6b/0x290 [ 3510.400865] ? iavf_free_all_tx_resources+0x156/0x160 [iavf] [ 3510.400868] kasan_report+0x14a/0x2b0 [ 3510.400873] iavf_free_all_tx_resources+0x156/0x160 [iavf] [ 3510.400880] iavf_remove+0x2b6/0xc70 [iavf] [ 3510.400884] ? iavf_free_all_rx_resources+0x160/0x160 [iavf] [ 3510.400891] ? wait_woken+0x1d0/0x1d0 [ 3510.400895] ? notifier_call_chain+0xc1/0x130 [ 3510.400903] pci_device_remove+0xa8/0x1f0 [ 3510.400910] device_release_driver_internal+0x1c6/0x460 [ 3510.400916] pci_stop_bus_device+0x101/0x150 [ 3510.400919] pci_stop_and_remove_bus_device+0xe/0x20 [ 3510.400924] pci_iov_remove_virtfn+0x187/0x420 [ 3510.400927] ? pci_iov_add_virtfn+0xe10/0xe10 [ 3510.400929] ? pci_get_subsys+0x90/0x90 [ 3510.400932] sriov_disable+0xed/0x3e0 [ 3510.400936] ? bus_find_device+0x12d/0x1a0 [ 3510.400953] i40e_free_vfs+0x754/0x1210 [i40e] [ 3510.400966] ? i40e_reset_all_vfs+0x880/0x880 [i40e] [ 3510.400968] ? pci_get_device+0x7c/0x90 [ 3510.400970] ? pci_get_subsys+0x90/0x90 [ 3510.400982] ? pci_vfs_assigned.part.7+0x144/0x210 [ 3510.400987] ? __mutex_lock_slowpath+0x10/0x10 [ 3510.400996] i40e_pci_sriov_configure+0x1fa/0x2e0 [i40e] [ 3510.401001] sriov_numvfs_store+0x214/0x290 [ 3510.401005] ? sriov_totalvfs_show+0x30/0x30 [ 3510.401007] ? __mutex_lock_slowpath+0x10/0x10 [ 3510.401011] ? __check_object_size+0x15a/0x350 [ 3510.401018] kernfs_fop_write+0x280/0x3f0 [ 3510.401022] vfs_write+0x145/0x440 [ 3510.401025] ksys_write+0xab/0x160 [ 3510.401028] ? __ia32_sys_read+0xb0/0xb0 [ 3510.401031] ? fput_many+0x1a/0x120 [ 3510.401032] ? filp_close+0xf0/0x130 [ 3510.401038] do_syscall_64+0xa0/0x370 [ 3510.401041] ? page_fault+0x8/0x30 [ 3510.401043] entry_SYSCALL_64_after_hwframe+0x65/0xca [ 3510.401073] RIP: 0033:0x7f3a9bb842c0 [ 3510.401079] Code: 73 01 c3 48 8b 0d d8 cb 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 89 24 2d 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 fe dd 01 00 48 89 04 24 [ 3510.401080] RSP: 002b:00007ffc05f1fe18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 3510.401083] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f3a9bb842c0 [ 3510.401085] RDX: 0000000000000002 RSI: 0000000002327408 RDI: 0000000000000001 [ 3510.401086] RBP: 0000000002327408 R08: 00007f3a9be53780 R09: 00007f3a9c8a4700 [ 3510.401086] R10: 0000000000000001 R11: 0000000000000246 R12: 0000000000000002 [ 3510.401087] R13: 0000000000000001 R14: 00007f3a9be52620 R15: 0000000000000001 [ 3510.401090] [ 3510.401093] Allocated by task 76795: [ 3510.401098] kasan_kmalloc+0xa6/0xd0 [ 3510.401099] __kmalloc+0xfb/0x200 [ 3510.401104] iavf_init_interrupt_scheme+0x26f/0x1310 [iavf] [ 3510.401108] iavf_watchdog_task+0x1d58/0x4050 [iavf] [ 3510.401114] process_one_work+0x56a/0x11f0 [ 3510.401115] worker_thread+0x8f/0xf40 [ 3510.401117] kthread+0x2a0/0x390 [ 3510.401119] ret_from_fork+0x1f/0x40 [ 3510.401122] 0xffffffffffffffff [ 3510.401123]
In timeout handling, we should keep the original num_active_queues and reset num_req_queues to 0.
--- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_ethtool.c +1 -1
@@ -1863,7 +1863,7 @@ static int iavf_set_channels(struct net_device *netdev, }if (i ==IAVF_RESET_WAIT_COMPLETE_COUNT ) { adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED ; - adapter->num_active_queues = num_req; + adapter->num_req_queues =0 ;return -EOPNOTSUPP ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 120/183 iavf: use internal state to free traffic IRQs
In reply to Greg Kroah-HartmanFrom: Ahmed Zaki <[email protected]>
[ Upstream commit a77ed5c5b768e9649be240a2d864e5cd9c6a2015 ]
If the system tries to close the netdev while iavf_reset_task() is running, __LINK_STATE_START will be cleared and netif_running() will return false in iavf_reinit_interrupt_scheme(). This will result in iavf_free_traffic_irqs() not being called and a leak as follows:
[7632.489326] remove_proc_entry: removing non-empty directory 'irq/999', leaking at least 'iavf-enp24s0f0v0-TxRx-0'
[7632.490214] WARNING: CPU: 0 PID: 10 at fs/proc/generic.c:718 remove_proc_entry+0x19b/0x1b0is shown when pci_disable_msix() is later called. Fix by using the internal adapter state. The traffic IRQs will always exist if state == __IAVF_RUNNING.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +4 -3
@@ -1941,15 +1941,16 @@ static void iavf_free_rss(struct iavf_adapter *adapter)/** * iavf_reinit_interrupt_scheme - Reallocate queues and vectors * @adapter: board private structure +* @running: true if adapter->state == __IAVF_RUNNING * * Returns 0 on success, negative on failure **/ -static int iavf_reinit_interrupt_scheme (struct iavf_adapter *adapter) +static int iavf_reinit_interrupt_scheme (struct iavf_adapter *adapter,bool running) {struct net_device *netdev = adapter->netdev;int err; -if (netif_running (netdev)) +if (running)iavf_free_traffic_irqs (adapter);iavf_free_misc_irq (adapter);iavf_reset_interrupt_capability (adapter);
@@ -3056,7 +3057,7 @@ static void iavf_reset_task(struct work_struct *work)if ((adapter->flags &IAVF_FLAG_REINIT_MSIX_NEEDED ) || (adapter->flags &IAVF_FLAG_REINIT_ITR_NEEDED )) { - err =iavf_reinit_interrupt_scheme (adapter); + err =iavf_reinit_interrupt_scheme (adapter, running);if (err) goto reset_err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 121/183 iavf: Move netdev_update_features() into watchdog task
In reply to Greg Kroah-HartmanFrom: Marcin Szycik <[email protected]>
[ Upstream commit 7598f4b40bd60e4a4280de645eb2893eea80b59d ]
Remove netdev_update_features() from iavf_adminq_task(), as it can cause deadlocks due to needing rtnl_lock. Instead use the IAVF_FLAG_SETUP_NETDEV_FEATURES flag to indicate that netdev features need to be updated in the watchdog task. iavf_set_vlan_offload_features() and iavf_set_queue_vlan_tag_loc() can be called directly from iavf_virtchnl_completion().
Stable-dep-of: c2ed2403f12c ("iavf: Wait for reset in callbacks which trigger it")
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 27 +++++++------------ .../net/ethernet/intel/iavf/iavf_virtchnl.c | 8 ++++++ 2 files changed, 17 insertions(+), 18 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +9 -18
@@ -2689,6 +2689,15 @@ static void iavf_watchdog_task(struct work_struct *work) goto restart_watchdog; } +if ((adapter->flags &IAVF_FLAG_SETUP_NETDEV_FEATURES ) && + adapter->netdev_registered && + !test_bit (__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && +rtnl_trylock ()) { +netdev_update_features (adapter->netdev); +rtnl_unlock (); + adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES ; + } +if (adapter->flags &IAVF_FLAG_PF_COMMS_FAILED )iavf_change_state (adapter, __IAVF_COMM_FAILED);
@@ -3228,24 +3237,6 @@ static void iavf_adminq_task(struct work_struct *work) }while (pending);mutex_unlock (&adapter->crit_lock); -if ((adapter->flags &IAVF_FLAG_SETUP_NETDEV_FEATURES )) { -if (adapter->netdev_registered || - !test_bit (__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) { -struct net_device *netdev = adapter->netdev; - -rtnl_lock (); -netdev_update_features (netdev); -rtnl_unlock (); -/* Request VLAN offload settings */ -if (VLAN_V2_ALLOWED (adapter)) -iavf_set_vlan_offload_features - (adapter,0 , netdev->features); - -iavf_set_queue_vlan_tag_loc (adapter); - } - - adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES ; - }if ((adapter->flags & (IAVF_FLAG_RESET_PENDING |IAVF_FLAG_RESET_NEEDED )) || adapter->state == __IAVF_RESETTING)
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +8 -0
@@ -2237,6 +2237,14 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,iavf_process_config (adapter); adapter->flags |=IAVF_FLAG_SETUP_NETDEV_FEATURES ; + +/* Request VLAN offload settings */ +if (VLAN_V2_ALLOWED (adapter)) +iavf_set_vlan_offload_features (adapter,0 , + netdev->features); + +iavf_set_queue_vlan_tag_loc (adapter); + was_mac_changed = !ether_addr_equal (netdev->dev_addr, adapter->hw.mac.addr);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 122/183 iavf: send VLAN offloading caps once after VFR
In reply to Greg Kroah-HartmanFrom: Ahmed Zaki <[email protected]>
[ Upstream commit 7dcbdf29282fbcdb646dc785e8a57ed2c2fec8ba ]
When the user disables rxvlan offloading and then changes the number of channels, all VLAN ports are unable to receive traffic.
Changing the number of channels triggers a VFR reset. During re-init, when VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS is received, we do:
1 - set the IAVF_FLAG_SETUP_NETDEV_FEATURES flag
2 - call
iavf_set_vlan_offload_features(adapter, 0, netdev->features);
The second step sends to the PF the __default__ features, in this case aq_required |= IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING
While the first step forces the watchdog task to call netdev_update_features() -> iavf_set_features() -> iavf_set_vlan_offload_features(adapter, netdev->features, features). Since the user disabled the "rxvlan", this sets:aq_required |= IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING
When we start processing the AQ commands, both flags are enabled. Since we process DISABLE_XTAG first then ENABLE_XTAG, this results in the PF enabling the rxvlan offload. This breaks all communications on the VLAN net devices.
Fix by removing the call to iavf_set_vlan_offload_features() (second step). Calling netdev_update_features() from watchdog task is enough for both init and reset paths.
Stable-dep-of: c2ed2403f12c ("iavf: Wait for reset in callbacks which trigger it")
--- drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +0 -5
@@ -2238,11 +2238,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,iavf_process_config (adapter); adapter->flags |=IAVF_FLAG_SETUP_NETDEV_FEATURES ; -/* Request VLAN offload settings */ -if (VLAN_V2_ALLOWED (adapter)) -iavf_set_vlan_offload_features (adapter,0 , - netdev->features); -iavf_set_queue_vlan_tag_loc (adapter); was_mac_changed = !ether_addr_equal(netdev->dev_addr,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 123/183 iavf: make functions static where possible
In reply to Greg Kroah-HartmanFrom: Przemek Kitszel <[email protected]>
[ Upstream commit a4aadf0f5905661cd25c366b96cc1c840f05b756 ]
Make all possible functions static.
Move iavf_force_wb() up to avoid forward declaration.
Stable-dep-of: c2ed2403f12c ("iavf: Wait for reset in callbacks which trigger it")
--- drivers/net/ethernet/intel/iavf/iavf.h | 10 ----- drivers/net/ethernet/intel/iavf/iavf_main.c | 14 +++---- drivers/net/ethernet/intel/iavf/iavf_txrx.c | 43 ++++++++++----------- drivers/net/ethernet/intel/iavf/iavf_txrx.h | 4 -- 4 files changed, 28 insertions(+), 43 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +0 -10
@@ -523,9 +523,6 @@ void iavf_schedule_request_stats(struct iavf_adapter *adapter);void iavf_reset (struct iavf_adapter *adapter);void iavf_set_ethtool_ops (struct net_device *netdev);void iavf_update_stats (struct iavf_adapter *adapter); -void iavf_reset_interrupt_capability (struct iavf_adapter *adapter); -int iavf_init_interrupt_scheme (struct iavf_adapter *adapter); -void iavf_irq_enable_queues (struct iavf_adapter *adapter);void iavf_free_all_tx_resources (struct iavf_adapter *adapter);void iavf_free_all_rx_resources (struct iavf_adapter *adapter);
@@ -579,17 +576,10 @@ void iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);void iavf_disable_vlan_stripping_v2 (struct iavf_adapter *adapter,u16 tpid);void iavf_enable_vlan_insertion_v2 (struct iavf_adapter *adapter,u16 tpid);void iavf_disable_vlan_insertion_v2 (struct iavf_adapter *adapter,u16 tpid); -int iavf_replace_primary_mac (struct iavf_adapter *adapter, -const u8 *new_mac); -void -iavf_set_vlan_offload_features (struct iavf_adapter *adapter, -netdev_features_t prev_features, -netdev_features_t features);void iavf_add_fdir_filter (struct iavf_adapter *adapter);void iavf_del_fdir_filter (struct iavf_adapter *adapter);void iavf_add_adv_rss_cfg (struct iavf_adapter *adapter);void iavf_del_adv_rss_cfg (struct iavf_adapter *adapter);struct iavf_mac_filter *iavf_add_filter (struct iavf_adapter *adapter,const u8 *macaddr); -int iavf_lock_timeout (struct mutex *lock,unsigned int msecs);#endif /* _IAVF_H_ */
drivers/net/ethernet/intel/iavf/iavf_main.c +7 -7
@@ -253,7 +253,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw,* * Returns 0 on success, negative on failure **/ -int iavf_lock_timeout (struct mutex *lock,unsigned int msecs) +static int iavf_lock_timeout (struct mutex *lock,unsigned int msecs) {unsigned int wait, delay =10 ;
@@ -362,7 +362,7 @@ static void iavf_irq_disable(struct iavf_adapter *adapter)* iavf_irq_enable_queues - Enable interrupt for all queues * @adapter: board private structure **/ -void iavf_irq_enable_queues (struct iavf_adapter *adapter) +static void iavf_irq_enable_queues (struct iavf_adapter *adapter) {struct iavf_hw *hw = &adapter->hw;int i;
@@ -1003,8 +1003,8 @@ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,* * Do not call this with mac_vlan_list_lock! **/ -int iavf_replace_primary_mac (struct iavf_adapter *adapter, -const u8 *new_mac) +static int iavf_replace_primary_mac (struct iavf_adapter *adapter, +const u8 *new_mac) {struct iavf_hw *hw = &adapter->hw;struct iavf_mac_filter *f;
@@ -1860,7 +1860,7 @@ static void iavf_free_q_vectors(struct iavf_adapter *adapter)* @adapter: board private structure * **/ -void iavf_reset_interrupt_capability (struct iavf_adapter *adapter) +static void iavf_reset_interrupt_capability (struct iavf_adapter *adapter) {if (!adapter->msix_entries)return ;
@@ -1875,7 +1875,7 @@ void iavf_reset_interrupt_capability(struct iavf_adapter *adapter)* @adapter: board private structure to initialize * **/ -int iavf_init_interrupt_scheme (struct iavf_adapter *adapter) +static int iavf_init_interrupt_scheme (struct iavf_adapter *adapter) {int err;
@@ -2174,7 +2174,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)* the watchdog if any changes are requested to expedite the request via * virtchnl. **/ -void +static void iavf_set_vlan_offload_features (struct iavf_adapter *adapter,netdev_features_t prev_features,netdev_features_t features)
drivers/net/ethernet/intel/iavf/iavf_txrx.c +21 -22
73 lines not on this page · raw message
drivers/net/ethernet/intel/iavf/iavf_txrx.h +0 -4
@@ -442,15 +442,11 @@ static inline unsigned int iavf_rx_pg_order(struct iavf_ring *ring)bool iavf_alloc_rx_buffers (struct iavf_ring *rxr,u16 cleaned_count);netdev_tx_t iavf_xmit_frame (struct sk_buff *skb,struct net_device *netdev); -void iavf_clean_tx_ring (struct iavf_ring *tx_ring); -void iavf_clean_rx_ring (struct iavf_ring *rx_ring);int iavf_setup_tx_descriptors (struct iavf_ring *tx_ring);int iavf_setup_rx_descriptors (struct iavf_ring *rx_ring);void iavf_free_tx_resources (struct iavf_ring *tx_ring);void iavf_free_rx_resources (struct iavf_ring *rx_ring);int iavf_napi_poll (struct napi_struct *napi,int budget); -void iavf_force_wb (struct iavf_vsi *vsi,struct iavf_q_vector *q_vector); -u32 iavf_get_tx_pending (struct iavf_ring *ring,bool in_sw);void iavf_detect_recover_hung (struct iavf_vsi *vsi);int __iavf_maybe_stop_tx (struct iavf_ring *tx_ring,int size);bool __iavf_chk_linearize (struct sk_buff *skb);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 124/183 iavf: Wait for reset in callbacks which trigger it
In reply to Greg Kroah-HartmanFrom: Marcin Szycik <[email protected]>
[ Upstream commit c2ed2403f12c74a74a0091ed5d830e72c58406e8 ]
There was a fail when trying to add the interface to bonding right after changing the MTU on the interface. It was caused by bonding interface unable to open the interface due to interface being in __RESETTING state because of MTU change.
Add new reset_waitqueue to indicate that reset has finished.
Add waiting for reset to finish in callbacks which trigger hw reset:iavf_set_priv_flags(), iavf_change_mtu() and iavf_set_ringparam(). We use a 5000ms timeout period because on Hyper-V based systems, this operation takes around 3000-4000ms. In normal circumstances, it doesn't take more than 500ms to complete.
Add a function iavf_wait_for_reset() to reuse waiting for reset code and use it also in iavf_set_channels(), which already waits for reset. We don't use error handling in iavf_set_channels() as this could cause the device to be in incorrect state if the reset was scheduled but hit timeout or the waitng function was interrupted by a signal.
--- drivers/net/ethernet/intel/iavf/iavf.h | 2 + .../net/ethernet/intel/iavf/iavf_ethtool.c | 31 ++++++----- drivers/net/ethernet/intel/iavf/iavf_main.c | 51 ++++++++++++++++++- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 1 + 4 files changed, 68 insertions(+), 17 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +2 -0
@@ -257,6 +257,7 @@ struct iavf_adapter {struct work_struct adminq_task;struct delayed_work client_task;wait_queue_head_t down_waitqueue; +wait_queue_head_t reset_waitqueue;wait_queue_head_t vc_waitqueue;struct iavf_q_vector *q_vectors;struct list_head vlan_filter_list;
@@ -582,4 +583,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);void iavf_del_adv_rss_cfg (struct iavf_adapter *adapter);struct iavf_mac_filter *iavf_add_filter (struct iavf_adapter *adapter,const u8 *macaddr); +int iavf_wait_for_reset (struct iavf_adapter *adapter);#endif /* _IAVF_H_ */
drivers/net/ethernet/intel/iavf/iavf_ethtool.c +15 -16
@@ -484,6 +484,7 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags) {struct iavf_adapter *adapter =netdev_priv (netdev);u32 orig_flags, new_flags, changed_flags; +int ret =0 ;u32 i; orig_flags =READ_ONCE (adapter->flags);
@@ -533,10 +534,13 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags)if (netif_running (netdev)) { adapter->flags |=IAVF_FLAG_RESET_NEEDED ;queue_work (adapter->wq, &adapter->reset_task); + ret =iavf_wait_for_reset (adapter); +if (ret) +netdev_warn (netdev,"Changing private flags timeout or interrupted waiting for reset" ); } } -return 0 ; +return ret; }/**
@@ -627,6 +631,7 @@ static int iavf_set_ringparam(struct net_device *netdev, {struct iavf_adapter *adapter =netdev_priv (netdev);u32 new_rx_count, new_tx_count; +int ret =0 ;if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))return -EINVAL ;
@@ -673,9 +678,12 @@ static int iavf_set_ringparam(struct net_device *netdev,if (netif_running (netdev)) { adapter->flags |=IAVF_FLAG_RESET_NEEDED ;queue_work (adapter->wq, &adapter->reset_task); + ret =iavf_wait_for_reset (adapter); +if (ret) +netdev_warn (netdev,"Changing ring parameters timeout or interrupted waiting for reset" ); } -return 0 ; +return ret; }/**
@@ -1830,7 +1838,7 @@ static int iavf_set_channels(struct net_device *netdev, {struct iavf_adapter *adapter =netdev_priv (netdev);u32 num_req = ch->combined_count; -int i; +int ret =0 ;if ((adapter->vf_res->vf_cap_flags &VIRTCHNL_VF_OFFLOAD_ADQ ) && adapter->num_tc) {
@@ -1854,20 +1862,11 @@ static int iavf_set_channels(struct net_device *netdev, adapter->flags |=IAVF_FLAG_REINIT_ITR_NEEDED ;iavf_schedule_reset (adapter); -/* wait for the reset is done */ -for (i =0 ; i <IAVF_RESET_WAIT_COMPLETE_COUNT ; i++) { -msleep (IAVF_RESET_WAIT_MS ); -if (adapter->flags &IAVF_FLAG_RESET_PENDING ) -continue ; -break ; - } -if (i ==IAVF_RESET_WAIT_COMPLETE_COUNT ) { - adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED ; - adapter->num_req_queues =0 ; -return -EOPNOTSUPP ; - } + ret =iavf_wait_for_reset (adapter); +if (ret) +netdev_warn (netdev,"Changing channel count timeout or interrupted waiting for reset" ); -return 0 ; +return ret; }/**
drivers/net/ethernet/intel/iavf/iavf_main.c +50 -1
83 lines not on this page · raw message
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +1 -0
@@ -2285,6 +2285,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,case VIRTCHNL_OP_ENABLE_QUEUES :/* enable transmits */ iavf_irq_enable (adapter, true); +wake_up (&adapter->reset_waitqueue); adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED ;break ;case VIRTCHNL_OP_DISABLE_QUEUES :
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 125/183 iavf: fix a deadlock caused by rtnl and drivers lock circular dependencies
In reply to Greg Kroah-HartmanFrom: Ahmed Zaki <[email protected]>
[ Upstream commit d1639a17319ba78a018280cd2df6577a7e5d9fab ]
A driver's lock (crit_lock) is used to serialize all the driver's tasks. Lockdep, however, shows a circular dependency between rtnl and crit_lock. This happens when an ndo that already holds the rtnl requests the driver to reset, since the reset task (in some paths) tries to grab rtnl to either change real number of queues of update netdev features.
[566.241851] ======================================================
[566.241893] WARNING: possible circular locking dependency detected
[566.241936] 6.2.14-100.fc36.x86_64+debug #1 Tainted: G OE
[566.241984] ------------------------------------------------------
[566.242025] repro.sh/2604 is trying to acquire lock:
[566.242061] ffff9280fc5ceee8 (&adapter->crit_lock){+.+.}-{3:3}, at: iavf_close+0x3c/0x240 [iavf]
[566.242167]
but task is already holding lock:
[566.242209] ffffffff9976d350 (rtnl_mutex){+.+.}-{3:3}, at: iavf_remove+0x6b5/0x730 [iavf]
[566.242300]
which lock already depends on the new lock. [566.242353]
the existing dependency chain (in reverse order) is:
[566.242401]
-> #1 (rtnl_mutex){+.+.}-{3:3}:
[566.242451] __mutex_lock+0xc1/0xbb0
[566.242489] iavf_init_interrupt_scheme+0x179/0x440 [iavf]
[566.242560] iavf_watchdog_task+0x80b/0x1400 [iavf]
[566.242627] process_one_work+0x2b3/0x560
[566.242663] worker_thread+0x4f/0x3a0
[566.242696] kthread+0xf2/0x120
[566.242730] ret_from_fork+0x29/0x50
[566.242763]
-> #0 (&adapter->crit_lock){+.+.}-{3:3}:
[566.242815] __lock_acquire+0x15ff/0x22b0
[566.242869] lock_acquire+0xd2/0x2c0
[566.242901] __mutex_lock+0xc1/0xbb0
[566.242934] iavf_close+0x3c/0x240 [iavf]
[566.242997] __dev_close_many+0xac/0x120
[566.243036] dev_close_many+0x8b/0x140
[566.243071] unregister_netdevice_many_notify+0x165/0x7c0
[566.243116] unregister_netdevice_queue+0xd3/0x110
[566.243157] iavf_remove+0x6c1/0x730 [iavf]
[566.243217] pci_device_remove+0x33/0xa0
[566.243257] device_release_driver_internal+0x1bc/0x240
[566.243299] pci_stop_bus_device+0x6c/0x90
[566.243338] pci_stop_and_remove_bus_device+0xe/0x20
[566.243380] pci_iov_remove_virtfn+0xd1/0x130
[566.243417] sriov_disable+0x34/0xe0
[566.243448] ice_free_vfs+0x2da/0x330 [ice]
[566.244383] ice_sriov_configure+0x88/0xad0 [ice]
[566.245353] sriov_numvfs_store+0xde/0x1d0
[566.246156] kernfs_fop_write_iter+0x15e/0x210
[566.246921] vfs_write+0x288/0x530
[566.247671] ksys_write+0x74/0xf0
[566.248408] do_syscall_64+0x58/0x80
[566.249145] entry_SYSCALL_64_after_hwframe+0x72/0xdc
[566.249886]
other info that might help us debug this:[566.252014] Possible unsafe locking scenario:
[566.253432] CPU0 CPU1
[566.254118] ---- ----
[566.254800] lock(rtnl_mutex);
[566.255514] lock(&adapter->crit_lock);
[566.256233] lock(rtnl_mutex);
[566.256897] lock(&adapter->crit_lock);
[566.257388]
*** DEADLOCK ***The deadlock can be triggered by a script that is continuously resetting the VF adapter while doing other operations requiring RTNL, e.g:
while :; do
ip link set $VF up
ethtool --set-channels $VF combined 2 ip link set $VF down
ip link set $VF up
ethtool --set-channels $VF combined 4 ip link set $VF down
done
Any operation that triggers a reset can substitute "ethtool --set-channles"
As a fix, add a new task "finish_config" that do all the work which needs rtnl lock. With the exception of iavf_remove(), all work that require rtnl should be called from this task.
As for iavf_remove(), at the point where we need to call unregister_netdevice() (and grab rtnl_lock), we make sure the finish_config task is not running (cancel_work_sync()) to safely grab rtnl. Subsequent finish_config work cannot restart after that since the task is guarded by the __IAVF_IN_REMOVE_TASK bit in iavf_schedule_finish_config().
--- drivers/net/ethernet/intel/iavf/iavf.h | 2 + drivers/net/ethernet/intel/iavf/iavf_main.c | 114 +++++++++++++----- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 1 + 3 files changed, 85 insertions(+), 32 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +2 -0
@@ -255,6 +255,7 @@ struct iavf_adapter {struct workqueue_struct *wq;struct work_struct reset_task;struct work_struct adminq_task; +struct work_struct finish_config;struct delayed_work client_task;wait_queue_head_t down_waitqueue;wait_queue_head_t reset_waitqueue;
@@ -521,6 +522,7 @@ int iavf_process_config(struct iavf_adapter *adapter);int iavf_parse_vf_resource_msg (struct iavf_adapter *adapter);void iavf_schedule_reset (struct iavf_adapter *adapter);void iavf_schedule_request_stats (struct iavf_adapter *adapter); +void iavf_schedule_finish_config (struct iavf_adapter *adapter);void iavf_reset (struct iavf_adapter *adapter);void iavf_set_ethtool_ops (struct net_device *netdev);void iavf_update_stats (struct iavf_adapter *adapter);
drivers/net/ethernet/intel/iavf/iavf_main.c +82 -32
180 lines not on this page · raw message
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +1 -0
@@ -2237,6 +2237,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,iavf_process_config (adapter); adapter->flags |=IAVF_FLAG_SETUP_NETDEV_FEATURES ; +iavf_schedule_finish_config (adapter);iavf_set_queue_vlan_tag_loc (adapter);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 126/183 iavf: fix reset task race with iavf_remove()
In reply to Greg Kroah-HartmanFrom: Ahmed Zaki <[email protected]>
[ Upstream commit c34743daca0eb1dc855831a5210f0800a850088e ]
The reset task is currently scheduled from the watchdog or adminq tasks. First, all direct calls to schedule the reset task are replaced with the iavf_schedule_reset(), which is modified to accept the flag showing the type of reset.
To prevent the reset task from starting once iavf_remove() starts, we need to check the __IAVF_IN_REMOVE_TASK bit before we schedule it. This is now easily added to iavf_schedule_reset().
Finally, remove the check for IAVF_FLAG_RESET_NEEDED in the watchdog task. It is redundant since all callers who set the flag immediately schedules the reset task.
--- drivers/net/ethernet/intel/iavf/iavf.h | 2 +- .../net/ethernet/intel/iavf/iavf_ethtool.c | 8 ++--- drivers/net/ethernet/intel/iavf/iavf_main.c | 32 +++++++------------ .../net/ethernet/intel/iavf/iavf_virtchnl.c | 3 +- 4 files changed, 16 insertions(+), 29 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +1 -1
@@ -520,7 +520,7 @@ int iavf_up(struct iavf_adapter *adapter);void iavf_down (struct iavf_adapter *adapter);int iavf_process_config (struct iavf_adapter *adapter);int iavf_parse_vf_resource_msg (struct iavf_adapter *adapter); -void iavf_schedule_reset (struct iavf_adapter *adapter); +void iavf_schedule_reset (struct iavf_adapter *adapter,u64 flags);void iavf_schedule_request_stats (struct iavf_adapter *adapter);void iavf_schedule_finish_config (struct iavf_adapter *adapter);void iavf_reset (struct iavf_adapter *adapter);
drivers/net/ethernet/intel/iavf/iavf_ethtool.c +3 -5
@@ -532,8 +532,7 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags)/* issue a reset to force legacy-rx change to take effect */ if (changed_flags &IAVF_FLAG_LEGACY_RX ) {if (netif_running (netdev)) { - adapter->flags |=IAVF_FLAG_RESET_NEEDED ; -queue_work (adapter->wq, &adapter->reset_task); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED ); ret =iavf_wait_for_reset (adapter);if (ret)netdev_warn (netdev,"Changing private flags timeout or interrupted waiting for reset" );
@@ -676,8 +675,7 @@ static int iavf_set_ringparam(struct net_device *netdev, }if (netif_running (netdev)) { - adapter->flags |=IAVF_FLAG_RESET_NEEDED ; -queue_work (adapter->wq, &adapter->reset_task); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED ); ret =iavf_wait_for_reset (adapter);if (ret)netdev_warn (netdev,"Changing ring parameters timeout or interrupted waiting for reset" );
@@ -1860,7 +1858,7 @@ static int iavf_set_channels(struct net_device *netdev, adapter->num_req_queues = num_req; adapter->flags |=IAVF_FLAG_REINIT_ITR_NEEDED ; -iavf_schedule_reset (adapter); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED ); ret =iavf_wait_for_reset (adapter);if (ret)
drivers/net/ethernet/intel/iavf/iavf_main.c +11 -21
@@ -309,12 +309,14 @@ static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)/** * iavf_schedule_reset - Set the flags and schedule a reset event * @adapter: board private structure +* @flags: IAVF_FLAG_RESET_PENDING or IAVF_FLAG_RESET_NEEDED **/ -void iavf_schedule_reset (struct iavf_adapter *adapter) +void iavf_schedule_reset (struct iavf_adapter *adapter,u64 flags) { -if (!(adapter->flags & - (IAVF_FLAG_RESET_PENDING |IAVF_FLAG_RESET_NEEDED ))) { - adapter->flags |=IAVF_FLAG_RESET_NEEDED ; +if (!test_bit (__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && + !(adapter->flags & + (IAVF_FLAG_RESET_PENDING |IAVF_FLAG_RESET_NEEDED ))) { + adapter->flags |= flags;queue_work (adapter->wq, &adapter->reset_task); } }
@@ -342,7 +344,7 @@ static void iavf_tx_timeout(struct net_device *netdev, unsigned int txqueue)struct iavf_adapter *adapter =netdev_priv (netdev); adapter->tx_timeout_count++; -iavf_schedule_reset (adapter); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED ); }/**
@@ -2490,7 +2492,7 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter) adapter->vsi_res->num_queue_pairs); adapter->flags |=IAVF_FLAG_REINIT_MSIX_NEEDED ; adapter->num_req_queues = adapter->vsi_res->num_queue_pairs; -iavf_schedule_reset (adapter); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED );return -EAGAIN ; }
@@ -2787,14 +2789,6 @@ static void iavf_watchdog_task(struct work_struct *work)if (adapter->flags &IAVF_FLAG_PF_COMMS_FAILED )iavf_change_state (adapter, __IAVF_COMM_FAILED); -if (adapter->flags &IAVF_FLAG_RESET_NEEDED ) { - adapter->aq_required =0 ; - adapter->current_op =VIRTCHNL_OP_UNKNOWN ; -mutex_unlock (&adapter->crit_lock); -queue_work (adapter->wq, &adapter->reset_task); -return ; - } -switch (adapter->state) {case __IAVF_STARTUP:iavf_startup (adapter);
@@ -2922,11 +2916,10 @@ static void iavf_watchdog_task(struct work_struct *work)/* check for hw reset */ reg_val =rd32 (hw,IAVF_VF_ARQLEN1 ) &IAVF_VF_ARQLEN1_ARQENABLE_MASK ;if (!reg_val) { - adapter->flags |=IAVF_FLAG_RESET_PENDING ; adapter->aq_required =0 ; adapter->current_op =VIRTCHNL_OP_UNKNOWN ;dev_err (&adapter->pdev->dev,"Hardware reset detected\n" ); -queue_work (adapter->wq, &adapter->reset_task); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_PENDING );mutex_unlock (&adapter->crit_lock);queue_delayed_work (adapter->wq, &adapter->watchdog_task,HZ *2 );
@@ -3324,9 +3317,7 @@ static void iavf_adminq_task(struct work_struct *work) }while (pending);mutex_unlock (&adapter->crit_lock); -if ((adapter->flags & - (IAVF_FLAG_RESET_PENDING |IAVF_FLAG_RESET_NEEDED )) || - adapter->state == __IAVF_RESETTING) +if (iavf_is_reset_in_progress (adapter)) goto freedom;/* check for error indications */
@@ -4423,8 +4414,7 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) }if (netif_running (netdev)) { - adapter->flags |=IAVF_FLAG_RESET_NEEDED ; -queue_work (adapter->wq, &adapter->reset_task); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_NEEDED ); ret =iavf_wait_for_reset (adapter);if (ret <0 )netdev_warn (netdev,"MTU change interrupted waiting for reset" );
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +1 -2
@@ -1961,9 +1961,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,case VIRTCHNL_EVENT_RESET_IMPENDING :dev_info (&adapter->pdev->dev,"Reset indication received from the PF\n" );if (!(adapter->flags &IAVF_FLAG_RESET_PENDING )) { - adapter->flags |=IAVF_FLAG_RESET_PENDING ;dev_info (&adapter->pdev->dev,"Scheduling reset task\n" ); -queue_work (adapter->wq, &adapter->reset_task); +iavf_schedule_reset (adapter,IAVF_FLAG_RESET_PENDING ); }break ;default :
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 127/183 security: keys: Modify mismatched function name
In reply to Greg Kroah-HartmanFrom: Jiapeng Chong <[email protected]>
[ Upstream commit 2a4152742025c5f21482e8cebc581702a0fa5b01 ]
No functional modification involved.
security/keys/trusted-keys/trusted_tpm2.c:203: warning: expecting prototype for tpm_buf_append_auth(). Prototype was for tpm2_buf_append_auth() instead.
--- security/keys/trusted-keys/trusted_tpm2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/keys/trusted-keys/trusted_tpm2.c +1 -1
@@ -186,7 +186,7 @@ int tpm2_key_priv(void *context, size_t hdrlen, }/** -* tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer. +* tpm2_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer. * * @buf: an allocated tpm_buf instance * @session_handle: session handle
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 128/183 octeontx2-pf: Dont allocate BPIDs for LBK interfaces
In reply to Greg Kroah-HartmanFrom: Geetha sowjanya <[email protected]>
[ Upstream commit 8fcd7c7b3a38ab5e452f542fda8f7940e77e479a ]
Current driver enables backpressure for LBK interfaces. But these interfaces do not support this feature. Hence, this patch fixes the issue by skipping the backpressure configuration for these interfaces.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +3 -2
@@ -1452,8 +1452,9 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)if (err) goto err_free_npa_lf; -/* Enable backpressure */ -otx2_nix_config_bp (pf, true); +/* Enable backpressure for CGX mapped PF/VFs */ +if (!is_otx2_lbkvf (pf->pdev)) +otx2_nix_config_bp (pf, true);/* Init Auras and pools used by NIX RQ, for free buffer ptrs */ err =otx2_rq_aura_pool_init (pf);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 129/183 bpf: Fix subprog idx logic in check_max_stack_depth
In reply to Greg Kroah-HartmanFrom: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit ba7b3e7d5f9014be65879ede8fd599cb222901c9 ]
The assignment to idx in check_max_stack_depth happens once we see a bpf_pseudo_call or bpf_pseudo_func. This is not an issue as the rest of the code performs a few checks and then pushes the frame to the frame stack, except the case of async callbacks. If the async callback case causes the loop iteration to be skipped, the idx assignment will be incorrect on the next iteration of the loop. The value stored in the frame stack (as the subprogno of the current subprog) will be incorrect.
This leads to incorrect checks and incorrect tail_call_reachable marking. Save the target subprog in a new variable and only assign to idx once we are done with the is_async_cb check which may skip pushing of frame to the frame stack and subsequent stack depth checks and tail call markings.
--- kernel/bpf/verifier.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
kernel/bpf/verifier.c +6 -5
@@ -4336,7 +4336,7 @@ static int check_max_stack_depth(struct bpf_verifier_env *env) continue_func: subprog_end = subprog[idx +1 ].start;for (; i < subprog_end; i++) { -int next_insn; +int next_insn, sidx;if (!bpf_pseudo_call (insn + i) && !bpf_pseudo_func (insn + i))continue ;
@@ -4346,14 +4346,14 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)/* find the callee */ next_insn = i + insn[i].imm +1 ; - idx =find_subprog (env, next_insn); -if (idx <0 ) { + sidx =find_subprog (env, next_insn); +if (sidx <0 ) {WARN_ONCE (1 ,"verifier bug. No program starts at insn %d\n" , next_insn);return -EFAULT ; } -if (subprog[idx].is_async_cb) { -if (subprog[idx].has_tail_call) { +if (subprog[sidx].is_async_cb) { +if (subprog[sidx].has_tail_call) {verbose (env,"verifier bug. subprog has tail_call and async cb\n" );return -EFAULT ; }
@@ -4362,6 +4362,7 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)continue ; } i = next_insn; + idx = sidx;if (subprog[idx].has_tail_call) tail_call_reachable = true;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 130/183 bpf: Repeat check_max_stack_depth for async callbacks
In reply to Greg Kroah-HartmanFrom: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit b5e9ad522c4ccd32d322877515cff8d47ed731b9 ]
While the check_max_stack_depth function explores call chains emanating from the main prog, which is typically enough to cover all possible call chains, it doesn't explore those rooted at async callbacks unless the async callback will have been directly called, since unlike non-async callbacks it skips their instruction exploration as they don't contribute to stack depth.
It could be the case that the async callback leads to a callchain which exceeds the stack depth, but this is never reachable while only exploring the entry point from main subprog. Hence, repeat the check for the main subprog *and* all async callbacks marked by the symbolic execution pass of the verifier, as execution of the program may begin at any of them.
Consider functions with following stack depths:
main: 256
async: 256
foo: 256
main:
rX = async
bpf_timer_set_callback(...)
async:
foo()
Here, async is not descended as it does not contribute to stack depth of main (since it is referenced using bpf_pseudo_func and not bpf_pseudo_call). However, when async is invoked asynchronously, it will end up breaching the MAX_BPF_STACK limit by calling foo.
Hence, in addition to main, we also need to explore call chains beginning at all async callback subprogs in a program.
--- kernel/bpf/verifier.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
kernel/bpf/verifier.c +19 -2
@@ -4288,16 +4288,17 @@ static int update_stack_depth(struct bpf_verifier_env *env,* Since recursion is prevented by check_cfg() this algorithm * only needs a local stack of MAX_CALL_FRAMES to remember callsites */ -static int check_max_stack_depth (struct bpf_verifier_env *env) +static int check_max_stack_depth_subprog (struct bpf_verifier_env *env,int idx) { -int depth =0 , frame =0 , idx =0 , i =0 , subprog_end;struct bpf_subprog_info *subprog = env->subprog_info;struct bpf_insn *insn = env->prog->insnsi; +int depth =0 , frame =0 , i, subprog_end;bool tail_call_reachable = false;int ret_insn[MAX_CALL_FRAMES ];int ret_prog[MAX_CALL_FRAMES ];int j; + i = subprog[idx].start; process_func:/* protect against potential stack overflow that might happen when * bpf2bpf calls get combined with tailcalls. Limit the caller's stack
@@ -4398,6 +4399,22 @@ static int check_max_stack_depth(struct bpf_verifier_env *env) goto continue_func; } +static int check_max_stack_depth (struct bpf_verifier_env *env) +{ +struct bpf_subprog_info *si = env->subprog_info; +int ret; + +for (int i =0 ; i < env->subprog_cnt; i++) { +if (!i || si[i].is_async_cb) { + ret =check_max_stack_depth_subprog (env, i); +if (ret <0 ) +return ret; + } +continue ; + } +return 0 ; +} +#ifndef CONFIG_BPF_JIT_ALWAYS_ON static int get_callee_stack_depth (struct bpf_verifier_env *env,const struct bpf_insn *insn,int idx)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 131/183 bpf, arm64: Fix BTI type used for freplace attached functions
In reply to Greg Kroah-HartmanFrom: Alexander Duyck <[email protected]>
[ Upstream commit a3f25d614bc73b45e8f02adc6769876dfd16ca84 ]
When running an freplace attached bpf program on an arm64 system w were seeing the following issue:
Unhandled 64-bit el1h sync exception on CPU47, ESR 0x0000000036000003 -- BTI
After a bit of work to track it down I determined that what appeared to be happening is that the 'bti c' at the start of the program was somehow being reached after a 'br' instruction. Further digging pointed me toward the fact that the function was attached via freplace. This in turn led me to build_plt which I believe is invoking the long jump which is triggering this error.
To resolve it we can replace the 'bti c' with 'bti jc' and add a comment explaining why this has to be modified as such.
--- arch/arm64/net/bpf_jit_comp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/net/bpf_jit_comp.c +7 -1
@@ -322,7 +322,13 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)* */ -emit_bti (A64_BTI_C , ctx); +/* bpf function may be invoked by 3 instruction types: +* 1. bl, attached via freplace to bpf prog via short jump +* 2. br, attached via freplace to bpf prog via long jump +* 3. blr, working as a function pointer, used by emit_call. +* So BTI_JC should used here to support both br and blr. +*/ +emit_bti (A64_BTI_JC , ctx);emit (A64_MOV (1 ,A64_R (9 ),A64_LR ), ctx);emit (A64_NOP , ctx);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 132/183 igc: Avoid transmit queue timeout for XDP
In reply to Greg Kroah-HartmanFrom: Kurt Kanzenbach <[email protected]>
[ Upstream commit 95b681485563c64585de78662ee52d06b7fa47d9 ]
High XDP load triggers the netdev watchdog:
|NETDEV WATCHDOG: enp3s0 (igc): transmit queue 2 timed out
The reason is the Tx queue transmission start (txq->trans_start) is not updated in XDP code path. Therefore, add it for all XDP transmission functions.
Stable-dep-of: 78adb4bcf99e ("igc: Prevent garbled TX queue with XDP ZEROCOPY")
--- drivers/net/ethernet/intel/igc/igc_main.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/ethernet/intel/igc/igc_main.c +8 -0
@@ -2402,6 +2402,8 @@ static int igc_xdp_xmit_back(struct igc_adapter *adapter, struct xdp_buff *xdp) nq =txring_txq (ring);__netif_tx_lock (nq, cpu); +/* Avoid transmit queue timeout since we share it with the slow path */ +txq_trans_cond_update (nq); res =igc_xdp_init_tx_descriptor (ring, xdpf);__netif_tx_unlock (nq);return res;
@@ -2804,6 +2806,9 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)__netif_tx_lock (nq, cpu); +/* Avoid transmit queue timeout since we share it with the slow path */ +txq_trans_cond_update (nq); + budget =igc_desc_unused (ring);while (xsk_tx_peek_desc (pool, &xdp_desc) && budget--) {
@@ -6297,6 +6302,9 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames,__netif_tx_lock (nq, cpu); +/* Avoid transmit queue timeout since we share it with the slow path */ +txq_trans_cond_update (nq); + drops =0 ;for (i =0 ; i < num_frames; i++) {int err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 133/183 igc: Prevent garbled TX queue with XDP ZEROCOPY
In reply to Greg Kroah-HartmanFrom: Florian Kauer <[email protected]>
[ Upstream commit 78adb4bcf99effbb960c5f9091e2e062509d1030 ]
In normal operation, each populated queue item has next_to_watch pointing to the last TX desc of the packet, while each cleaned item has it set to 0. In particular, next_to_use that points to the next (necessarily clean) item to use has next_to_watch set to 0.
When the TX queue is used both by an application using AF_XDP with ZEROCOPY as well as a second non-XDP application generating high traffic, the queue pointers can get in an invalid state where next_to_use points to an item where next_to_watch is NOT set to 0.
However, the implementation assumes at several places that this is never the case, so if it does hold,
bad things happen. In particular, within the loop inside of igc_clean_tx_irq(), next_to_clean can overtake next_to_use. Finally, this prevents any further transmission via this queue and it never gets unblocked or signaled. Secondly, if the queue is in this garbled state,
the inner loop of igc_clean_tx_ring() will never terminate, completely hogging a CPU core.
The reason is that igc_xdp_xmit_zc() reads next_to_use before acquiring the lock, and writing it back (potentially unmodified) later. If it got modified before locking, the outdated next_to_use is written pointing to an item that was already used elsewhere (and thus next_to_watch got written).
--- drivers/net/ethernet/intel/igc/igc_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igc/igc_main.c +2 -2
@@ -2797,9 +2797,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)struct netdev_queue *nq =txring_txq (ring);union igc_adv_tx_desc *tx_desc =NULL ;int cpu =smp_processor_id (); -u16 ntu = ring->next_to_use;struct xdp_desc xdp_desc; -u16 budget; +u16 budget, ntu;if (!netif_carrier_ok (ring->netdev))return ;
@@ -2809,6 +2808,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)/* Avoid transmit queue timeout since we share it with the slow path */ txq_trans_cond_update (nq); + ntu = ring->next_to_use; budget =igc_desc_unused (ring);while (xsk_tx_peek_desc (pool, &xdp_desc) && budget--) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 134/183 net: ipv4: use consistent txhash in TIME_WAIT and SYN_RECV
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit c0a8966e2bc7d31f77a7246947ebc09c1ff06066 ]
When using IPv4/TCP, skb->hash comes from sk->sk_txhash except in TIME_WAIT and SYN_RECV where it's not set in the reply skb from ip_send_unicast_reply. Those packets will have a mismatched hash with others from the same flow as their hashes will be 0. IPv6 does not have the same issue as the hash is set from the socket txhash in those cases.
This commits sets the hash in the reply skb from ip_send_unicast_reply, which makes the IPv4 code behaving like IPv6.
Stable-dep-of: 5e5265522a9a ("tcp: annotate data-races around tcp_rsk(req)->txhash")
--- include/net/ip.h | 2 +- net/ipv4/ip_output.c | 4 +++- net/ipv4/tcp_ipv4.c | 14 +++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-)
include/net/ip.h +1 -1
@@ -282,7 +282,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,const struct ip_options *sopt, __be32 daddr, __be32 saddr, const struct ip_reply_arg *arg, - unsigned int len, u64 transmit_time); + unsigned int len, u64 transmit_time, u32 txhash);#define IP_INC_STATS (net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field)#define __IP_INC_STATS (net, field) __SNMP_INC_STATS64((net)->mib.ip_statistics, field)
net/ipv4/ip_output.c +3 -1
@@ -1691,7 +1691,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,const struct ip_options *sopt, __be32 daddr, __be32 saddr, const struct ip_reply_arg *arg, - unsigned int len, u64 transmit_time) + unsigned int len, u64 transmit_time, u32 txhash) { struct ip_options_data replyopts;struct ipcm_cookie ipc;
@@ -1754,6 +1754,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, arg->csum)); nskb->ip_summed =CHECKSUM_NONE ; nskb->mono_delivery_time = !!transmit_time; +if (txhash) +skb_set_hash (nskb, txhash,PKT_HASH_TYPE_L4 );ip_push_pending_frames (sk, &fl4); } out:
net/ipv4/tcp_ipv4.c +9 -5
@@ -692,6 +692,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)u64 transmit_time =0 ;struct sock *ctl_sk;struct net *net; +u32 txhash =0 ;/* Never send a reset in response to a reset. */ if (th->rst)
@@ -829,6 +830,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) inet_twsk(sk)->tw_priority : sk->sk_priority; transmit_time =tcp_transmit_time (sk);xfrm_sk_clone_policy (ctl_sk, sk); + txhash = (sk->sk_state ==TCP_TIME_WAIT ) ? +inet_twsk (sk)->tw_txhash : sk->sk_txhash; }else { ctl_sk->sk_mark =0 ; ctl_sk->sk_priority =0 ;
@@ -837,7 +840,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) skb, &TCP_SKB_CB (skb)->header.h4.opt,ip_hdr (skb)->saddr,ip_hdr (skb)->daddr, &arg, arg.iov[0 ].iov_len, - transmit_time); + transmit_time, txhash);xfrm_sk_free_policy (ctl_sk);sock_net_set (ctl_sk, &init_net);
@@ -859,7 +862,7 @@ static void tcp_v4_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, struct tcp_md5sig_key *key, - int reply_flags, u8 tos) + int reply_flags, u8 tos, u32 txhash) { const struct tcphdr *th = tcp_hdr(skb); struct {
@@ -935,7 +938,7 @@ static void tcp_v4_send_ack(const struct sock *sk, skb, &TCP_SKB_CB (skb)->header.h4.opt,ip_hdr (skb)->saddr,ip_hdr (skb)->daddr, &arg, arg.iov[0 ].iov_len, - transmit_time); + transmit_time, txhash);sock_net_set (ctl_sk, &init_net);__TCP_INC_STATS (net,TCP_MIB_OUTSEGS );
@@ -955,7 +958,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) tw->tw_bound_dev_if,tcp_twsk_md5_key (tcptw), tw->tw_transparent ?IP_REPLY_ARG_NOSRCCHECK :0 , - tw->tw_tos + tw->tw_tos, + tw->tw_txhash );inet_twsk_put (tw);
@@ -988,7 +992,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,0 ,tcp_md5_do_lookup (sk, l3index, addr,AF_INET ),inet_rsk (req)->no_srccheck ?IP_REPLY_ARG_NOSRCCHECK :0 , - ip_hdr(skb)->tos); + ip_hdr(skb)->tos, tcp_rsk(req)->txhash); }/*
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 135/183 tcp: annotate data-races around tcp_rsk(req)->txhash
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 5e5265522a9a7f91d1b0bd411d634bdaf16c80cd ]
TCP request sockets are lockless, some of their fields can change while being read by another cpu as syzbot noticed.
This is usually harmless, but we should annotate the known races.
This patch takes care of tcp_rsk(req)->txhash, a separate one is needed for tcp_rsk(req)->ts_recent.
BUG: KCSAN: data-race in tcp_make_synack / tcp_rtx_synack
write to 0xffff8881362304bc of 4 bytes by task 32083 on cpu 1:
tcp_rtx_synack+0x9d/0x2a0 net/ipv4/tcp_output.c:4213 inet_rtx_syn_ack+0x38/0x80 net/ipv4/inet_connection_sock.c:880 tcp_check_req+0x379/0xc70 net/ipv4/tcp_minisocks.c:665 tcp_v6_rcv+0x125b/0x1b20 net/ipv6/tcp_ipv6.c:1673 ip6_protocol_deliver_rcu+0x92f/0xf30 net/ipv6/ip6_input.c:437 ip6_input_finish net/ipv6/ip6_input.c:482 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] ip6_input+0xbd/0x1b0 net/ipv6/ip6_input.c:491 dst_input include/net/dst.h:468 [inline] ip6_rcv_finish+0x1e2/0x2e0 net/ipv6/ip6_input.c:79 NF_HOOK include/linux/netfilter.h:303 [inline] ipv6_rcv+0x74/0x150 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core net/core/dev.c:5452 [inline] __netif_receive_skb+0x90/0x1b0 net/core/dev.c:5566 netif_receive_skb_internal net/core/dev.c:5652 [inline] netif_receive_skb+0x4a/0x310 net/core/dev.c:5711 tun_rx_batched+0x3bf/0x400 tun_get_user+0x1d24/0x22b0 drivers/net/tun.c:1997 tun_chr_write_iter+0x18e/0x240 drivers/net/tun.c:2043 call_write_iter include/linux/fs.h:1871 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x4ab/0x7d0 fs/read_write.c:584 ksys_write+0xeb/0x1a0 fs/read_write.c:637 __do_sys_write fs/read_write.c:649 [inline] __se_sys_write fs/read_write.c:646 [inline] __x64_sys_write+0x42/0x50 fs/read_write.c:646 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
read to 0xffff8881362304bc of 4 bytes by task 32078 on cpu 0:
tcp_make_synack+0x367/0xb40 net/ipv4/tcp_output.c:3663 tcp_v6_send_synack+0x72/0x420 net/ipv6/tcp_ipv6.c:544 tcp_conn_request+0x11a8/0x1560 net/ipv4/tcp_input.c:7059 tcp_v6_conn_request+0x13f/0x180 net/ipv6/tcp_ipv6.c:1175 tcp_rcv_state_process+0x156/0x1de0 net/ipv4/tcp_input.c:6494 tcp_v6_do_rcv+0x98a/0xb70 net/ipv6/tcp_ipv6.c:1509 tcp_v6_rcv+0x17b8/0x1b20 net/ipv6/tcp_ipv6.c:1735 ip6_protocol_deliver_rcu+0x92f/0xf30 net/ipv6/ip6_input.c:437 ip6_input_finish net/ipv6/ip6_input.c:482 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] ip6_input+0xbd/0x1b0 net/ipv6/ip6_input.c:491 dst_input include/net/dst.h:468 [inline] ip6_rcv_finish+0x1e2/0x2e0 net/ipv6/ip6_input.c:79 NF_HOOK include/linux/netfilter.h:303 [inline] ipv6_rcv+0x74/0x150 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core net/core/dev.c:5452 [inline] __netif_receive_skb+0x90/0x1b0 net/core/dev.c:5566 netif_receive_skb_internal net/core/dev.c:5652 [inline] netif_receive_skb+0x4a/0x310 net/core/dev.c:5711 tun_rx_batched+0x3bf/0x400 tun_get_user+0x1d24/0x22b0 drivers/net/tun.c:1997 tun_chr_write_iter+0x18e/0x240 drivers/net/tun.c:2043 call_write_iter include/linux/fs.h:1871 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x4ab/0x7d0 fs/read_write.c:584 ksys_write+0xeb/0x1a0 fs/read_write.c:637 __do_sys_write fs/read_write.c:649 [inline] __se_sys_write fs/read_write.c:646 [inline] __x64_sys_write+0x42/0x50 fs/read_write.c:646 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x91d25731 -> 0xe79325cd
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 32078 Comm: syz-executor.4 Not tainted 6.5.0-rc1-syzkaller-00033-geb26cbb1a754 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/03/2023
--- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 4 ++-- net/ipv6/tcp_ipv6.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-)
net/ipv4/tcp_ipv4.c +2 -1
@@ -992,7 +992,8 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,0 ,tcp_md5_do_lookup (sk, l3index, addr,AF_INET ),inet_rsk (req)->no_srccheck ?IP_REPLY_ARG_NOSRCCHECK :0 , - ip_hdr(skb)->tos, tcp_rsk(req)->txhash); +ip_hdr (skb)->tos, + READ_ONCE(tcp_rsk(req)->txhash)); }/*
net/ipv4/tcp_minisocks.c +1 -1
@@ -510,7 +510,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newicsk->icsk_ack.lrcvtime = tcp_jiffies32; newtp->lsndtime = tcp_jiffies32; - newsk->sk_txhash = treq->txhash; + newsk->sk_txhash =READ_ONCE (treq->txhash); newtp->total_retrans = req->num_retrans;tcp_init_xmit_timers (newsk);
net/ipv4/tcp_output.c +2 -2
@@ -3581,7 +3581,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,rcu_read_lock (); md5 =tcp_rsk (req)->af_specific->req_md5_lookup (sk,req_to_sk (req));#endif -skb_set_hash (skb,tcp_rsk (req)->txhash,PKT_HASH_TYPE_L4 ); +skb_set_hash (skb,READ_ONCE (tcp_rsk (req)->txhash),PKT_HASH_TYPE_L4 );/* bpf program will be interested in the tcp_flags */ TCP_SKB_CB (skb)->tcp_flags =TCPHDR_SYN |TCPHDR_ACK ; tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5,
@@ -4124,7 +4124,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req)/* Paired with WRITE_ONCE() in sock_setsockopt() */ if (READ_ONCE (sk->sk_txrehash) ==SOCK_TXREHASH_ENABLED ) -tcp_rsk (req)->txhash =net_tx_rndhash (); +WRITE_ONCE (tcp_rsk (req)->txhash,net_tx_rndhash ()); res = af_ops->send_synack (sk,NULL , &fl, req,NULL ,TCP_SYNACK_NORMAL ,NULL );if (!res) {
net/ipv6/tcp_ipv6.c +1 -1
@@ -1133,7 +1133,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, req->ts_recent, sk->sk_bound_dev_if,tcp_v6_md5_do_lookup (sk, &ipv6_hdr (skb)->saddr, l3index),ipv6_get_dsfield (ipv6_hdr (skb)),0 , sk->sk_priority, - tcp_rsk(req)->txhash); + READ_ONCE(tcp_rsk(req)->txhash)); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 136/183 tcp: annotate data-races around tcp_rsk(req)->ts_recent
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit eba20811f32652bc1a52d5e7cc403859b86390d9 ]
TCP request sockets are lockless, tcp_rsk(req)->ts_recent can change while being read by another cpu as syzbot noticed.
This is harmless, but we should annotate the known races.
Note that tcp_check_req() changes req->ts_recent a bit early, we might change this in the future.
BUG: KCSAN: data-race in tcp_check_req / tcp_check_req
write to 0xffff88813c8afb84 of 4 bytes by interrupt on cpu 1:
tcp_check_req+0x694/0xc70 net/ipv4/tcp_minisocks.c:762 tcp_v4_rcv+0x12db/0x1b70 net/ipv4/tcp_ipv4.c:2071 ip_protocol_deliver_rcu+0x356/0x6d0 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x13c/0x1a0 net/ipv4/ip_input.c:233 NF_HOOK include/linux/netfilter.h:303 [inline] ip_local_deliver+0xec/0x1c0 net/ipv4/ip_input.c:254 dst_input include/net/dst.h:468 [inline] ip_rcv_finish net/ipv4/ip_input.c:449 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] ip_rcv+0x197/0x270 net/ipv4/ip_input.c:569 __netif_receive_skb_one_core net/core/dev.c:5493 [inline] __netif_receive_skb+0x90/0x1b0 net/core/dev.c:5607 process_backlog+0x21f/0x380 net/core/dev.c:5935 __napi_poll+0x60/0x3b0 net/core/dev.c:6498 napi_poll net/core/dev.c:6565 [inline] net_rx_action+0x32b/0x750 net/core/dev.c:6698 __do_softirq+0xc1/0x265 kernel/softirq.c:571 do_softirq+0x7e/0xb0 kernel/softirq.c:472 __local_bh_enable_ip+0x64/0x70 kernel/softirq.c:396 local_bh_enable+0x1f/0x20 include/linux/bottom_half.h:33 rcu_read_unlock_bh include/linux/rcupdate.h:843 [inline] __dev_queue_xmit+0xabb/0x1d10 net/core/dev.c:4271 dev_queue_xmit include/linux/netdevice.h:3088 [inline] neigh_hh_output include/net/neighbour.h:528 [inline] neigh_output include/net/neighbour.h:542 [inline] ip_finish_output2+0x700/0x840 net/ipv4/ip_output.c:229 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:317 NF_HOOK_COND include/linux/netfilter.h:292 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:431 dst_output include/net/dst.h:458 [inline] ip_local_out net/ipv4/ip_output.c:126 [inline] __ip_queue_xmit+0xa4d/0xa70 net/ipv4/ip_output.c:533 ip_queue_xmit+0x38/0x40 net/ipv4/ip_output.c:547 __tcp_transmit_skb+0x1194/0x16e0 net/ipv4/tcp_output.c:1399 tcp_transmit_skb net/ipv4/tcp_output.c:1417 [inline] tcp_write_xmit+0x13ff/0x2fd0 net/ipv4/tcp_output.c:2693 __tcp_push_pending_frames+0x6a/0x1a0 net/ipv4/tcp_output.c:2877 tcp_push_pending_frames include/net/tcp.h:1952 [inline] __tcp_sock_set_cork net/ipv4/tcp.c:3336 [inline] tcp_sock_set_cork+0xe8/0x100 net/ipv4/tcp.c:3343 rds_tcp_xmit_path_complete+0x3b/0x40 net/rds/tcp_send.c:52 rds_send_xmit+0xf8d/0x1420 net/rds/send.c:422 rds_send_worker+0x42/0x1d0 net/rds/threads.c:200 process_one_work+0x3e6/0x750 kernel/workqueue.c:2408 worker_thread+0x5f2/0xa10 kernel/workqueue.c:2555 kthread+0x1d7/0x210 kernel/kthread.c:379 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
read to 0xffff88813c8afb84 of 4 bytes by interrupt on cpu 0:
tcp_check_req+0x32a/0xc70 net/ipv4/tcp_minisocks.c:622 tcp_v4_rcv+0x12db/0x1b70 net/ipv4/tcp_ipv4.c:2071 ip_protocol_deliver_rcu+0x356/0x6d0 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x13c/0x1a0 net/ipv4/ip_input.c:233 NF_HOOK include/linux/netfilter.h:303 [inline] ip_local_deliver+0xec/0x1c0 net/ipv4/ip_input.c:254 dst_input include/net/dst.h:468 [inline] ip_rcv_finish net/ipv4/ip_input.c:449 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] ip_rcv+0x197/0x270 net/ipv4/ip_input.c:569 __netif_receive_skb_one_core net/core/dev.c:5493 [inline] __netif_receive_skb+0x90/0x1b0 net/core/dev.c:5607 process_backlog+0x21f/0x380 net/core/dev.c:5935 __napi_poll+0x60/0x3b0 net/core/dev.c:6498 napi_poll net/core/dev.c:6565 [inline] net_rx_action+0x32b/0x750 net/core/dev.c:6698 __do_softirq+0xc1/0x265 kernel/softirq.c:571 run_ksoftirqd+0x17/0x20 kernel/softirq.c:939 smpboot_thread_fn+0x30a/0x4a0 kernel/smpboot.c:164 kthread+0x1d7/0x210 kernel/kthread.c:379 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
value changed: 0x1cd237f1 -> 0x1cd237f2
--- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_minisocks.c | 9 ++++++--- net/ipv4/tcp_output.c | 2 +- net/ipv6/tcp_ipv6.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-)
net/ipv4/tcp_ipv4.c +1 -1
@@ -988,7 +988,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,tcp_rsk (req)->rcv_nxt, req->rsk_rcv_wnd >>inet_rsk (req)->rcv_wscale,tcp_time_stamp_raw () +tcp_rsk (req)->ts_off, - req->ts_recent, +READ_ONCE (req->ts_recent),0 ,tcp_md5_do_lookup (sk, l3index, addr,AF_INET ), inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
net/ipv4/tcp_minisocks.c +6 -3
@@ -537,7 +537,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newtp->max_window = newtp->snd_wnd;if (newtp->rx_opt.tstamp_ok) { - newtp->rx_opt.ts_recent = req->ts_recent; + newtp->rx_opt.ts_recent =READ_ONCE (req->ts_recent); newtp->rx_opt.ts_recent_stamp =ktime_get_seconds (); newtp->tcp_header_len =sizeof (struct tcphdr ) +TCPOLEN_TSTAMP_ALIGNED ; }else {
@@ -601,7 +601,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,tcp_parse_options (sock_net (sk), skb, &tmp_opt,0 ,NULL );if (tmp_opt.saw_tstamp) { - tmp_opt.ts_recent = req->ts_recent; + tmp_opt.ts_recent =READ_ONCE (req->ts_recent);if (tmp_opt.rcv_tsecr) tmp_opt.rcv_tsecr -=tcp_rsk (req)->ts_off;/* We do not store true stamp, but it is not required,
@@ -740,8 +740,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,/* In sequence, PAWS is OK. */ +/* TODO: We probably should defer ts_recent change once +* we take ownership of @req. +*/ if (tmp_opt.saw_tstamp && !after (TCP_SKB_CB (skb)->seq,tcp_rsk (req)->rcv_nxt)) - req->ts_recent = tmp_opt.rcv_tsval; +WRITE_ONCE (req->ts_recent, tmp_opt.rcv_tsval);if (TCP_SKB_CB (skb)->seq ==tcp_rsk (req)->rcv_isn) {/* Truncate SYN, it is out of window starting
net/ipv4/tcp_output.c +1 -1
@@ -876,7 +876,7 @@ static unsigned int tcp_synack_options(const struct sock *sk,if (likely (ireq->tstamp_ok)) { opts->options |=OPTION_TS ; opts->tsval =tcp_skb_timestamp (skb) +tcp_rsk (req)->ts_off; - opts->tsecr = req->ts_recent; + opts->tsecr =READ_ONCE (req->ts_recent); remaining -=TCPOLEN_TSTAMP_ALIGNED ; }if (likely (ireq->sack_ok)) {
net/ipv6/tcp_ipv6.c +1 -1
@@ -1130,7 +1130,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,tcp_rsk (req)->rcv_nxt, req->rsk_rcv_wnd >>inet_rsk (req)->rcv_wscale,tcp_time_stamp_raw () +tcp_rsk (req)->ts_off, - req->ts_recent, sk->sk_bound_dev_if, +READ_ONCE (req->ts_recent), sk->sk_bound_dev_if,tcp_v6_md5_do_lookup (sk, &ipv6_hdr (skb)->saddr, l3index),ipv6_get_dsfield (ipv6_hdr (skb)),0 , sk->sk_priority, READ_ONCE(tcp_rsk(req)->txhash));
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 137/183 net: ipv4: Use kfree_sensitive instead of kfree
In reply to Greg Kroah-HartmanFrom: Wang Ming <[email protected]>
[ Upstream commit daa751444fd9d4184270b1479d8af49aaf1a1ee6 ]
key might contain private part of the key, so better use kfree_sensitive to free it.
--- net/ipv4/esp4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/esp4.c +1 -1
@@ -1132,7 +1132,7 @@ static int esp_init_authenc(struct xfrm_state *x, err =crypto_aead_setkey (aead, key, keylen); free_key: -kfree (key); +kfree_sensitive (key); error:return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 138/183 net:ipv6: check return value of pskb_trim()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit 4258faa130be4ea43e5e2d839467da421b8ff274 ]
goto tx_err if an unexpected result is returned by pskb_tirm() in ip6erspan_tunnel_xmit().
--- net/ipv6/ip6_gre.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/ip6_gre.c +2 -1
@@ -977,7 +977,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, goto tx_err;if (skb->len > dev->mtu + dev->hard_header_len) { -pskb_trim (skb, dev->mtu + dev->hard_header_len); +if (pskb_trim (skb, dev->mtu + dev->hard_header_len)) + goto tx_err; truncate = true; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 139/183 Revert "tcp: avoid the lookup process failing to get sk in ehash table"
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 81b3ade5d2b98ad6e0a473b0e1e420a801275592 ]
This reverts commit 3f4ca5fafc08881d7a57daa20449d171f2887043.
Commit 3f4ca5fafc08 ("tcp: avoid the lookup process failing to get sk in ehash table") reversed the order in how a socket is inserted into ehash to fix an issue that ehash-lookup could fail when reqsk/full sk/twsk are swapped. However, it introduced another lookup failure.
The full socket in ehash is allocated from a slab with SLAB_TYPESAFE_BY_RCU and does not have SOCK_RCU_FREE, so the socket could be reused even while it is being referenced on another CPU doing RCU lookup.
Let's say a socket is reused and inserted into the same hash bucket during lookup. After the blamed commit, a new socket is inserted at the end of the list. If that happens, we will skip sockets placed after the previous position of the reused socket, resulting in ehash lookup failure.
As described in Documentation/RCU/rculist_nulls.rst, we should insert a new socket at the head of the list to avoid such an issue.
This issue, the swap-lookup-failure, and another variant reported in [0] can all be handled properly by adding a locked ehash lookup suggested by Eric Dumazet [1].
However, this issue could occur for every packet, thus more likely than the other two races, so let's revert the change for now.
--- net/ipv4/inet_hashtables.c | 17 ++--------------- net/ipv4/inet_timewait_sock.c | 8 ++++---- 2 files changed, 6 insertions(+), 19 deletions(-)
net/ipv4/inet_hashtables.c +2 -15
@@ -650,20 +650,8 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)spin_lock (lock);if (osk) {WARN_ON_ONCE (sk->sk_hash != osk->sk_hash); - ret =sk_hashed (osk); -if (ret) { -/* Before deleting the node, we insert a new one to make -* sure that the look-up-sk process would not miss either -* of them and that at least one node would exist in ehash -* table all the time. Otherwise there's a tiny chance -* that lookup process could find nothing in ehash table. -*/ -__sk_nulls_add_node_tail_rcu (sk, list); -sk_nulls_del_node_init_rcu (osk); - } - goto unlock; - } -if (found_dup_sk) { + ret =sk_nulls_del_node_init_rcu (osk); + }else if (found_dup_sk) { *found_dup_sk =inet_ehash_lookup_by_sk (sk, list);if (*found_dup_sk) ret = false;
@@ -672,7 +660,6 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)if (ret)__sk_nulls_add_node_rcu (sk, list); -unlock:spin_unlock (lock);return ret;
net/ipv4/inet_timewait_sock.c +4 -4
@@ -91,10 +91,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw) }EXPORT_SYMBOL_GPL (inet_twsk_put); -static void inet_twsk_add_node_tail_rcu (struct inet_timewait_sock *tw, -struct hlist_nulls_head *list) +static void inet_twsk_add_node_rcu (struct inet_timewait_sock *tw, +struct hlist_nulls_head *list) { -hlist_nulls_add_tail_rcu (&tw->tw_node, list); +hlist_nulls_add_head_rcu (&tw->tw_node, list); } static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
@@ -147,7 +147,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,spin_lock (lock); -inet_twsk_add_node_tail_rcu (tw, &ehead->chain); +inet_twsk_add_node_rcu (tw, &ehead->chain);/* Step 3: Remove SK from hash chain */ if (__sk_nulls_del_node_init_rcu (sk))
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 140/183 fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe
In reply to Greg Kroah-HartmanFrom: Zhang Shurong <[email protected]>
[ Upstream commit 4e88761f5f8c7869f15a2046b1a1116f4fab4ac8 ]
This func misses checking for platform_get_irq()'s call and may passes the negative error codes to request_irq(), which takes unsigned IRQ #, causing it to fail with -EINVAL, overriding an original error code.
Fix this by stop calling request_irq() with invalid IRQ #s.
--- drivers/video/fbdev/au1200fb.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/video/fbdev/au1200fb.c +3 -0
@@ -1732,6 +1732,9 @@ static int au1200fb_drv_probe(struct platform_device *dev)/* Now hook interrupt too */ irq =platform_get_irq (dev,0 ); +if (irq <0 ) +return irq; + ret =request_irq (irq, au1200fb_handle_irq,IRQF_SHARED ,"lcd" , (void *)dev);if (ret) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 141/183 llc: Dont drop packet from non-root netns.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 6631463b6e6673916d2481f692938f393148aa82 ]
Now these upper layer protocol handlers can be called from llc_rcv() as sap->rcv_func(), which is registered by llc_sap_open().
* function which is passed to register_8022_client()
-> no in-kernel user calls register_8022_client().
* snap_rcv()
`- proto->rcvfunc() : registered by register_snap_client()
-> aarp_rcv() and atalk_rcv() drop packets from non-root netns * stp_pdu_rcv()
`- garp_protos[]->rcv() : registered by stp_proto_register()
-> garp_pdu_rcv() and br_stp_rcv() are netns-awareSo, we can safely remove the netns restriction in llc_rcv().
--- net/llc/llc_input.c | 3 --- 1 file changed, 3 deletions(-)
net/llc/llc_input.c +0 -3
@@ -163,9 +163,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,void (*sta_handler)(struct sk_buff *skb);void (*sap_handler)(struct llc_sap *sap,struct sk_buff *skb); -if (!net_eq (dev_net (dev), &init_net)) - goto drop; -/* * When the interface is in promisc. mode, drop all the crap that it * receives, do not try to analyse it.
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 142/183 ALSA: hda/realtek: Fix generic fixup definition for cs35l41 amp
In reply to Greg Kroah-HartmanFrom: Vitaly Rodionov <[email protected]>
[ Upstream commit f7b069cf08816252f494d193b9ecdff172bf9aa1 ]
Generic fixup for CS35L41 amplifies should not have vendor specific chained fixup. For ThinkPad laptops with led issue, we can just add specific fixup.
--- sound/pci/hda/patch_realtek.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
sound/pci/hda/patch_realtek.c +15 -10
@@ -7220,6 +7220,7 @@ enum {ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ,ALC236_FIXUP_DELL_DUAL_CODECS , + ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, };/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9090,8 +9091,6 @@ static const struct hda_fixup alc269_fixups[] = { [ALC287_FIXUP_CS35L41_I2C_2] = { .type = HDA_FIXUP_FUNC, .v.func = cs35l41_fixup_i2c_two, - .chained = true, - .chain_id = ALC269_FIXUP_THINKPAD_ACPI, }, [ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED] = { .type = HDA_FIXUP_FUNC,
@@ -9228,6 +9227,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, }, + [ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_i2c_two, + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9750,14 +9755,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x17aa ,0x22be ,"Thinkpad X1 Carbon 8th" ,ALC285_FIXUP_THINKPAD_HEADSET_JACK ),SND_PCI_QUIRK (0x17aa ,0x22c1 ,"Thinkpad P1 Gen 3" ,ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK ),SND_PCI_QUIRK (0x17aa ,0x22c2 ,"Thinkpad X1 Extreme Gen 3" ,ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK ), -SND_PCI_QUIRK (0x17aa ,0x22f1 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x22f2 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x22f3 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x2316 ,"Thinkpad P1 Gen 6" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x2317 ,"Thinkpad P1 Gen 6" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x2318 ,"Thinkpad Z13 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x2319 ,"Thinkpad Z16 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x17aa ,0x231a ,"Thinkpad Z16 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2 ), +SND_PCI_QUIRK (0x17aa ,0x22f1 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x22f2 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x22f3 ,"Thinkpad" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x2316 ,"Thinkpad P1 Gen 6" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x2317 ,"Thinkpad P1 Gen 6" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x2318 ,"Thinkpad Z13 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x2319 ,"Thinkpad Z16 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x231a ,"Thinkpad Z16 Gen2" ,ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI ),SND_PCI_QUIRK (0x17aa ,0x30bb ,"ThinkCentre AIO" ,ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY ),SND_PCI_QUIRK (0x17aa ,0x30e2 ,"ThinkCentre AIO" ,ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY ), SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 143/183 netfilter: nf_tables: fix spurious set element insertion failure
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit ddbd8be68941985f166f5107109a90ce13147c44 ]
On some platforms there is a padding hole in the nft_verdict structure, between the verdict code and the chain pointer.
On element insertion, if the new element clashes with an existing one and NLM_F_EXCL flag isn't set, we want to ignore the -EEXIST error as long as the data associated with duplicated element is the same as the existing one. The data equality check uses memcmp.
For normal data (NFT_DATA_VALUE) this works fine, but for NFT_DATA_VERDICT padding area leads to spurious failure even if the verdict data is the same.
This then makes the insertion fail with 'already exists' error, even though the new "key : data" matches an existing entry and userspace told the kernel that it doesn't want to receive an error indication.
--- net/netfilter/nf_tables_api.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/nf_tables_api.c +3 -0
@@ -10114,6 +10114,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,if (!tb[NFTA_VERDICT_CODE ])return -EINVAL ; + +/* zero padding hole for memcmp */ +memset (data,0 ,sizeof (*data)); data->verdict.code =ntohl (nla_get_be32 (tb[NFTA_VERDICT_CODE ]));switch (data->verdict.code) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 144/183 netfilter: nf_tables: cant schedule in nft_chain_validate
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit 314c82841602a111c04a7210c21dc77e0d560242 ]
Can be called via nft set element list iteration, which may acquire rcu and/or bh read lock (depends on set type).
BUG: sleeping function called from invalid context at net/netfilter/nf_tables_api.c:3353
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 1232, name: nftpreempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
2 locks held by nft/1232:
#0: ffff8881180e3ea8 (&nft_net->commit_mutex){+.+.}-{3:3}, at: nf_tables_valid_genid #1: ffffffff83f5f540 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire
Call Trace: nft_chain_validate nft_lookup_validate_setelem nft_pipapo_walk nft_lookup_validate nft_chain_validate nft_immediate_validate nft_chain_validate nf_tables_validate nf_tables_abort
No choice but to move it to nf_tables_validate().
--- net/netfilter/nf_tables_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nf_tables_api.c +2 -2
@@ -3500,8 +3500,6 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)if (err <0 )return err; } - -cond_resched (); }return 0 ;
@@ -3525,6 +3523,8 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) err =nft_chain_validate (&ctx, chain);if (err <0 )return err; + +cond_resched (); }return 0 ;
Signature · 1 line
2.39.2