5.15.166-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 5.15.166-rc1 review
This is the start of the stable review cycle for the 5.15.166 release. There are 215 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 Tue, 03 Sep 2024 16:07:34 +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/v5.x/stable-review/patch-5.15.166-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.15.166-rc1
Guenter Roeck <[email protected]>
apparmor: fix policy_unpack_test on big endian systems
Ben Hutchings <[email protected]>
scsi: aacraid: Fix double-free on probe failure
Faizal Rahim <[email protected]>
igc: Fix qbv tx latency by setting gtxoffset
Faizal Rahim <[email protected]>
igc: Fix reset adapter logics when tx mode change
Sean Anderson <[email protected]>
phy: zynqmp: Enable reference clock correctly
Pawel Laszczak <[email protected]>
usb: cdnsp: fix for Link TRB with TC
Pawel Laszczak <[email protected]>
usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function
Zijun Hu <[email protected]>
usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in remove_power_attributes()
Krzysztof Kozlowski <[email protected]>
usb: dwc3: st: add missing depopulate in probe error path
Krzysztof Kozlowski <[email protected]>
usb: dwc3: st: fix probed platform device ref count on probe error path
Selvarasu Ganesan <[email protected]>
usb: dwc3: core: Prevent USB core invalid event buffer address access
Krzysztof Kozlowski <[email protected]>
usb: dwc3: omap: add missing depopulate in probe error path
ZHANG Yuntian <[email protected]>
USB: serial: option: add MeiG Smart SRM825L
Ian Ray <[email protected]>
cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller
Volodymyr Babchuk <[email protected]>
soc: qcom: cmd-db: Map shared memory as WC, not WB
Aleksandr Mishin <[email protected]>
nfc: pn533: Add poll mod list filling check
Eric Dumazet <[email protected]>
net: busy-poll: use ktime_get_ns() instead of local_clock()
Cong Wang <[email protected]>
gtp: fix a potential NULL pointer dereference
Jamie Bainbridge <[email protected]>
ethtool: check device is present when getting link settings
Serge Semin <[email protected]>
dmaengine: dw: Add memory bus width verification
Serge Semin <[email protected]>
dmaengine: dw: Add peripheral bus width verification
Piyush Mehta <[email protected]>
phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume
Piyush Mehta <[email protected]>
phy: xilinx: phy-zynqmp: dynamic clock support for power-save
Piyush Mehta <[email protected]>
phy: xilinx: add runtime PM support
Paul Cercueil <[email protected]>
PM: runtime: Add DEFINE_RUNTIME_DEV_PM_OPS() macro
Paul Cercueil <[email protected]>
PM: core: Add EXPORT[_GPL]_SIMPLE_DEV_PM_OPS macros
Paul Cercueil <[email protected]>
PM: core: Remove DEFINE_UNIVERSAL_DEV_PM_OPS() macro
Krzysztof Kozlowski <[email protected]>
soundwire: stream: fix programming slave ports for non-continous port maps
Namjae Jeon <[email protected]>
ksmbd: the buffer of smb2 query dir response has at least 1 byte
Allison Henderson <[email protected]>
net:rds: Fix possible deadlock in rds_message_put
Chen Ridong <[email protected]>
cgroup/cpuset: Prevent UAF in proc_cpuset_show()
Niklas Cassel <[email protected]>
ata: libata-core: Fix null pointer dereference on error
Alex Deucher <[email protected]>
drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
Greg Kroah-Hartman <[email protected]>
Revert "MIPS: Loongson64: reset: Prioritise firmware service"
Matthieu Baerts (NGI0) <[email protected]>
mptcp: sched: check both backup in retrans
Haiyang Zhang <[email protected]>
net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response
Sascha Hauer <[email protected]>
wifi: mwifiex: duplicate static structs used in driver instances
Ma Ke <[email protected]>
pinctrl: single: fix potential NULL dereference in pcs_get_function()
Huang-Huang Bao <[email protected]>
pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins
Josef Bacik <[email protected]>
btrfs: run delayed iputs when flushing delalloc
Jesse Zhang <[email protected]>
drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc
Alexander Lobakin <[email protected]>
tools: move alignment-related macros to new <linux/align.h>
Tetsuo Handa <[email protected]>
Input: MT - limit max slots
Lee, Chun-Yi <[email protected]>
Bluetooth: hci_ldisc: check HCI_UART_PROTO_READY flag in HCIUARTGETPROTO
Zi Yan <[email protected]>
mm/numa: no task_numa_fault() call if PTE is changed
Zi Yan <[email protected]>
mm/numa: no task_numa_fault() call if PMD is changed
Takashi Iwai <[email protected]>
ALSA: timer: Relax start tick time check for slave timer elements
Javier Carrasco <[email protected]>
hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt()
Alex Hung <[email protected]>
Revert "drm/amd/display: Validate hw_points_num before using it"
Ben Whitten <[email protected]>
mmc: dw_mmc: allow biu and ciu clocks to defer
Marc Zyngier <[email protected]>
KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3
Nikolay Kuratov <[email protected]>
cxgb4: add forgotten u64 ivlan cast before shift
Siarhei Vishniakou <[email protected]>
HID: microsoft: Add rumble support to latest xbox controllers
Jason Gerecke <[email protected]>
HID: wacom: Defer calculation of resolution until resolution_code is known
Jiaxun Yang <[email protected]>
MIPS: Loongson64: Set timer mode in cpu-probe
Chaotian Jing <[email protected]>
scsi: core: Fix the return value of scsi_logical_block_count()
Griffin Kroah-Hartman <[email protected]>
Bluetooth: MGMT: Add error handling to pair_device()
Dan Carpenter <[email protected]>
mmc: mmc_test: Fix NULL dereference on allocation failure
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails
Abhinav Kumar <[email protected]>
drm/msm/dp: reset the link phy params before link training
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: don't play tricks with debug macros
Sean Anderson <[email protected]>
net: xilinx: axienet: Fix dangling multicast addresses
Sean Anderson <[email protected]>
net: xilinx: axienet: Always disable promiscuous mode
Pablo Neira Ayuso <[email protected]>
netfilter: flowtable: validate vlan header
Eric Dumazet <[email protected]>
ipv6: prevent possible UAF in ip6_xmit()
Eric Dumazet <[email protected]>
ipv6: fix possible UAF in ip6_finish_output2()
Eric Dumazet <[email protected]>
ipv6: prevent UAF in ip6_send_skb()
Stephen Hemminger <[email protected]>
netem: fix return value if duplicate enqueue fails
Joseph Huang <[email protected]>
net: dsa: mv88e6xxx: Fix out-of-bound access
Vladimir Oltean <[email protected]>
net: dsa: mv88e6xxx: replace ATU violation prints with trace points
Hans J. Schultz <[email protected]>
net: dsa: mv88e6xxx: read FID when handling ATU violations
Dan Carpenter <[email protected]>
dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp()
Maciej Fijalkowski <[email protected]>
ice: fix ICE_LAST_OFFSET formula
Nikolay Aleksandrov <[email protected]>
bonding: fix xfrm state handling when clearing active slave
Nikolay Aleksandrov <[email protected]>
bonding: fix xfrm real_dev null pointer dereference
Nikolay Aleksandrov <[email protected]>
bonding: fix null pointer deref in bond_ipsec_offload_ok
Nikolay Aleksandrov <[email protected]>
bonding: fix bond_ipsec_offload_ok return type
Thomas Bogendoerfer <[email protected]>
ip6_tunnel: Fix broken GRO
Sebastian Andrzej Siewior <[email protected]>
netfilter: nft_counter: Synchronize nft_counter_reset() against reader.
Sebastian Andrzej Siewior <[email protected]>
netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
Kuniyuki Iwashima <[email protected]>
kcm: Serialise kcm_sendmsg() for the same socket.
Simon Horman <[email protected]>
tc-testing: don't access non-existent variable on exception
Luiz Augusto von Dentz <[email protected]>
Bluetooth: SMP: Fix assumption of Central always being Initiator
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_core: Fix LE quote calculation
Maximilian Luz <[email protected]>
platform/surface: aggregator: Fix warning when controller is destroyed in probe
Long Li <[email protected]>
net: mana: Fix doorbell out of order violation and avoid unnecessary doorbell rings
Mikulas Patocka <[email protected]>
dm suspend: return -ERESTARTSYS instead of -EINTR
Aurelien Jarno <[email protected]>
media: solo6x10: replace max(a, min(b, c)) by clamp(b, a, c)
Josef Bacik <[email protected]>
nfsd: make svc_stat per-network namespace instead of global
Josef Bacik <[email protected]>
nfsd: remove nfsd_stats, make th_cnt a global counter
Josef Bacik <[email protected]>
nfsd: make all of the nfsd stats per-network namespace
Josef Bacik <[email protected]>
nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
Josef Bacik <[email protected]>
nfsd: rename NFSD_NET_* to NFSD_STATS_*
Josef Bacik <[email protected]>
sunrpc: use the struct net as the svc proc private
Josef Bacik <[email protected]>
sunrpc: remove ->pg_stats from svc_program
Josef Bacik <[email protected]>
sunrpc: pass in the sv_stats struct through svc_create_pooled
Josef Bacik <[email protected]>
nfsd: stop setting ->pg_stats for unused stats
Josef Bacik <[email protected]>
sunrpc: don't change ->sv_stats if it doesn't exist
Chuck Lever <[email protected]>
NFSD: Fix frame size warning in svc_export_parse()
Chuck Lever <[email protected]>
NFSD: Rewrite synopsis of nfsd_percpu_counters_init()
Chuck Lever <[email protected]>
NFSD: Refactor the duplicate reply cache shrinker
Chuck Lever <[email protected]>
NFSD: Replace nfsd_prune_bucket()
Chuck Lever <[email protected]>
NFSD: Rename nfsd_reply_cache_alloc()
Chuck Lever <[email protected]>
NFSD: Refactor nfsd_reply_cache_free_locked()
Jeff Layton <[email protected]>
nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net
Jeff Layton <[email protected]>
nfsd: move reply cache initialization into nfsd startup
Tetsuo Handa <[email protected]>
block: use "unsigned long" for blk_validate_block_size().
Eric Dumazet <[email protected]>
gtp: pull network headers in gtp_dev_xmit()
Phil Chang <[email protected]>
hrtimer: Prevent queuing of hrtimer without a function callback
Sagi Grimberg <[email protected]>
nvmet-rdma: fix possible bad dereference when freeing rsps
Baokun Li <[email protected]>
ext4: set the type of max_zeroout to unsigned int to avoid overflow
Guanrui Huang <[email protected]>
irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc
Abdulrasaq Lawani <[email protected]>
fbdev: offb: replace of_node_put with __free(device_node)
Krishna Kurapati <[email protected]>
usb: dwc3: core: Skip setting event buffers for host only controllers
Gergo Koteles <[email protected]>
platform/x86: lg-laptop: fix %s null argument warning
Adrian Hunter <[email protected]>
clocksource: Make watchdog and suspend-timing multiplication overflow safe
Alexander Gordeev <[email protected]>
s390/iucv: fix receive buffer virtual vs physical address confusion
Oreoluwa Babatunde <[email protected]>
openrisc: Call setup_memory() earlier in the init sequence
NeilBrown <[email protected]>
NFS: avoid infinite loop in pnfs_update_layout.
Hannes Reinecke <[email protected]>
nvmet-tcp: do not continue for invalid icreq
Jian Shen <[email protected]>
net: hns3: add checking for vf id of mailbox
Luiz Augusto von Dentz <[email protected]>
Bluetooth: bnep: Fix out-of-bound access
Uwe Kleine-König <[email protected]>
usb: gadget: fsl: Increase size of name buffer for endpoints
Zhiguo Niu <[email protected]>
f2fs: fix to do sanity check in update_sit_entry
David Sterba <[email protected]>
btrfs: delete pointless BUG_ON check on quota root in btrfs_qgroup_account_extent()
David Sterba <[email protected]>
btrfs: change BUG_ON to assertion in tree_move_down()
David Sterba <[email protected]>
btrfs: send: handle unexpected data in header buffer in begin_cmd()
David Sterba <[email protected]>
btrfs: handle invalid root reference found in may_destroy_subvol()
David Sterba <[email protected]>
btrfs: change BUG_ON to assertion when checking for delayed_node root
Michael Ellerman <[email protected]>
powerpc/boot: Only free if realloc() succeeds
Li zeming <[email protected]>
powerpc/boot: Handle allocation failure in simple_realloc()
Helge Deller <[email protected]>
parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367
Christophe Kerello <[email protected]>
memory: stm32-fmc2-ebi: check regmap_read return value
Kees Cook <[email protected]>
x86: Increase brk randomness entropy for 64-bit systems
Li Nan <[email protected]>
md: clean up invalid BUG_ON in md_ioctl
Eric Dumazet <[email protected]>
netlink: hold nlk->cb_mutex longer in __netlink_dump_start()
Martin Blumenstingl <[email protected]>
clocksource/drivers/arm_global_timer: Guard against division by zero
Stefan Hajnoczi <[email protected]>
virtiofs: forbid newlines in tags
Erico Nunes <[email protected]>
drm/lima: set gp bus_stop bit before hard reset
Kees Cook <[email protected]>
net/sun3_82586: Avoid reading past buffer in debug output
Philipp Stanner <[email protected]>
media: drivers/media/dvb-core: copy user arrays safely
Justin Tee <[email protected]>
scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list()
Max Filippov <[email protected]>
fs: binfmt_elf_efpic: don't use missing interpreter's properties
Hans Verkuil <[email protected]>
media: pci: cx23885: check cx23885_vdev_init() return
Jan Kara <[email protected]>
quota: Remove BUG_ON from dqget()
Al Viro <[email protected]>
fuse: fix UAF in rcu pathwalks
Al Viro <[email protected]>
afs: fix __afs_break_callback() / afs_drop_open_mmap() race
Baokun Li <[email protected]>
ext4: do not trim the group with corrupted block bitmap
Daniel Wagner <[email protected]>
nvmet-trace: avoid dereferencing pointer too early
Kunwu Chan <[email protected]>
powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu
Ashish Mhetre <[email protected]>
memory: tegra: Skip SID programming if SID registers aren't set
Samuel Holland <[email protected]>
arm64: Fix KASAN random tag seed initialization
Antoniu Miclaus <[email protected]>
hwmon: (ltc2992) Avoid division by zero
Chengfeng Ye <[email protected]>
IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock
Mukesh Sisodiya <[email protected]>
wifi: iwlwifi: fw: Fix debugfs command sending
Miri Korenblit <[email protected]>
wifi: iwlwifi: abort scan when rfkill on but device enabled
Andreas Gruenbacher <[email protected]>
gfs2: setattr_chown: Add missing initialization
Mike Christie <[email protected]>
scsi: spi: Fix sshdr use
Hans Verkuil <[email protected]>
media: qcom: venus: fix incorrect return value
Christian Brauner <[email protected]>
binfmt_misc: cleanup on filesystem umount
Chengfeng Ye <[email protected]>
staging: ks7010: disable bh on tx_dev_lock
Alex Hung <[email protected]>
drm/amd/display: Validate hw_points_num before using it
David Lechner <[email protected]>
staging: iio: resolver: ad2s1210: fix use before initialization
Hans Verkuil <[email protected]>
media: radio-isa: use dev_name to fill in bus_info
Jarkko Nikula <[email protected]>
i3c: mipi-i3c-hci: Do not unmap region not mapped for transfer
Jarkko Nikula <[email protected]>
i3c: mipi-i3c-hci: Remove BUG() when Ring Abort request times out
Heiko Carstens <[email protected]>
s390/smp,mcck: fix early IPI handling
Zhu Yanjun <[email protected]>
RDMA/rtrs: Fix the problem of variable not initialized fully
Wolfram Sang <[email protected]>
i2c: riic: avoid potential division by zero
Jeff Johnson <[email protected]>
wifi: cw1200: Avoid processing an invalid TIM IE
Johannes Berg <[email protected]>
wifi: mac80211: fix BA session teardown race
Johannes Berg <[email protected]>
wifi: cfg80211: check wiphy mutex is held for wdev mutex
Rand Deeb <[email protected]>
ssb: Fix division by zero issue in ssb_calc_clock_rate
Parsa Poorshikhian <[email protected]>
ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7
Jie Wang <[email protected]>
net: hns3: fix a deadlock problem when config TC during resetting
Jie Wang <[email protected]>
net: hns3: fix wrong use of semaphore up
Florian Westphal <[email protected]>
netfilter: nf_queue: drop packets with cloned unconfirmed conntracks
Donald Hunter <[email protected]>
netfilter: flowtable: initialise extack before use
Tom Hughes <[email protected]>
netfilter: allow ipv6 fragments to arrive on different devices
Eugene Syromiatnikov <[email protected]>
mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size
David Thompson <[email protected]>
mlxbf_gige: disable RX filters until RX path initialized
Yue Haibing <[email protected]>
mlxbf_gige: Remove two unused function declarations
Pawel Dembicki <[email protected]>
net: dsa: vsc73xx: check busy flag in MDIO operations
Pawel Dembicki <[email protected]>
net: dsa: vsc73xx: use read_poll_timeout instead delay loop
Pawel Dembicki <[email protected]>
net: dsa: vsc73xx: pass value in phy_write operation
Radhey Shyam Pandey <[email protected]>
net: axienet: Fix register defines comment description
Dan Carpenter <[email protected]>
atm: idt77252: prevent use after free in dequeue_rx()
Cosmin Ratiu <[email protected]>
net/mlx5e: Correctly report errors for ethtool rx flows
Faizal Rahim <[email protected]>
igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer
Muhammad Husaini Zulkifli <[email protected]>
igc: remove I226 Qbv BaseTime restriction
Muhammad Husaini Zulkifli <[email protected]>
igc: Correct the launchtime offset
Claudio Imbrenda <[email protected]>
s390/uv: Panic for set and remove shared access UVC errors
Alex Deucher <[email protected]>
drm/amdgpu/jpeg2: properly set atomics vmid field
Al Viro <[email protected]>
memcg_write_event_control(): fix a user-triggerable oops
Bas Nieuwenhuizen <[email protected]>
drm/amdgpu: Actually check flags for all context ops.
Qu Wenruo <[email protected]>
btrfs: tree-checker: add dev extent item checks
Zhen Lei <[email protected]>
selinux: fix potential counting error in avc_add_xperms_decision()
Al Viro <[email protected]>
fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
Alexander Lobakin <[email protected]>
bitmap: introduce generic optimized bitmap_size()
Alexander Lobakin <[email protected]>
btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits()
Alexander Lobakin <[email protected]>
s390/cio: rename bitmap_size() -> idset_bitmap_size()
Alexander Lobakin <[email protected]>
fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64()
Zhihao Cheng <[email protected]>
vfs: Don't evict inode under the inode lru traversing context
Mikulas Patocka <[email protected]>
dm persistent data: fix memory allocation failure
Khazhismel Kumykov <[email protected]>
dm resume: don't return EINVAL when signalled
Haibo Xu <[email protected]>
arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to NUMA_NO_NODE
Stefan Haberland <[email protected]>
s390/dasd: fix error recovery leading to data corruption on ESE devices
Mika Westerberg <[email protected]>
thunderbolt: Mark XDomain as unplugged when router is removed
Mathias Nyman <[email protected]>
xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
Juan José Arboleda <[email protected]>
ALSA: usb-audio: Support Yamaha P-125 quirk entry
Lianqin Hu <[email protected]>
ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET
Eli Billauer <[email protected]>
char: xillybus: Check USB endpoints when probing device
Eli Billauer <[email protected]>
char: xillybus: Refine workqueue handling
Eli Billauer <[email protected]>
char: xillybus: Don't destroy workqueue from work item running on it
Jann Horn <[email protected]>
fuse: Initialize beyond-EOF page contents before setting uptodate
-------------
Diffstat:
Makefile | 4 +- arch/arm64/kernel/acpi_numa.c | 2 +- arch/arm64/kernel/setup.c | 3 - arch/arm64/kernel/smp.c | 2 + arch/arm64/kvm/sys_regs.c | 6 + arch/arm64/kvm/vgic/vgic.h | 7 + arch/mips/kernel/cpu-probe.c | 4 + arch/mips/loongson64/reset.c | 38 ++-- arch/openrisc/kernel/setup.c | 6 +- arch/parisc/kernel/irq.c | 4 +- arch/powerpc/boot/simple_alloc.c | 7 +- arch/powerpc/sysdev/xics/icp-native.c | 2 + arch/s390/include/asm/uv.h | 5 +- arch/s390/kernel/early.c | 12 +- arch/s390/kernel/smp.c | 4 +- arch/x86/kernel/process.c | 5 +- drivers/ata/libata-core.c | 3 + drivers/atm/idt77252.c | 9 +- drivers/bluetooth/hci_ldisc.c | 3 +- drivers/char/xillybus/xillyusb.c | 42 +++- drivers/clocksource/arm_global_timer.c | 11 +- drivers/dma/dw/core.c | 89 ++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 8 + drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 3 +- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 4 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 5 +- drivers/gpu/drm/lima/lima_gp.c | 12 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 + drivers/gpu/drm/msm/dp/dp_ctrl.c | 2 + drivers/hid/hid-ids.h | 10 +- drivers/hid/hid-microsoft.c | 11 +- drivers/hid/wacom_wac.c | 4 +- drivers/hwmon/ltc2992.c | 8 +- drivers/i2c/busses/i2c-riic.c | 2 +- drivers/i3c/master/mipi-i3c-hci/dma.c | 5 +- drivers/infiniband/hw/hfi1/chip.c | 5 +- drivers/infiniband/ulp/rtrs/rtrs.c | 2 +- drivers/input/input-mt.c | 3 + drivers/irqchip/irq-gic-v3-its.c | 2 - drivers/md/dm-clone-metadata.c | 5 - drivers/md/dm-ioctl.c | 22 ++- drivers/md/dm.c | 4 +- drivers/md/md.c | 5 - drivers/md/persistent-data/dm-space-map-metadata.c | 4 +- drivers/media/dvb-core/dvb_frontend.c | 12 +- drivers/media/pci/cx23885/cx23885-video.c | 8 + drivers/media/pci/solo6x10/solo6x10-offsets.h | 10 +- drivers/media/platform/qcom/venus/pm_helpers.c | 2 +- drivers/media/radio/radio-isa.c | 2 +- drivers/memory/stm32-fmc2-ebi.c | 122 ++++++++---- drivers/memory/tegra/tegra186.c | 3 + drivers/mmc/core/mmc_test.c | 9 +- drivers/mmc/host/dw_mmc.c | 8 + drivers/net/bonding/bond_main.c | 21 +- drivers/net/bonding/bond_options.c | 2 +- drivers/net/dsa/mv88e6xxx/Makefile | 4 + drivers/net/dsa/mv88e6xxx/global1_atu.c | 82 ++++++-- drivers/net/dsa/mv88e6xxx/trace.c | 6 + drivers/net/dsa/mv88e6xxx/trace.h | 66 +++++++ drivers/net/dsa/vitesse-vsc73xx-core.c | 69 +++++-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 3 +- .../net/ethernet/freescale/dpaa2/dpaa2-switch.c | 7 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 + .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 7 +- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 +- drivers/net/ethernet/i825xx/sun3_82586.c | 2 +- drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +- drivers/net/ethernet/intel/igc/igc_base.c | 29 +++ drivers/net/ethernet/intel/igc/igc_base.h | 2 + drivers/net/ethernet/intel/igc/igc_defines.h | 16 ++ drivers/net/ethernet/intel/igc/igc_main.c | 12 +- drivers/net/ethernet/intel/igc/igc_regs.h | 1 + drivers/net/ethernet/intel/igc/igc_tsn.c | 113 +++++++++-- drivers/net/ethernet/intel/igc/igc_tsn.h | 1 + .../ethernet/mellanox/mlx5/core/en_fs_ethtool.c | 2 +- .../net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h | 9 +- .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c | 10 + .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h | 2 + .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c | 50 ++++- drivers/net/ethernet/microsoft/mana/hw_channel.c | 68 ++++--- drivers/net/ethernet/microsoft/mana/mana.h | 1 + drivers/net/ethernet/microsoft/mana/mana_en.c | 22 ++- drivers/net/ethernet/xilinx/xilinx_axienet.h | 17 +- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 25 +-- drivers/net/gtp.c | 5 +- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 32 ++- drivers/net/wireless/st/cw1200/txrx.c | 2 +- drivers/nfc/pn533/pn533.c | 5 + drivers/nvme/target/rdma.c | 16 +- drivers/nvme/target/tcp.c | 1 + drivers/nvme/target/trace.c | 6 +- drivers/nvme/target/trace.h | 28 +-- drivers/phy/xilinx/phy-zynqmp.c | 152 ++++++++++----- drivers/pinctrl/pinctrl-rockchip.c | 2 +- drivers/pinctrl/pinctrl-single.c | 2 + drivers/platform/surface/aggregator/controller.c | 3 +- drivers/platform/x86/lg-laptop.c | 2 +- drivers/s390/block/dasd.c | 36 ++-- drivers/s390/block/dasd_3990_erp.c | 10 +- drivers/s390/block/dasd_eckd.c | 57 +++--- drivers/s390/block/dasd_int.h | 2 +- drivers/s390/cio/idset.c | 12 +- drivers/scsi/aacraid/comminit.c | 2 + drivers/scsi/lpfc/lpfc_sli.c | 2 +- drivers/scsi/scsi_transport_spi.c | 4 +- drivers/soc/qcom/cmd-db.c | 2 +- drivers/soundwire/stream.c | 8 +- drivers/ssb/main.c | 2 +- drivers/staging/iio/resolver/ad2s1210.c | 7 +- drivers/staging/ks7010/ks7010_sdio.c | 4 +- drivers/thunderbolt/switch.c | 1 + drivers/usb/cdns3/cdnsp-gadget.h | 3 + drivers/usb/cdns3/cdnsp-ring.c | 30 ++- drivers/usb/class/cdc-acm.c | 3 + drivers/usb/core/sysfs.c | 1 + drivers/usb/dwc3/core.c | 21 ++ drivers/usb/dwc3/dwc3-omap.c | 4 +- drivers/usb/dwc3/dwc3-st.c | 16 +- drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- drivers/usb/host/xhci.c | 8 +- drivers/usb/serial/option.c | 5 + drivers/video/fbdev/offb.c | 3 +- fs/afs/file.c | 8 +- fs/binfmt_elf_fdpic.c | 2 +- fs/binfmt_misc.c | 216 ++++++++++++++++----- fs/btrfs/delayed-inode.c | 2 +- fs/btrfs/free-space-cache.c | 8 +- fs/btrfs/inode.c | 9 +- fs/btrfs/qgroup.c | 4 +- fs/btrfs/send.c | 9 +- fs/btrfs/tree-checker.c | 69 +++++++ fs/ext4/extents.c | 3 +- fs/ext4/mballoc.c | 3 + fs/f2fs/segment.c | 5 +- fs/file.c | 28 ++- fs/fuse/cuse.c | 3 +- fs/fuse/dev.c | 6 +- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 15 +- fs/fuse/virtio_fs.c | 10 + fs/gfs2/inode.c | 2 +- fs/inode.c | 39 +++- fs/ksmbd/smb2pdu.c | 3 +- fs/lockd/svc.c | 3 - fs/nfs/callback.c | 3 - fs/nfs/pnfs.c | 8 + fs/nfsd/export.c | 32 ++- fs/nfsd/export.h | 4 +- fs/nfsd/netns.h | 25 ++- fs/nfsd/nfs4proc.c | 6 +- fs/nfsd/nfscache.c | 202 +++++++++++-------- fs/nfsd/nfsctl.c | 24 ++- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfsfh.c | 3 +- fs/nfsd/nfssvc.c | 24 ++- fs/nfsd/stats.c | 52 ++--- fs/nfsd/stats.h | 83 +++----- fs/nfsd/trace.h | 22 +++ fs/nfsd/vfs.c | 6 +- fs/ntfs3/bitmap.c | 4 +- fs/ntfs3/fsntfs.c | 2 +- fs/ntfs3/index.c | 11 +- fs/ntfs3/ntfs_fs.h | 4 +- fs/ntfs3/super.c | 2 +- fs/quota/dquot.c | 5 +- include/linux/bitmap.h | 20 +- include/linux/blkdev.h | 2 +- include/linux/cpumask.h | 2 +- include/linux/fs.h | 5 + include/linux/pm.h | 55 ++++-- include/linux/pm_runtime.h | 14 ++ include/linux/sunrpc/svc.h | 5 +- include/net/busy_poll.h | 2 +- include/net/kcm.h | 1 + include/scsi/scsi_cmnd.h | 2 +- kernel/cgroup/cpuset.c | 13 +- kernel/time/clocksource.c | 42 ++-- kernel/time/hrtimer.c | 2 + lib/math/prime_numbers.c | 2 - mm/huge_memory.c | 30 ++- mm/memcontrol.c | 7 +- mm/memory.c | 29 ++- net/bluetooth/bnep/core.c | 3 +- net/bluetooth/hci_core.c | 19 +- net/bluetooth/mgmt.c | 4 + net/bluetooth/smp.c | 146 +++++++------- net/bridge/br_netfilter_hooks.c | 6 +- net/core/net-sysfs.c | 2 +- net/ethtool/ioctl.c | 3 + net/ipv6/ip6_output.c | 10 + net/ipv6/ip6_tunnel.c | 12 +- net/ipv6/netfilter/nf_conntrack_reasm.c | 4 + net/iucv/iucv.c | 3 +- net/kcm/kcmsock.c | 4 + net/mac80211/agg-tx.c | 6 +- net/mac80211/driver-ops.c | 3 - net/mac80211/sta_info.c | 14 ++ net/mptcp/diag.c | 2 +- net/mptcp/protocol.c | 2 +- net/netfilter/nf_flow_table_inet.c | 3 + net/netfilter/nf_flow_table_ip.c | 3 + net/netfilter/nf_flow_table_offload.c | 2 +- net/netfilter/nfnetlink_queue.c | 35 +++- net/netfilter/nft_counter.c | 9 +- net/netlink/af_netlink.c | 13 +- net/rds/recv.c | 13 +- net/sched/sch_netem.c | 47 +++-- net/sunrpc/stats.c | 2 +- net/sunrpc/svc.c | 36 ++-- net/wireless/core.h | 8 +- security/apparmor/policy_unpack_test.c | 6 +- security/selinux/avc.c | 2 +- sound/core/timer.c | 2 +- sound/pci/hda/patch_realtek.c | 1 - sound/usb/quirks-table.h | 1 + sound/usb/quirks.c | 2 + tools/include/linux/align.h | 12 ++ tools/include/linux/bitmap.h | 9 +- tools/testing/selftests/core/close_range_test.c | 35 ++++ tools/testing/selftests/tc-testing/tdc.py | 1 - 224 files changed, 2394 insertions(+), 1053 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/215 fuse: Initialize beyond-EOF page contents before setting uptodate
5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 3c0da3d163eb32f1f91891efaade027fa9b245b9 upstream.
fuse_notify_store(), unlike fuse_do_readpage(), does not enable page zeroing (because it can be used to change partial page contents).
So fuse_notify_store() must be more careful to fully initialize page contents (including parts of the page that are beyond end-of-file) before marking the page uptodate.
The current code can leave beyond-EOF page contents uninitialized, which makes these uninitialized page contents visible to userspace via mmap().
This is an information leak, but only affects systems which do not enable init-on-alloc (via CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y or the corresponding kernel command line parameter).
--- fs/fuse/dev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/fuse/dev.c +4 -2
@@ -1623,9 +1623,11 @@ static int fuse_notify_store(struct fuse this_num =min_t (unsigned, num,PAGE_SIZE - offset); err =fuse_copy_page (cs, &page, offset, this_num,0 ); -if (!err && offset ==0 && - (this_num ==PAGE_SIZE || file_size == end)) +if (!PageUptodate (page) && !err && offset ==0 && + (this_num ==PAGE_SIZE || file_size == end)) { +zero_user_segment (page, this_num,PAGE_SIZE );SetPageUptodate (page); + }unlock_page (page);put_page (page);
Greg Kroah-Hartman
maintainerPATCH 2/215 char: xillybus: Dont destroy workqueue from work item running on it
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eli Billauer <[email protected]>
commit ccbde4b128ef9c73d14d0d7817d68ef795f6d131 upstream.
Triggered by a kref decrement, destroy_workqueue() may be called from within a work item for destroying its own workqueue. This illegal situation is averted by adding a module-global workqueue for exclusive use of the offending work item. Other work items continue to be queued on per-device workqueues to ensure performance.
--- drivers/char/xillybus/xillyusb.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/char/xillybus/xillyusb.c +11 -5
@@ -50,6 +50,7 @@ MODULE_LICENSE("GPL v2");static const char xillyname[] ="xillyusb" ;static unsigned int fifo_buf_order; +static struct workqueue_struct *wakeup_wq;#define USB_VENDOR_ID_XILINX 0x03fd#define USB_VENDOR_ID_ALTERA 0x09fb
@@ -561,10 +562,6 @@ static void cleanup_dev(struct kref *kre* errors if executed. The mechanism relies on that xdev->error is assigned * a non-zero value by report_io_error() prior to queueing wakeup_all(), * which prevents bulk_in_work() from calling process_bulk_in(). -* -* The fact that wakeup_all() and bulk_in_work() are queued on the same -* workqueue makes their concurrent execution very unlikely, however the -* kernel's API doesn't seem to ensure this strictly. */ static void wakeup_all (struct work_struct *work)
@@ -619,7 +616,7 @@ static void report_io_error(struct xillyif (do_once) {kref_get (&xdev->kref);/* xdev is used by work item */ -queue_work (xdev->workq, &xdev->wakeup_workitem); +queue_work (wakeup_wq, &xdev->wakeup_workitem); } }
@@ -2242,6 +2239,10 @@ static int __init xillyusb_init(void) {int rc =0 ; + wakeup_wq =alloc_workqueue (xillyname,0 ,0 ); +if (!wakeup_wq) +return -ENOMEM ; +if (LOG2_INITIAL_FIFO_BUF_SIZE >PAGE_SHIFT ) fifo_buf_order =LOG2_INITIAL_FIFO_BUF_SIZE -PAGE_SHIFT ;else
@@ -2249,11 +2250,16 @@ static int __init xillyusb_init(void) rc =usb_register (&xillyusb_driver); +if (rc) +destroy_workqueue (wakeup_wq); +return rc; } static void __exit xillyusb_exit(void) { +destroy_workqueue (wakeup_wq); +usb_deregister (&xillyusb_driver); }
Greg Kroah-Hartman
maintainerPATCH 3/215 char: xillybus: Refine workqueue handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eli Billauer <[email protected]>
commit ad899c301c880766cc709aad277991b3ab671b66 upstream.
As the wakeup work item now runs on a separate workqueue, it needs to be flushed separately along with flushing the device's workqueue.
Also, move the destroy_workqueue() call to the end of the exit method, so that deinitialization is done in the opposite order of initialization.
--- drivers/char/xillybus/xillyusb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/char/xillybus/xillyusb.c +5 -3
@@ -2079,9 +2079,11 @@ static int xillyusb_discovery(struct usb* just after responding with the IDT, there is no reason for any * work item to be running now. To be sure that xdev->channels * is updated on anything that might run in parallel, flush the -* workqueue, which rarely does anything. +* device's workqueue and the wakeup work item. This rarely +* does anything. */ flush_workqueue (xdev->workq); +flush_work (&xdev->wakeup_workitem); xdev->num_channels = num_channels;
@@ -2258,9 +2260,9 @@ static int __init xillyusb_init(void) static void __exit xillyusb_exit(void) { -destroy_workqueue (wakeup_wq); -usb_deregister (&xillyusb_driver); + +destroy_workqueue (wakeup_wq); }module_init (xillyusb_init);
Greg Kroah-Hartman
maintainerPATCH 4/215 char: xillybus: Check USB endpoints when probing device
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eli Billauer <[email protected]>
commit 2374bf7558de915edc6ec8cb10ec3291dfab9594 upstream.
Ensure, as the driver probes the device, that all endpoints that the driver may attempt to access exist and are of the correct type.
All XillyUSB devices must have a Bulk IN and Bulk OUT endpoint at address 1. This is verified in xillyusb_setup_base_eps().
On top of that, a XillyUSB device may have additional Bulk OUT endpoints. The information about these endpoints' addresses is deduced from a data structure (the IDT) that the driver fetches from the device while probing it. These endpoints are checked in setup_channels().
A XillyUSB device never has more than one IN endpoint, as all data towards the host is multiplexed in this single Bulk IN endpoint. This is why setup_channels() only checks OUT endpoints.
--- drivers/char/xillybus/xillyusb.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
drivers/char/xillybus/xillyusb.c +20 -2
@@ -1889,6 +1889,13 @@ static const struct file_operations xillstatic int xillyusb_setup_base_eps (struct xillyusb_dev *xdev) { +struct usb_device *udev = xdev->udev; + +/* Verify that device has the two fundamental bulk in/out endpoints */ +if (usb_pipe_type_check (udev,usb_sndbulkpipe (udev,MSG_EP_NUM )) || +usb_pipe_type_check (udev,usb_rcvbulkpipe (udev,IN_EP_NUM ))) +return -ENODEV ; + xdev->msg_ep =endpoint_alloc (xdev,MSG_EP_NUM |USB_DIR_OUT , bulk_out_work,1 ,2 );if (!xdev->msg_ep)
@@ -1918,14 +1925,15 @@ static int setup_channels(struct xillyus __le16 *chandesc, int num_channels) { -struct xillyusb_channel *chan; +struct usb_device *udev = xdev->udev; +struct xillyusb_channel *chan, *new_channels;int i; chan =kcalloc (num_channels,sizeof (*chan),GFP_KERNEL );if (!chan)return -ENOMEM ; - xdev->channels = chan; + new_channels = chan;for (i =0 ; i < num_channels; i++, chan++) {unsigned int in_desc =le16_to_cpu (*chandesc++);
@@ -1954,6 +1962,15 @@ static int setup_channels(struct xillyus*/ if ((out_desc &0x80 ) && i <14 ) {/* Entry is valid */ +if (usb_pipe_type_check (udev, +usb_sndbulkpipe (udev, i +2 ))) { +dev_err (xdev->dev, +"Missing BULK OUT endpoint %d\n" , + i +2 ); +kfree (new_channels); +return -ENODEV ; + } + chan->writable =1 ; chan->out_synchronous = !!(out_desc &0x40 ); chan->out_seekable = !!(out_desc &0x20 );
@@ -1963,6 +1980,7 @@ static int setup_channels(struct xillyus } } + xdev->channels = new_channels;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 5/215 ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lianqin Hu <[email protected]>
commit 004eb8ba776ccd3e296ea6f78f7ae7985b12824e upstream.
Audio control requests that sets sampling frequency sometimes fail on this card. Adding delay between control messages eliminates that problem.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -1900,6 +1900,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_GENERIC_IMPLICIT_FB),DEVICE_FLG (0x2b53 ,0x0031 ,/* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB ), +DEVICE_FLG (0x2d95 ,0x8021 ,/* VIVO USB-C-XE710 HEADSET */ +QUIRK_FLAG_CTL_MSG_DELAY_1M ),DEVICE_FLG (0x30be ,0x0101 ,/* Schiit Hel */ QUIRK_FLAG_IGNORE_CTL_ERROR ), DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
Greg Kroah-Hartman
maintainerPATCH 6/215 ALSA: usb-audio: Support Yamaha P-125 quirk entry
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juan José Arboleda <[email protected]>
commit c286f204ce6ba7b48e3dcba53eda7df8eaa64dd9 upstream.
This patch adds a USB quirk for the Yamaha P-125 digital piano.
--- sound/usb/quirks-table.h | 1 + 1 file changed, 1 insertion(+)
sound/usb/quirks-table.h +1 -0
@@ -273,6 +273,7 @@ YAMAHA_DEVICE(0x105a, NULL), YAMAHA_DEVICE(0x105b, NULL), YAMAHA_DEVICE(0x105c, NULL), YAMAHA_DEVICE(0x105d, NULL), +YAMAHA_DEVICE(0x1718, "P-125"), { USB_DEVICE(0x0499, 0x1503), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
Greg Kroah-Hartman
maintainerPATCH 7/215 xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit af8e119f52e9c13e556be9e03f27957554a84656 upstream.
re-enumerating full-speed devices after a failed address device command can trigger a NULL pointer dereference.
Full-speed devices may need to reconfigure the endpoint 0 Max Packet Size value during enumeration. Usb core calls usb_ep0_reinit() in this case, which ends up calling xhci_configure_endpoint().
On Panther point xHC the xhci_configure_endpoint() function will additionally check and reserve bandwidth in software. Other hosts do this in hardware
If xHC address device command fails then a new xhci_virt_device structure is allocated as part of re-enabling the slot, but the bandwidth table pointers are not set up properly here.
This triggers the NULL pointer dereference the next time usb_ep0_reinit() is called and xhci_configure_endpoint() tries to check and reserve bandwidth
[46710.713538] usb 3-1: new full-speed USB device number 5 using xhci_hcd [46710.713699] usb 3-1: Device not responding to setup address. [46710.917684] usb 3-1: Device not responding to setup address. [46711.125536] usb 3-1: device not accepting address 5, error -71 [46711.125594] BUG: kernel NULL pointer dereference, address: 0000000000000008 [46711.125600] #PF: supervisor read access in kernel mode [46711.125603] #PF: error_code(0x0000) - not-present page [46711.125606] PGD 0 P4D 0 [46711.125610] Oops: Oops: 0000 [#1] PREEMPT SMP PTI [46711.125615] CPU: 1 PID: 25760 Comm: kworker/1:2 Not tainted 6.10.3_2 #1 [46711.125620] Hardware name: Gigabyte Technology Co., Ltd. [46711.125623] Workqueue: usb_hub_wq hub_event [usbcore] [46711.125668] RIP: 0010:xhci_reserve_bandwidth (drivers/usb/host/xhci.c
Fix this by making sure bandwidth table pointers are set up correctly after a failed address device command, and additionally by avoiding checking for bandwidth in cases like this where no actual endpoints are added or removed, i.e. only context for default control endpoint 0 is evaluated.
--- drivers/usb/host/xhci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/usb/host/xhci.c +5 -3
@@ -2954,7 +2954,7 @@ static int xhci_configure_endpoint(struc xhci->num_active_eps);return -ENOMEM ; } -if ((xhci->quirks &XHCI_SW_BW_CHECKING ) && +if ((xhci->quirks &XHCI_SW_BW_CHECKING ) && !ctx_change &&xhci_reserve_bandwidth (xhci, virt_dev, command->in_ctx)) {if ((xhci->quirks &XHCI_EP_LIMIT_QUIRK ))xhci_free_host_resources (xhci, ctrl_ctx);
@@ -4294,8 +4294,10 @@ static int xhci_setup_device(struct usb_mutex_unlock (&xhci->mutex); ret =xhci_disable_slot (xhci, udev->slot_id);xhci_free_virt_device (xhci, udev->slot_id); -if (!ret) -xhci_alloc_dev (hcd, udev); +if (!ret) { +if (xhci_alloc_dev (hcd, udev) ==1 ) +xhci_setup_addressable_virt_dev (xhci, udev); + }kfree (command->completion);kfree (command);return -EPROTO ;
Greg Kroah-Hartman
maintainerPATCH 8/215 thunderbolt: Mark XDomain as unplugged when router is removed
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg <[email protected]>
commit e2006140ad2e01a02ed0aff49cc2ae3ceeb11f8d upstream.
I noticed that when we do discrete host router NVM upgrade and it gets hot-removed from the PCIe side as a result of NVM firmware authentication, if there is another host connected with enabled paths we hang in tearing them down. This is due to fact that the Thunderbolt networking driver also tries to cleanup the paths and ends up blocking in tb_disconnect_xdomain_paths() waiting for the domain lock.
However, at this point we already cleaned the paths in tb_stop() so there is really no need for tb_disconnect_xdomain_paths() to do that anymore. Furthermore it already checks if the XDomain is unplugged and bails out early so take advantage of that and mark the XDomain as unplugged when we remove the parent router.
--- drivers/thunderbolt/switch.c | 1 + 1 file changed, 1 insertion(+)
drivers/thunderbolt/switch.c +1 -0
@@ -2877,6 +2877,7 @@ void tb_switch_remove(struct tb_switch *tb_switch_remove (port->remote->sw); port->remote =NULL ; }else if (port->xdomain) { + port->xdomain->is_unplugged = true;tb_xdomain_remove (port->xdomain); port->xdomain =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 9/215 s390/dasd: fix error recovery leading to data corruption on ESE devices
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Haberland <[email protected]>
commit 7db4042336580dfd75cb5faa82c12cd51098c90b upstream.
Extent Space Efficient (ESE) or thin provisioned volumes need to be formatted on demand during usual IO processing.
The dasd_ese_needs_format function checks for error codes that signal the non existence of a proper track format.
The check for incorrect length is to imprecise since other error cases leading to transport of insufficient data also have this flag set. This might lead to data corruption in certain error cases for example during a storage server warmstart.
Fix by removing the check for incorrect length and replacing by explicitly checking for invalid track format in transport mode.
Also remove the check for file protected since this is not a valid ESE handling case.
--- drivers/s390/block/dasd.c | 36 +++++++++++++++--------- drivers/s390/block/dasd_3990_erp.c | 10 +----- drivers/s390/block/dasd_eckd.c | 55 ++++++++++++++++--------------------- drivers/s390/block/dasd_int.h | 2 - 4 files changed, 50 insertions(+), 53 deletions(-)
drivers/s390/block/dasd.c +23 -13
@@ -1622,9 +1622,15 @@ static int dasd_ese_needs_format(structif (!sense)return 0 ; -return !!(sense[1 ] &SNS1_NO_REC_FOUND ) || - !!(sense[1 ] &SNS1_FILE_PROTECTED ) || -scsw_cstat (&irb->scsw) ==SCHN_STAT_INCORR_LEN ; +if (sense[1 ] &SNS1_NO_REC_FOUND ) +return 1 ; + +if ((sense[1 ] &SNS1_INV_TRACK_FORMAT ) && +scsw_is_tm (&irb->scsw) && + !(sense[2 ] &SNS2_ENV_DATA_PRESENT )) +return 1 ; + +return 0 ; }static int dasd_ese_oos_cond (u8 *sense)
@@ -1645,7 +1651,7 @@ void dasd_int_handler(struct ccw_devicestruct dasd_device *device;unsigned long now;int nrf_suppressed =0 ; -int fp_suppressed =0 ; +int it_suppressed =0 ;struct request *req;u8 *sense =NULL ;int expires;
@@ -1700,8 +1706,9 @@ void dasd_int_handler(struct ccw_device*/ sense =dasd_get_sense (irb);if (sense) { - fp_suppressed = (sense[1 ] &SNS1_FILE_PROTECTED ) && -test_bit (DASD_CQR_SUPPRESS_FP , &cqr->flags); + it_suppressed = (sense[1 ] &SNS1_INV_TRACK_FORMAT ) && + !(sense[2 ] &SNS2_ENV_DATA_PRESENT ) && +test_bit (DASD_CQR_SUPPRESS_IT , &cqr->flags); nrf_suppressed = (sense[1 ] &SNS1_NO_REC_FOUND ) &&test_bit (DASD_CQR_SUPPRESS_NRF , &cqr->flags);
@@ -1716,7 +1723,7 @@ void dasd_int_handler(struct ccw_devicereturn ; } } -if (!(fp_suppressed || nrf_suppressed)) +if (!(it_suppressed || nrf_suppressed)) device->discipline->dump_sense_dbf (device, irb,"int" );if (device->features &DASD_FEATURE_ERPLOG )
@@ -2474,14 +2481,17 @@ retry: rc =0 ;list_for_each_entry_safe (cqr, n, ccw_queue, blocklist) {/* -* In some cases the 'File Protected' or 'Incorrect Length' -* error might be expected and error recovery would be -* unnecessary in these cases. Check if the according suppress -* bit is set. +* In some cases certain errors might be expected and +* error recovery would be unnecessary in these cases. +* Check if the according suppress bit is set. */ sense =dasd_get_sense (&cqr->irb); -if (sense && sense[1 ] &SNS1_FILE_PROTECTED && -test_bit (DASD_CQR_SUPPRESS_FP , &cqr->flags)) +if (sense && (sense[1 ] &SNS1_INV_TRACK_FORMAT ) && + !(sense[2 ] &SNS2_ENV_DATA_PRESENT ) && +test_bit (DASD_CQR_SUPPRESS_IT , &cqr->flags)) +continue ; +if (sense && (sense[1 ] &SNS1_NO_REC_FOUND ) && +test_bit (DASD_CQR_SUPPRESS_NRF , &cqr->flags))continue ;if (scsw_cstat (&cqr->irb.scsw) ==0x40 &&test_bit (DASD_CQR_SUPPRESS_IL , &cqr->flags))
drivers/s390/block/dasd_3990_erp.c +2 -8
@@ -1401,14 +1401,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_struct dasd_device *device = erp->startdev; -/* -* In some cases the 'File Protected' error might be expected and -* log messages shouldn't be written then. -* Check if the according suppress bit is set. -*/ -if (!test_bit (DASD_CQR_SUPPRESS_FP , &erp->flags)) -dev_err (&device->cdev->dev, -"Accessing the DASD failed because of a hardware error\n" ); +dev_err (&device->cdev->dev, +"Accessing the DASD failed because of a hardware error\n" );return dasd_3990_erp_cleanup (erp,DASD_CQR_FAILED );
drivers/s390/block/dasd_eckd.c +24 -31
90 lines not on this page · raw message
drivers/s390/block/dasd_int.h +1 -1
@@ -226,7 +226,7 @@ struct dasd_ccw_req {* The following flags are used to suppress output of certain errors. */ #define DASD_CQR_SUPPRESS_NRF 4/* Suppress 'No Record Found' error */ -#define DASD_CQR_SUPPRESS_FP 5/* Suppress 'File Protected' error*/ +#define DASD_CQR_SUPPRESS_IT 5/* Suppress 'Invalid Track' error*/ #define DASD_CQR_SUPPRESS_IL 6/* Suppress 'Incorrect Length' error */ #define DASD_CQR_SUPPRESS_CR 7/* Suppress 'Command Reject' error */
Greg Kroah-Hartman
maintainerPATCH 10/215 arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to NUMA_NO_NODE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Xu <[email protected]>
commit a21dcf0ea8566ebbe011c79d6ed08cdfea771de3 upstream.
Currently, only acpi_early_node_map[0] was initialized to NUMA_NO_NODE. To ensure all the values were properly initialized, switch to initialize all of them to NUMA_NO_NODE.
--- arch/arm64/kernel/acpi_numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/acpi_numa.c +1 -1
@@ -27,7 +27,7 @@#include <asm/numa.h> -static int acpi_early_node_map[NR_CPUS ]__initdata = {NUMA_NO_NODE }; +static int acpi_early_node_map[NR_CPUS ]__initdata = { [0 ...NR_CPUS -1 ] =NUMA_NO_NODE };int __init acpi_numa_get_nid (unsigned int cpu) {
Greg Kroah-Hartman
maintainerPATCH 11/215 dm resume: dont return EINVAL when signalled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Khazhismel Kumykov <[email protected]>
commit 7a636b4f03af9d541205f69e373672e7b2b60a8a upstream.
If the dm_resume method is called on a device that is not suspended, the method will suspend the device briefly, before resuming it (so that the table will be swapped).
However, there was a bug that the return value of dm_suspended_md was not checked. dm_suspended_md may return an error when it is interrupted by a signal. In this case, do_resume would call dm_swap_table, which would return -EINVAL.
This commit fixes the logic, so that error returned by dm_suspend is checked and the resume operation is undone.
--- drivers/md/dm-ioctl.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
drivers/md/dm-ioctl.c +20 -2
@@ -1151,8 +1151,26 @@ static int do_resume(struct dm_ioctl *pa suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG ;if (param->flags &DM_NOFLUSH_FLAG ) suspend_flags |=DM_SUSPEND_NOFLUSH_FLAG ; -if (!dm_suspended_md (md)) -dm_suspend (md, suspend_flags); +if (!dm_suspended_md (md)) { + r =dm_suspend (md, suspend_flags); +if (r) { +down_write (&_hash_lock); + hc =dm_get_mdptr (md); +if (hc && !hc->new_map) { + hc->new_map = new_map; + new_map =NULL ; + }else { + r = -ENXIO ; + } +up_write (&_hash_lock); +if (new_map) { +dm_sync_table (md); +dm_table_destroy (new_map); + } +dm_put (md); +return r; + } + } old_size =dm_get_size (md); old_map =dm_swap_table (md, new_map);
Greg Kroah-Hartman
maintainerPATCH 12/215 dm persistent data: fix memory allocation failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit faada2174c08662ae98b439c69efe3e79382c538 upstream.
kmalloc is unreliable when allocating more than 8 pages of memory. It may fail when there is plenty of free memory but the memory is fragmented. Zdenek Kabelac observed such failure in his tests.
This commit changes kmalloc to kvmalloc - kvmalloc will fall back to vmalloc if the large allocation fails.
--- drivers/md/persistent-data/dm-space-map-metadata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/persistent-data/dm-space-map-metadata.c +2 -2
@@ -274,7 +274,7 @@ static void sm_metadata_destroy(struct d { struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); -kfree (smm); +kvfree (smm); }static int sm_metadata_get_nr_blocks (struct dm_space_map *sm,dm_block_t *count)
@@ -768,7 +768,7 @@ struct dm_space_map *dm_sm_metadata_init {struct sm_metadata *smm; - smm =kmalloc (sizeof (*smm),GFP_KERNEL ); + smm =kvmalloc (sizeof (*smm),GFP_KERNEL );if (!smm)return ERR_PTR (-ENOMEM );
Greg Kroah-Hartman
maintainerPATCH 13/215 vfs: Dont evict inode under the inode lru traversing context
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit 2a0629834cd82f05d424bbc193374f9a43d1f87d upstream.
The inode reclaiming process(See function prune_icache_sb) collects all reclaimable inodes and mark them with I_FREEING flag at first, at that time, other processes will be stuck if they try getting these inodes (See function find_inode_fast), then the reclaiming process destroy the inodes by function dispose_list(). Some filesystems(eg. ext4 with ea_inode feature, ubifs with xattr) may do inode lookup in the inode evicting callback function, if the inode lookup is operated under the inode lru traversing context, deadlock problems may happen.
Case 1: In function ext4_evict_inode(), the ea inode lookup could happen
if ea_inode feature is enabled, the lookup process will be stuck under the evicting context like this:
1. File A has inode i_reg and an ea inode i_ea
2. getfattr(A, xattr_buf) // i_ea is added into lru // lru->i_ea
3. Then, following three processes running like this:
PA PB
echo 2 > /proc/sys/vm/drop_caches
shrink_slab
prune_dcache_sb
// i_reg is added into lru, lru->i_ea->i_reg
prune_icache_sb
list_lru_walk_one
inode_lru_isolate
i_ea->i_state |= I_FREEING // set inode state
inode_lru_isolate
__iget(i_reg)
spin_unlock(&i_reg->i_lock)
spin_unlock(lru_lock)
rm file A
i_reg->nlink = 0
iput(i_reg) // i_reg->nlink is 0, do evict
ext4_evict_inode
ext4_xattr_delete_inode
ext4_xattr_inode_dec_ref_all
ext4_xattr_inode_iget
ext4_iget(i_ea->i_ino)
iget_locked
find_inode_fast
__wait_on_freeing_inode(i_ea) ----→ AA deadlock
dispose_list // cannot be executed by prune_icache_sb
wake_up_bit(&i_ea->i_state)Case 2: In deleted inode writing function ubifs_jnl_write_inode(), file
deleting process holds BASEHD's wbuf->io_mutex while getting the xattr inode, which could race with inode reclaiming process(The reclaiming process could try locking BASEHD's wbuf->io_mutex in inode evicting function), then an ABBA deadlock problem would happen as following:
1. File A has inode ia and a xattr(with inode ixa), regular file B has inode ib and a xattr.
2. getfattr(A, xattr_buf) // ixa is added into lru // lru->ixa
3. Then, following three processes running like this:
PA PB PC
echo 2 > /proc/sys/vm/drop_caches
shrink_slab
prune_dcache_sb
// ib and ia are added into lru, lru->ixa->ib->ia
prune_icache_sb
list_lru_walk_one
inode_lru_isolate
ixa->i_state |= I_FREEING // set inode state
inode_lru_isolate
__iget(ib)
spin_unlock(&ib->i_lock)
spin_unlock(lru_lock)
rm file B
ib->nlink = 0
rm file A
iput(ia)
ubifs_evict_inode(ia)
ubifs_jnl_delete_inode(ia)
ubifs_jnl_write_inode(ia)
make_reservation(BASEHD) // Lock wbuf->io_mutex
ubifs_iget(ixa->i_ino)
iget_locked
find_inode_fast
__wait_on_freeing_inode(ixa)
| iput(ib) // ib->nlink is 0, do evict
| ubifs_evict_inode
| ubifs_jnl_delete_inode(ib)
↓ ubifs_jnl_write_inode
ABBA deadlock ←-----make_reservation(BASEHD)
dispose_list // cannot be executed by prune_icache_sb
wake_up_bit(&ixa->i_state)Fix the possible deadlock by using new inode state flag I_LRU_ISOLATING to pin the inode in memory while inode_lru_isolate() reclaims its pages instead of using ordinary inode reference. This way inode deletion cannot be triggered from inode_lru_isolate() thus avoiding the deadlock. evict() is made to wait for I_LRU_ISOLATING to be cleared before proceeding with inode cleanup.
--- fs/inode.c | 39 +++++++++++++++++++++++++++++++++++++-- include/linux/fs.h | 5 +++++ 2 files changed, 42 insertions(+), 2 deletions(-)
fs/inode.c +37 -2
@@ -456,6 +456,39 @@ static void inode_lru_list_del(struct inthis_cpu_dec (nr_unused); } +static void inode_pin_lru_isolating (struct inode *inode) +{ +lockdep_assert_held (&inode->i_lock); +WARN_ON (inode->i_state & (I_LRU_ISOLATING |I_FREEING |I_WILL_FREE )); + inode->i_state |=I_LRU_ISOLATING ; +} + +static void inode_unpin_lru_isolating (struct inode *inode) +{ +spin_lock (&inode->i_lock); +WARN_ON (!(inode->i_state &I_LRU_ISOLATING )); + inode->i_state &= ~I_LRU_ISOLATING ; +smp_mb (); +wake_up_bit (&inode->i_state, __I_LRU_ISOLATING); +spin_unlock (&inode->i_lock); +} + +static void inode_wait_for_lru_isolating (struct inode *inode) +{ +spin_lock (&inode->i_lock); +if (inode->i_state &I_LRU_ISOLATING ) { +DEFINE_WAIT_BIT (wq, &inode->i_state, __I_LRU_ISOLATING); +wait_queue_head_t *wqh; + + wqh =bit_waitqueue (&inode->i_state, __I_LRU_ISOLATING); +spin_unlock (&inode->i_lock); +__wait_on_bit (wqh, &wq, bit_wait,TASK_UNINTERRUPTIBLE ); +spin_lock (&inode->i_lock); +WARN_ON (inode->i_state &I_LRU_ISOLATING ); + } +spin_unlock (&inode->i_lock); +} +/** * inode_sb_list_add - add inode to the superblock list of inodes * @inode: inode to add
@@ -575,6 +608,8 @@ static void evict(struct inode *inode)inode_sb_list_del (inode); +inode_wait_for_lru_isolating (inode); +/* * Wait for flusher thread to be done with the inode so that filesystem * does not start destroying it while writeback is still running. Since
@@ -772,7 +807,7 @@ static enum lru_status inode_lru_isolate }if (inode_has_buffers (inode) || !mapping_empty (&inode->i_data)) { -__iget (inode); +inode_pin_lru_isolating (inode);spin_unlock (&inode->i_lock);spin_unlock (lru_lock);if (remove_inode_buffers (inode)) {
@@ -785,7 +820,7 @@ static enum lru_status inode_lru_isolateif (current->reclaim_state) current->reclaim_state->reclaimed_slab += reap; } -iput (inode); +inode_unpin_lru_isolating (inode);spin_lock (lru_lock);return LRU_RETRY ; }
include/linux/fs.h +5 -0
@@ -2429,6 +2429,9 @@ static inline void kiocb_clone(struct ki* Used to detect that mark_inode_dirty() should not move * inode between dirty lists. * +* I_LRU_ISOLATING Inode is pinned being isolated from LRU without holding +* i_count. +* * Q: What is the difference between I_WILL_FREE and I_FREEING? */ #define I_DIRTY_SYNC (1 << 0)
@@ -2451,6 +2454,8 @@ static inline void kiocb_clone(struct ki#define I_CREATING (1 << 15)#define I_DONTCACHE (1 << 16)#define I_SYNC_QUEUED (1 << 17) +#define __I_LRU_ISOLATING 19 +#define I_LRU_ISOLATING (1 << __I_LRU_ISOLATING)#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
Greg Kroah-Hartman
maintainerPATCH 14/215 fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Lobakin <[email protected]>
commit 3f5ef5109f6a054ce58b3bec7214ed76c9cc269f upstream.
bitmap_size() is a pretty generic name and one may want to use it for a generic bitmap API function. At the same time, its logic is NTFS-specific, as it aligns to the sizeof(u64), not the sizeof(long) (although it uses ideologically right ALIGN() instead of division). Add the prefix 'ntfs3_' used for that FS (not just 'ntfs_' to not mix it with the legacy module) and use generic BITS_TO_U64() while at it.
--- fs/ntfs3/bitmap.c | 4 ++-- fs/ntfs3/fsntfs.c | 2 +- fs/ntfs3/index.c | 11 ++++++----- fs/ntfs3/ntfs_fs.h | 4 ++-- fs/ntfs3/super.c | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-)
fs/ntfs3/bitmap.c +2 -2
@@ -661,7 +661,7 @@ int wnd_init(struct wnd_bitmap *wnd, str wnd->total_zeroes = nbits; wnd->extent_max =MINUS_ONE_T ; wnd->zone_bit = wnd->zone_end =0 ; - wnd->nwnd =bytes_to_block (sb,bitmap_size (nbits)); + wnd->nwnd =bytes_to_block (sb,ntfs3_bitmap_size (nbits)); wnd->bits_last = nbits & (wbits -1 );if (!wnd->bits_last) wnd->bits_last = wbits;
@@ -1325,7 +1325,7 @@ int wnd_extend(struct wnd_bitmap *wnd, sreturn -EINVAL ;/* Align to 8 byte boundary. */ - new_wnd =bytes_to_block (sb,bitmap_size (new_bits)); + new_wnd =bytes_to_block (sb,ntfs3_bitmap_size (new_bits)); new_last = new_bits & (wbits -1 );if (!new_last) new_last = wbits;
fs/ntfs3/fsntfs.c +1 -1
@@ -493,7 +493,7 @@ static int ntfs_extend_mft(struct ntfs_s ni->mi.dirty = true;/* Step 2: Resize $MFT::BITMAP. */ - new_bitmap_bytes =bitmap_size (new_mft_total); + new_bitmap_bytes =ntfs3_bitmap_size (new_mft_total); err =attr_set_size (ni,ATTR_BITMAP ,NULL ,0 , &sbi->mft.bitmap.run, new_bitmap_bytes, &new_bitmap_bytes, true,NULL );
fs/ntfs3/index.c +6 -5
@@ -1461,8 +1461,8 @@ static int indx_create_allocate(struct n alloc->nres.valid_size = alloc->nres.data_size =cpu_to_le64 (data_size); - err =ni_insert_resident (ni,bitmap_size (1 ),ATTR_BITMAP , in->name, - in->name_len, &bitmap,NULL ,NULL ); + err =ni_insert_resident (ni,ntfs3_bitmap_size (1 ),ATTR_BITMAP , + in->name, in->name_len, &bitmap,NULL ,NULL );if (err) goto out2;
@@ -1523,8 +1523,9 @@ static int indx_add_allocate(struct ntfsif (bmp) {/* Increase bitmap. */ err =attr_set_size (ni,ATTR_BITMAP , in->name, in->name_len, - &indx->bitmap_run,bitmap_size (bit +1 ), -NULL , true,NULL ); + &indx->bitmap_run, +ntfs3_bitmap_size (bit +1 ),NULL , true, +NULL );if (err) goto out1; }
@@ -2087,7 +2088,7 @@ static int indx_shrink(struct ntfs_indexif (err)return err; - bpb =bitmap_size (bit); + bpb =ntfs3_bitmap_size (bit);if (bpb *8 == nbits)return 0 ;
fs/ntfs3/ntfs_fs.h +2 -2
@@ -950,9 +950,9 @@ static inline bool run_is_empty(struct r }/* NTFS uses quad aligned bitmaps. */ -static inline size_t bitmap_size (size_t bits) +static inline size_t ntfs3_bitmap_size (size_t bits) { -return ALIGN ((bits +7 ) >>3 ,8 ); +return BITS_TO_U64 (bits) *sizeof (u64); }#define _100ns2seconds 10000000
fs/ntfs3/super.c +1 -1
@@ -1103,7 +1103,7 @@ static int ntfs_fill_super(struct super_/* Check bitmap boundary. */ tt = sbi->used.bitmap.nbits; -if (inode->i_size <bitmap_size (tt)) { +if (inode->i_size <ntfs3_bitmap_size (tt)) { err = -EINVAL ; goto put_inode_out; }
Greg Kroah-Hartman
maintainerPATCH 15/215 s390/cio: rename bitmap_size() -> idset_bitmap_size()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Lobakin <[email protected]>
commit c1023f5634b9bfcbfff0dc200245309e3cde9b54 upstream.
bitmap_size() is a pretty generic name and one may want to use it for a generic bitmap API function. At the same time, its logic is not "generic", i.e. it's not just nbits -> size of bitmap in bytes converter as it would be expected from its name.
Add the prefix 'idset_' used throughout the file where the function resides.
--- drivers/s390/cio/idset.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/s390/cio/idset.c +6 -4
@@ -16,7 +16,7 @@ struct idset {unsigned long bitmap[]; }; -static inline unsigned long bitmap_size (int num_ssid,int num_id) +static inline unsigned long idset_bitmap_size (int num_ssid,int num_id) {return BITS_TO_LONGS (num_ssid * num_id) *sizeof (unsigned long ); }
@@ -25,11 +25,12 @@ static struct idset *idset_new(int num_s {struct idset *set; - set =vmalloc (sizeof (struct idset ) +bitmap_size (num_ssid, num_id)); + set =vmalloc (sizeof (struct idset ) + +idset_bitmap_size (num_ssid, num_id));if (set) { set->num_ssid = num_ssid; set->num_id = num_id; -memset (set->bitmap,0 ,bitmap_size (num_ssid, num_id)); +memset (set->bitmap,0 ,idset_bitmap_size (num_ssid, num_id)); }return set; }
@@ -41,7 +42,8 @@ void idset_free(struct idset *set)void idset_fill (struct idset *set) { -memset (set->bitmap,0xff ,bitmap_size (set->num_ssid, set->num_id)); +memset (set->bitmap,0xff , +idset_bitmap_size (set->num_ssid, set->num_id)); }static inline void idset_add (struct idset *set,int ssid,int id)
Greg Kroah-Hartman
maintainerPATCH 16/215 btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Lobakin <[email protected]>
commit 4ca532d64648d4776d15512caed3efea05ca7195 upstream.
bitmap_set_bits() does not start with the FS' prefix and may collide with a new generic helper one day. It operates with the FS-specific types, so there's no change those two could do the same thing. Just add the prefix to exclude such possible conflict.
--- fs/btrfs/free-space-cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/btrfs/free-space-cache.c +4 -4
@@ -1787,9 +1787,9 @@ static void bitmap_clear_bits(struct btr ctl->free_space -= bytes; } -static void bitmap_set_bits (struct btrfs_free_space_ctl *ctl, -struct btrfs_free_space *info,u64 offset, -u64 bytes) +static void btrfs_bitmap_set_bits (struct btrfs_free_space_ctl *ctl, +struct btrfs_free_space *info,u64 offset, +u64 bytes) {unsigned long start, count, end;int extent_delta =1 ;
@@ -2085,7 +2085,7 @@ static u64 add_bytes_to_bitmap(struct bt bytes_to_set =min (end - offset, bytes); -bitmap_set_bits (ctl, info, offset, bytes_to_set); +btrfs_bitmap_set_bits (ctl, info, offset, bytes_to_set);/* * We set some bytes, we have no idea what the max extent size is
Greg Kroah-Hartman
maintainerPATCH 17/215 bitmap: introduce generic optimized bitmap_size()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Lobakin <[email protected]>
commit a37fbe666c016fd89e4460d0ebfcea05baba46dc upstream.
The number of times yet another open coded BITS_TO_LONGS(nbits) * sizeof(long) can be spotted is huge. Some generic helper is long overdue.
Add one, bitmap_size(), but with one detail. BITS_TO_LONGS() uses DIV_ROUND_UP(). The latter works well when both divident and divisor are compile-time constants or when the divisor is not a pow-of-2. When it is however, the compilers sometimes tend to generate suboptimal code (GCC 13):
48 83 c0 3f add $0x3f,%rax 48 c1 e8 06 shr $0x6,%rax
48 8d 14 c5 00 00 00 00 lea 0x0(,%rax,8),%rdx
%BITS_PER_LONG is always a pow-2 (either 32 or 64), but GCC still does full division of nbits + 63 by it and then multiplication by 8. Instead of BITS_TO_LONGS(), use ALIGN() and then divide by 8. GCC:
8d 50 3f lea 0x3f(%rax),%edx c1 ea 03 shr $0x3,%edx 81 e2 f8 ff ff 1f and $0x1ffffff8,%edx
Now it shifts nbits + 63 by 3 positions (IOW performs fast division by 8) and then masks bits[2:0]. bloat-o-meter:
add/remove: 0/0 grow/shrink: 20/133 up/down: 156/-773 (-617)
Clang does it better and generates the same code before/after starting from -O1, except that with the ALIGN() approach it uses %edx and thus still saves some bytes:
add/remove: 0/0 grow/shrink: 9/133 up/down: 18/-538 (-520)
Note that we can't expand DIV_ROUND_UP() by adding a check and using this approach there, as it's used in array declarations where expressions are not allowed.
Add this helper to tools/ as well.
--- drivers/md/dm-clone-metadata.c | 5 ----- drivers/s390/cio/idset.c | 2 +- include/linux/bitmap.h | 8 +++++--- include/linux/cpumask.h | 2 +- lib/math/prime_numbers.c | 2 -- tools/include/linux/bitmap.h | 7 ++++--- 6 files changed, 11 insertions(+), 15 deletions(-)
drivers/md/dm-clone-metadata.c +0 -5
@@ -465,11 +465,6 @@ static void __destroy_persistent_data_st/*---------------------------------------------------------------------------*/ -static size_t bitmap_size (unsigned long nr_bits) -{ -return BITS_TO_LONGS (nr_bits) *sizeof (long ); -} -static int __dirty_map_init (struct dirty_map *dmap,unsigned long nr_words,unsigned long nr_regions) {
drivers/s390/cio/idset.c +1 -1
@@ -18,7 +18,7 @@ struct idset {static inline unsigned long idset_bitmap_size (int num_ssid,int num_id) { -return BITS_TO_LONGS (num_ssid * num_id) *sizeof (unsigned long ); +return bitmap_size (size_mul (num_ssid, num_id)); }static struct idset *idset_new (int num_ssid,int num_id)
include/linux/bitmap.h +5 -3
@@ -236,22 +236,24 @@ extern int bitmap_print_list_to_buf(char#define BITMAP_FIRST_WORD_MASK (start) (~0UL << ((start) & (BITS_PER_LONG - 1)))#define BITMAP_LAST_WORD_MASK (nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) +#define bitmap_size (nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) +static inline void bitmap_zero (unsigned long *dst,unsigned int nbits) { -unsigned int len =BITS_TO_LONGS (nbits) *sizeof (unsigned long ); +unsigned int len =bitmap_size (nbits);memset (dst,0 , len); }static inline void bitmap_fill (unsigned long *dst,unsigned int nbits) { -unsigned int len =BITS_TO_LONGS (nbits) *sizeof (unsigned long ); +unsigned int len =bitmap_size (nbits);memset (dst,0xff , len); }static inline void bitmap_copy (unsigned long *dst,const unsigned long *src,unsigned int nbits) { -unsigned int len =BITS_TO_LONGS (nbits) *sizeof (unsigned long ); +unsigned int len =bitmap_size (nbits);memcpy (dst, src, len); }
include/linux/cpumask.h +1 -1
@@ -667,7 +667,7 @@ static inline int cpulist_parse(const ch*/ static inline unsigned int cpumask_size (void ) { -return BITS_TO_LONGS (nr_cpumask_bits) *sizeof (long ); +return bitmap_size (nr_cpumask_bits); }/*
lib/math/prime_numbers.c +0 -2
@@ -6,8 +6,6 @@#include <linux/prime_numbers.h> #include <linux/slab.h> -#define bitmap_size (nbits) (BITS_TO_LONGS(nbits) * sizeof(unsigned long)) -struct primes {struct rcu_head rcu;unsigned long last, sz;
tools/include/linux/bitmap.h +4 -3
@@ -24,13 +24,14 @@ int __bitmap_intersects(const unsigned l#define BITMAP_FIRST_WORD_MASK (start) (~0UL << ((start) & (BITS_PER_LONG - 1)))#define BITMAP_LAST_WORD_MASK (nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) +#define bitmap_size (nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) +static inline void bitmap_zero (unsigned long *dst,unsigned int nbits) {if (small_const_nbits (nbits)) *dst =0UL ;else { -int len =BITS_TO_LONGS (nbits) *sizeof (unsigned long ); -memset (dst,0 , len); +memset (dst,0 ,bitmap_size (nbits)); } }
@@ -116,7 +117,7 @@ static inline int test_and_clear_bit(int*/ static inline unsigned long *bitmap_zalloc (int nbits) { -return calloc (1 ,BITS_TO_LONGS (nbits) *sizeof (unsigned long )); +return calloc (1 ,bitmap_size (nbits)); }/*
Greg Kroah-Hartman
maintainerPATCH 18/215 fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 9a2fa1472083580b6c66bdaf291f591e1170123a upstream.
copy_fd_bitmaps(new, old, count) is expected to copy the first count/BITS_PER_LONG bits from old->full_fds_bits[] and fill the rest with zeroes. What it does is copying enough words (BITS_TO_LONGS(count/BITS_PER_LONG)), then memsets the rest. That works fine, *if* all bits past the cutoff point are clear. Otherwise we are risking garbage from the last word we'd copied.
For most of the callers that is true - expand_fdtable() has count equal to old->max_fds, so there's no open descriptors past count, let alone fully occupied words in ->open_fds[], which is what bits in ->full_fds_bits[] correspond to.
The other caller (dup_fd()) passes sane_fdtable_size(old_fdt, max_fds), which is the smallest multiple of BITS_PER_LONG that covers all opened descriptors below max_fds. In the common case (copying on fork()) max_fds is ~0U, so all opened descriptors will be below it and we are fine, by the same reasons why the call in expand_fdtable() is safe.
Unfortunately, there is a case where max_fds is less than that and where we might, indeed, end up with junk in ->full_fds_bits[] - close_range(from, to, CLOSE_RANGE_UNSHARE) with
* descriptor table being currently shared
* 'to' being above the current capacity of descriptor table
* 'from' being just under some chunk of opened descriptors.
In that case we end up with observably wrong behaviour - e.g. spawn a child with CLONE_FILES, get all descriptors in range 0..127 open, then close_range(64, ~0U, CLOSE_RANGE_UNSHARE) and watch dup(0) ending up with descriptor #128, despite #64 being observably not open.
The minimally invasive fix would be to deal with that in dup_fd(). If this proves to add measurable overhead, we can go that way, but let's try to fix copy_fd_bitmaps() first.
* new helper: bitmap_copy_and_expand(to, from, bits_to_copy, size).
* make copy_fd_bitmaps() take the bitmap size in words, rather than bits; it's 'count' argument is always a multiple of BITS_PER_LONG, so we are not losing any information, and that way we can use the same helper for all three bitmaps - compiler will see that count is a multiple of BITS_PER_LONG for the large ones, so it'll generate plain memcpy()+memset().
Reproducer added to tools/testing/selftests/core/close_range_test.c
--- fs/file.c | 28 ++++++++----------- include/linux/bitmap.h | 12 ++++++++ tools/testing/selftests/core/close_range_test.c | 35 ++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 16 deletions(-)
fs/file.c +12 -16
@@ -46,27 +46,23 @@ static void free_fdtable_rcu(struct rcu_#define BITBIT_NR (nr) BITS_TO_LONGS(BITS_TO_LONGS(nr))#define BITBIT_SIZE (nr) (BITBIT_NR(nr) * sizeof(long)) +#define fdt_words (fdt) ((fdt)->max_fds / BITS_PER_LONG) // words in ->open_fds/* * Copy 'count' fd bits from the old table to the new table and clear the extra * space if any. This does not copy the file pointers. Called with the files * spinlock held for write. */ -static void copy_fd_bitmaps (struct fdtable *nfdt,struct fdtable *ofdt, -unsigned int count) +static inline void copy_fd_bitmaps (struct fdtable *nfdt,struct fdtable *ofdt, +unsigned int copy_words) { -unsigned int cpy, set; +unsigned int nwords =fdt_words (nfdt); - cpy = count /BITS_PER_BYTE ; - set = (nfdt->max_fds - count) /BITS_PER_BYTE ; -memcpy (nfdt->open_fds, ofdt->open_fds, cpy); -memset ((char *)nfdt->open_fds + cpy,0 , set); -memcpy (nfdt->close_on_exec, ofdt->close_on_exec, cpy); -memset ((char *)nfdt->close_on_exec + cpy,0 , set); - - cpy =BITBIT_SIZE (count); - set =BITBIT_SIZE (nfdt->max_fds) - cpy; -memcpy (nfdt->full_fds_bits, ofdt->full_fds_bits, cpy); -memset ((char *)nfdt->full_fds_bits + cpy,0 , set); +bitmap_copy_and_extend (nfdt->open_fds, ofdt->open_fds, + copy_words *BITS_PER_LONG , nwords *BITS_PER_LONG ); +bitmap_copy_and_extend (nfdt->close_on_exec, ofdt->close_on_exec, + copy_words *BITS_PER_LONG , nwords *BITS_PER_LONG ); +bitmap_copy_and_extend (nfdt->full_fds_bits, ofdt->full_fds_bits, + copy_words, nwords); }/*
@@ -84,7 +80,7 @@ static void copy_fdtable(struct fdtablememcpy (nfdt->fd, ofdt->fd, cpy);memset ((char *)nfdt->fd + cpy,0 , set); -copy_fd_bitmaps (nfdt, ofdt, ofdt->max_fds); +copy_fd_bitmaps (nfdt, ofdt,fdt_words (ofdt)); }/*
@@ -374,7 +370,7 @@ struct files_struct *dup_fd(struct files open_files =sane_fdtable_size (old_fdt, max_fds); } -copy_fd_bitmaps (new_fdt, old_fdt, open_files); +copy_fd_bitmaps (new_fdt, old_fdt, open_files /BITS_PER_LONG ); old_fds = old_fdt->fd; new_fds = new_fdt->fd;
include/linux/bitmap.h +12 -0
@@ -268,6 +268,18 @@ static inline void bitmap_copy_clear_tai dst[nbits /BITS_PER_LONG ] &=BITMAP_LAST_WORD_MASK (nbits); } +static inline void bitmap_copy_and_extend (unsigned long *to, +const unsigned long *from, +unsigned int count,unsigned int size) +{ +unsigned int copy =BITS_TO_LONGS (count); + +memcpy (to, from, copy *sizeof (long )); +if (count %BITS_PER_LONG ) + to[copy -1 ] &=BITMAP_LAST_WORD_MASK (count); +memset (to + copy,0 ,bitmap_size (size) - copy *sizeof (long )); +} +/* * On 32-bit systems bitmaps are represented as u32 arrays internally, and * therefore conversion is not needed when copying data from/to arrays of u32.
tools/testing/selftests/core/close_range_test.c +35 -0
@@ -567,4 +567,39 @@ TEST(close_range_cloexec_unshare_syzbot)EXPECT_EQ (close (fd3),0 ); } +TEST (close_range_bitmap_corruption) +{ +pid_t pid; +int status; +struct __clone_args args = { + .flags =CLONE_FILES , + .exit_signal =SIGCHLD , + }; + +/* get the first 128 descriptors open */ +for (int i =2 ; i <128 ; i++) +EXPECT_GE (dup2 (0 , i),0 ); + +/* get descriptor table shared */ + pid =sys_clone3 (&args,sizeof (args)); +ASSERT_GE (pid,0 ); + +if (pid ==0 ) { +/* unshare and truncate descriptor table down to 64 */ +if (sys_close_range (64 , ~0U ,CLOSE_RANGE_UNSHARE )) +exit (EXIT_FAILURE ); + +ASSERT_EQ (fcntl (64 ,F_GETFD ),-1 ); +/* ... and verify that the range 64..127 is not +stuck "fully used" according to secondary bitmap */ + EXPECT_EQ(dup(0), 64) +exit (EXIT_FAILURE ); +exit (EXIT_SUCCESS ); + } + +EXPECT_EQ (waitpid (pid, &status,0 ), pid); +EXPECT_EQ (true,WIFEXITED (status)); +EXPECT_EQ (0 ,WEXITSTATUS (status)); +} +TEST_HARNESS_MAIN
Greg Kroah-Hartman
maintainerPATCH 19/215 selinux: fix potential counting error in avc_add_xperms_decision()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
commit 379d9af3f3da2da1bbfa67baf1820c72a080d1f1 upstream.
The count increases only when a node is successfully added to the linked list.
--- security/selinux/avc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/selinux/avc.c +1 -1
@@ -332,12 +332,12 @@ static int avc_add_xperms_decision(struc {struct avc_xperms_decision_node *dest_xpd; - node->ae.xp_node->xp.len++; dest_xpd =avc_xperms_decision_alloc (src->used);if (!dest_xpd)return -ENOMEM ;avc_copy_xperms_decision (&dest_xpd->xpd, src);list_add (&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head); + node->ae.xp_node->xp.len++;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 20/215 btrfs: tree-checker: add dev extent item checks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 008e2512dc5696ab2dc5bf264e98a9fe9ceb830e upstream.
[REPORT]
There is a corruption report that btrfs refused to mount a fs that has overlapping dev extents:
BTRFS error (device sdc): dev extent devid 4 physical offset 14263979671552 overlap with previous dev extent end 14263980982272 BTRFS error (device sdc): failed to verify dev extents against chunks: -117
BTRFS error (device sdc): open_ctree failed
[CAUSE]
The direct cause is very obvious, there is a bad dev extent item with incorrect length.
With btrfs check reporting two overlapping extents, the second one shows some clue on the cause:
ERROR: dev extent devid 4 offset 14263979671552 len 6488064 overlap with previous dev extent end 14263980982272
ERROR: dev extent devid 13 offset 2257707008000 len 6488064 overlap with previous dev extent end 2257707270144
ERROR: errors found in extent allocation tree or chunk allocation
The second one looks like a bitflip happened during new chunk allocation:
hex(2257707008000) = 0x20da9d30000 hex(2257707270144) = 0x20da9d70000
diff = 0x00000040000
So it looks like a bitflip happened during new dev extent allocation, resulting the second overlap.
Currently we only do the dev-extent verification at mount time, but if the corruption is caused by memory bitflip, we really want to catch it before writing the corruption to the storage.
Furthermore the dev extent items has the following key definition:
(<device id> DEV_EXTENT <physical offset>)
Thus we can not just rely on the generic key order check to make sure there is no overlapping.
[ENHANCEMENT]
Introduce dedicated dev extent checks, including:
- Fixed member checks
* chunk_tree should always be BTRFS_CHUNK_TREE_OBJECTID (3)
* chunk_objectid should always be BTRFS_FIRST_CHUNK_CHUNK_TREE_OBJECTID (256)
- Alignment checks
* chunk_offset should be aligned to sectorsize
* length should be aligned to sectorsize
* key.offset should be aligned to sectorsize
- Overlap checks
If the previous key is also a dev-extent item, with the same device id, make sure we do not overlap with the previous dev extent.
Reported: Stefan N <[email protected]>
--- fs/btrfs/tree-checker.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+)
fs/btrfs/tree-checker.c +69 -0
@@ -1596,6 +1596,72 @@ static int check_inode_ref(struct extentreturn 0 ; } +static int check_dev_extent_item (const struct extent_buffer *leaf, +const struct btrfs_key *key, +int slot, +struct btrfs_key *prev_key) +{ +struct btrfs_dev_extent *de; +const u32 sectorsize = leaf->fs_info->sectorsize; + + de = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent); +/* Basic fixed member checks. */ +if (unlikely (btrfs_dev_extent_chunk_tree (leaf, de) != +BTRFS_CHUNK_TREE_OBJECTID )) { +generic_err (leaf, slot, +"invalid dev extent chunk tree id, has %llu expect %llu" , +btrfs_dev_extent_chunk_tree (leaf, de), +BTRFS_CHUNK_TREE_OBJECTID ); +return -EUCLEAN ; + } +if (unlikely (btrfs_dev_extent_chunk_objectid (leaf, de) != +BTRFS_FIRST_CHUNK_TREE_OBJECTID )) { +generic_err (leaf, slot, +"invalid dev extent chunk objectid, has %llu expect %llu" , +btrfs_dev_extent_chunk_objectid (leaf, de), +BTRFS_FIRST_CHUNK_TREE_OBJECTID ); +return -EUCLEAN ; + } +/* Alignment check. */ +if (unlikely (!IS_ALIGNED (key->offset, sectorsize))) { +generic_err (leaf, slot, +"invalid dev extent key.offset, has %llu not aligned to %u" , + key->offset, sectorsize); +return -EUCLEAN ; + } +if (unlikely (!IS_ALIGNED (btrfs_dev_extent_chunk_offset (leaf, de), + sectorsize))) { +generic_err (leaf, slot, +"invalid dev extent chunk offset, has %llu not aligned to %u" , +btrfs_dev_extent_chunk_objectid (leaf, de), + sectorsize); +return -EUCLEAN ; + } +if (unlikely (!IS_ALIGNED (btrfs_dev_extent_length (leaf, de), + sectorsize))) { +generic_err (leaf, slot, +"invalid dev extent length, has %llu not aligned to %u" , +btrfs_dev_extent_length (leaf, de), sectorsize); +return -EUCLEAN ; + } +/* Overlap check with previous dev extent. */ +if (slot && prev_key->objectid == key->objectid && + prev_key->type == key->type) { +struct btrfs_dev_extent *prev_de; +u64 prev_len; + + prev_de = btrfs_item_ptr(leaf, slot - 1, struct btrfs_dev_extent); + prev_len =btrfs_dev_extent_length (leaf, prev_de); +if (unlikely (prev_key->offset + prev_len > key->offset)) { +generic_err (leaf, slot, +"dev extent overlap, prev offset %llu len %llu current offset %llu" , + prev_key->objectid, prev_len, key->offset); +return -EUCLEAN ; + } + } +return 0 ; +} +/* * Common point to switch the item-specific validation. */
@@ -1631,6 +1697,9 @@ static int check_leaf_item(struct extentcase BTRFS_DEV_ITEM_KEY : ret =check_dev_item (leaf, key, slot);break ; +case BTRFS_DEV_EXTENT_KEY : + ret =check_dev_extent_item (leaf, key, slot, prev_key); +break ;case BTRFS_INODE_ITEM_KEY : ret =check_inode_item (leaf, key, slot);break ;
Greg Kroah-Hartman
maintainerPATCH 21/215 drm/amdgpu: Actually check flags for all context ops.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bas Nieuwenhuizen <[email protected]>
commit 0573a1e2ea7e35bff08944a40f1adf2bb35cea61 upstream.
Missing validation ...
Checked libdrm and it clears all the structs, so we should be safe to just check everything.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +8 -0
@@ -413,16 +413,24 @@ int amdgpu_ctx_ioctl(struct drm_device *switch (args->in.op) {case AMDGPU_CTX_OP_ALLOC_CTX : +if (args->in.flags) +return -EINVAL ; r =amdgpu_ctx_alloc (adev, fpriv, filp, priority, &id); args->out.alloc.ctx_id = id;break ;case AMDGPU_CTX_OP_FREE_CTX : +if (args->in.flags) +return -EINVAL ; r =amdgpu_ctx_free (fpriv, id);break ;case AMDGPU_CTX_OP_QUERY_STATE : +if (args->in.flags) +return -EINVAL ; r =amdgpu_ctx_query (adev, fpriv, id, &args->out);break ;case AMDGPU_CTX_OP_QUERY_STATE2 : +if (args->in.flags) +return -EINVAL ; r =amdgpu_ctx_query2 (adev, fpriv, id, &args->out);break ;default :
Greg Kroah-Hartman
maintainerPATCH 22/215 memcg_write_event_control(): fix a user-triggerable oops
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 046667c4d3196938e992fba0dfcde570aa85cd0e upstream.
we are *not* guaranteed that anything past the terminating NUL is mapped (let alone initialized with anything sane).
--- mm/memcontrol.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
mm/memcontrol.c +5 -2
@@ -4807,9 +4807,12 @@ static ssize_t memcg_write_event_control buf = endp +1 ; cfd =simple_strtoul (buf, &endp,10 ); -if ((*endp !=' ' ) && (*endp !='\0' )) +if (*endp =='\0' ) + buf = endp; +else if (*endp ==' ' ) + buf = endp +1 ; +else return -EINVAL ; - buf = endp +1 ; event =kzalloc (sizeof (*event),GFP_KERNEL );if (!event)
Greg Kroah-Hartman
maintainerPATCH 23/215 drm/amdgpu/jpeg2: properly set atomics vmid field
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit e414a304f2c5368a84f03ad34d29b89f965a33c9 upstream.
This needs to be set as well if the IB uses atomics.
--- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +2 -2
@@ -557,11 +557,11 @@ void jpeg_v2_0_dec_ring_emit_ib(struct aamdgpu_ring_write (ring,PACKETJ (mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,0 ,0 ,PACKETJ_TYPE0 )); -amdgpu_ring_write (ring, (vmid | (vmid <<4 ))); +amdgpu_ring_write (ring, (vmid | (vmid <<4 ) | (vmid <<8 )));amdgpu_ring_write (ring,PACKETJ (mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,0 ,0 ,PACKETJ_TYPE0 )); -amdgpu_ring_write (ring, (vmid | (vmid <<4 ))); +amdgpu_ring_write (ring, (vmid | (vmid <<4 ) | (vmid <<8 )));amdgpu_ring_write (ring,PACKETJ (mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,0 ,0 ,PACKETJ_TYPE0 ));
Greg Kroah-Hartman
maintainerPATCH 24/215 s390/uv: Panic for set and remove shared access UVC errors
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit cff59d8631e1409ffdd22d9d717e15810181b32c ]
The return value uv_set_shared() and uv_remove_shared() (which are wrappers around the share() function) is not always checked. The system integrity of a protected guest depends on the Share and Unshare UVCs being successful. This means that any caller that fails to check the return value will compromise the security of the protected guest.
No code path that would lead to such violation of the security guarantees is currently exercised, since all the areas that are shared never get unshared during the lifetime of the system. This might change and become an issue in the future.
The Share and Unshare UVCs can only fail in case of hypervisor misbehaviour (either a bug or malicious behaviour). In such cases there is no reasonable way forward, and the system needs to panic.
This patch replaces the return at the end of the share() function with a panic, to guarantee system integrity.
Message-ID: <[email protected]>
--- arch/s390/include/asm/uv.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/s390/include/asm/uv.h +4 -1
@@ -312,7 +312,10 @@ static inline int share(unsigned long addr, u16 cmd)if (!uv_call (0 , (u64)&uvcb))return 0 ; -return -EINVAL ; +pr_err ("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n" , + uvcb.header.cmd ==UVC_CMD_SET_SHARED_ACCESS ?"Share" :"Unshare" , + uvcb.header.rc, uvcb.header.rrc); +panic ("System security cannot be guaranteed unless the system panics now.\n" ); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 25/215 igc: Correct the launchtime offset
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Husaini Zulkifli <[email protected]>
[ Upstream commit 790835fcc0cb9992349ae3c9010dbc7321aaa24d ]
The launchtime offset should be corrected according to sections 7.5.2.6 Transmit Scheduling Latency of the Intel Ethernet I225/I226 Software User Manual.
Software can compensate the latency between the transmission scheduling and the time that packet is transmitted to the network by setting this GTxOffset register. Without setting this register, there may be a significant delay between the packet scheduling and the network point.
This patch helps to reduce the latency for each of the link speed.
Before:
10Mbps : 11000 - 13800 nanosecond
100Mbps : 1300 - 1700 nanosecond
1000Mbps : 190 - 600 nanosecond
2500Mbps : 1400 - 1700 nanosecond
After:
10Mbps : less than 750 nanosecond
100Mbps : less than 192 nanosecond
1000Mbps : less than 128 nanosecond
2500Mbps : less than 128 nanosecond
Test Setup:
Talker : Use l2_tai.c to generate the launchtime into packet payload.
Listener: Use timedump.c to compute the delta between packet arrival and LaunchTime packet payload.
Stable-dep-of: e037a26ead18 ("igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer")
--- drivers/net/ethernet/intel/igc/igc_defines.h | 9 ++++++ drivers/net/ethernet/intel/igc/igc_main.c | 7 +++++ drivers/net/ethernet/intel/igc/igc_regs.h | 1 + drivers/net/ethernet/intel/igc/igc_tsn.c | 30 ++++++++++++++++++++ drivers/net/ethernet/intel/igc/igc_tsn.h | 1 + 5 files changed, 48 insertions(+)
drivers/net/ethernet/intel/igc/igc_defines.h +9 -0
@@ -405,6 +405,15 @@#define IGC_DTXMXPKTSZ_TSN 0x19/* 1600 bytes of max TX DMA packet size */ #define IGC_DTXMXPKTSZ_DEFAULT 0x98/* 9728-byte Jumbo frames */ +/* Transmit Scheduling Latency */ +/* Latency between transmission scheduling (LaunchTime) and the time +* the packet is transmitted to the network in nanosecond. +*/ +#define IGC_TXOFFSET_SPEED_10 0x000034BC +#define IGC_TXOFFSET_SPEED_100 0x00000578 +#define IGC_TXOFFSET_SPEED_1000 0x0000012C +#define IGC_TXOFFSET_SPEED_2500 0x00000578 +/* Time Sync Interrupt Causes */ #define IGC_TSICR_SYS_WRAP BIT(0)/* SYSTIM Wrap around. */ #define IGC_TSICR_TXTS BIT(1)/* Transmit Timestamp. */
drivers/net/ethernet/intel/igc/igc_main.c +7 -0
@@ -5532,6 +5532,13 @@ static void igc_watchdog_task(struct work_struct *work)break ; } +/* Once the launch time has been set on the wire, there +* is a delay before the link speed can be determined +* based on link-up activity. Write into the register +* as soon as we know the correct link speed. +*/ +igc_tsn_adjust_txtime_offset (adapter); +if (adapter->link_speed !=SPEED_1000 ) goto no_wait;
drivers/net/ethernet/intel/igc/igc_regs.h +1 -0
@@ -227,6 +227,7 @@/* Transmit Scheduling Registers */ #define IGC_TQAVCTRL 0x3570#define IGC_TXQCTL (_n) (0x3344 + 0x4 * (_n)) +#define IGC_GTXOFFSET 0x3310#define IGC_BASET_L 0x3314#define IGC_BASET_H 0x3318#define IGC_QBVCYCLET 0x331C
drivers/net/ethernet/intel/igc/igc_tsn.c +30 -0
@@ -48,6 +48,35 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)return new_flags; } +void igc_tsn_adjust_txtime_offset (struct igc_adapter *adapter) +{ +struct igc_hw *hw = &adapter->hw; +u16 txoffset; + +if (!is_any_launchtime (adapter)) +return ; + +switch (adapter->link_speed) { +case SPEED_10 : + txoffset =IGC_TXOFFSET_SPEED_10 ; +break ; +case SPEED_100 : + txoffset =IGC_TXOFFSET_SPEED_100 ; +break ; +case SPEED_1000 : + txoffset =IGC_TXOFFSET_SPEED_1000 ; +break ; +case SPEED_2500 : + txoffset =IGC_TXOFFSET_SPEED_2500 ; +break ; +default : + txoffset =0 ; +break ; + } + +wr32 (IGC_GTXOFFSET , txoffset); +} +/* Returns the TSN specific registers to their default values after * the adapter is reset. */
@@ -57,6 +86,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)u32 tqavctrl;int i; +wr32 (IGC_GTXOFFSET ,0 );wr32 (IGC_TXPBS ,I225_TXPBSIZE_DEFAULT );wr32 (IGC_DTXMXPKTSZ ,IGC_DTXMXPKTSZ_DEFAULT );
drivers/net/ethernet/intel/igc/igc_tsn.h +1 -0
@@ -6,5 +6,6 @@int igc_tsn_offload_apply (struct igc_adapter *adapter);int igc_tsn_reset (struct igc_adapter *adapter); +void igc_tsn_adjust_txtime_offset (struct igc_adapter *adapter);#endif /* _IGC_BASE_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 26/215 igc: remove I226 Qbv BaseTime restriction
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Husaini Zulkifli <[email protected]>
[ Upstream commit b8897dc54e3bc9d25281bbb42a7d730782ff4588 ]
Remove the Qbv BaseTime restriction for I226 so that the BaseTime can be scheduled to the future time. A new register bit of Tx Qav Control (Bit-7: FutScdDis) was introduced to allow I226 scheduling future time as Qbv BaseTime and not having the Tx hang timeout issue.
Besides, according to datasheet section 7.5.2.9.3.3, FutScdDis bit has to be configured first before the cycle time and base time.
Indeed the FutScdDis bit is only active on re-configuration, thus we have to set the BASET_L to zero and then only set it to the desired value.
Please also note that the Qbv configuration flow is moved around based on the Qbv programming guideline that is documented in the latest datasheet.
Stable-dep-of: e037a26ead18 ("igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer")
--- drivers/net/ethernet/intel/igc/igc_base.c | 29 +++++++++++++ drivers/net/ethernet/intel/igc/igc_base.h | 2 + drivers/net/ethernet/intel/igc/igc_defines.h | 1 + drivers/net/ethernet/intel/igc/igc_main.c | 5 ++- drivers/net/ethernet/intel/igc/igc_tsn.c | 44 +++++++++++++------- 5 files changed, 65 insertions(+), 16 deletions(-)
drivers/net/ethernet/intel/igc/igc_base.c +29 -0
@@ -402,6 +402,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw)rd32 (IGC_MPC ); } +bool igc_is_device_id_i225 (struct igc_hw *hw) +{ +switch (hw->device_id) { +case IGC_DEV_ID_I225_LM : +case IGC_DEV_ID_I225_V : +case IGC_DEV_ID_I225_I : +case IGC_DEV_ID_I225_K : +case IGC_DEV_ID_I225_K2 : +case IGC_DEV_ID_I225_LMVP : +case IGC_DEV_ID_I225_IT : +return true; +default : +return false; + } +} + +bool igc_is_device_id_i226 (struct igc_hw *hw) +{ +switch (hw->device_id) { +case IGC_DEV_ID_I226_LM : +case IGC_DEV_ID_I226_V : +case IGC_DEV_ID_I226_K : +case IGC_DEV_ID_I226_IT : +return true; +default : +return false; + } +} +static struct igc_mac_operations igc_mac_ops_base = { .init_hw = igc_init_hw_base, .check_for_link = igc_check_for_copper_link,
drivers/net/ethernet/intel/igc/igc_base.h +2 -0
@@ -7,6 +7,8 @@/* forward declaration */ void igc_rx_fifo_flush_base (struct igc_hw *hw);void igc_power_down_phy_copper_base (struct igc_hw *hw); +bool igc_is_device_id_i225 (struct igc_hw *hw); +bool igc_is_device_id_i226 (struct igc_hw *hw);/* Transmit Descriptor - Advanced */ union igc_adv_tx_desc {
drivers/net/ethernet/intel/igc/igc_defines.h +1 -0
@@ -527,6 +527,7 @@/* Transmit Scheduling */ #define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001#define IGC_TQAVCTRL_ENHANCED_QAV 0x00000008 +#define IGC_TQAVCTRL_FUTSCDDIS 0x00000080#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001#define IGC_TXQCTL_STRICT_CYCLE 0x00000002
drivers/net/ethernet/intel/igc/igc_main.c +4 -1
@@ -5991,6 +5991,7 @@ static bool validate_schedule(struct igc_adapter *adapter, const struct tc_taprio_qopt_offload *qopt) {int queue_uses[IGC_MAX_TX_QUEUES ] = { }; +struct igc_hw *hw = &adapter->hw;struct timespec64 now;size_t n;
@@ -6003,8 +6004,10 @@ static bool validate_schedule(struct igc_adapter *adapter,* in the future, it will hold all the packets until that * time, causing a lot of TX Hangs, so to avoid that, we * reject schedules that would start in the future. +* Note: Limitation above is no longer in i226. */ -if (!is_base_time_past (qopt->base_time, &now)) +if (!is_base_time_past (qopt->base_time, &now) && +igc_is_device_id_i225 (hw))return false;for (n =0 ; n < qopt->num_entries; n++) {
drivers/net/ethernet/intel/igc/igc_tsn.c +29 -15
83 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 27/215 igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Faizal Rahim <[email protected]>
[ Upstream commit e037a26ead187901f83cad9c503ccece5ff6817a ]
Testing uncovered that even when the taprio gate is closed, some packets still transmit.
According to i225/6 hardware errata [1], traffic might overflow the planned QBV window. This happens because MAC maintains an internal buffer, primarily for supporting half duplex retries. Therefore, even when the gate closes, residual MAC data in the buffer may still transmit.
To mitigate this for i226, reduce the MAC's internal buffer from 192 bytes to the recommended 88 bytes by modifying the RETX_CTL register value.
This follows guidelines from:
[1] Ethernet Controller I225/I22 Spec Update Rev 2.1 Errata Item 9:
TSN: Packet Transmission Might Cross Qbv Window
[2] I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control
Note that the RETX_CTL register can't be used in TSN mode because half duplex feature cannot coexist with TSN.
Test Steps:
1. Send taprio cmd to board A:
tc qdisc replace dev enp1s0 parent root handle 100 taprio \
num_tc 4 \
map 3 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
queues 1@0 1@1 1@2 1@3 \
base-time 0 \
sched-entry S 0x07 500000 \
sched-entry S 0x0f 500000 \
flags 0x2 \
txtime-delay 0
Note that for TC3, gate should open for 500us and close for another
500us.3. Take tcpdump log on Board B.
4. Send udp packets via UDP tai app from Board A to Board B.
5. Analyze tcpdump log via wireshark log on Board B. Ensure that the total time from the first to the last packet received during one cycle for TC3 does not exceed 500us.
--- drivers/net/ethernet/intel/igc/igc_defines.h | 6 ++++ drivers/net/ethernet/intel/igc/igc_tsn.c | 34 ++++++++++++++++++++ 2 files changed, 40 insertions(+)
drivers/net/ethernet/intel/igc/igc_defines.h +6 -0
@@ -405,6 +405,12 @@#define IGC_DTXMXPKTSZ_TSN 0x19/* 1600 bytes of max TX DMA packet size */ #define IGC_DTXMXPKTSZ_DEFAULT 0x98/* 9728-byte Jumbo frames */ +/* Retry Buffer Control */ +#define IGC_RETX_CTL 0x041C +#define IGC_RETX_CTL_WATERMARK_MASK 0xF +#define IGC_RETX_CTL_QBVFULLTH_SHIFT 8/* QBV Retry Buffer Full Threshold */ +#define IGC_RETX_CTL_QBVFULLEN 0x1000/* Enable QBV Retry Buffer Full Threshold */ +/* Transmit Scheduling Latency */ /* Latency between transmission scheduling (LaunchTime) and the time * the packet is transmitted to the network in nanosecond.
drivers/net/ethernet/intel/igc/igc_tsn.c +34 -0
@@ -78,6 +78,15 @@ void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)wr32 (IGC_GTXOFFSET , txoffset); } +static void igc_tsn_restore_retx_default (struct igc_adapter *adapter) +{ +struct igc_hw *hw = &adapter->hw; +u32 retxctl; + + retxctl =rd32 (IGC_RETX_CTL ) &IGC_RETX_CTL_WATERMARK_MASK ; +wr32 (IGC_RETX_CTL , retxctl); +} +/* Returns the TSN specific registers to their default values after * the adapter is reset. */
@@ -91,6 +100,9 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)wr32 (IGC_TXPBS ,I225_TXPBSIZE_DEFAULT );wr32 (IGC_DTXMXPKTSZ ,IGC_DTXMXPKTSZ_DEFAULT ); +if (igc_is_device_id_i226 (hw)) +igc_tsn_restore_retx_default (adapter); + tqavctrl =rd32 (IGC_TQAVCTRL ); tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |IGC_TQAVCTRL_ENHANCED_QAV |IGC_TQAVCTRL_FUTSCDDIS );
@@ -111,6 +123,25 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)return 0 ; } +/* To partially fix i226 HW errata, reduce MAC internal buffering from 192 Bytes +* to 88 Bytes by setting RETX_CTL register using the recommendation from: +* a) Ethernet Controller I225/I226 Specification Update Rev 2.1 +* Item 9: TSN: Packet Transmission Might Cross the Qbv Window +* b) I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control +*/ +static void igc_tsn_set_retx_qbvfullthreshold (struct igc_adapter *adapter) +{ +struct igc_hw *hw = &adapter->hw; +u32 retxctl, watermark; + + retxctl =rd32 (IGC_RETX_CTL ); + watermark = retxctl &IGC_RETX_CTL_WATERMARK_MASK ; +/* Set QBVFULLTH value using watermark and set QBVFULLEN */ + retxctl |= (watermark <<IGC_RETX_CTL_QBVFULLTH_SHIFT ) | +IGC_RETX_CTL_QBVFULLEN ; +wr32 (IGC_RETX_CTL , retxctl); +} +static int igc_tsn_enable_offload (struct igc_adapter *adapter) {struct igc_hw *hw = &adapter->hw;
@@ -123,6 +154,9 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)wr32 (IGC_DTXMXPKTSZ ,IGC_DTXMXPKTSZ_TSN );wr32 (IGC_TXPBS ,IGC_TXPBSIZE_TSN ); +if (igc_is_device_id_i226 (hw)) +igc_tsn_set_retx_qbvfullthreshold (adapter); +for (i =0 ; i < adapter->num_tx_queues; i++) {struct igc_ring *ring = adapter->tx_ring[i];u32 txqctl =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 28/215 net/mlx5e: Correctly report errors for ethtool rx flows
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cosmin Ratiu <[email protected]>
[ Upstream commit cbc796be1779c4dbc9a482c7233995e2a8b6bfb3 ]
Previously, an ethtool rx flow with no attrs would not be added to the NIC as it has no rules to configure the hw with, but it would be reported as successful to the caller (return code 0). This is confusing for the user as ethtool then reports "Added rule $num", but no rule was actually added.
This change corrects that by instead reporting these wrong rules as -EINVAL.
--- drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +1 -1
@@ -727,7 +727,7 @@ mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,if (num_tuples <=0 ) {netdev_warn (priv->netdev,"%s: flow is not valid %d\n" , __func__, num_tuples); -return num_tuples; +return num_tuples <0 ? num_tuples : -EINVAL ; } eth_ft =get_flow_table (priv, fs, num_tuples);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 29/215 atm: idt77252: prevent use after free in dequeue_rx()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit a9a18e8f770c9b0703dab93580d0b02e199a4c79 ]
We can't dereference "skb" after calling vcc->push() because the skb is released.
--- drivers/atm/idt77252.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/atm/idt77252.c +5 -4
@@ -1118,8 +1118,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) rpp->len += skb->len;if (stat &SAR_RSQE_EPDU ) { +unsigned int len, truesize;unsigned char *l1l2; -unsigned int len; l1l2 = (unsigned char *) ((unsigned long ) skb->data + skb->len -6 );
@@ -1189,14 +1189,15 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)ATM_SKB (skb)->vcc = vcc;__net_timestamp (skb); + truesize = skb->truesize; vcc->push (vcc, skb);atomic_inc (&vcc->stats->rx); -if (skb->truesize >SAR_FB_SIZE_3 ) +if (truesize >SAR_FB_SIZE_3 )add_rx_skb (card,3 ,SAR_FB_SIZE_3 ,1 ); -else if (skb->truesize >SAR_FB_SIZE_2 ) +else if (truesize >SAR_FB_SIZE_2 )add_rx_skb (card,2 ,SAR_FB_SIZE_2 ,1 ); -else if (skb->truesize >SAR_FB_SIZE_1 ) +else if (truesize >SAR_FB_SIZE_1 )add_rx_skb (card,1 ,SAR_FB_SIZE_1 ,1 );else add_rx_skb (card,0 ,SAR_FB_SIZE_0 ,1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 30/215 net: axienet: Fix register defines comment description
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radhey Shyam Pandey <[email protected]>
[ Upstream commit 9ff2f816e2aa65ca9a1cdf0954842f8173c0f48d ]
In axiethernet header fix register defines comment description to be inline with IP documentation. It updates MAC configuration register, MDIO configuration register and frame filter control description.
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +8 -8
@@ -159,16 +159,16 @@#define XAE_RCW1_OFFSET 0x00000404/* Rx Configuration Word 1 */ #define XAE_TC_OFFSET 0x00000408/* Tx Configuration */ #define XAE_FCC_OFFSET 0x0000040C/* Flow Control Configuration */ -#define XAE_EMMC_OFFSET 0x00000410/* EMAC mode configuration */ -#define XAE_PHYC_OFFSET 0x00000414/* RGMII/SGMII configuration */ +#define XAE_EMMC_OFFSET 0x00000410/* MAC speed configuration */ +#define XAE_PHYC_OFFSET 0x00000414/* RX Max Frame Configuration */ #define XAE_ID_OFFSET 0x000004F8/* Identification register */ -#define XAE_MDIO_MC_OFFSET 0x00000500/* MII Management Config */ -#define XAE_MDIO_MCR_OFFSET 0x00000504/* MII Management Control */ -#define XAE_MDIO_MWD_OFFSET 0x00000508/* MII Management Write Data */ -#define XAE_MDIO_MRD_OFFSET 0x0000050C/* MII Management Read Data */ +#define XAE_MDIO_MC_OFFSET 0x00000500/* MDIO Setup */ +#define XAE_MDIO_MCR_OFFSET 0x00000504/* MDIO Control */ +#define XAE_MDIO_MWD_OFFSET 0x00000508/* MDIO Write Data */ +#define XAE_MDIO_MRD_OFFSET 0x0000050C/* MDIO Read Data */ #define XAE_UAW0_OFFSET 0x00000700/* Unicast address word 0 */ #define XAE_UAW1_OFFSET 0x00000704/* Unicast address word 1 */ -#define XAE_FMI_OFFSET 0x00000708/* Filter Mask Index */ +#define XAE_FMI_OFFSET 0x00000708/* Frame Filter Control */ #define XAE_AF0_OFFSET 0x00000710/* Address Filter 0 */ #define XAE_AF1_OFFSET 0x00000714/* Address Filter 1 */
@@ -307,7 +307,7 @@*/ #define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF -/* Bit masks for Axi Ethernet FMI register */ +/* Bit masks for Axi Ethernet FMC register */ #define XAE_FMI_PM_MASK 0x80000000/* Promis. mode enable */ #define XAE_FMI_IND_MASK 0x00000003/* Index Mask */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 31/215 net: dsa: vsc73xx: pass value in phy_write operation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit 5b9eebc2c7a5f0cc7950d918c1e8a4ad4bed5010 ]
In the 'vsc73xx_phy_write' function, the register value is missing, and the phy write operation always sends zeros.
This commit passes the value variable into the proper register.
--- drivers/net/dsa/vitesse-vsc73xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/vitesse-vsc73xx-core.c +1 -1
@@ -531,7 +531,7 @@ static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum,return 0 ; } - cmd = (phy <<21 ) | (regnum <<16 ); + cmd = (phy <<21 ) | (regnum <<16 ) | val; ret =vsc73xx_write (vsc,VSC73XX_BLOCK_MII ,0 ,1 , cmd);if (ret)return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 32/215 net: dsa: vsc73xx: use read_poll_timeout instead delay loop
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit eb7e33d01db3aec128590391b2397384bab406b6 ]
Switch the delay loop during the Arbiter empty check from vsc73xx_adjust_link() to use read_poll_timeout(). Functionally, one msleep() call is eliminated at the end of the loop in the timeout case.
As Russell King suggested:
"This [change] avoids the issue that on the last iteration, the code reads the register, tests it, finds the condition that's being waiting for is false, _then_ waits and end up printing the error message - that last wait is rather useless, and as the arbiter state isn't checked after waiting, it could be that we had success during the last wait."
Stable-dep-of: fa63c6434b6f ("net: dsa: vsc73xx: check busy flag in MDIO operations")
--- drivers/net/dsa/vitesse-vsc73xx-core.c | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-)
drivers/net/dsa/vitesse-vsc73xx-core.c +16 -14
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/iopoll.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_mdio.h>
@@ -269,6 +270,9 @@#define IS_7398 (a) ((a)->chipid == VSC73XX_CHIPID_ID_7398)#define IS_739X (a) (IS_7395(a) || IS_7398(a)) +#define VSC73XX_POLL_SLEEP_US 1000 +#define VSC73XX_POLL_TIMEOUT_US 10000 +struct vsc73xx_counter {u8 counter;const char *name;
@@ -780,7 +784,7 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port,* after a PHY or the CPU port comes up or down. */ if (!phydev->link) { -int maxloop =10 ; +int ret, err;dev_dbg (vsc->dev,"port %d: went down\n" , port);
@@ -795,19 +799,17 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, VSC73XX_ARBDISC, BIT(port), BIT(port));/* Wait until queue is empty */ -vsc73xx_read (vsc,VSC73XX_BLOCK_ARBITER ,0 , -VSC73XX_ARBEMPTY , &val); -while (!(val &BIT (port))) { -msleep (1 ); -vsc73xx_read (vsc,VSC73XX_BLOCK_ARBITER ,0 , -VSC73XX_ARBEMPTY , &val); -if (--maxloop ==0 ) { -dev_err (vsc->dev, -"timeout waiting for block arbiter\n" ); -/* Continue anyway */ -break ; - } - } + ret =read_poll_timeout (vsc73xx_read, err, + err <0 || (val &BIT (port)), +VSC73XX_POLL_SLEEP_US , +VSC73XX_POLL_TIMEOUT_US , false, + vsc,VSC73XX_BLOCK_ARBITER ,0 , +VSC73XX_ARBEMPTY , &val); +if (ret) +dev_err (vsc->dev, +"timeout waiting for block arbiter\n" ); +else if (err <0 ) +dev_err (vsc->dev,"error reading arbiter\n" );/* Put this port into reset */ vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 33/215 net: dsa: vsc73xx: check busy flag in MDIO operations
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit fa63c6434b6f6aaf9d8d599dc899bc0a074cc0ad ]
The VSC73xx has a busy flag used during MDIO operations. It is raised when MDIO read/write operations are in progress. Without it, PHYs are misconfigured and bus operations do not work as expected.
--- drivers/net/dsa/vitesse-vsc73xx-core.c | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
drivers/net/dsa/vitesse-vsc73xx-core.c +36 -1
@@ -39,6 +39,10 @@#define VSC73XX_BLOCK_ARBITER 0x5/* Only subblock 0 */ #define VSC73XX_BLOCK_SYSTEM 0x7/* Only subblock 0 */ +/* MII Block subblock */ +#define VSC73XX_BLOCK_MII_INTERNAL 0x0/* Internal MDIO subblock */ +#define VSC73XX_BLOCK_MII_EXTERNAL 0x1/* External MDIO subblock */ +#define CPU_PORT 6/* CPU port */ /* MAC Block registers */
@@ -197,6 +201,8 @@#define VSC73XX_MII_CMD 0x1#define VSC73XX_MII_DATA 0x2 +#define VSC73XX_MII_STAT_BUSY BIT(3) +/* Arbiter block 5 registers */ #define VSC73XX_ARBEMPTY 0x0c#define VSC73XX_ARBDISC 0x0e
@@ -271,6 +277,7 @@#define IS_739X (a) (IS_7395(a) || IS_7398(a))#define VSC73XX_POLL_SLEEP_US 1000 +#define VSC73XX_MDIO_POLL_SLEEP_US 5#define VSC73XX_POLL_TIMEOUT_US 10000struct vsc73xx_counter {
@@ -488,6 +495,22 @@ static int vsc73xx_detect(struct vsc73xx *vsc)return 0 ; } +static int vsc73xx_mdio_busy_check (struct vsc73xx *vsc) +{ +int ret, err; +u32 val; + + ret =read_poll_timeout (vsc73xx_read, err, + err <0 || !(val &VSC73XX_MII_STAT_BUSY ), +VSC73XX_MDIO_POLL_SLEEP_US , +VSC73XX_POLL_TIMEOUT_US , false, vsc, +VSC73XX_BLOCK_MII ,VSC73XX_BLOCK_MII_INTERNAL , +VSC73XX_MII_STAT , &val); +if (ret) +return ret; +return err; +} +static int vsc73xx_phy_read (struct dsa_switch *ds,int phy,int regnum) {struct vsc73xx *vsc = ds->priv;
@@ -495,12 +518,20 @@ static int vsc73xx_phy_read(struct dsa_switch *ds, int phy, int regnum)u32 val;int ret; + ret =vsc73xx_mdio_busy_check (vsc); +if (ret) +return ret; +/* Setting bit 26 means "read" */ cmd =BIT (26 ) | (phy <<21 ) | (regnum <<16 ); ret =vsc73xx_write (vsc,VSC73XX_BLOCK_MII ,0 ,1 , cmd);if (ret)return ret; -msleep (2 ); + + ret =vsc73xx_mdio_busy_check (vsc); +if (ret) +return ret; + ret =vsc73xx_read (vsc,VSC73XX_BLOCK_MII ,0 ,2 , &val);if (ret)return ret;
@@ -524,6 +555,10 @@ static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum,u32 cmd;int ret; + ret =vsc73xx_mdio_busy_check (vsc); +if (ret) +return ret; +/* It was found through tedious experiments that this router * chip really hates to have it's PHYs reset. They * never recover if that happens: autonegotiation stops
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 34/215 mlxbf_gige: Remove two unused function declarations
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yue Haibing <[email protected]>
[ Upstream commit 98261be155f8de38f11b6542d4a8935e5532687b ]
Commit f92e1869d74e ("Add Mellanox BlueField Gigabit Ethernet driver") declared but never implemented these.
Stable-dep-of: df934abb185c ("mlxbf_gige: disable RX filters until RX path initialized")
--- drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h | 3 --- 1 file changed, 3 deletions(-)
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h +0 -3
@@ -151,9 +151,6 @@ enum mlxbf_gige_res {int mlxbf_gige_mdio_probe (struct platform_device *pdev,struct mlxbf_gige *priv);void mlxbf_gige_mdio_remove (struct mlxbf_gige *priv); -irqreturn_t mlxbf_gige_mdio_handle_phy_interrupt (int irq,void *dev_id); -void mlxbf_gige_mdio_enable_phy_int (struct mlxbf_gige *priv); -void mlxbf_gige_set_mac_rx_filter (struct mlxbf_gige *priv,unsigned int index,u64 dmac); void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 35/215 mlxbf_gige: disable RX filters until RX path initialized
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Thompson <[email protected]>
[ Upstream commit df934abb185c71c9f2fa07a5013672d0cbd36560 ]
A recent change to the driver exposed a bug where the MAC RX filters (unicast MAC, broadcast MAC, and multicast MAC) are configured and enabled before the RX path is fully initialized. The result of this bug is that after the PHY is started packets that match these MAC RX filters start to flow into the RX FIFO. And then, after rx_init() is completed, these packets will go into the driver RX ring as well. If enough packets are received to fill the RX ring (default size is 128 packets) before the call to request_irq() completes, the driver RX function becomes stuck.
This bug is intermittent but is most likely to be seen where the oob_net0 interface is connected to a busy network with lots of broadcast and multicast traffic.
All the MAC RX filters must be disabled until the RX path is ready, i.e. all initialization is done and all the IRQs are installed.
--- .../ethernet/mellanox/mlxbf_gige/mlxbf_gige.h | 8 +++ .../mellanox/mlxbf_gige/mlxbf_gige_main.c | 10 ++++ .../mellanox/mlxbf_gige/mlxbf_gige_regs.h | 2 + .../mellanox/mlxbf_gige/mlxbf_gige_rx.c | 50 ++++++++++++++++--- 4 files changed, 64 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h +8 -0
@@ -39,6 +39,7 @@*/ #define MLXBF_GIGE_BCAST_MAC_FILTER_IDX 0#define MLXBF_GIGE_LOCAL_MAC_FILTER_IDX 1 +#define MLXBF_GIGE_MAX_FILTER_IDX 3/* Define for broadcast MAC literal */ #define BCAST_MAC_ADDR 0xFFFFFFFFFFFF
@@ -151,6 +152,13 @@ enum mlxbf_gige_res {int mlxbf_gige_mdio_probe (struct platform_device *pdev,struct mlxbf_gige *priv);void mlxbf_gige_mdio_remove (struct mlxbf_gige *priv); + +void mlxbf_gige_enable_multicast_rx (struct mlxbf_gige *priv); +void mlxbf_gige_disable_multicast_rx (struct mlxbf_gige *priv); +void mlxbf_gige_enable_mac_rx_filter (struct mlxbf_gige *priv, +unsigned int index); +void mlxbf_gige_disable_mac_rx_filter (struct mlxbf_gige *priv, +unsigned int index);void mlxbf_gige_set_mac_rx_filter (struct mlxbf_gige *priv,unsigned int index,u64 dmac); void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv,
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +10 -0
@@ -170,6 +170,10 @@ static int mlxbf_gige_open(struct net_device *netdev)if (err) goto napi_deinit; +mlxbf_gige_enable_mac_rx_filter (priv,MLXBF_GIGE_BCAST_MAC_FILTER_IDX ); +mlxbf_gige_enable_mac_rx_filter (priv,MLXBF_GIGE_LOCAL_MAC_FILTER_IDX ); +mlxbf_gige_enable_multicast_rx (priv); +/* Set bits in INT_EN that we care about */ int_en =MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR | MLXBF_GIGE_INT_EN_TX_CHECKSUM_INPUTS |
@@ -295,6 +299,7 @@ static int mlxbf_gige_probe(struct platform_device *pdev)void __iomem *plu_base;void __iomem *base;int addr, phy_irq; +unsigned int i;int err; base =devm_platform_ioremap_resource (pdev,MLXBF_GIGE_RES_MAC );
@@ -337,6 +342,11 @@ static int mlxbf_gige_probe(struct platform_device *pdev) priv->rx_q_entries =MLXBF_GIGE_DEFAULT_RXQ_SZ ; priv->tx_q_entries =MLXBF_GIGE_DEFAULT_TXQ_SZ ; +for (i =0 ; i <=MLXBF_GIGE_MAX_FILTER_IDX ; i++) +mlxbf_gige_disable_mac_rx_filter (priv, i); +mlxbf_gige_disable_multicast_rx (priv); +mlxbf_gige_disable_promisc (priv); +/* Write initial MAC address to hardware */ mlxbf_gige_initial_mac (priv);
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h +2 -0
@@ -59,6 +59,8 @@#define MLXBF_GIGE_TX_STATUS_DATA_FIFO_FULL BIT(1)#define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_START 0x0520#define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_END 0x0528 +#define MLXBF_GIGE_RX_MAC_FILTER_GENERAL 0x0530 +#define MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST BIT(1)#define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC 0x0540#define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC_EN BIT(0)#define MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS 0x0548
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +44 -6
65 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 36/215 mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugene Syromiatnikov <[email protected]>
[ Upstream commit 655111b838cdabdb604f3625a9ff08c5eedb11da ]
ssn_offset field is u32 and is placed into the netlink response with nla_put_u32(), but only 2 bytes are reserved for the attribute payload in subflow_get_info_size() (even though it makes no difference in the end, as it is aligned up to 4 bytes). Supply the correct argument to the relevant nla_total_size() call to make it less confusing.
--- net/mptcp/diag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mptcp/diag.c +1 -1
@@ -95,7 +95,7 @@ static size_t subflow_get_info_size(const struct sock *sk)nla_total_size (4 ) +/* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */ nla_total_size_64bit (8 ) +/* MPTCP_SUBFLOW_ATTR_MAP_SEQ */ nla_total_size (4 ) +/* MPTCP_SUBFLOW_ATTR_MAP_SFSEQ */ -nla_total_size (2 ) +/* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */ +nla_total_size (4 ) +/* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */ nla_total_size (2 ) +/* MPTCP_SUBFLOW_ATTR_MAP_DATALEN */ nla_total_size (4 ) +/* MPTCP_SUBFLOW_ATTR_FLAGS */ nla_total_size(1) + /* MPTCP_SUBFLOW_ATTR_ID_REM */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 37/215 netfilter: allow ipv6 fragments to arrive on different devices
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Hughes <[email protected]>
[ Upstream commit 3cd740b985963f874a1a094f1969e998b9d05554 ]
Commit 264640fc2c5f4 ("ipv6: distinguish frag queues by device for multicast and link-local packets") modified the ipv6 fragment reassembly logic to distinguish frag queues by device for multicast and link-local packets but in fact only the main reassembly code limits the use of the device to those address types and the netfilter reassembly code uses the device for all packets.
This means that if fragments of a packet arrive on different interfaces then netfilter will fail to reassemble them and the fragments will be expired without going any further through the filters.
--- net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++++ 1 file changed, 4 insertions(+)
net/ipv6/netfilter/nf_conntrack_reasm.c +4 -0
@@ -155,6 +155,10 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user, };struct inet_frag_queue *q; +if (!(ipv6_addr_type (&hdr->daddr) & (IPV6_ADDR_MULTICAST | +IPV6_ADDR_LINKLOCAL ))) + key.iif =0 ; + q =inet_frag_find (nf_frag->fqdir, &key);if (!q)return NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 38/215 netfilter: flowtable: initialise extack before use
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donald Hunter <[email protected]>
[ Upstream commit e9767137308daf906496613fd879808a07f006a2 ]
Fix missing initialisation of extack in flow offload.
--- net/netfilter/nf_flow_table_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_flow_table_offload.c +1 -1
@@ -830,8 +830,8 @@ static int nf_flow_offload_tuple(struct nf_flowtable *flowtable, struct list_head *block_cb_list) {struct flow_cls_offload cls_flow = {}; +struct netlink_ext_ack extack = {};struct flow_block_cb *block_cb; -struct netlink_ext_ack extack;__be16 proto =ETH_P_ALL ;int err, i =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 39/215 netfilter: nf_queue: drop packets with cloned unconfirmed conntracks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit 7d8dc1c7be8d3509e8f5164dd5df64c8e34d7eeb ]
Conntrack assumes an unconfirmed entry (not yet committed to global hash table) has a refcount of 1 and is not visible to other cores.
With multicast forwarding this assumption breaks down because such skbs get cloned after being picked up, i.e. ct->use refcount is > 1.
Likewise, bridge netfilter will clone broad/mutlicast frames and all frames in case they need to be flood-forwarded during learning phase.
For ip multicast forwarding or plain bridge flood-forward this will "work" because packets don't leave softirq and are implicitly serialized.
With nfqueue this no longer holds true, the packets get queued and can be reinjected in arbitrary ways.
Disable this feature, I see no other solution.
After this patch, nfqueue cannot queue packets except the last multicast/broadcast packet.
--- net/bridge/br_netfilter_hooks.c | 6 +++++- net/netfilter/nfnetlink_queue.c | 35 +++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-)
net/bridge/br_netfilter_hooks.c +5 -1
@@ -602,8 +602,12 @@ static unsigned int br_nf_local_in(void *priv,if (likely (nf_ct_is_confirmed (ct)))return NF_ACCEPT ; +if (WARN_ON_ONCE (refcount_read (&nfct->use) !=1 )) { +nf_reset_ct (skb); +return NF_ACCEPT ; + } +WARN_ON_ONCE (skb_shared (skb)); -WARN_ON_ONCE (refcount_read (&nfct->use) !=1 );/* We can't call nf_confirm here, it would create a dependency * on nf_conntrack module.
net/netfilter/nfnetlink_queue.c +33 -2
@@ -640,10 +640,41 @@ static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry) {#if IS_ENABLED (CONFIG_NF_CONNTRACK )static const unsigned long flags =IPS_CONFIRMED |IPS_DYING ; -const struct nf_conn *ct = (void *)skb_nfct (entry->skb); +struct nf_conn *ct = (void *)skb_nfct (entry->skb); +unsigned long status; +unsigned int use; -if (ct && ((ct->status & flags) ==IPS_DYING )) +if (!ct) +return false; + + status =READ_ONCE (ct->status); +if ((status & flags) ==IPS_DYING )return true; + +if (status &IPS_CONFIRMED ) +return false; + +/* in some cases skb_clone() can occur after initial conntrack +* pickup, but conntrack assumes exclusive skb->_nfct ownership for +* unconfirmed entries. +* +* This happens for br_netfilter and with ip multicast routing. +* We can't be solved with serialization here because one clone could +* have been queued for local delivery. +*/ + use =refcount_read (&ct->ct_general.use); +if (likely (use ==1 )) +return false; + +/* Can't decrement further? Exclusive ownership. */ +if (!refcount_dec_not_one (&ct->ct_general.use)) +return false; + +skb_set_nfct (entry->skb,0 ); +/* No nf_ct_put(): we already decremented .use and it cannot +* drop down to 0. +*/ +return true;#endif return false; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 40/215 net: hns3: fix wrong use of semaphore up
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Wang <[email protected]>
[ Upstream commit 8445d9d3c03101859663d34fda747f6a50947556 ]
Currently, if hns3 PF or VF FLR reset failed after five times retry, the reset done process will directly release the semaphore which has already released in hclge_reset_prepare_general. This will cause down operation fail.
So this patch fixes it by adding reset state judgement. The up operation is only called after successful PF FLR reset.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++-- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +2 -2
@@ -11636,8 +11636,8 @@ static void hclge_reset_done(struct hnae3_ae_dev *ae_dev)dev_err (&hdev->pdev->dev,"fail to rebuild, ret=%d\n" , ret); hdev->reset_type =HNAE3_NONE_RESET ; -clear_bit (HCLGE_STATE_RST_HANDLING , &hdev->state); -up (&hdev->reset_sem); +if (test_and_clear_bit (HCLGE_STATE_RST_HANDLING , &hdev->state)) +up (&hdev->reset_sem); }static void hclge_clear_resetting_state (struct hclge_dev *hdev)
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +2 -2
@@ -2217,8 +2217,8 @@ static void hclgevf_reset_done(struct hnae3_ae_dev *ae_dev) ret); hdev->reset_type =HNAE3_NONE_RESET ; -clear_bit (HCLGEVF_STATE_RST_HANDLING , &hdev->state); -up (&hdev->reset_sem); +if (test_and_clear_bit (HCLGEVF_STATE_RST_HANDLING , &hdev->state)) +up (&hdev->reset_sem); }static u32 hclgevf_get_fw_version (struct hnae3_handle *handle)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 41/215 net: hns3: fix a deadlock problem when config TC during resetting
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Wang <[email protected]>
[ Upstream commit be5e816d00a506719e9dbb1a9c861c5ced30a109 ]
When config TC during the reset process, may cause a deadlock, the flow is as below:
pf reset start
│
▼
......
setup tc │
│ ▼
▼ DOWN: napi_disable()
napi_disable()(skip) │
│ │
▼ ▼
...... ......
│ │
▼ │
napi_enable() │
▼
UINIT: netif_napi_del()
│
▼
......
│
▼
INIT: netif_napi_add()
│
▼
...... global reset start
│ │
▼ ▼
UP: napi_enable()(skip) ......
│ │
▼ ▼
...... napi_disable()In reset process, the driver will DOWN the port and then UINIT, in this case, the setup tc process will UP the port before UINIT, so cause the problem. Adds a DOWN process in UINIT to fix it.
--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +3 -0
@@ -5504,6 +5504,9 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)struct net_device *netdev = handle->kinfo.netdev;struct hns3_nic_priv *priv =netdev_priv (netdev); +if (!test_bit (HNS3_NIC_STATE_DOWN , &priv->state)) +hns3_nic_net_stop (netdev); +if (!test_and_clear_bit (HNS3_NIC_STATE_INITED , &priv->state)) {netdev_warn (netdev,"already uninitialized\n" );return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 42/215 ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Parsa Poorshikhian <[email protected]>
[ Upstream commit ef9718b3d54e822de294351251f3a574f8a082ce ]
Fix noise from speakers connected to AUX port when no sound is playing. The problem occurs because the alc_shutup_pins function includes a 0x10ec0257 vendor ID, which causes noise on Lenovo IdeaPad 3 15IAU7 with Realtek ALC257 codec when no sound is playing.
Removing this vendor ID from the function fixes the bug.
--- sound/pci/hda/patch_realtek.c | 1 - 1 file changed, 1 deletion(-)
sound/pci/hda/patch_realtek.c +0 -1
@@ -577,7 +577,6 @@ static void alc_shutup_pins(struct hda_codec *codec)switch (codec->core.vendor_id) {case 0x10ec0236 :case 0x10ec0256 : -case 0x10ec0257 :case 0x19e58326 :case 0x10ec0283 :case 0x10ec0285 :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 43/215 ssb: Fix division by zero issue in ssb_calc_clock_rate
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rand Deeb <[email protected]>
[ Upstream commit e0b5127fa134fe0284d58877b6b3133939c8b3ce ]
In ssb_calc_clock_rate(), there is a potential issue where the value of m1 could be zero due to initialization using clkfactor_f6_resolv(). This situation raised concerns about the possibility of a division by zero error.
We fixed it by following the suggestions provided by Larry Finger <[email protected]> and Michael Büsch <[email protected]>. The fix involves returning a value of 1 instead of 0 in clkfactor_f6_resolv(). This modification ensures the proper functioning of the code and eliminates the risk of division by zero errors.
--- drivers/ssb/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ssb/main.c +1 -1
@@ -837,7 +837,7 @@ static u32 clkfactor_f6_resolve(u32 v)case SSB_CHIPCO_CLK_F6_7 :return 7 ; } -return 0 ; +return 1 ; }/* Calculate the speed the backplane would run at a given set of clockcontrol values */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 44/215 wifi: cfg80211: check wiphy mutex is held for wdev mutex
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 1474bc87fe57deac726cc10203f73daa6c3212f7 ]
This might seem pretty pointless rather than changing the locking immediately, but it seems safer to run for a while with checks and the old locking scheme, and then remove the wdev lock later.
--- net/wireless/core.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/wireless/core.h +7 -1
@@ -217,6 +217,7 @@ void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,static inline void wdev_lock (struct wireless_dev *wdev)__acquires (wdev) { +lockdep_assert_held (&wdev->wiphy->mtx);mutex_lock (&wdev->mtx);__acquire (wdev->mtx); }
@@ -224,11 +225,16 @@ static inline void wdev_lock(struct wireless_dev *wdev)static inline void wdev_unlock (struct wireless_dev *wdev)__releases (wdev) { +lockdep_assert_held (&wdev->wiphy->mtx);__release (wdev->mtx);mutex_unlock (&wdev->mtx); } -#define ASSERT_WDEV_LOCK (wdev) lockdep_assert_held(&(wdev)->mtx) +static inline void ASSERT_WDEV_LOCK (struct wireless_dev *wdev) +{ +lockdep_assert_held (&wdev->wiphy->mtx); +lockdep_assert_held (&wdev->mtx); +}static inline bool cfg80211_has_monitors_only (struct cfg80211_registered_device *rdev) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 45/215 wifi: mac80211: fix BA session teardown race
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 05f136220d17839eb7c155f015ace9152f603225 ]
As previously reported by Alexander, whose commit 69403bad97aa ("wifi: mac80211: sdata can be NULL during AMPDU start") I'm reverting as part of this commit, there's a race between station destruction and aggregation setup, where the aggregation setup can happen while the station is being removed and queue the work after ieee80211_sta_tear_down_BA_sessions() has already run in __sta_info_destroy_part1(), and thus the worker will run with a now freed station. In his case, this manifested in a NULL sdata pointer, but really there's no guarantee whatsoever.
The real issue seems to be that it's possible at all to have a situation where this occurs - we want to stop the BA sessions when doing _part1, but we cannot be sure, and WLAN_STA_BLOCK_BA isn't necessarily effective since we don't know that the setup isn't concurrently running and already got past the check.
Simply call ieee80211_sta_tear_down_BA_sessions() again in the second part of station destruction, since at that point really nothing else can hold a reference to the station any more.
Also revert the sdata checks since those are just misleading at this point.
--- net/mac80211/agg-tx.c | 6 +----- net/mac80211/driver-ops.c | 3 --- net/mac80211/sta_info.c | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 8 deletions(-)
net/mac80211/agg-tx.c +1 -5
@@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) {struct tid_ampdu_tx *tid_tx;struct ieee80211_local *local = sta->local; -struct ieee80211_sub_if_data *sdata; +struct ieee80211_sub_if_data *sdata = sta->sdata;struct ieee80211_ampdu_params params = { .sta = &sta->sta, .action =IEEE80211_AMPDU_TX_START ,
@@ -521,7 +521,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)*/ synchronize_net (); - sdata = sta->sdata; params.ssn = sta->tid_seq[tid] >>4 ; ret =drv_ampdu_action (local, sdata, ¶ms); tid_tx->ssn = params.ssn;
@@ -535,9 +534,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)*/ set_bit (HT_AGG_STATE_DRV_READY , &tid_tx->state); }else if (ret) { -if (!sdata) -return ; -ht_dbg (sdata,"BA request denied - HW unavailable for %pM tid %d\n" , sta->sta.addr, tid);
net/mac80211/driver-ops.c +0 -3
@@ -331,9 +331,6 @@ int drv_ampdu_action(struct ieee80211_local *local,might_sleep (); -if (!sdata) -return -EIO ; - sdata =get_bss_sdata (sdata);if (!check_sdata_in_driver (sdata))return -EIO ;
net/mac80211/sta_info.c +14 -0
@@ -1060,6 +1060,20 @@ static void __sta_info_destroy_part2(struct sta_info *sta)* after _part1 and before _part2! */ +/* +* There's a potential race in _part1 where we set WLAN_STA_BLOCK_BA +* but someone might have just gotten past a check, and not yet into +* queuing the work/creating the data/etc. +* +* Do another round of destruction so that the worker is certainly +* canceled before we later free the station. +* +* Since this is after synchronize_rcu()/synchronize_net() we're now +* certain that nobody can actually hold a reference to the STA and +* be calling e.g. ieee80211_start_tx_ba_session(). +*/ +ieee80211_sta_tear_down_BA_sessions (sta,AGG_STOP_DESTROY_STA ); +might_sleep ();lockdep_assert_held (&local->sta_mtx);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 46/215 wifi: cw1200: Avoid processing an invalid TIM IE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Johnson <[email protected]>
[ Upstream commit b7bcea9c27b3d87b54075735c870500123582145 ]
While converting struct ieee80211_tim_ie::virtual_map to be a flexible array it was observed that the TIM IE processing in cw1200_rx_cb() could potentially process a malformed IE in a manner that could result in a buffer over-read. Add logic to verify that the TIM IE length is large enough to hold a valid TIM payload before processing it.
--- drivers/net/wireless/st/cw1200/txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/st/cw1200/txrx.c +1 -1
@@ -1170,7 +1170,7 @@ void cw1200_rx_cb(struct cw1200_common *priv,size_t ies_len = skb->len - (ies - (u8 *)(skb->data)); tim_ie =cfg80211_find_ie (WLAN_EID_TIM , ies, ies_len); -if (tim_ie) { +if (tim_ie && tim_ie[1 ] >=sizeof (struct ieee80211_tim_ie )) {struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *)&tim_ie[2 ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 47/215 i2c: riic: avoid potential division by zero
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 7890fce6201aed46d3576e3d641f9ee5c1f0e16f ]
Value comes from DT, so it could be 0. Unlikely, but could be.
--- drivers/i2c/busses/i2c-riic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-riic.c +1 -1
@@ -319,7 +319,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)* frequency with only 62 clock ticks max (31 high, 31 low). * Aim for a duty of 60% LOW, 40% HIGH. */ - total_ticks =DIV_ROUND_UP (rate, t->bus_freq_hz); + total_ticks =DIV_ROUND_UP (rate, t->bus_freq_hz ?:1 );for (cks =0 ; cks <7 ; cks++) {/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 48/215 RDMA/rtrs: Fix the problem of variable not initialized fully
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit c5930a1aa08aafe6ffe15b5d28fe875f88f6ac86 ]
No functionality change. The variable which is not initialized fully will introduce potential risks.
--- drivers/infiniband/ulp/rtrs/rtrs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/ulp/rtrs/rtrs.c +1 -1
@@ -255,7 +255,7 @@ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,static int create_qp (struct rtrs_con *con,struct ib_pd *pd,u32 max_send_wr,u32 max_recv_wr,u32 max_sge) { -struct ib_qp_init_attr init_attr = {NULL }; +struct ib_qp_init_attr init_attr = {};struct rdma_cm_id *cm_id = con->cm_id;int ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 49/215 s390/smp,mcck: fix early IPI handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
[ Upstream commit 4a1725281fc5b0009944b1c0e1d2c1dc311a09ec ]
Both the external call as well as the emergency signal submask bits in control register 0 are set before any interrupt handler is registered.
Change the order and first register the interrupt handler and only then enable the interrupts by setting the corresponding bits in control register 0.
This prevents that the second part of the machine check handler for early machine check handling is not executed: the machine check handler sends an IPI to the CPU it runs on. If the corresponding interrupts are enabled, but no interrupt handler is present, the interrupt is ignored.
--- arch/s390/kernel/early.c | 12 +++--------- arch/s390/kernel/smp.c | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-)
arch/s390/kernel/early.c +3 -9
@@ -250,15 +250,9 @@ static inline void save_vector_registers(void)#endif } -static inline void setup_control_registers (void ) +static inline void setup_low_address_protection (void ) { -unsigned long reg; - -__ctl_store (reg,0 ,0 ); - reg |=CR0_LOW_ADDRESS_PROTECTION ; - reg |=CR0_EMERGENCY_SIGNAL_SUBMASK ; - reg |=CR0_EXTERNAL_CALL_SUBMASK ; -__ctl_load (reg,0 ,0 ); +__ctl_set_bit (0 ,28 ); }static inline void setup_access_registers (void )
@@ -311,7 +305,7 @@ void __init startup_init(void)save_vector_registers ();setup_topology ();sclp_early_detect (); -setup_control_registers (); +setup_low_address_protection ();setup_access_registers ();lockdep_on (); }
arch/s390/kernel/smp.c +2 -2
@@ -1003,12 +1003,12 @@ void __init smp_fill_possible_mask(void)void __init smp_prepare_cpus (unsigned int max_cpus) { -/* request the 0x1201 emergency signal external interrupt */ if (register_external_irq (EXT_IRQ_EMERGENCY_SIG , do_ext_call_interrupt))panic ("Couldn't request external interrupt 0x1201" ); -/* request the 0x1202 external call external interrupt */ +ctl_set_bit (0 ,14 );if (register_external_irq (EXT_IRQ_EXTERNAL_CALL , do_ext_call_interrupt))panic ("Couldn't request external interrupt 0x1202" ); +ctl_set_bit (0 ,13 ); }void __init smp_prepare_boot_cpu (void )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 50/215 i3c: mipi-i3c-hci: Remove BUG() when Ring Abort request times out
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Nikula <[email protected]>
[ Upstream commit 361acacaf7c706223968c8186f0d3b6e214e7403 ]
Ring Abort request will timeout in case there is an error in the Host Controller interrupt delivery or Ring Header configuration. Using BUG() makes hard to debug those cases.
Make it less severe and turn BUG() to WARN_ON().
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/i3c/master/mipi-i3c-hci/dma.c +1 -2
@@ -450,10 +450,9 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,/* * We're deep in it if ever this condition is ever met. * Hardware might still be writing to memory, etc. -* Better suspend the world than risking silent corruption. */ dev_crit (&hci->master.dev,"unable to abort the ring\n" ); -BUG (); +WARN_ON (1 ); }for (i =0 ; i < n; i++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 51/215 i3c: mipi-i3c-hci: Do not unmap region not mapped for transfer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Nikula <[email protected]>
[ Upstream commit b8806e0c939f168237593af0056c309bf31022b0 ]
Fix following warning (with CONFIG_DMA_API_DEBUG) which happens with a transfer without a data buffer.
DMA-API: i3c mipi-i3c-hci.0: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=0 bytes]
For those transfers the hci_dma_queue_xfer() doesn't create a mapping and the DMA address pointer xfer->data_dma is not set.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i3c/master/mipi-i3c-hci/dma.c +2 -0
@@ -345,6 +345,8 @@ static void hci_dma_unmap_xfer(struct i3c_hci *hci,for (i =0 ; i < n; i++) { xfer = xfer_list + i; +if (!xfer->data) +continue ;dma_unmap_single (&hci->master.dev, xfer->data_dma, xfer->data_len, xfer->rnw ?DMA_FROM_DEVICE :DMA_TO_DEVICE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 52/215 media: radio-isa: use dev_name to fill in bus_info
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
[ Upstream commit 8b7f3cf4eb9a95940eaabad3226caeaa0d9aa59d ]
This fixes this warning:
drivers/media/radio/radio-isa.c: In function 'radio_isa_querycap':drivers/media/radio/radio-isa.c:39:57: warning: '%s' directive output may be truncated writing up to 35 bytes into a region of size 28 [-Wformat-truncation=]
39 | snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name);
| ^~drivers/media/radio/radio-isa.c:39:9: note: 'snprintf' output between 5 and 40 bytes into a destination of size 32
39 | snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- drivers/media/radio/radio-isa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/radio/radio-isa.c +1 -1
@@ -36,7 +36,7 @@ static int radio_isa_querycap(struct file *file, void *priv,strscpy (v->driver, isa->drv->driver.driver.name,sizeof (v->driver));strscpy (v->card, isa->drv->card,sizeof (v->card)); -snprintf (v->bus_info,sizeof (v->bus_info),"ISA:%s" , isa->v4l2_dev.name); +snprintf (v->bus_info,sizeof (v->bus_info),"ISA:%s" ,dev_name (isa->v4l2_dev.dev));return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 53/215 staging: iio: resolver: ad2s1210: fix use before initialization
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 7fe2d05cee46b1c4d9f1efaeab08cc31a0dfff60 ]
This fixes a use before initialization in ad2s1210_probe(). The ad2s1210_setup_gpios() function uses st->sdev but it was being called before this field was initialized.
--- drivers/staging/iio/resolver/ad2s1210.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/staging/iio/resolver/ad2s1210.c +4 -3
@@ -658,9 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi)if (!indio_dev)return -ENOMEM ; st =iio_priv (indio_dev); - ret =ad2s1210_setup_gpios (st); -if (ret <0 ) -return ret;spi_set_drvdata (spi, indio_dev);
@@ -671,6 +668,10 @@ static int ad2s1210_probe(struct spi_device *spi) st->resolution =12 ; st->fexcit =AD2S1210_DEF_EXCIT ; + ret =ad2s1210_setup_gpios (st); +if (ret <0 ) +return ret; + indio_dev->info = &ad2s1210_info; indio_dev->modes =INDIO_DIRECT_MODE ; indio_dev->channels = ad2s1210_channels;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 54/215 drm/amd/display: Validate hw_points_num before using it
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 58c3b3341cea4f75dc8c003b89f8a6dd8ec55e50 ]
[WHAT]hw_points_num is 0 before ogam LUT is programmed; however, function "dwb3_program_ogam_pwl" assumes hw_points_num is always greater than 0, i.e. substracting it by 1 as an array index.
[HOW]
Check hw_points_num is not equal to 0 before using it.
--- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c +3 -0
@@ -243,6 +243,9 @@ static bool dwb3_program_ogam_lut(return false; } +if (params->hw_points_num ==0 ) +return false; +REG_SET (DWB_OGAM_CONTROL ,0 ,DWB_OGAM_MODE ,2 ); current_mode =dwb3_get_ogam_current (dwbc30);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 55/215 staging: ks7010: disable bh on tx_dev_lock
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
[ Upstream commit 058cbee52ccd7be77e373d31a4f14670cfd32018 ]
As &priv->tx_dev.tx_dev_lock is also acquired by xmit callback which could be call from timer under softirq context, use spin_lock_bh() on it to prevent potential deadlock.
hostif_sme_work()
--> hostif_sme_set_pmksa()
--> hostif_mib_set_request()
--> ks_wlan_hw_tx()
--> spin_lock(&priv->tx_dev.tx_dev_lock)
ks_wlan_start_xmit()
--> hostif_data_request()
--> ks_wlan_hw_tx()
--> spin_lock(&priv->tx_dev.tx_dev_lock)
--- drivers/staging/ks7010/ks7010_sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/ks7010/ks7010_sdio.c +2 -2
@@ -395,9 +395,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, priv->hostt.buff[priv->hostt.qtail] =le16_to_cpu (hdr->event); priv->hostt.qtail = (priv->hostt.qtail +1 ) %SME_EVENT_BUFF_SIZE ; -spin_lock (&priv->tx_dev.tx_dev_lock); +spin_lock_bh (&priv->tx_dev.tx_dev_lock); result =enqueue_txdev (priv, p, size, complete_handler, skb); -spin_unlock (&priv->tx_dev.tx_dev_lock); +spin_unlock_bh (&priv->tx_dev.tx_dev_lock);if (txq_has_space (priv))queue_delayed_work (priv->wq, &priv->rw_dwork,0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 56/215 binfmt_misc: cleanup on filesystem umount
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit 1c5976ef0f7ad76319df748ccb99a4c7ba2ba464 ]
Currently, registering a new binary type pins the binfmt_misc filesystem. Specifically, this means that as long as there is at least one binary type registered the binfmt_misc filesystem survives all umounts, i.e. the superblock is not destroyed. Meaning that a umount followed by another mount will end up with the same superblock and the same binary type handlers. This is a behavior we tend to discourage for any new filesystems (apart from a few special filesystems such as e.g. configfs or debugfs). A umount operation without the filesystem being pinned - by e.g. someone holding a file descriptor to an open file - should usually result in the destruction of the superblock and all associated resources. This makes introspection easier and leads to clearly defined, simple and clean semantics. An administrator can rely on the fact that a umount will guarantee a clean slate making it possible to reinitialize a filesystem. Right now all binary types would need to be explicitly deleted before that can happen.
This allows us to remove the heavy-handed calls to simple_pin_fs() and simple_release_fs() when creating and deleting binary types. This in turn allows us to replace the current brittle pinning mechanism abusing dget() which has caused a range of bugs judging from prior fixes in [2] and [3]. The additional dget() in load_misc_binary() pins the dentry but only does so for the sake to prevent ->evict_inode() from freeing the node when a user removes the binary type and kill_node() is run. Which would mean ->interpreter and ->interp_file would be freed causing a UAF.
This isn't really nicely documented nor is it very clean because it relies on simple_pin_fs() pinning the filesystem as long as at least one binary type exists. Otherwise it would cause load_misc_binary() to hold on to a dentry belonging to a superblock that has been shutdown. Replace that implicit pinning with a clean and simple per-node refcount and get rid of the ugly dget() pinning. A similar mechanism exists for e.g. binderfs (cf. [4]). All the cleanup work can now be done in ->evict_inode().
In a follow-up patch we will make it possible to use binfmt_misc in sandboxes. We will use the cleaner semantics where a umount for the filesystem will cause the superblock and all resources to be deallocated. In preparation for this apply the same semantics to the initial binfmt_misc mount. Note, that this is a user-visible change and as such a uapi change but one that we can reasonably risk. We've discussed this in earlier versions of this patchset (cf. [1]).
The main user and provider of binfmt_misc is systemd. Systemd provides binfmt_misc via autofs since it is configurable as a kernel module and is used by a few exotic packages and users. As such a binfmt_misc mount is triggered when /proc/sys/fs/binfmt_misc is accessed and is only provided on demand. Other autofs on demand filesystems include EFI ESP which systemd umounts if the mountpoint stays idle for a certain amount of time. This doesn't apply to the binfmt_misc autofs mount which isn't touched once it is mounted meaning this change can't accidently wipe binary type handlers without someone having explicitly unmounted binfmt_misc. After speaking to systemd folks they don't expect this change to affect them.
In line with our general policy, if we see a regression for systemd or other users with this change we will switch back to the old behavior for the initial binfmt_misc mount and have binary types pin the filesystem again. But while we touch this code let's take the chance and let's improve on the status quo.
[1]: https://lore.kernel.org/r/[email protected]
[2]: commit 43a4f2619038 ("exec: binfmt_misc: fix race between load_misc_binary() and kill_node()" [3]: commit 83f918274e4b ("exec: binfmt_misc: shift filp_close(interp_file) from kill_node() to bm_evict_inode()") [4]: commit f0fe2c0f050d ("binder: prevent UAF for binderfs devices II")
--- fs/binfmt_misc.c | 216 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 168 insertions(+), 48 deletions(-)
fs/binfmt_misc.c +168 -48
@@ -60,12 +60,11 @@ typedef struct {char *name;struct dentry *dentry;struct file *interp_file; +refcount_t users;/* sync removal with load_misc_binary() */ } Node;static DEFINE_RWLOCK (entries_lock);static struct file_system_type bm_fs_type; -static struct vfsmount *bm_mnt; -static int entry_count;/* * Max length of the register string. Determined by:
@@ -82,19 +81,23 @@ static int entry_count;*/ #define MAX_REGISTER_LENGTH 1920 -/* -* Check if we support the binfmt -* if we do, return the node, else NULL -* locking is done in load_misc_binary +/** +* search_binfmt_handler - search for a binary handler for @bprm +* @misc: handle to binfmt_misc instance +* @bprm: binary for which we are looking for a handler +* +* Search for a binary type handler for @bprm in the list of registered binary +* type handlers. +* +* Return: binary type list entry on success, NULL on failure */ -static Node *check_file (struct linux_binprm *bprm) +static Node *search_binfmt_handler (struct linux_binprm *bprm) {char *p =strrchr (bprm->interp,'.' ); -struct list_head *l; +Node *e;/* Walk all the registered handlers. */ -list_for_each (l, &entries) { -Node *e =list_entry (l, Node, list); +list_for_each_entry (e, &entries, list) {char *s;int j;
@@ -123,9 +126,49 @@ static Node *check_file(struct linux_binprm *bprm)if (j == e->size)return e; } +return NULL ; } +/** +* get_binfmt_handler - try to find a binary type handler +* @misc: handle to binfmt_misc instance +* @bprm: binary for which we are looking for a handler +* +* Try to find a binfmt handler for the binary type. If one is found take a +* reference to protect against removal via bm_{entry,status}_write(). +* +* Return: binary type list entry on success, NULL on failure +*/ +static Node *get_binfmt_handler (struct linux_binprm *bprm) +{ +Node *e; + +read_lock (&entries_lock); + e =search_binfmt_handler (bprm); +if (e) +refcount_inc (&e->users); +read_unlock (&entries_lock); +return e; +} + +/** +* put_binfmt_handler - put binary handler node +* @e: node to put +* +* Free node syncing with load_misc_binary() and defer final free to +* load_misc_binary() in case it is using the binary type handler we were +* requested to remove. +*/ +static void put_binfmt_handler (Node *e) +{ +if (refcount_dec_and_test (&e->users)) { +if (e->flags &MISC_FMT_OPEN_FILE ) +filp_close (e->interp_file,NULL ); +kfree (e); + } +} +/* * the loader itself */
@@ -139,12 +182,7 @@ static int load_misc_binary(struct linux_binprm *bprm)if (!enabled)return retval; -/* to keep locking time low, we copy the interpreter string */ -read_lock (&entries_lock); - fmt =check_file (bprm); -if (fmt) -dget (fmt->dentry); -read_unlock (&entries_lock); + fmt =get_binfmt_handler (bprm);if (!fmt)return retval;
@@ -198,7 +236,16 @@ static int load_misc_binary(struct linux_binprm *bprm) retval =0 ; ret: -dput (fmt->dentry); + +/* +* If we actually put the node here all concurrent calls to +* load_misc_binary() will have finished. We also know +* that for the refcount to be zero ->evict_inode() must have removed +* the node to be deleted from the list. All that is left for us is to +* close and free. +*/ +put_binfmt_handler (fmt); +return retval; }
@@ -553,30 +600,90 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode)return inode; } +/** +* bm_evict_inode - cleanup data associated with @inode +* @inode: inode to which the data is attached +* +* Cleanup the binary type handler data associated with @inode if a binary type +* entry is removed or the filesystem is unmounted and the super block is +* shutdown. +* +* If the ->evict call was not caused by a super block shutdown but by a write +* to remove the entry or all entries via bm_{entry,status}_write() the entry +* will have already been removed from the list. We keep the list_empty() check +* to make that explicit. +*/ static void bm_evict_inode (struct inode *inode) {Node *e = inode->i_private; -if (e && e->flags &MISC_FMT_OPEN_FILE ) -filp_close (e->interp_file,NULL ); -clear_inode (inode); -kfree (e); + +if (e) { +write_lock (&entries_lock); +if (!list_empty (&e->list)) +list_del_init (&e->list); +write_unlock (&entries_lock); +put_binfmt_handler (e); + } } -static void kill_node (Node *e) +/** +* unlink_binfmt_dentry - remove the dentry for the binary type handler +* @dentry: dentry associated with the binary type handler +* +* Do the actual filesystem work to remove a dentry for a registered binary +* type handler. Since binfmt_misc only allows simple files to be created +* directly under the root dentry of the filesystem we ensure that we are +* indeed passed a dentry directly beneath the root dentry, that the inode +* associated with the root dentry is locked, and that it is a regular file we +* are asked to remove. +*/ +static void unlink_binfmt_dentry (struct dentry *dentry) { -struct dentry *dentry; +struct dentry *parent = dentry->d_parent; +struct inode *inode, *parent_inode; + +/* All entries are immediate descendants of the root dentry. */ +if (WARN_ON_ONCE (dentry->d_sb->s_root != parent)) +return ; +/* We only expect to be called on regular files. */ + inode =d_inode (dentry); +if (WARN_ON_ONCE (!S_ISREG (inode->i_mode))) +return ; + +/* The parent inode must be locked. */ + parent_inode =d_inode (parent); +if (WARN_ON_ONCE (!inode_is_locked (parent_inode))) +return ; + +if (simple_positive (dentry)) { +dget (dentry); +simple_unlink (parent_inode, dentry); +d_delete (dentry); +dput (dentry); + } +} + +/** +* remove_binfmt_handler - remove a binary type handler +* @misc: handle to binfmt_misc instance +* @e: binary type handler to remove +* +* Remove a binary type handler from the list of binary type handlers and +* remove its associated dentry. This is called from +* binfmt_{entry,status}_write(). In the future, we might want to think about +* adding a proper ->unlink() method to binfmt_misc instead of forcing caller's +* to use writes to files in order to delete binary type handlers. But it has +* worked for so long that it's not a pressing issue. +*/ +static void remove_binfmt_handler (Node *e) +{write_lock (&entries_lock);list_del_init (&e->list);write_unlock (&entries_lock); - - dentry = e->dentry; -drop_nlink (d_inode (dentry)); -d_drop (dentry); -dput (dentry); -simple_release_fs (&bm_mnt, &entry_count); +unlink_binfmt_dentry (e->dentry); }/* /<entry> */
@@ -603,8 +710,8 @@ bm_entry_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)static ssize_t bm_entry_write (struct file *file,const char __user *buffer,size_t count,loff_t *ppos) { -struct dentry *root; -Node *e =file_inode (file)->i_private; +struct inode *inode =file_inode (file); +Node *e = inode->i_private;int res =parse_command (buffer, count);switch (res) {
@@ -618,13 +725,22 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,break ;case 3 :/* Delete this handler. */ - root =file_inode (file)->i_sb->s_root; -inode_lock (d_inode (root)); + inode =d_inode (inode->i_sb->s_root); +inode_lock (inode); +/* +* In order to add new element or remove elements from the list +* via bm_{entry,register,status}_write() inode_lock() on the +* root inode must be held. +* The lock is exclusive ensuring that the list can't be +* modified. Only load_misc_binary() can access but does so +* read-only. So we only need to take the write lock when we +* actually remove the entry from the list. +*/ if (!list_empty (&e->list)) -kill_node (e); +remove_binfmt_handler (e); -inode_unlock (d_inode (root)); +inode_unlock (inode);break ;default :return res;
@@ -683,13 +799,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,if (!inode) goto out2; - err =simple_pin_fs (&bm_fs_type, &bm_mnt, &entry_count); -if (err) { -iput (inode); - inode =NULL ; - goto out2; - } - +refcount_set (&e->users,1 ); e->dentry =dget (dentry); inode->i_private = e; inode->i_fop = &bm_entry_operations;
@@ -733,7 +843,8 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { int res = parse_command(buffer, count); -struct dentry *root; +Node *e, *next; +struct inode *inode;switch (res) {case 1 :
@@ -746,13 +857,22 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer,break ;case 3 :/* Delete all handlers. */ - root =file_inode (file)->i_sb->s_root; -inode_lock (d_inode (root)); + inode =d_inode (file_inode (file)->i_sb->s_root); +inode_lock (inode); -while (!list_empty (&entries)) -kill_node (list_first_entry (&entries, Node, list)); +/* +* In order to add new element or remove elements from the list +* via bm_{entry,register,status}_write() inode_lock() on the +* root inode must be held. +* The lock is exclusive ensuring that the list can't be +* modified. Only load_misc_binary() can access but does so +* read-only. So we only need to take the write lock when we +* actually remove the entry from the list. +*/ +list_for_each_entry_safe (e, next, &entries, list) +remove_binfmt_handler (e); -inode_unlock (d_inode (root)); +inode_unlock (inode);break ;default :return res;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 57/215 media: qcom: venus: fix incorrect return value
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
[ Upstream commit 51b74c09ac8c5862007fc2bf0d465529d06dd446 ]
'pd' can be NULL, and in that case it shouldn't be passed to PTR_ERR. Fixes a smatch warning:
drivers/media/platform/qcom/venus/pm_helpers.c:873 vcodec_domains_get() warn: passing zero to 'PTR_ERR'
--- drivers/media/platform/qcom/venus/pm_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/venus/pm_helpers.c +1 -1
@@ -870,7 +870,7 @@ static int vcodec_domains_get(struct venus_core *core) pd =dev_pm_domain_attach_by_name (dev, res->vcodec_pmdomains[i]);if (IS_ERR_OR_NULL (pd)) -return PTR_ERR (pd) ? : -ENODATA ; +return pd ?PTR_ERR (pd) : -ENODATA ; core->pmdomains[i] = pd; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 58/215 scsi: spi: Fix sshdr use
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Christie <[email protected]>
[ Upstream commit 0b149cee836aa53989ea089af1cb9d90d7c6ac9e ]
If scsi_execute_cmd returns < 0, it doesn't initialize the sshdr, so we shouldn't access the sshdr. If it returns 0, then the cmd executed successfully, so there is no need to check the sshdr. This has us access the sshdr when we get a return value > 0.
--- drivers/scsi/scsi_transport_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/scsi_transport_spi.c +2 -2
@@ -677,10 +677,10 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,for (r =0 ; r < retries; r++) { result =spi_execute (sdev, spi_write_buffer,DMA_TO_DEVICE , buffer, len, &sshdr); -if (result || !scsi_device_online (sdev)) { +if (result || !scsi_device_online (sdev)) {scsi_device_set_state (sdev,SDEV_QUIESCE ); -if (scsi_sense_valid (&sshdr) +if (result >0 &&scsi_sense_valid (&sshdr) && sshdr.sense_key ==ILLEGAL_REQUEST /* INVALID FIELD IN CDB */ && sshdr.asc ==0x24 && sshdr.ascq ==0x00 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 59/215 gfs2: setattr_chown: Add missing initialization
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 2d8d7990619878a848b1d916c2f936d3012ee17d ]
Add a missing initialization of variable ap in setattr_chown(). Without, chown() may be able to bypass quotas.
--- fs/gfs2/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/gfs2/inode.c +1 -1
@@ -1910,7 +1910,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)kuid_t ouid, nuid;kgid_t ogid, ngid;int error; -struct gfs2_alloc_parms ap; +struct gfs2_alloc_parms ap = {}; ouid = inode->i_uid; ogid = inode->i_gid;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 60/215 wifi: iwlwifi: abort scan when rfkill on but device enabled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miri Korenblit <[email protected]>
[ Upstream commit 3c6a0b1f0add72e7f522bc9145222b86d0a7712a ]
In RFKILL we first set the RFKILL bit, then we abort scan (if one exists) by waiting for the notification from FW
and notifying mac80211. And then we stop the device.
But in case we have a scan ongoing in the period of time between rfkill on and before the device is stopped - we will not wait for the FW notification because of the iwl_mvm_is_radio_killed() condition, and then the scan_status and uid_status are misconfigured, (scan_status is cleared but uid_status not)
and when the notification suddenly arrives (before stopping the device) we will get into the assert about scan_status and uid_status mismatch. Fix this by waiting for FW notif when rfkill is on but the device isn't disabled yet.
--- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/scan.c +1 -1
@@ -3068,7 +3068,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)if (!(mvm->scan_status & type))return 0 ; -if (iwl_mvm_is_radio_killed (mvm)) { +if (!test_bit (STATUS_DEVICE_ENABLED , &mvm->trans->status)) { ret =0 ; goto out; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 61/215 wifi: iwlwifi: fw: Fix debugfs command sending
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Sisodiya <[email protected]>
[ Upstream commit 048449fc666d736a1a17d950fde0b5c5c8fd10cc ]
During debugfs command handling transport function is used directly, this bypasses the locking used by runtime operation function and leads to a kernel warning when two commands are
sent in parallel.
Fix it by using runtime operations function when sending debugfs command.
--- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +5 -1
@@ -163,7 +163,11 @@ static int iwl_dbgfs_enabled_severities_write(struct iwl_fw_runtime *fwrt, event_cfg.enabled_severities =cpu_to_le32 (enabled_severities); - ret =iwl_trans_send_cmd (fwrt->trans, &hcmd); +if (fwrt->ops && fwrt->ops->send_hcmd) + ret = fwrt->ops->send_hcmd (fwrt->ops_ctx, &hcmd); +else + ret = -EPERM ; +IWL_INFO (fwrt,"sent host event cfg with enabled_severities: %u, ret: %d\n" , enabled_severities, ret);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 62/215 IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
[ Upstream commit 2f19c4b8395ccb6eb25ccafee883c8cfbe3fc193 ]
handle_receive_interrupt_napi_sp() running inside interrupt handler could introduce inverse lock ordering between &dd->irq_src_lock and &dd->uctxt_lock, if read_mod_write() is preempted by the isr.
[CPU0] | [CPU1]
hfi1_ipoib_dev_open() |
--> hfi1_netdev_enable_queues() |
--> enable_queues(rx) |
--> hfi1_rcvctrl() |
--> set_intr_bits() |
--> read_mod_write() |
--> spin_lock(&dd->irq_src_lock) |
| hfi1_poll()
| --> poll_next()
| --> spin_lock_irq(&dd->uctxt_lock)
|
| --> hfi1_rcvctrl()
| --> set_intr_bits()
| --> read_mod_write()
| --> spin_lock(&dd->irq_src_lock)
<interrupt> |
--> handle_receive_interrupt_napi_sp() |
--> set_all_fastpath() |
--> hfi1_rcd_get_by_index() |
--> spin_lock_irqsave(&dd->uctxt_lock) |This flaw was found by an experimental static analysis tool I am developing for irq-related deadlock.
To prevent the potential deadlock, the patch use spin_lock_irqsave() on &dd->irq_src_lock inside read_mod_write() to prevent the possible deadlock scenario.
--- drivers/infiniband/hw/hfi1/chip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +3 -2
@@ -13182,15 +13182,16 @@ static void read_mod_write(struct hfi1_devdata *dd, u16 src, u64 bits, {u64 reg;u16 idx = src /BITS_PER_REGISTER ; +unsigned long flags; -spin_lock (&dd->irq_src_lock); +spin_lock_irqsave (&dd->irq_src_lock, flags); reg =read_csr (dd,CCE_INT_MASK + (8 * idx));if (set) reg |= bits;else reg &= ~bits;write_csr (dd,CCE_INT_MASK + (8 * idx), reg); -spin_unlock (&dd->irq_src_lock); +spin_unlock_irqrestore (&dd->irq_src_lock, flags); }/**
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 63/215 hwmon: (ltc2992) Avoid division by zero
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
[ Upstream commit 10b02902048737f376104bc69e5212466e65a542 ]
Do not allow setting shunt resistor to 0. This results in a division by zero when performing current value computations based on input voltages and connected resistor values.
--- drivers/hwmon/ltc2992.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/hwmon/ltc2992.c +5 -1
@@ -912,8 +912,12 @@ static int ltc2992_parse_dt(struct ltc2992_state *st) } ret =fwnode_property_read_u32 (child,"shunt-resistor-micro-ohms" , &val); -if (!ret) +if (!ret) { +if (!val) +return dev_err_probe (&st->client->dev, -EINVAL , +"shunt resistor value cannot be zero\n" ); st->r_sense_uohm[addr] = val; + } }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 64/215 arm64: Fix KASAN random tag seed initialization
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Holland <[email protected]>
[ Upstream commit f75c235565f90c4a17b125e47f1c68ef6b8c2bce ]
Currently, kasan_init_sw_tags() is called before setup_per_cpu_areas(), so per_cpu(prng_state, cpu) accesses the same address regardless of the value of "cpu", and the same seed value gets copied to the percpu area for every CPU. Fix this by moving the call to smp_prepare_boot_cpu(), which is the first architecture hook after setup_per_cpu_areas().
--- arch/arm64/kernel/setup.c | 3 --- arch/arm64/kernel/smp.c | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-)
arch/arm64/kernel/setup.c +0 -3
@@ -364,9 +364,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)smp_init_cpus ();smp_build_mpidr_hash (); -/* Init percpu seeds for random tags after cpus are set up. */ -kasan_init_sw_tags (); -#ifdef CONFIG_ARM64_SW_TTBR0_PAN /* * Make sure init_thread_info.ttbr0 always generates translation
arch/arm64/kernel/smp.c +2 -0
@@ -464,6 +464,8 @@ void __init smp_prepare_boot_cpu(void)init_gic_priority_masking ();kasan_init_hw_tags (); +/* Init percpu seeds for random tags after cpus are set up. */ +kasan_init_sw_tags (); }static u64 __init of_get_cpu_mpidr (struct device_node *dn)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 65/215 memory: tegra: Skip SID programming if SID registers arent set
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ashish Mhetre <[email protected]>
[ Upstream commit 0d6c918011ce4764ed277de4726a468b7ffe5fed ]
There are few MC clients where SID security and override register offsets are not specified like "sw_cluster0" in tegra234. Don't program SID override for such clients because it leads to access to invalid addresses.
--- drivers/memory/tegra/tegra186.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/memory/tegra/tegra186.c +3 -0
@@ -43,6 +43,9 @@ static void tegra186_mc_client_sid_override(struct tegra_mc *mc, {u32 value, old; +if (client->regs.sid.security ==0 && client->regs.sid.override ==0 ) +return ; + value =readl (mc->regs + client->regs.sid.security);if ((value &MC_SID_STREAMID_SECURITY_OVERRIDE ) ==0 ) {/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 66/215 powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kunwu Chan <[email protected]>
[ Upstream commit 45b1ba7e5d1f6881050d558baf9bc74a2ae13930 ]
kasprintf() returns a pointer to dynamically allocated memory which can be NULL upon failure. Ensure the allocation was successful by checking the pointer validity.
--- arch/powerpc/sysdev/xics/icp-native.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/sysdev/xics/icp-native.c +2 -0
@@ -235,6 +235,8 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr, rname =kasprintf (GFP_KERNEL ,"CPU %d [0x%x] Interrupt Presentation" , cpu, hw_id); +if (!rname) +return -ENOMEM ;if (!request_mem_region (addr, size, rname)) {pr_warn ("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n" , cpu, hw_id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 67/215 nvmet-trace: avoid dereferencing pointer too early
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Wagner <[email protected]>
[ Upstream commit 0e716cec6fb11a14c220ee17c404b67962e902f7 ]
The first command issued from the host to the target is the fabrics connect command. At this point, neither the target queue nor the controller have been allocated. But we already try to trace this command in nvmet_req_init.
Reported by KASAN.
--- drivers/nvme/target/trace.c | 6 +++--- drivers/nvme/target/trace.h | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 14 deletions(-)
drivers/nvme/target/trace.c +3 -3
@@ -211,7 +211,7 @@ const char *nvmet_trace_disk_name(struct trace_seq *p, char *name)return ret; } -const char *nvmet_trace_ctrl_name (struct trace_seq *p,struct nvmet_ctrl *ctrl) +const char *nvmet_trace_ctrl_id (struct trace_seq *p,u16 ctrl_id) {const char *ret =trace_seq_buffer_ptr (p);
@@ -224,8 +224,8 @@ const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl)* If we can know the extra data of the connect command in this stage, * we can update this print statement later. */ -if (ctrl) -trace_seq_printf (p,"%d" , ctrl->cntlid); +if (ctrl_id) +trace_seq_printf (p,"%d" , ctrl_id);else trace_seq_printf (p,"_" );trace_seq_putc (p,0 );
drivers/nvme/target/trace.h +17 -11
@@ -32,18 +32,24 @@ const char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype, nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \ nvmet_trace_parse_admin_cmd(p, opcode, cdw10))) -const char *nvmet_trace_ctrl_name (struct trace_seq *p,struct nvmet_ctrl *ctrl); -#define __print_ctrl_name (ctrl) \ - nvmet_trace_ctrl_name(p, ctrl) +const char *nvmet_trace_ctrl_id (struct trace_seq *p,u16 ctrl_id); +#define __print_ctrl_id (ctrl_id) \ + nvmet_trace_ctrl_id(p, ctrl_id)const char *nvmet_trace_disk_name (struct trace_seq *p,char *name);#define __print_disk_name (name) \ nvmet_trace_disk_name(p, name)#ifndef TRACE_HEADER_MULTI_READ -static inline struct nvmet_ctrl *nvmet_req_to_ctrl (struct nvmet_req *req) +static inline u16 nvmet_req_to_ctrl_id (struct nvmet_req *req) { -return req->sq->ctrl; +/* +* The queue and controller pointers are not valid until an association +* has been established. +*/ +if (!req->sq || !req->sq->ctrl) +return 0 ; +return req->sq->ctrl->cntlid; }static inline void __assign_req_name (char *name,struct nvmet_req *req)
@@ -62,7 +68,7 @@ TRACE_EVENT(nvmet_req_init, TP_ARGS(req, cmd),TP_STRUCT__entry (__field (struct nvme_command *,cmd ) - __field(struct nvmet_ctrl *, ctrl) +__field (u16, ctrl_id)__array (char, disk,DISK_NAME_LEN )__field (int, qid) __field(u16, cid)
@@ -75,7 +81,7 @@ TRACE_EVENT(nvmet_req_init, ), TP_fast_assign( __entry->cmd = cmd; - __entry->ctrl =nvmet_req_to_ctrl (req); + __entry->ctrl_id =nvmet_req_to_ctrl_id (req);__assign_req_name (__entry->disk, req); __entry->qid = req->sq->qid; __entry->cid = cmd->common.command_id;
@@ -89,7 +95,7 @@ TRACE_EVENT(nvmet_req_init, ), TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " "meta=%#llx, cmd=(%s, %s)", - __print_ctrl_name(__entry->ctrl), + __print_ctrl_id(__entry->ctrl_id), __print_disk_name(__entry->disk), __entry->qid, __entry->cid, __entry->nsid, __entry->flags, __entry->metadata,
@@ -103,7 +109,7 @@ TRACE_EVENT(nvmet_req_complete, TP_PROTO(struct nvmet_req *req), TP_ARGS(req), TP_STRUCT__entry( - __field(struct nvmet_ctrl *, ctrl) + __field(u16, ctrl_id) __array(char, disk, DISK_NAME_LEN) __field(int, qid) __field(int, cid)
@@ -111,7 +117,7 @@ TRACE_EVENT(nvmet_req_complete,__field (u16, status) ),TP_fast_assign ( - __entry->ctrl = nvmet_req_to_ctrl(req); + __entry->ctrl_id = nvmet_req_to_ctrl_id(req); __entry->qid = req->cq->qid; __entry->cid = req->cqe->command_id; __entry->result =le64_to_cpu (req->cqe->result.u64);
@@ -119,7 +125,7 @@ TRACE_EVENT(nvmet_req_complete,__assign_req_name (__entry->disk, req); ),TP_printk ("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x" , -__print_ctrl_name (__entry->ctrl), +__print_ctrl_id (__entry->ctrl_id),__print_disk_name (__entry->disk), __entry->qid, __entry->cid, __entry->result, __entry->status)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 68/215 ext4: do not trim the group with corrupted block bitmap
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
[ Upstream commit 172202152a125955367393956acf5f4ffd092e0d ]
Otherwise operating on an incorrupted block bitmap can lead to all sorts of unknown problems.
--- fs/ext4/mballoc.c | 3 +++ 1 file changed, 3 insertions(+)
fs/ext4/mballoc.c +3 -0
@@ -6496,6 +6496,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group))bool set_trimmed = false;void *bitmap; +if (unlikely (EXT4_MB_GRP_BBITMAP_CORRUPT (e4b->bd_info))) +return 0 ; + last =ext4_last_grp_cluster (sb, e4b->bd_group); bitmap = e4b->bd_bitmap;if (start ==0 && max >= last)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 69/215 afs: fix __afs_break_callback() / afs_drop_open_mmap() race
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit 275655d3207b9e65d1561bf21c06a622d9ec1d43 ]
In __afs_break_callback() we might check ->cb_nr_mmap and if it's non-zero do queue_work(&vnode->cb_work). In afs_drop_open_mmap() we decrement ->cb_nr_mmap and do flush_work(&vnode->cb_work) if it reaches zero.
The trouble is, there's nothing to prevent __afs_break_callback() from seeing ->cb_nr_mmap before the decrement and do queue_work() after both the decrement and flush_work(). If that happens, we might be in trouble - vnode might get freed before the queued work runs.
__afs_break_callback() is always done under ->cb_lock, so let's make sure that ->cb_nr_mmap can change from non-zero to zero while holding ->cb_lock (the spinlock component of it - it's a seqlock and we don't need to mess with the counter).
--- fs/afs/file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/afs/file.c +6 -2
@@ -512,13 +512,17 @@ static void afs_add_open_mmap(struct afs_vnode *vnode)static void afs_drop_open_mmap (struct afs_vnode *vnode) { -if (!atomic_dec_and_test (&vnode->cb_nr_mmap)) +if (atomic_add_unless (&vnode->cb_nr_mmap,-1 ,1 ))return ;down_write (&vnode->volume->cell->fs_open_mmaps_lock); -if (atomic_read (&vnode->cb_nr_mmap) ==0 ) +read_seqlock_excl (&vnode->cb_lock); +// the only place where ->cb_nr_mmap may hit 0 +// see __afs_break_callback() for the other side... +if (atomic_dec_and_test (&vnode->cb_nr_mmap))list_del_init (&vnode->cb_mmap_link); +read_sequnlock_excl (&vnode->cb_lock);up_write (&vnode->volume->cell->fs_open_mmaps_lock);flush_work (&vnode->cb_work);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 70/215 fuse: fix UAF in rcu pathwalks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit 053fc4f755ad43cf35210677bcba798ccdc48d0c ]
->permission(), ->get_link() and ->inode_get_acl() might dereference ->s_fs_info (and, in case of ->permission(), ->s_fs_info->fc->user_ns as well) when called from rcu pathwalk.
Freeing ->s_fs_info->fc is rcu-delayed; we need to make freeing ->s_fs_info and dropping ->user_ns rcu-delayed too.
--- fs/fuse/cuse.c | 3 +-- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 15 +++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-)
fs/fuse/cuse.c +1 -2
@@ -474,8 +474,7 @@ static int cuse_send_init(struct cuse_conn *cc)static void cuse_fc_release (struct fuse_conn *fc) { -struct cuse_conn *cc =fc_to_cc (fc); -kfree_rcu (cc, fc.rcu); +kfree (fc_to_cc (fc)); }/**
fs/fuse/fuse_i.h +1 -0
@@ -848,6 +848,7 @@ struct fuse_mount {/* Entry on fc->mounts */ struct list_head fc_entry; +struct rcu_head rcu; };static inline struct fuse_mount *get_fuse_mount_super (struct super_block *sb)
fs/fuse/inode.c +11 -4
@@ -883,6 +883,14 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, }EXPORT_SYMBOL_GPL (fuse_conn_init); +static void delayed_release (struct rcu_head *p) +{ + struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu); + +put_user_ns (fc->user_ns); + fc->release (fc); +} +void fuse_conn_put (struct fuse_conn *fc) {if (refcount_dec_and_test (&fc->count)) {
@@ -894,13 +902,12 @@ void fuse_conn_put(struct fuse_conn *fc)if (fiq->ops->release) fiq->ops->release (fiq);put_pid_ns (fc->pid_ns); -put_user_ns (fc->user_ns); bucket =rcu_dereference_protected (fc->curr_bucket,1 );if (bucket) {WARN_ON (atomic_read (&bucket->count) !=1 );kfree (bucket); } - fc->release (fc); +call_rcu (&fc->rcu, delayed_release); } }EXPORT_SYMBOL_GPL (fuse_conn_put);
@@ -1297,7 +1304,7 @@ EXPORT_SYMBOL_GPL(fuse_send_init);void fuse_free_conn (struct fuse_conn *fc) {WARN_ON (!list_empty (&fc->devices)); -kfree_rcu (fc, rcu); +kfree (fc); }EXPORT_SYMBOL_GPL (fuse_free_conn);
@@ -1836,7 +1843,7 @@ static void fuse_sb_destroy(struct super_block *sb)void fuse_mount_destroy (struct fuse_mount *fm) {fuse_conn_put (fm->fc); -kfree (fm); +kfree_rcu (fm, rcu); }EXPORT_SYMBOL (fuse_mount_destroy);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 71/215 quota: Remove BUG_ON from dqget()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
[ Upstream commit 249f374eb9b6b969c64212dd860cc1439674c4a8 ]
dqget() checks whether dquot->dq_sb is set when returning it using BUG_ON. Firstly this doesn't work as an invalidation check for quite some time (we release dquot with dq_sb set these days), secondly using BUG_ON is quite harsh. Use WARN_ON_ONCE and check whether dquot is still hashed instead.
--- fs/quota/dquot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/quota/dquot.c +2 -3
@@ -995,9 +995,8 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid)* smp_mb__before_atomic() in dquot_acquire(). */ smp_rmb (); -#ifdef CONFIG_QUOTA_DEBUG -BUG_ON (!dquot->dq_sb);/* Has somebody invalidated entry under us? */ -#endif +/* Has somebody invalidated entry under us? */ +WARN_ON_ONCE (hlist_unhashed (&dquot->dq_hash)); out:if (empty)do_destroy_dquot (empty);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 72/215 media: pci: cx23885: check cx23885_vdev_init() return
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
[ Upstream commit 15126b916e39b0cb67026b0af3c014bfeb1f76b3 ]
cx23885_vdev_init() can return a NULL pointer, but that pointer is used in the next line without a check.
Add a NULL pointer check and go to the error unwind if it is NULL.
--- drivers/media/pci/cx23885/cx23885-video.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/media/pci/cx23885/cx23885-video.c +8 -0
@@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev)/* register Video device */ dev->video_dev =cx23885_vdev_init (dev, dev->pci, &cx23885_video_template,"video" ); +if (!dev->video_dev) { + err = -ENOMEM ; + goto fail_unreg; + } dev->video_dev->queue = &dev->vb2_vidq; dev->video_dev->device_caps =V4L2_CAP_READWRITE |V4L2_CAP_STREAMING |V4L2_CAP_AUDIO |V4L2_CAP_VIDEO_CAPTURE ;
@@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev)/* register VBI device */ dev->vbi_dev =cx23885_vdev_init (dev, dev->pci, &cx23885_vbi_template,"vbi" ); +if (!dev->vbi_dev) { + err = -ENOMEM ; + goto fail_unreg; + } dev->vbi_dev->queue = &dev->vb2_vbiq; dev->vbi_dev->device_caps =V4L2_CAP_READWRITE |V4L2_CAP_STREAMING |V4L2_CAP_AUDIO |V4L2_CAP_VBI_CAPTURE ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 73/215 fs: binfmt_elf_efpic: dont use missing interpreters properties
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Filippov <[email protected]>
[ Upstream commit 15fd1dc3dadb4268207fa6797e753541aca09a2a ]
Static FDPIC executable may get an executable stack even when it has non-executable GNU_STACK segment. This happens when STACK segment has rw permissions, but does not specify stack size. In that case FDPIC loader uses permissions of the interpreter's stack, and for static executables with no interpreter it results in choosing the arch-default permissions for the stack.
Fix that by using the interpreter's properties only when the interpreter is actually used.
--- fs/binfmt_elf_fdpic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/binfmt_elf_fdpic.c +1 -1
@@ -320,7 +320,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)else executable_stack =EXSTACK_DEFAULT ; -if (stack_size ==0 ) { +if (stack_size ==0 && interp_params.flags &ELF_FDPIC_FLAG_PRESENT ) { stack_size = interp_params.stack_size;if (interp_params.flags &ELF_FDPIC_FLAG_EXEC_STACK ) executable_stack =EXSTACK_ENABLE_X ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 74/215 scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 3d0f9342ae200aa1ddc4d6e7a573c6f8f068d994 ]
A static code analyzer tool indicates that the local variable called status in the lpfc_sli4_repost_sgl_list() routine could be used to print garbage uninitialized values in the routine's log message.
Fix by initializing to zero.
--- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_sli.c +1 -1
@@ -7490,7 +7490,7 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba,struct lpfc_sglq *sglq_entry =NULL ;struct lpfc_sglq *sglq_entry_next =NULL ;struct lpfc_sglq *sglq_entry_first =NULL ; -int status, total_cnt; +int status =0 , total_cnt;int post_cnt =0 , num_posted =0 , block_cnt =0 ;int last_xritag =NO_XRI ;LIST_HEAD (prep_sgl_list);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 75/215 media: drivers/media/dvb-core: copy user arrays safely
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philipp Stanner <[email protected]>
[ Upstream commit 102fb77c2deb0df3683ef8ff7a6f4cf91dc456e2 ]
At several positions in dvb_frontend.c, memdup_user() is utilized to copy userspace arrays. This is done without overflow checks.
Use the new wrapper memdup_array_user() to copy the arrays more safely.
--- drivers/media/dvb-core/dvb_frontend.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +8 -4
@@ -2160,7 +2160,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,if (!tvps->num || (tvps->num >DTV_IOCTL_MAX_MSGS ))return -EINVAL ; - tvp =memdup_user (compat_ptr (tvps->props), tvps->num *sizeof (*tvp)); + tvp =memdup_array_user (compat_ptr (tvps->props), + tvps->num,sizeof (*tvp));if (IS_ERR (tvp))return PTR_ERR (tvp);
@@ -2191,7 +2192,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,if (!tvps->num || (tvps->num >DTV_IOCTL_MAX_MSGS ))return -EINVAL ; - tvp =memdup_user (compat_ptr (tvps->props), tvps->num *sizeof (*tvp)); + tvp =memdup_array_user (compat_ptr (tvps->props), + tvps->num,sizeof (*tvp));if (IS_ERR (tvp))return PTR_ERR (tvp);
@@ -2368,7 +2370,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file,if (!tvps->num || tvps->num >DTV_IOCTL_MAX_MSGS )return -EINVAL ; - tvp =memdup_user ((void __user *)tvps->props, tvps->num *sizeof (*tvp)); + tvp =memdup_array_user ((void __user *)tvps->props, + tvps->num,sizeof (*tvp));if (IS_ERR (tvp))return PTR_ERR (tvp);
@@ -2446,7 +2449,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,if (!tvps->num || (tvps->num >DTV_IOCTL_MAX_MSGS ))return -EINVAL ; - tvp =memdup_user ((void __user *)tvps->props, tvps->num *sizeof (*tvp)); + tvp =memdup_array_user ((void __user *)tvps->props, + tvps->num,sizeof (*tvp));if (IS_ERR (tvp))return PTR_ERR (tvp);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 76/215 net/sun3_82586: Avoid reading past buffer in debug output
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 4bea747f3fbec33c16d369b2f51e55981d7c78d0 ]
Since NUM_XMIT_BUFFS is always 1, building m68k with sun3_defconfig and -Warraybounds, this build warning is visible[1]:
drivers/net/ethernet/i825xx/sun3_82586.c: In function 'sun3_82586_timeout':drivers/net/ethernet/i825xx/sun3_82586.c:990:122: warning: array subscript 1 is above array bounds of 'volatile struct transmit_cmd_struct *[1]' [-Warray-bounds=]
990 | printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status));
| ~~~~~~~~~~~~^~~
...drivers/net/ethernet/i825xx/sun3_82586.c:156:46: note: while referencing 'xmit_cmds'
156 | volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
Avoid accessing index 1 since it doesn't exist.
--- drivers/net/ethernet/i825xx/sun3_82586.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/i825xx/sun3_82586.c +1 -1
@@ -987,7 +987,7 @@ static void sun3_82586_timeout(struct net_device *dev, unsigned int txqueue) {#ifdef DEBUG printk ("%s: xmitter timed out, try to restart! stat: %02x\n" ,dev->name,p->scb->cus); -printk ("%s: command-stats: %04x %04x\n" ,dev->name,swab16 (p->xmit_cmds[0 ]->cmd_status),swab16 (p->xmit_cmds[1 ]->cmd_status)); +printk ("%s: command-stats: %04x\n" , dev->name,swab16 (p->xmit_cmds[0 ]->cmd_status));printk ("%s: check, whether you set the right interrupt number!\n" ,dev->name);#endif sun3_82586_close (dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 77/215 drm/lima: set gp bus_stop bit before hard reset
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Erico Nunes <[email protected]>
[ Upstream commit 27aa58ec85f973d98d336df7b7941149308db80f ]
This is required for reliable hard resets. Otherwise, doing a hard reset while a task is still running (such as a task which is being stopped by the drm_sched timeout handler) may result in random mmu write timeouts or lockups which cause the entire gpu to hang.
--- drivers/gpu/drm/lima/lima_gp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/gpu/drm/lima/lima_gp.c +12 -0
@@ -166,6 +166,11 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe,gp_write (LIMA_GP_CMD , cmd); } +static int lima_gp_bus_stop_poll (struct lima_ip *ip) +{ +return !!(gp_read (LIMA_GP_STATUS ) &LIMA_GP_STATUS_BUS_STOPPED ); +} +static int lima_gp_hard_reset_poll (struct lima_ip *ip) {gp_write (LIMA_GP_PERF_CNT_0_LIMIT ,0xC01A0000 );
@@ -179,6 +184,13 @@ static int lima_gp_hard_reset(struct lima_ip *ip)gp_write (LIMA_GP_PERF_CNT_0_LIMIT ,0xC0FFE000 );gp_write (LIMA_GP_INT_MASK ,0 ); + +gp_write (LIMA_GP_CMD ,LIMA_GP_CMD_STOP_BUS ); + ret =lima_poll_timeout (ip, lima_gp_bus_stop_poll,10 ,100 ); +if (ret) { +dev_err (dev->dev,"%s bus stop timeout\n" ,lima_ip_name (ip)); +return ret; + }gp_write (LIMA_GP_CMD ,LIMA_GP_CMD_RESET ); ret =lima_poll_timeout (ip, lima_gp_hard_reset_poll,10 ,100 );if (ret) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 78/215 virtiofs: forbid newlines in tags
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Hajnoczi <[email protected]>
[ Upstream commit 40488cc16f7ea0d193a4e248f0d809c25cc377db ]
Newlines in virtiofs tags are awkward for users and potential vectors for string injection attacks.
--- fs/fuse/virtio_fs.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/fuse/virtio_fs.c +10 -0
@@ -310,6 +310,16 @@ static int virtio_fs_read_tag(struct virtio_device *vdev, struct virtio_fs *fs)return -ENOMEM ;memcpy (fs->tag, tag_buf, len); fs->tag[len] ='\0' ; + +/* While the VIRTIO specification allows any character, newlines are +* awkward on mount(8) command-lines and cause problems in the sysfs +* "tag" attr and uevent TAG= properties. Forbid them. +*/ +if (strchr (fs->tag,'\n' )) { +dev_dbg (&vdev->dev,"refusing virtiofs tag with newline character\n" ); +return -EINVAL ; + } +return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 79/215 clocksource/drivers/arm_global_timer: Guard against division by zero
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Blumenstingl <[email protected]>
[ Upstream commit e651f2fae33634175fae956d896277cf916f5d09 ]
The result of the division of new_rate by gt_target_rate can be zero (if new_rate is smaller than gt_target_rate). Using that result as divisor without checking can result in a division by zero error. Guard against this by checking for a zero value earlier.
While here, also change the psv variable to an unsigned long to make sure we don't overflow the datatype as all other types involved are also unsiged long.
--- drivers/clocksource/arm_global_timer.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/clocksource/arm_global_timer.c +5 -6
@@ -290,18 +290,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,switch (event) {case PRE_RATE_CHANGE : { -int psv; +unsigned long psv; - psv =DIV_ROUND_CLOSEST (ndata->new_rate, - gt_target_rate); - -if (abs (gt_target_rate - (ndata->new_rate / psv)) >MAX_F_ERR ) + psv =DIV_ROUND_CLOSEST (ndata->new_rate, gt_target_rate); +if (!psv || +abs (gt_target_rate - (ndata->new_rate / psv)) >MAX_F_ERR )return NOTIFY_BAD ; psv--;/* prescaler within legal range? */ -if (psv <0 || psv >GT_CONTROL_PRESCALER_MAX ) +if (psv >GT_CONTROL_PRESCALER_MAX )return NOTIFY_BAD ;/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 80/215 netlink: hold nlk->cb_mutex longer in __netlink_dump_start()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit b5590270068c4324dac4a2b5a4a156e02e21339f ]
__netlink_dump_start() releases nlk->cb_mutex right before calling netlink_dump() which grabs it again.
This seems dangerous, even if KASAN did not bother yet.
Add a @lock_taken parameter to netlink_dump() to let it grab the mutex if called from netlink_recvmsg() only.
--- net/netlink/af_netlink.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
net/netlink/af_netlink.c +6 -7
@@ -128,7 +128,7 @@ static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = { "nlk_cb_mutex-MAX_LINKS" }; -static int netlink_dump (struct sock *sk); +static int netlink_dump (struct sock *sk,bool lock_taken);/* nl_table locking explained: * Lookup and traversal are protected with an RCU read-side lock. Insertion
@@ -2000,7 +2000,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,if (READ_ONCE (nlk->cb_running) &&atomic_read (&sk->sk_rmem_alloc) <= sk->sk_rcvbuf /2 ) { - ret =netlink_dump (sk); + ret =netlink_dump (sk, false);if (ret) {WRITE_ONCE (sk->sk_err, -ret);sk_error_report (sk);
@@ -2210,7 +2210,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb,return 0 ; } -static int netlink_dump (struct sock *sk) +static int netlink_dump (struct sock *sk,bool lock_taken) {struct netlink_sock *nlk =nlk_sk (sk);struct netlink_ext_ack extack = {};
@@ -2222,7 +2222,8 @@ static int netlink_dump(struct sock *sk)int alloc_min_size;int alloc_size; -mutex_lock (nlk->cb_mutex); +if (!lock_taken) +mutex_lock (nlk->cb_mutex);if (!nlk->cb_running) { err = -EINVAL ; goto errout_skb;
@@ -2378,9 +2379,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,WRITE_ONCE (nlk->cb_running, true); nlk->dump_done_errno =INT_MAX ; -mutex_unlock (nlk->cb_mutex); - - ret =netlink_dump (sk); + ret =netlink_dump (sk, true);sock_put (sk);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 81/215 md: clean up invalid BUG_ON in md_ioctl
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Nan <[email protected]>
[ Upstream commit 9dd8702e7cd28ebf076ff838933f29cf671165ec ]
'disk->private_data' is set to mddev in md_alloc() and never set to NULL, and users need to open mddev before submitting ioctl. So mddev must not have been freed during ioctl, and there is no need to check mddev here. Clean up it.
--- drivers/md/md.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/md/md.c +0 -5
@@ -7589,11 +7589,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, mddev = bdev->bd_disk->private_data; -if (!mddev) { -BUG (); - goto out; - } -/* Some actions do not requires the mutex */ switch (cmd) {case GET_ARRAY_INFO :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 82/215 x86: Increase brk randomness entropy for 64-bit systems
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 44c76825d6eefee9eb7ce06c38e1a6632ac7eb7d ]
In commit c1d171a00294 ("x86: randomize brk"), arch_randomize_brk() was defined to use a 32MB range (13 bits of entropy), but was never increased when moving to 64-bit. The default arch_randomize_brk() uses 32MB for 32-bit tasks, and 1GB (18 bits of entropy) for 64-bit tasks.
Update x86_64 to match the entropy used by arm64 and other 64-bit architectures.
--- arch/x86/kernel/process.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/kernel/process.c +4 -1
@@ -937,7 +937,10 @@ unsigned long arch_align_stack(unsigned long sp)unsigned long arch_randomize_brk (struct mm_struct *mm) { -return randomize_page (mm->brk,0x02000000 ); +if (mmap_is_ia32 ()) +return randomize_page (mm->brk,SZ_32M ); + +return randomize_page (mm->brk,SZ_1G ); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 83/215 memory: stm32-fmc2-ebi: check regmap_read return value
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Kerello <[email protected]>
[ Upstream commit 722463f73bcf65a8c818752a38c14ee672c77da1 ]
Check regmap_read return value to avoid to use uninitialized local variables.
--- drivers/memory/stm32-fmc2-ebi.c | 122 +++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 34 deletions(-)
drivers/memory/stm32-fmc2-ebi.c +88 -34
@@ -179,8 +179,11 @@ static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr; +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret;if (bcr &FMC2_BCR_MTYP )return 0 ;
@@ -193,8 +196,11 @@ static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr, val =FIELD_PREP (FMC2_BCR_MTYP ,FMC2_BCR_MTYP_NOR ); +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret;if ((bcr &FMC2_BCR_MTYP ) == val && bcr &FMC2_BCR_BURSTEN )return 0 ;
@@ -207,8 +213,11 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr; +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret;if (bcr &FMC2_BCR_BURSTEN )return 0 ;
@@ -221,8 +230,11 @@ static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr; +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret;if (!(bcr &FMC2_BCR_BURSTEN ) || !(bcr &FMC2_BCR_CBURSTRW ))return 0 ;
@@ -235,8 +247,11 @@ static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr, val =FIELD_PREP (FMC2_BCR_MTYP ,FMC2_BCR_MTYP_PSRAM ); +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret;if ((bcr &FMC2_BCR_MTYP ) == val && bcr &FMC2_BCR_BURSTEN )return 0 ;
@@ -249,12 +264,18 @@ static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr, bxtr, val =FIELD_PREP (FMC2_BXTR_ACCMOD ,FMC2_BXTR_EXTMOD_D ); +int ret; + + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr);if (prop->reg_type ==FMC2_REG_BWTR ) -regmap_read (ebi->regmap,FMC2_BWTR (cs), &bxtr); + ret =regmap_read (ebi->regmap,FMC2_BWTR (cs), &bxtr);else -regmap_read (ebi->regmap,FMC2_BTR (cs), &bxtr); + ret =regmap_read (ebi->regmap,FMC2_BTR (cs), &bxtr); +if (ret) +return ret;if ((!(bcr &FMC2_BCR_BURSTEN ) || !(bcr &FMC2_BCR_CBURSTRW )) && ((bxtr &FMC2_BXTR_ACCMOD ) == val || bcr &FMC2_BCR_MUXEN ))
@@ -268,12 +289,19 @@ static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi, int cs) {u32 bcr, bcr1; +int ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); -if (cs) -regmap_read (ebi->regmap,FMC2_BCR1 , &bcr1); -else + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret; + +if (cs) { + ret =regmap_read (ebi->regmap,FMC2_BCR1 , &bcr1); +if (ret) +return ret; + }else { bcr1 = bcr; + }if (bcr &FMC2_BCR_BURSTEN && (!cs || !(bcr1 &FMC2_BCR1_CCLKEN )))return 0 ;
@@ -305,12 +333,18 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi, {u32 nb_clk_cycles =stm32_fmc2_ebi_ns_to_clock_cycles (ebi, cs, setup);u32 bcr, btr, clk_period; +int ret; + + ret =regmap_read (ebi->regmap,FMC2_BCR1 , &bcr); +if (ret) +return ret; -regmap_read (ebi->regmap,FMC2_BCR1 , &bcr);if (bcr &FMC2_BCR1_CCLKEN || !cs) -regmap_read (ebi->regmap,FMC2_BTR1 , &btr); + ret =regmap_read (ebi->regmap,FMC2_BTR1 , &btr);else -regmap_read (ebi->regmap,FMC2_BTR (cs), &btr); + ret =regmap_read (ebi->regmap,FMC2_BTR (cs), &btr); +if (ret) +return ret; clk_period =FIELD_GET (FMC2_BTR_CLKDIV , btr) +1 ;
@@ -569,11 +603,16 @@ static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi,if (ret)return ret; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret; +if (prop->reg_type ==FMC2_REG_BWTR ) -regmap_read (ebi->regmap,FMC2_BWTR (cs), &bxtr); + ret =regmap_read (ebi->regmap,FMC2_BWTR (cs), &bxtr);else -regmap_read (ebi->regmap,FMC2_BTR (cs), &bxtr); + ret =regmap_read (ebi->regmap,FMC2_BTR (cs), &bxtr); +if (ret) +return ret;if ((bxtr &FMC2_BXTR_ACCMOD ) == val || bcr &FMC2_BCR_MUXEN ) val =clamp_val (setup,1 ,FMC2_BXTR_ADDSET_MAX );
@@ -691,11 +730,14 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi, int cs, u32 setup) {u32 old_val, new_val, pcscntr; +int ret;if (setup <1 )return 0 ; -regmap_read (ebi->regmap,FMC2_PCSCNTR , &pcscntr); + ret =regmap_read (ebi->regmap,FMC2_PCSCNTR , &pcscntr); +if (ret) +return ret;/* Enable counter for the bank */ regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,
@@ -942,17 +984,20 @@ static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)regmap_update_bits (ebi->regmap,FMC2_BCR (cs),FMC2_BCR_MBKEN ,0 ); } -static void stm32_fmc2_ebi_save_setup (struct stm32_fmc2_ebi *ebi) +static int stm32_fmc2_ebi_save_setup (struct stm32_fmc2_ebi *ebi) {unsigned int cs; +int ret;for (cs =0 ; cs <FMC2_MAX_EBI_CE ; cs++) { -regmap_read (ebi->regmap,FMC2_BCR (cs), &ebi->bcr[cs]); -regmap_read (ebi->regmap,FMC2_BTR (cs), &ebi->btr[cs]); -regmap_read (ebi->regmap,FMC2_BWTR (cs), &ebi->bwtr[cs]); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &ebi->bcr[cs]); + ret |=regmap_read (ebi->regmap,FMC2_BTR (cs), &ebi->btr[cs]); + ret |=regmap_read (ebi->regmap,FMC2_BWTR (cs), &ebi->bwtr[cs]); +if (ret) +return ret; } -regmap_read (ebi->regmap,FMC2_PCSCNTR , &ebi->pcscntr); +return regmap_read (ebi->regmap,FMC2_PCSCNTR , &ebi->pcscntr); }static void stm32_fmc2_ebi_set_setup (struct stm32_fmc2_ebi *ebi)
@@ -981,22 +1026,29 @@ static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) }/* NWAIT signal can not be connected to EBI controller and NAND controller */ -static bool stm32_fmc2_ebi_nwait_used_by_ctrls (struct stm32_fmc2_ebi *ebi) +static int stm32_fmc2_ebi_nwait_used_by_ctrls (struct stm32_fmc2_ebi *ebi) { +struct device *dev = ebi->dev;unsigned int cs;u32 bcr; +int ret;for (cs =0 ; cs <FMC2_MAX_EBI_CE ; cs++) {if (!(ebi->bank_assigned &BIT (cs)))continue ; -regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); + ret =regmap_read (ebi->regmap,FMC2_BCR (cs), &bcr); +if (ret) +return ret; +if ((bcr &FMC2_BCR_WAITEN || bcr &FMC2_BCR_ASYNCWAIT ) && - ebi->bank_assigned &BIT (FMC2_NAND )) -return true; + ebi->bank_assigned &BIT (FMC2_NAND )) { +dev_err (dev,"NWAIT signal connected to EBI and NAND controllers\n" ); +return -EINVAL ; + } } -return false; +return 0 ; }static void stm32_fmc2_ebi_enable (struct stm32_fmc2_ebi *ebi)
@@ -1083,10 +1135,9 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)return -ENODEV ; } -if (stm32_fmc2_ebi_nwait_used_by_ctrls (ebi)) { -dev_err (dev,"NWAIT signal connected to EBI and NAND controllers\n" ); -return -EINVAL ; - } + ret =stm32_fmc2_ebi_nwait_used_by_ctrls (ebi); +if (ret) +return ret;stm32_fmc2_ebi_enable (ebi);
@@ -1131,7 +1182,10 @@ static int stm32_fmc2_ebi_probe(struct platform_device *pdev)if (ret) goto err_release; -stm32_fmc2_ebi_save_setup (ebi); + ret =stm32_fmc2_ebi_save_setup (ebi); +if (ret) + goto err_release; +platform_set_drvdata (pdev, ebi);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 84/215 parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
[ Upstream commit 73cb4a2d8d7e0259f94046116727084f21e4599f ]
Use irq*_rcu() functions to fix this kernel warning:
WARNING: CPU: 0 PID: 0 at kernel/context_tracking.c:367 ct_irq_enter+0xa0/0xd0 Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.7.0-rc3-64bit+ #1037 Hardware name: 9000/785/C3700
IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000412cd758 00000000412cd75c
IIR: 03ffe01f ISR: 0000000000000000 IOR: 0000000043c20c20
CPU: 0 CR30: 0000000041caa000 CR31: 0000000000000000
ORIG_R28: 0000000000000005
IAOQ[0]: ct_irq_enter+0xa0/0xd0
IAOQ[1]: ct_irq_enter+0xa4/0xd0
RP(r2): irq_enter+0x34/0x68
Backtrace: [<000000004034a3ec>] irq_enter+0x34/0x68 [<000000004030dc48>] do_cpu_irq_mask+0xc0/0x450 [<0000000040303070>] intr_return+0x0/0xc
--- arch/parisc/kernel/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/irq.c +2 -2
@@ -518,7 +518,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) old_regs =set_irq_regs (regs);local_irq_disable (); -irq_enter (); +irq_enter_rcu (); eirr_val =mfctl (23 ) & cpu_eiem &per_cpu (local_ack_eiem, cpu);if (!eirr_val)
@@ -553,7 +553,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)#endif /* CONFIG_IRQSTACKS */ out: -irq_exit (); +irq_exit_rcu ();set_irq_regs (old_regs);return ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 85/215 powerpc/boot: Handle allocation failure in simple_realloc()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li zeming <[email protected]>
[ Upstream commit 69b0194ccec033c208b071e019032c1919c2822d ]
simple_malloc() will return NULL when there is not enough memory left. Check pointer 'new' before using it to copy the old data.
--- arch/powerpc/boot/simple_alloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/boot/simple_alloc.c +3 -1
@@ -114,7 +114,9 @@ static void *simple_realloc(void *ptr, unsigned long size)return ptr; new =simple_malloc (size); -memcpy (new, ptr, p->size); +if (new) +memcpy (new, ptr, p->size); +simple_free (ptr);return new; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 86/215 powerpc/boot: Only free if realloc() succeeds
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit f2d5bccaca3e8c09c9b9c8485375f7bdbb2631d2 ]
simple_realloc() frees the original buffer (ptr) even if the reallocation failed.
Fix it to behave like standard realloc() and only free the original buffer if the reallocation succeeded.
--- arch/powerpc/boot/simple_alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/powerpc/boot/simple_alloc.c +3 -2
@@ -114,10 +114,11 @@ static void *simple_realloc(void *ptr, unsigned long size)return ptr; new =simple_malloc (size); -if (new) +if (new) {memcpy (new, ptr, p->size); +simple_free (ptr); + } -simple_free (ptr);return new; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 87/215 btrfs: change BUG_ON to assertion when checking for delayed_node root
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit be73f4448b607e6b7ce41cd8ef2214fdf6e7986f ]
The pointer to root is initialized in btrfs_init_delayed_node(), no need to check for it again. Change the BUG_ON to assertion.
--- fs/btrfs/delayed-inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/delayed-inode.c +1 -1
@@ -901,7 +901,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)if (delayed_node &&test_bit (BTRFS_DELAYED_NODE_INODE_DIRTY , &delayed_node->flags)) { -BUG_ON (!delayed_node->root); +ASSERT (delayed_node->root);clear_bit (BTRFS_DELAYED_NODE_INODE_DIRTY , &delayed_node->flags); delayed_node->count--;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 88/215 btrfs: handle invalid root reference found in may_destroy_subvol()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit 6fbc6f4ac1f4907da4fc674251527e7dc79ffbf6 ]
The may_destroy_subvol() looks up a root by a key, allowing to do an inexact search when key->offset is -1. It's never expected to find such item, as it would break the allowed range of a root id.
--- fs/btrfs/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +8 -1
@@ -4411,7 +4411,14 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) ret =btrfs_search_slot (NULL , fs_info->tree_root, &key, path,0 ,0 );if (ret <0 ) goto out; -BUG_ON (ret ==0 ); +if (ret ==0 ) { +/* +* Key with offset -1 found, there would have to exist a root +* with such id, but this is out of valid range. +*/ + ret = -EUCLEAN ; + goto out; + } ret =0 ;if (path->slots[0 ] >0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 89/215 btrfs: send: handle unexpected data in header buffer in begin_cmd()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit e80e3f732cf53c64b0d811e1581470d67f6c3228 ]
Change BUG_ON to a proper error handling in the unlikely case of seeing data when the command is started. This is supposed to be reset when the command is finished (send_cmd, send_encoded_extent).
--- fs/btrfs/send.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/btrfs/send.c +6 -1
@@ -695,7 +695,12 @@ static int begin_cmd(struct send_ctx *sctx, int cmd)if (WARN_ON (!sctx->send_buf))return -EINVAL ; -BUG_ON (sctx->send_size); +if (unlikely (sctx->send_size !=0 )) { +btrfs_err (sctx->send_root->fs_info, +"send: command header buffer not empty cmd %d offset %llu" , + cmd, sctx->send_off); +return -EINVAL ; + } sctx->send_size +=sizeof (*hdr); hdr = (struct btrfs_cmd_header *)sctx->send_buf;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 90/215 btrfs: change BUG_ON to assertion in tree_move_down()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit 56f335e043ae73c32dbb70ba95488845dc0f1e6e ]
There's only one caller of tree_move_down() that does not pass level 0 so the assertion is better suited here.
--- fs/btrfs/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/send.c +1 -1
@@ -6882,8 +6882,8 @@ static int tree_move_down(struct btrfs_path *path, int *level, u64 reada_min_genu64 reada_done =0 ;lockdep_assert_held_read (&parent->fs_info->commit_root_sem); +ASSERT (*level !=0 ); -BUG_ON (*level ==0 ); eb =btrfs_read_node_slot (parent, slot);if (IS_ERR (eb))return PTR_ERR (eb);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 91/215 btrfs: delete pointless BUG_ON check on quota root in btrfs_qgroup_account_extent()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit f40a3ea94881f668084f68f6b9931486b1606db0 ]
The BUG_ON is deep in the qgroup code where we can expect that it exists. A NULL pointer would cause a crash.
It was added long ago in 550d7a2ed5db35 ("btrfs: qgroup: Add new qgroup calculation function btrfs_qgroup_account_extents()."). It maybe made sense back then as the quota enable/disable state machine was not that robust as it is nowadays, so we can just delete it.
--- fs/btrfs/qgroup.c | 2 -- 1 file changed, 2 deletions(-)
fs/btrfs/qgroup.c +0 -2
@@ -2648,8 +2648,6 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr,if (nr_old_roots ==0 && nr_new_roots ==0 ) goto out_free; -BUG_ON (!fs_info->quota_root); -trace_btrfs_qgroup_account_extent (fs_info, trans->transid, bytenr, num_bytes, nr_old_roots, nr_new_roots);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 92/215 f2fs: fix to do sanity check in update_sit_entry
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiguo Niu <[email protected]>
[ Upstream commit 36959d18c3cf09b3c12157c6950e18652067de77 ]
If GET_SEGNO return NULL_SEGNO for some unecpected case, update_sit_entry will access invalid memory address, cause system crash. It is better to do sanity check about GET_SEGNO just like update_segment_mtime & locate_dirty_segment.
Also remove some redundant judgment code.
--- fs/f2fs/segment.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/f2fs/segment.c +3 -2
@@ -2269,6 +2269,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)#endif segno =GET_SEGNO (sbi, blkaddr); +if (segno ==NULL_SEGNO ) +return ; se =get_seg_entry (sbi, segno); new_vblocks = se->valid_blocks + del;
@@ -3443,8 +3445,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,* since SSR needs latest valid block information. */ update_sit_entry (sbi, *new_blkaddr,1 ); -if (GET_SEGNO (sbi, old_blkaddr) !=NULL_SEGNO ) -update_sit_entry (sbi, old_blkaddr,-1 ); +update_sit_entry (sbi, old_blkaddr,-1 );if (!__has_curseg_space (sbi, curseg)) {if (from_gc)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 93/215 usb: gadget: fsl: Increase size of name buffer for endpoints
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 87850f6cc20911e35eafcbc1d56b0d649ae9162d ]
This fixes a W=1 warning about sprintf writing up to 16 bytes into a buffer of size 14. There is no practical relevance because there are not more than 32 endpoints.
--- drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/fsl_udc_core.c +1 -1
@@ -2485,7 +2485,7 @@ static int fsl_udc_probe(struct platform_device *pdev)/* setup the udc->eps[] for non-control endpoints and link * to gadget.ep_list */ for (i =1 ; i < (int )(udc_controller->max_ep /2 ); i++) { -char name[14 ]; +char name[16 ];sprintf (name,"ep%dout" , i);struct_ep_setup (udc_controller, i *2 , name,1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 94/215 Bluetooth: bnep: Fix out-of-bound access
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 0f0639b4d6f649338ce29c62da3ec0787fa08cd1 ]
This fixes attempting to access past ethhdr.h_source, although it seems intentional to copy also the contents of h_proto this triggers out-of-bound access problems with the likes of static analyzer, so this instead just copy ETH_ALEN and then proceed to use put_unaligned to copy h_proto separetely.
--- net/bluetooth/bnep/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/bnep/core.c +2 -1
@@ -385,7 +385,8 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)case BNEP_COMPRESSED_DST_ONLY :__skb_put_data (nskb,skb_mac_header (skb),ETH_ALEN ); -__skb_put_data (nskb, s->eh.h_source,ETH_ALEN +2 ); +__skb_put_data (nskb, s->eh.h_source,ETH_ALEN ); +put_unaligned (s->eh.h_proto, (__be16 *)__skb_put (nskb,2 ));break ;case BNEP_GENERAL :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 95/215 net: hns3: add checking for vf id of mailbox
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Shen <[email protected]>
[ Upstream commit 4e2969a0d6a7549bc0bc1ebc990588b622c4443d ]
Add checking for vf id of mailbox, in order to avoid array out-of-bounds risk.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +4 -3
@@ -1066,10 +1066,11 @@ void hclge_mbx_handler(struct hclge_dev *hdev) req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data; flag =le16_to_cpu (crq->desc[crq->next_to_use].flag); -if (unlikely (!hnae3_get_bit (flag,HCLGE_CMDQ_RX_OUTVLD_B ))) { +if (unlikely (!hnae3_get_bit (flag,HCLGE_CMDQ_RX_OUTVLD_B ) || + req->mbx_src_vfid > hdev->num_req_vfs)) {dev_warn (&hdev->pdev->dev, -"dropped invalid mailbox message, code = %u\n" , - req->msg.code); +"dropped invalid mailbox message, code = %u, vfid = %u\n" , + req->msg.code, req->mbx_src_vfid);/* dropping/not processing this invalid message */ crq->desc[crq->next_to_use].flag =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 96/215 nvmet-tcp: do not continue for invalid icreq
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
[ Upstream commit 0889d13b9e1cbef49e802ae09f3b516911ad82a1 ]
When the length check for an icreq sqe fails we should not continue processing but rather return immediately as all other contents of that sqe cannot be relied on.
--- drivers/nvme/target/tcp.c | 1 + 1 file changed, 1 insertion(+)
drivers/nvme/target/tcp.c +1 -0
@@ -858,6 +858,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)pr_err ("bad nvme-tcp pdu length (%d)\n" ,le32_to_cpu (icreq->hdr.plen));nvmet_tcp_fatal_error (queue); +return -EPROTO ; }if (icreq->pfv !=NVME_TCP_PFV_1_0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 97/215 NFS: avoid infinite loop in pnfs_update_layout.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
[ Upstream commit 2fdbc20036acda9e5694db74a032d3c605323005 ]
If pnfsd_update_layout() is called on a file for which recovery has failed it will enter a tight infinite loop.
NFS_LAYOUT_INVALID_STID will be set, nfs4_select_rw_stateid() will return -EIO, and nfs4_schedule_stateid_recovery() will do nothing, so nfs4_client_recover_expired_lease() will not wait. So the code will loop indefinitely.
Break the loop by testing the validity of the open stateid at the top of the loop.
--- fs/nfs/pnfs.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/nfs/pnfs.c +8 -0
@@ -1994,6 +1994,14 @@ pnfs_update_layout(struct inode *ino, } lookup_again: +if (!nfs4_valid_open_stateid (ctx->state)) { +trace_pnfs_update_layout (ino, pos, count, + iomode, lo, lseg, +PNFS_UPDATE_LAYOUT_INVALID_OPEN ); + lseg =ERR_PTR (-EIO ); + goto out; + } + lseg =ERR_PTR (nfs4_client_recover_expired_lease (clp));if (IS_ERR (lseg)) goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 98/215 openrisc: Call setup_memory() earlier in the init sequence
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oreoluwa Babatunde <[email protected]>
[ Upstream commit 7b432bf376c9c198a7ff48f1ed14a14c0ffbe1fe ]
The unflatten_and_copy_device_tree() function contains a call to memblock_alloc(). This means that memblock is allocating memory before any of the reserved memory regions are set aside in the setup_memory() function which calls early_init_fdt_scan_reserved_mem(). Therefore, there is a possibility for memblock to allocate from any of the reserved memory regions.
Hence, move the call to setup_memory() to be earlier in the init sequence so that the reserved memory regions are set aside before any allocations are done using memblock.
--- arch/openrisc/kernel/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/openrisc/kernel/setup.c +3 -3
@@ -270,6 +270,9 @@ void calibrate_delay(void)void __init setup_arch (char **cmdline_p) { +/* setup memblock allocator */ +setup_memory (); +unflatten_and_copy_device_tree ();setup_cpuinfo ();
@@ -293,9 +296,6 @@ void __init setup_arch(char **cmdline_p) }#endif -/* setup memblock allocator */ -setup_memory (); -/* paging_init() sets up the MMU and marks all pages as reserved */ paging_init ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 99/215 s390/iucv: fix receive buffer virtual vs physical address confusion
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Gordeev <[email protected]>
[ Upstream commit 4e8477aeb46dfe74e829c06ea588dd00ba20c8cc ]
Fix IUCV_IPBUFLST-type buffers virtual vs physical address confusion. This does not fix a bug since virtual and physical address spaces are currently the same.
--- net/iucv/iucv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/iucv/iucv.c +1 -2
@@ -1090,8 +1090,7 @@ static int iucv_message_receive_iprmdata(struct iucv_path *path, size = (size <8 ) ? size :8 ;for (array = buffer; size >0 ; array++) { copy =min_t (size_t, size, array->length); -memcpy ((u8 *)(addr_t ) array->address, - rmmsg, copy); +memcpy (phys_to_virt (array->address), rmmsg, copy); rmmsg += copy; size -= copy; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 100/215 clocksource: Make watchdog and suspend-timing multiplication overflow safe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
[ Upstream commit d0304569fb019d1bcfbbbce1ce6df6b96f04079b ]
Kernel timekeeping is designed to keep the change in cycles (since the last timer interrupt) below max_cycles, which prevents multiplication overflow when converting cycles to nanoseconds. However, if timer interrupts stop, the clocksource_cyc2ns() calculation will eventually overflow.
Add protection against that. Simplify by folding together clocksource_delta() and clocksource_cyc2ns() into cycles_to_nsec_safe(). Check against max_cycles, falling back to a slower higher precision calculation.
--- kernel/time/clocksource.c | 42 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 22 deletions(-)
kernel/time/clocksource.c +20 -22
@@ -20,6 +20,16 @@#include "tick-internal.h" #include "timekeeping_internal.h" +static noinline u64 cycles_to_nsec_safe(struct clocksource *cs, u64 start, u64 end) +{ +u64 delta =clocksource_delta (end, start, cs->mask); + +if (likely (delta < cs->max_cycles)) +return clocksource_cyc2ns (delta, cs->mult, cs->shift); + +return mul_u64_u32_shr (delta, cs->mult, cs->shift); +} +/** * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks * @mult: pointer to mult variable
@@ -213,8 +223,8 @@ enum wd_read_status {static enum wd_read_status cs_watchdog_read (struct clocksource *cs,u64 *csnow,u64 *wdnow) {unsigned int nretries, max_retries; -u64 wd_end, wd_end2, wd_delta;int64_t wd_delay, wd_seq_delay; +u64 wd_end, wd_end2; max_retries =clocksource_get_max_watchdog_retry ();for (nretries =0 ; nretries <= max_retries; nretries++) {
@@ -225,9 +235,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, wd_end2 = watchdog->read (watchdog);local_irq_enable (); - wd_delta =clocksource_delta (wd_end, *wdnow, watchdog->mask); - wd_delay =clocksource_cyc2ns (wd_delta, watchdog->mult, - watchdog->shift); + wd_delay =cycles_to_nsec_safe (watchdog, *wdnow, wd_end);if (wd_delay <=WATCHDOG_MAX_SKEW ) {if (nretries >1 && nretries >= max_retries) { pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",
@@ -245,8 +253,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow,* report system busy, reinit the watchdog and skip the current * watchdog test. */ - wd_delta =clocksource_delta (wd_end2, wd_end, watchdog->mask); - wd_seq_delay =clocksource_cyc2ns (wd_delta, watchdog->mult, watchdog->shift); + wd_seq_delay =cycles_to_nsec_safe (watchdog, wd_end, wd_end2);if (wd_seq_delay >WATCHDOG_MAX_SKEW /2 ) goto skip_test; }
@@ -357,8 +364,7 @@ void clocksource_verify_percpu(struct clocksource *cs) delta = (csnow_end - csnow_mid) & cs->mask;if (delta <0 )cpumask_set_cpu (cpu, &cpus_ahead); - delta =clocksource_delta (csnow_end, csnow_begin, cs->mask); - cs_nsec =clocksource_cyc2ns (delta, cs->mult, cs->shift); + cs_nsec =cycles_to_nsec_safe (cs, csnow_begin, csnow_end);if (cs_nsec > cs_nsec_max) cs_nsec_max = cs_nsec;if (cs_nsec < cs_nsec_min)
@@ -389,8 +395,8 @@ static inline void clocksource_reset_watchdog(void)static void clocksource_watchdog (struct timer_list *unused) { -u64 csnow, wdnow, cslast, wdlast, delta;int64_t wd_nsec, cs_nsec, interval; +u64 csnow, wdnow, cslast, wdlast;int next_cpu, reset_pending;struct clocksource *cs;enum wd_read_status read_ret;
@@ -447,12 +453,8 @@ static void clocksource_watchdog(struct timer_list *unused)continue ; } - delta =clocksource_delta (wdnow, cs->wd_last, watchdog->mask); - wd_nsec =clocksource_cyc2ns (delta, watchdog->mult, - watchdog->shift); - - delta =clocksource_delta (csnow, cs->cs_last, cs->mask); - cs_nsec =clocksource_cyc2ns (delta, cs->mult, cs->shift); + wd_nsec =cycles_to_nsec_safe (watchdog, cs->wd_last, wdnow); + cs_nsec =cycles_to_nsec_safe (cs, cs->cs_last, csnow); wdlast = cs->wd_last;/* save these in case we print them */ cslast = cs->cs_last; cs->cs_last = csnow;
@@ -815,7 +817,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles)*/ u64 clocksource_stop_suspend_timing (struct clocksource *cs,u64 cycle_now) { -u64 now, delta, nsec =0 ; +u64 now, nsec =0 ;if (!suspend_clocksource)return 0 ;
@@ -830,12 +832,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now)else now = suspend_clocksource->read (suspend_clocksource); -if (now > suspend_start) { - delta =clocksource_delta (now, suspend_start, - suspend_clocksource->mask); - nsec =mul_u64_u32_shr (delta, suspend_clocksource->mult, - suspend_clocksource->shift); - } +if (now > suspend_start) + nsec =cycles_to_nsec_safe (suspend_clocksource, suspend_start, now);/* * Disable the suspend timer to save power if current clocksource is
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 101/215 platform/x86: lg-laptop: fix %s null argument warning
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gergo Koteles <[email protected]>
[ Upstream commit e71c8481692582c70cdfd0996c20cdcc71e425d3 ]
W=1 warns about null argument to kprintf:
warning: ‘%s’ directive argument is null [-Wformat-overflow=] pr_info("product: %s year: %d\n", product, year);
Use "unknown" instead of NULL.
--- drivers/platform/x86/lg-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/lg-laptop.c +1 -1
@@ -665,7 +665,7 @@ static int acpi_add(struct acpi_device *device)default : year =2019 ; } -pr_info ("product: %s year: %d\n" , product, year); +pr_info ("product: %s year: %d\n" , product ?:"unknown" , year);if (year >=2019 ) battery_limit_use_wmbb =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 102/215 usb: dwc3: core: Skip setting event buffers for host only controllers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krishna Kurapati <[email protected]>
[ Upstream commit 89d7f962994604a3e3d480832788d06179abefc5 ]
On some SoC's like SA8295P where the tertiary controller is host-only capable, GEVTADDRHI/LO, GEVTSIZ, GEVTCOUNT registers are not accessible. Trying to access them leads to a crash.
For DRD/Peripheral supported controllers, event buffer setup is done again in gadget_pullup. Skip setup or cleanup of event buffers if controller is host-only capable.
--- drivers/usb/dwc3/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/usb/dwc3/core.c +13 -0
@@ -430,6 +430,13 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)static int dwc3_alloc_event_buffers (struct dwc3 *dwc,unsigned length) {struct dwc3_event_buffer *evt; +unsigned int hw_mode; + + hw_mode =DWC3_GHWPARAMS0_MODE (dwc->hwparams.hwparams0); +if (hw_mode ==DWC3_GHWPARAMS0_MODE_HOST ) { + dwc->ev_buf =NULL ; +return 0 ; + } evt =dwc3_alloc_one_event_buffer (dwc, length);if (IS_ERR (evt)) {
@@ -451,6 +458,9 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) {struct dwc3_event_buffer *evt; +if (!dwc->ev_buf) +return 0 ; + evt = dwc->ev_buf; evt->lpos =0 ; dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
@@ -468,6 +478,9 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) {struct dwc3_event_buffer *evt; +if (!dwc->ev_buf) +return ; + evt = dwc->ev_buf; evt->lpos =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 103/215 fbdev: offb: replace of_node_put with __free(device_node)
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdulrasaq Lawani <[email protected]>
[ Upstream commit ce4a7ae84a58b9f33aae8d6c769b3c94f3d5ce76 ]
Replaced instance of of_node_put with __free(device_node) to simplify code and protect against any memory leaks due to future changes in the control flow.
--- drivers/video/fbdev/offb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/video/fbdev/offb.c +1 -2
@@ -354,7 +354,7 @@ static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp par->cmap_type = cmap_gxt2000; }else if (of_node_name_prefix (dp,"vga,Display-" )) {/* Look for AVIVO initialized by SLOF */ -struct device_node *pciparent =of_get_parent (dp); + struct device_node *pciparent __free(device_node) = of_get_parent(dp);const u32 *vid, *did; vid =of_get_property (pciparent,"vendor-id" ,NULL ); did =of_get_property (pciparent,"device-id" ,NULL );
@@ -366,7 +366,6 @@ static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dpif (par->cmap_adr) par->cmap_type = cmap_avivo; } -of_node_put (pciparent); }else if (dp &&of_device_is_compatible (dp,"qemu,std-vga" )) {#ifdef __BIG_ENDIANconst __be32 io_of_addr[3 ] = {0x01000000 ,0x0 ,0x0 };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 104/215 irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanrui Huang <[email protected]>
[ Upstream commit 382d2ffe86efb1e2fa803d2cf17e5bfc34e574f3 ]
This BUG_ON() is useless, because the same effect will be obtained by letting the code run its course and vm being dereferenced, triggering an exception.
So just remove this check.
--- drivers/irqchip/irq-gic-v3-its.c | 2 -- 1 file changed, 2 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +0 -2
@@ -4491,8 +4491,6 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virqstruct page *vprop_page;int base, nr_ids, i, err =0 ; -BUG_ON (!vm); - bitmap =its_lpi_alloc (roundup_pow_of_two (nr_irqs), &base, &nr_ids);if (!bitmap)return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 105/215 ext4: set the type of max_zeroout to unsigned int to avoid overflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
[ Upstream commit 261341a932d9244cbcd372a3659428c8723e5a49 ]
The max_zeroout is of type int and the s_extent_max_zeroout_kb is of type uint, and the s_extent_max_zeroout_kb can be freely modified via the sysfs interface. When the block size is 1024, max_zeroout may overflow, so declare it as unsigned int to avoid overflow.
--- fs/ext4/extents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/extents.c +2 -1
@@ -3404,9 +3404,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,struct ext4_extent *ex, *abut_ex;ext4_lblk_t ee_block, eof_block;unsigned int ee_len, depth, map_len = map->m_len; -int allocated =0 , max_zeroout =0 ;int err =0 ;int split_flag =EXT4_EXT_DATA_VALID2 ; +int allocated =0 ; +unsigned int max_zeroout =0 ;ext_debug (inode,"logical block %llu, max_blocks %u\n" , (unsigned long long )map->m_lblk, map_len);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 106/215 nvmet-rdma: fix possible bad dereference when freeing rsps
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sagi Grimberg <[email protected]>
[ Upstream commit 73964c1d07c054376f1b32a62548571795159148 ]
It is possible that the host connected and saw a cm established event and started sending nvme capsules on the qp, however the ctrl did not yet see an established event. This is why the rsp_wait_list exists (for async handling of these cmds, we move them to a pending list).
Furthermore, it is possible that the ctrl cm times out, resulting in a connect-error cm event. in this case we hit a bad deref [1] because in nvmet_rdma_free_rsps we assume that all the responses are in the free list.
We are freeing the cmds array anyways, so don't even bother to remove the rsp from the free_list. It is also guaranteed that we are not racing anything when we are releasing the queue so no other context accessing this array should be running.
[1]:
--
Workqueue: nvmet-free-wq nvmet_rdma_free_queue_work [nvmet_rdma] [...] pc : nvmet_rdma_free_rsps+0x78/0xb8 [nvmet_rdma] lr : nvmet_rdma_free_queue_work+0x88/0x120 [nvmet_rdma] Call trace: nvmet_rdma_free_rsps+0x78/0xb8 [nvmet_rdma] nvmet_rdma_free_queue_work+0x88/0x120 [nvmet_rdma] process_one_work+0x1ec/0x4a0 worker_thread+0x48/0x490 kthread+0x158/0x160 ret_from_fork+0x10/0x18
--
--- drivers/nvme/target/rdma.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
drivers/nvme/target/rdma.c +4 -12
@@ -472,12 +472,8 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue)return 0 ; out_free: -while (--i >=0 ) { -struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; - -list_del (&rsp->free_list); -nvmet_rdma_free_rsp (ndev, rsp); - } +while (--i >=0 ) +nvmet_rdma_free_rsp (ndev, &queue->rsps[i]);kfree (queue->rsps); out:return ret;
@@ -488,12 +484,8 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue)struct nvmet_rdma_device *ndev = queue->dev;int i, nr_rsps = queue->recv_queue_size *2 ; -for (i =0 ; i < nr_rsps; i++) { -struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; - -list_del (&rsp->free_list); -nvmet_rdma_free_rsp (ndev, rsp); - } +for (i =0 ; i < nr_rsps; i++) +nvmet_rdma_free_rsp (ndev, &queue->rsps[i]);kfree (queue->rsps); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 107/215 hrtimer: Prevent queuing of hrtimer without a function callback
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Chang <[email protected]>
[ Upstream commit 5a830bbce3af16833fe0092dec47b6dd30279825 ]
The hrtimer function callback must not be NULL. It has to be specified by the call side but it is not validated by the hrtimer code. When a hrtimer is queued without a function callback, the kernel crashes with a null pointer dereference when trying to execute the callback in __run_hrtimer().
Introduce a validation before queuing the hrtimer in hrtimer_start_range_ns().
[anna-maria: Rephrase commit message]
--- kernel/time/hrtimer.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/time/hrtimer.c +2 -0
@@ -1284,6 +1284,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,struct hrtimer_clock_base *base;unsigned long flags; +if (WARN_ON_ONCE (!timer->function)) +return ;/* * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 108/215 gtp: pull network headers in gtp_dev_xmit()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 3a3be7ff9224f424e485287b54be00d2c6bd9c40 upstream.
syzbot/KMSAN reported use of uninit-value in get_dev_xmit() [1]
We must make sure the IPv4 or Ipv6 header is pulled in skb->head before accessing fields in them.
Use pskb_inet_may_pull() to fix this issue.
[1]
BUG: KMSAN: uninit-value in ipv6_pdp_find drivers/net/gtp.c:220 [inline] BUG: KMSAN: uninit-value in gtp_build_skb_ip6 drivers/net/gtp.c:1229 [inline] BUG: KMSAN: uninit-value in gtp_dev_xmit+0x1424/0x2540 drivers/net/gtp.c:1281 ipv6_pdp_find drivers/net/gtp.c:220 [inline] gtp_build_skb_ip6 drivers/net/gtp.c:1229 [inline] gtp_dev_xmit+0x1424/0x2540 drivers/net/gtp.c:1281 __netdev_start_xmit include/linux/netdevice.h:4913 [inline] netdev_start_xmit include/linux/netdevice.h:4922 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3596 __dev_queue_xmit+0x358c/0x5610 net/core/dev.c:4423 dev_queue_xmit include/linux/netdevice.h:3105 [inline] packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276 packet_snd net/packet/af_packet.c:3145 [inline] packet_sendmsg+0x90e3/0xa3a0 net/packet/af_packet.c:3177 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:745 __sys_sendto+0x685/0x830 net/socket.c:2204 __do_sys_sendto net/socket.c:2216 [inline] __se_sys_sendto net/socket.c:2212 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2212 x64_sys_call+0x3799/0x3c10 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
slab_post_alloc_hook mm/slub.c:3994 [inline] slab_alloc_node mm/slub.c:4037 [inline] kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4080 kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:583 __alloc_skb+0x363/0x7b0 net/core/skbuff.c:674 alloc_skb include/linux/skbuff.h:1320 [inline] alloc_skb_with_frags+0xc8/0xbf0 net/core/skbuff.c:6526 sock_alloc_send_pskb+0xa81/0xbf0 net/core/sock.c:2815 packet_alloc_skb net/packet/af_packet.c:2994 [inline] packet_snd net/packet/af_packet.c:3088 [inline] packet_sendmsg+0x749c/0xa3a0 net/packet/af_packet.c:3177 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:745 __sys_sendto+0x685/0x830 net/socket.c:2204 __do_sys_sendto net/socket.c:2216 [inline] __se_sys_sendto net/socket.c:2212 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2212 x64_sys_call+0x3799/0x3c10 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f CPU: 0 UID: 0 PID: 7115 Comm: syz.1.515 Not tainted 6.11.0-rc1-syzkaller-00043-g94ede2a3e913 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024
--- drivers/net/gtp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/gtp.c +3 -0
@@ -572,6 +572,9 @@ static netdev_tx_t gtp_dev_xmit(struct sif (skb_cow_head (skb, dev->needed_headroom)) goto tx_err; +if (!pskb_inet_may_pull (skb)) + goto tx_err; +skb_reset_inner_headers (skb);/* PDP context lookups in gtp_build_skb_*() need rcu read-side lock. */
Greg Kroah-Hartman
maintainerPATCH 109/215 block: use "unsigned long" for blk_validate_block_size().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit 37ae5a0f5287a52cf51242e76ccf198d02ffe495 upstream.
Since lo_simple_ioctl(LOOP_SET_BLOCK_SIZE) and ioctl(NBD_SET_BLKSIZE) pass user-controlled "unsigned long arg" to blk_validate_block_size(), "unsigned long" should be used for validation.
--- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/blkdev.h +1 -1
@@ -235,7 +235,7 @@ struct request {void *end_io_data; }; -static inline int blk_validate_block_size (unsigned int bsize) +static inline int blk_validate_block_size (unsigned long bsize) {if (bsize <512 || bsize >PAGE_SIZE || !is_power_of_2 (bsize))return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 110/215 nfsd: move reply cache initialization into nfsd startup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit f5f9d4a314da88c0a5faa6d168bf69081b7a25ae ]
There's no need to start the reply cache before nfsd is up and running, and doing so means that we register a shrinker for every net namespace instead of just the ones where nfsd is running.
Move it to the per-net nfsd startup instead.
Stable-dep-of: ed9ab7346e90 ("nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net")
--- fs/nfsd/nfsctl.c | 8 -------- fs/nfsd/nfssvc.c | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-)
fs/nfsd/nfsctl.c +0 -8
@@ -1461,16 +1461,11 @@ static __net_init int nfsd_init_net(stru nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn); - retval =nfsd_reply_cache_init (nn); -if (retval) - goto out_cache_error;get_random_bytes (&nn->siphash_key,sizeof (nn->siphash_key));seqlock_init (&nn->writeverf_lock);return 0 ; -out_cache_error: -nfsd_idmap_shutdown (net); out_idmap_error:nfsd_export_shutdown (net); out_export_error:
@@ -1479,9 +1474,6 @@ out_export_error: static __net_exit void nfsd_exit_net(struct net *net) { -struct nfsd_net *nn =net_generic (net, nfsd_net_id); - -nfsd_reply_cache_shutdown (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);nfsd_netns_free_versions (net_generic (net, nfsd_net_id));
fs/nfsd/nfssvc.c +9 -1
@@ -427,16 +427,23 @@ static int nfsd_startup_net(struct net * ret =nfsd_file_cache_start_net (net);if (ret) goto out_lockd; - ret =nfs4_state_start_net (net); + + ret =nfsd_reply_cache_init (nn);if (ret) goto out_filecache; + ret =nfs4_state_start_net (net); +if (ret) + goto out_reply_cache; +#ifdef CONFIG_NFSD_V4_2_INTER_SSC nfsd4_ssc_init_umount_work (nn);#endif nn->nfsd_net_up = true;return 0 ; +out_reply_cache: +nfsd_reply_cache_shutdown (nn); out_filecache:nfsd_file_cache_shutdown_net (net); out_lockd:
@@ -454,6 +461,7 @@ static void nfsd_shutdown_net(struct netstruct nfsd_net *nn =net_generic (net, nfsd_net_id);nfs4_state_shutdown_net (net); +nfsd_reply_cache_shutdown (nn);nfsd_file_cache_shutdown_net (net);if (nn->lockd_up) {lockd_down (net);
Greg Kroah-Hartman
maintainerPATCH 111/215 nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit ed9ab7346e908496816cffdecd46932035f66e2e ]
Commit f5f9d4a314da ("nfsd: move reply cache initialization into nfsd startup") moved the initialization of the reply cache into nfsd startup, but didn't account for the stats counters, which can be accessed before nfsd is ever started. The result can be a NULL pointer dereference when someone accesses /proc/fs/nfsd/reply_cache_stats while nfsd is still shut down.
This is a regression and a user-triggerable oops in the right situation:
- non-x86_64 arch
- /proc/fs/nfsd is mounted in the namespace
- nfsd is not started in the namespace
- unprivileged user calls "cat /proc/fs/nfsd/reply_cache_stats"
Although this is easy to trigger on some arches (like aarch64), on x86_64, calling this_cpu_ptr(NULL) evidently returns a pointer to the fixed_percpu_data. That struct looks just enough like a newly initialized percpu var to allow nfsd_reply_cache_stats_show to access it without Oopsing.
Move the initialization of the per-net+per-cpu reply-cache counters back into nfsd_init_net, while leaving the rest of the reply cache allocations to be done at nfsd startup time.
Kudos to Eirik who did most of the legwork to track this down.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/cache.h | 2 ++ fs/nfsd/nfscache.c | 25 ++++++++++++++----------- fs/nfsd/nfsctl.c | 10 +++++++++- 3 files changed, 25 insertions(+), 12 deletions(-)
fs/nfsd/cache.h +2 -0
@@ -80,6 +80,8 @@ enum {int nfsd_drc_slab_create (void );void nfsd_drc_slab_free (void ); +int nfsd_net_reply_cache_init (struct nfsd_net *nn); +void nfsd_net_reply_cache_destroy (struct nfsd_net *nn);int nfsd_reply_cache_init (struct nfsd_net *);void nfsd_reply_cache_shutdown (struct nfsd_net *);int nfsd_cache_lookup (struct svc_rqst *);
fs/nfsd/nfscache.c +14 -11
@@ -148,12 +148,23 @@ void nfsd_drc_slab_free(void)kmem_cache_destroy (drc_slab); } -static int nfsd_reply_cache_stats_init (struct nfsd_net *nn) +/** +* nfsd_net_reply_cache_init - per net namespace reply cache set-up +* @nn: nfsd_net being initialized +* +* Returns zero on succes; otherwise a negative errno is returned. +*/ +int nfsd_net_reply_cache_init (struct nfsd_net *nn) {return nfsd_percpu_counters_init (nn->counter,NFSD_NET_COUNTERS_NUM ); } -static void nfsd_reply_cache_stats_destroy (struct nfsd_net *nn) +/** +* nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down +* @nn: nfsd_net being freed +* +*/ +void nfsd_net_reply_cache_destroy (struct nfsd_net *nn) {nfsd_percpu_counters_destroy (nn->counter,NFSD_NET_COUNTERS_NUM ); }
@@ -169,16 +180,12 @@ int nfsd_reply_cache_init(struct nfsd_ne hashsize =nfsd_hashsize (nn->max_drc_entries); nn->maskbits =ilog2 (hashsize); - status =nfsd_reply_cache_stats_init (nn); -if (status) - goto out_nomem; - nn->nfsd_reply_cache_shrinker.scan_objects = nfsd_reply_cache_scan; nn->nfsd_reply_cache_shrinker.count_objects = nfsd_reply_cache_count; nn->nfsd_reply_cache_shrinker.seeks =1 ; status =register_shrinker (&nn->nfsd_reply_cache_shrinker);if (status) - goto out_stats_destroy; +return status; nn->drc_hashtbl =kvzalloc (array_size (hashsize,sizeof (*nn->drc_hashtbl)),GFP_KERNEL );
@@ -194,9 +201,6 @@ int nfsd_reply_cache_init(struct nfsd_nereturn 0 ; out_shrinker:unregister_shrinker (&nn->nfsd_reply_cache_shrinker); -out_stats_destroy: -nfsd_reply_cache_stats_destroy (nn); -out_nomem:printk (KERN_ERR "nfsd: failed to allocate reply cache\n" );return -ENOMEM ; }
@@ -216,7 +220,6 @@ void nfsd_reply_cache_shutdown(struct nf rp, nn); } } -nfsd_reply_cache_stats_destroy (nn);kvfree (nn->drc_hashtbl); nn->drc_hashtbl =NULL ;
fs/nfsd/nfsctl.c +9 -1
@@ -1458,6 +1458,9 @@ static __net_init int nfsd_init_net(stru retval =nfsd_idmap_init (net);if (retval) goto out_idmap_error; + retval =nfsd_net_reply_cache_init (nn); +if (retval) + goto out_repcache_error; nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn);
@@ -1466,6 +1469,8 @@ static __net_init int nfsd_init_net(strureturn 0 ; +out_repcache_error: +nfsd_idmap_shutdown (net); out_idmap_error:nfsd_export_shutdown (net); out_export_error:
@@ -1474,9 +1479,12 @@ out_export_error: static __net_exit void nfsd_exit_net(struct net *net) { +struct nfsd_net *nn =net_generic (net, nfsd_net_id); + +nfsd_net_reply_cache_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net); -nfsd_netns_free_versions (net_generic (net, nfsd_net_id)); +nfsd_netns_free_versions (nn); }static struct pernet_operations nfsd_net_ops = {
Greg Kroah-Hartman
maintainerPATCH 112/215 NFSD: Refactor nfsd_reply_cache_free_locked()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 35308e7f0fc3942edc87d9c6dc78c4a096428957 ]
To reduce contention on the bucket locks, we must avoid calling kfree() while each bucket lock is held.
Start by refactoring nfsd_reply_cache_free_locked() into a helper that removes an entry from the bucket (and must therefore run under the lock) and a second helper that frees the entry (which does not need to hold the lock).
For readability, rename the helpers nfsd_cacherep_<verb>.
Stable-dep-of: a9507f6af145 ("NFSD: Replace nfsd_prune_bucket()")
--- fs/nfsd/nfscache.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
fs/nfsd/nfscache.c +20 -7
@@ -110,21 +110,33 @@ nfsd_reply_cache_alloc(struct svc_rqst *return rp; } +static void nfsd_cacherep_free (struct svc_cacherep *rp) +{ +if (rp->c_type ==RC_REPLBUFF ) +kfree (rp->c_replvec.iov_base); +kmem_cache_free (drc_slab, rp); +} +static void -nfsd_reply_cache_free_locked (struct nfsd_drc_bucket *b,struct svc_cacherep *rp, -struct nfsd_net *nn) +nfsd_cacherep_unlink_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b, +struct svc_cacherep *rp) { -if (rp->c_type ==RC_REPLBUFF && rp->c_replvec.iov_base) { +if (rp->c_type ==RC_REPLBUFF && rp->c_replvec.iov_base)nfsd_stats_drc_mem_usage_sub (nn, rp->c_replvec.iov_len); -kfree (rp->c_replvec.iov_base); - }if (rp->c_state !=RC_UNUSED ) {rb_erase (&rp->c_node, &b->rb_head);list_del (&rp->c_lru);atomic_dec (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_sub (nn,sizeof (*rp)); } -kmem_cache_free (drc_slab, rp); +} + +static void +nfsd_reply_cache_free_locked (struct nfsd_drc_bucket *b,struct svc_cacherep *rp, +struct nfsd_net *nn) +{ +nfsd_cacherep_unlink_locked (nn, b, rp); +nfsd_cacherep_free (rp); } static void
@@ -132,8 +144,9 @@ nfsd_reply_cache_free(struct nfsd_drc_bu struct nfsd_net *nn) {spin_lock (&b->cache_lock); -nfsd_reply_cache_free_locked (b, rp, nn); +nfsd_cacherep_unlink_locked (nn, b, rp);spin_unlock (&b->cache_lock); +nfsd_cacherep_free (rp); }int nfsd_drc_slab_create (void )
Greg Kroah-Hartman
maintainerPATCH 113/215 NFSD: Rename nfsd_reply_cache_alloc()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit ff0d169329768c1102b7b07eebe5a9839aa1c143 ]
For readability, rename to match the other helpers.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/nfscache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/nfsd/nfscache.c +3 -3
@@ -85,8 +85,8 @@ nfsd_hashsize(unsigned int limit) }static struct svc_cacherep * -nfsd_reply_cache_alloc (struct svc_rqst *rqstp,__wsum csum, -struct nfsd_net *nn) +nfsd_cacherep_alloc (struct svc_rqst *rqstp,__wsum csum, +struct nfsd_net *nn) {struct svc_cacherep *rp;
@@ -457,7 +457,7 @@ int nfsd_cache_lookup(struct svc_rqst *r* preallocate an entry. */ nn =net_generic (SVC_NET (rqstp), nfsd_net_id); - rp =nfsd_reply_cache_alloc (rqstp, csum, nn); + rp =nfsd_cacherep_alloc (rqstp, csum, nn);if (!rp) goto out;
Greg Kroah-Hartman
maintainerPATCH 114/215 NFSD: Replace nfsd_prune_bucket()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a9507f6af1450ed26a4a36d979af518f5bb21e5d ]
Enable nfsd_prune_bucket() to drop the bucket lock while calling kfree(). Use the same pattern that Jeff recently introduced in the NFSD filecache.
A few percpu operations are moved outside the lock since they temporarily disable local IRQs which is expensive and does not need to be done while the lock is held.
Stable-dep-of: c135e1269f34 ("NFSD: Refactor the duplicate reply cache shrinker")
--- fs/nfsd/nfscache.c | 78 ++++++++++++++++++++++++++++++++++++++++++----------- fs/nfsd/trace.h | 22 ++++++++++++++ 2 files changed, 85 insertions(+), 15 deletions(-)
fs/nfsd/nfscache.c +63 -15
@@ -117,6 +117,21 @@ static void nfsd_cacherep_free(struct svkmem_cache_free (drc_slab, rp); } +static unsigned long +nfsd_cacherep_dispose (struct list_head *dispose) +{ +struct svc_cacherep *rp; +unsigned long freed =0 ; + +while (!list_empty (dispose)) { + rp = list_first_entry(dispose, struct svc_cacherep, c_lru); +list_del (&rp->c_lru); +nfsd_cacherep_free (rp); + freed++; + } +return freed; +} +static void nfsd_cacherep_unlink_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b,struct svc_cacherep *rp)
@@ -259,6 +274,41 @@ nfsd_cache_bucket_find(__be32 xid, strucreturn &nn->drc_hashtbl[hash]; } +/* +* Remove and return no more than @max expired entries in bucket @b. +* If @max is zero, do not limit the number of removed entries. +*/ +static void +nfsd_prune_bucket_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b, +unsigned int max,struct list_head *dispose) +{ +unsigned long expiry = jiffies -RC_EXPIRE ; +struct svc_cacherep *rp, *tmp; +unsigned int freed =0 ; + +lockdep_assert_held (&b->cache_lock); + +/* The bucket LRU is ordered oldest-first. */ +list_for_each_entry_safe (rp, tmp, &b->lru_head, c_lru) { +/* +* Don't free entries attached to calls that are still +* in-progress, but do keep scanning the list. +*/ +if (rp->c_state ==RC_INPROG ) +continue ; + +if (atomic_read (&nn->num_drc_entries) <= nn->max_drc_entries && +time_before (expiry, rp->c_timestamp)) +break ; + +nfsd_cacherep_unlink_locked (nn, b, rp); +list_add (&rp->c_lru, dispose); + +if (max && ++freed > max) +break ; + } +} +static long prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn,unsigned int max) {
@@ -282,11 +332,6 @@ static long prune_bucket(struct nfsd_drcreturn freed; } -static long nfsd_prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn) -{ -return prune_bucket (b, nn,3 ); -} -/* * Walk the LRU list and prune off entries that are older than RC_EXPIRE. * Also prune the oldest ones when the total exceeds the max number of entries.
@@ -442,6 +487,8 @@ int nfsd_cache_lookup(struct svc_rqst *r__wsum csum;struct nfsd_drc_bucket *b;int type = rqstp->rq_cachetype; +unsigned long freed; +LIST_HEAD (dispose);int rtn =RC_DOIT ; rqstp->rq_cacherep =NULL ;
@@ -466,20 +513,18 @@ int nfsd_cache_lookup(struct svc_rqst *r found =nfsd_cache_insert (b, rp, nn);if (found != rp) goto found_entry; - -nfsd_stats_rc_misses_inc (); rqstp->rq_cacherep = rp; rp->c_state =RC_INPROG ; +nfsd_prune_bucket_locked (nn, b,3 , &dispose); +spin_unlock (&b->cache_lock); + freed =nfsd_cacherep_dispose (&dispose); +trace_nfsd_drc_gc (nn, freed); + +nfsd_stats_rc_misses_inc ();atomic_inc (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_add (nn,sizeof (*rp)); - -nfsd_prune_bucket (b, nn); - -out_unlock: -spin_unlock (&b->cache_lock); -out: -return rtn; + goto out; found_entry:/* We found a matching entry which is either in progress or done. */
@@ -517,7 +562,10 @@ found_entry: out_trace:trace_nfsd_drc_found (nn, rqstp, rtn); - goto out_unlock; +out_unlock: +spin_unlock (&b->cache_lock); +out: +return rtn; }/**
fs/nfsd/trace.h +22 -0
@@ -1260,6 +1260,28 @@ TRACE_EVENT(nfsd_drc_mismatch, __entry->ingress) ); +TRACE_EVENT_CONDITION (nfsd_drc_gc, +TP_PROTO ( + const struct nfsd_net *nn, + unsigned long freed + ), +TP_ARGS (nn, freed), +TP_CONDITION (freed >0 ), +TP_STRUCT__entry ( + __field(unsigned long long, boot_time) + __field(unsigned long, freed) +__field (int, total) + ), +TP_fast_assign ( + __entry->boot_time = nn->boot_time; + __entry->freed = freed; + __entry->total = atomic_read(&nn->num_drc_entries); + ), +TP_printk ("boot_time=%16llx total=%d freed=%lu" , + __entry->boot_time, __entry->total, __entry->freed + ) +); + TRACE_EVENT(nfsd_cb_args, TP_PROTO( const struct nfs4_client *clp,
Greg Kroah-Hartman
maintainerPATCH 115/215 NFSD: Refactor the duplicate reply cache shrinker
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit c135e1269f34dfdea4bd94c11060c83a3c0b3c12 ]
Avoid holding the bucket lock while freeing cache entries. This change also caps the number of entries that are freed when the shrinker calls to reduce the shrinker's impact on the cache's effectiveness.
--- fs/nfsd/nfscache.c | 82 +++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 43 deletions(-)
fs/nfsd/nfscache.c +39 -43
@@ -309,68 +309,64 @@ nfsd_prune_bucket_locked(struct nfsd_net } } -static long prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn, -unsigned int max) +/** +* nfsd_reply_cache_count - count_objects method for the DRC shrinker +* @shrink: our registered shrinker context +* @sc: garbage collection parameters +* +* Returns the total number of entries in the duplicate reply cache. To +* keep things simple and quick, this is not the number of expired entries +* in the cache (ie, the number that would be removed by a call to +* nfsd_reply_cache_scan). +*/ +static unsigned long +nfsd_reply_cache_count (struct shrinker *shrink,struct shrink_control *sc) { -struct svc_cacherep *rp, *tmp; -long freed =0 ; +struct nfsd_net *nn =container_of (shrink, + struct nfsd_net, nfsd_reply_cache_shrinker); -list_for_each_entry_safe (rp, tmp, &b->lru_head, c_lru) { -/* -* Don't free entries attached to calls that are still -* in-progress, but do keep scanning the list. -*/ -if (rp->c_state ==RC_INPROG ) -continue ; -if (atomic_read (&nn->num_drc_entries) <= nn->max_drc_entries && -time_before (jiffies, rp->c_timestamp +RC_EXPIRE )) -break ; -nfsd_reply_cache_free_locked (b, rp, nn); -if (max && freed++ > max) -break ; - } -return freed; +return atomic_read (&nn->num_drc_entries); } -/* -* Walk the LRU list and prune off entries that are older than RC_EXPIRE. -* Also prune the oldest ones when the total exceeds the max number of entries. +/** +* nfsd_reply_cache_scan - scan_objects method for the DRC shrinker +* @shrink: our registered shrinker context +* @sc: garbage collection parameters +* +* Free expired entries on each bucket's LRU list until we've released +* nr_to_scan freed objects. Nothing will be released if the cache +* has not exceeded it's max_drc_entries limit. +* +* Returns the number of entries released by this call. */ -static long -prune_cache_entries (struct nfsd_net *nn) +static unsigned long +nfsd_reply_cache_scan (struct shrinker *shrink,struct shrink_control *sc) { +struct nfsd_net *nn =container_of (shrink, + struct nfsd_net, nfsd_reply_cache_shrinker); +unsigned long freed =0 ; +LIST_HEAD (dispose);unsigned int i; -long freed =0 ;for (i =0 ; i < nn->drc_hashsize; i++) {struct nfsd_drc_bucket *b = &nn->drc_hashtbl[i];if (list_empty (&b->lru_head))continue ; +spin_lock (&b->cache_lock); - freed +=prune_bucket (b, nn,0 ); +nfsd_prune_bucket_locked (nn, b,0 , &dispose);spin_unlock (&b->cache_lock); - } -return freed; -} -static unsigned long -nfsd_reply_cache_count (struct shrinker *shrink,struct shrink_control *sc) -{ -struct nfsd_net *nn =container_of (shrink, - struct nfsd_net, nfsd_reply_cache_shrinker); + freed +=nfsd_cacherep_dispose (&dispose); +if (freed > sc->nr_to_scan) +break ; + } -return atomic_read (&nn->num_drc_entries); +trace_nfsd_drc_gc (nn, freed); +return freed; } -static unsigned long -nfsd_reply_cache_scan (struct shrinker *shrink,struct shrink_control *sc) -{ -struct nfsd_net *nn =container_of (shrink, - struct nfsd_net, nfsd_reply_cache_shrinker); - -return prune_cache_entries (nn); -}/* * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes */
Greg Kroah-Hartman
maintainerPATCH 116/215 NFSD: Rewrite synopsis of nfsd_percpu_counters_init()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 5ec39944f874e1ecc09f624a70dfaa8ac3bf9d08 ]
In function ‘export_stats_init’,
inlined from ‘svc_export_alloc’ at fs/nfsd/export.c:866:6:fs/nfsd/export.c:337:16: warning: ‘nfsd_percpu_counters_init’ accessing 40 bytes in a region of size 0 [-Wstringop-overflow=]
337 | return nfsd_percpu_counters_init(&stats->counter, EXP_STATS_COUNTERS_NUM);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/nfsd/export.c:337:16: note: referencing argument 1 of type ‘struct percpu_counter[0]’
fs/nfsd/stats.h: In function ‘svc_export_alloc’:
fs/nfsd/stats.h:40:5: note: in a call to function ‘nfsd_percpu_counters_init’
40 | int nfsd_percpu_counters_init(struct percpu_counter counters[], int num);
| ^~~~~~~~~~~~~~~~~~~~~~~~~Stable-dep-of: 93483ac5fec6 ("nfsd: expose /proc/net/sunrpc/nfsd in net namespaces")
--- fs/nfsd/stats.c | 2 +- fs/nfsd/stats.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/stats.c +1 -1
@@ -74,7 +74,7 @@ static int nfsd_show(struct seq_file *seDEFINE_PROC_SHOW_ATTRIBUTE (nfsd); -int nfsd_percpu_counters_init (struct percpu_counter counters[],int num) +int nfsd_percpu_counters_init (struct percpu_counter *counters,int num) {int i, err =0 ;
fs/nfsd/stats.h +3 -3
@@ -36,9 +36,9 @@ extern struct nfsd_stats nfsdstats;extern struct svc_stat nfsd_svcstats; -int nfsd_percpu_counters_init (struct percpu_counter counters[],int num); -void nfsd_percpu_counters_reset (struct percpu_counter counters[],int num); -void nfsd_percpu_counters_destroy (struct percpu_counter counters[],int num); +int nfsd_percpu_counters_init (struct percpu_counter *counters,int num); +void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num); +void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num);int nfsd_stat_init (void );void nfsd_stat_shutdown (void );
Greg Kroah-Hartman
maintainerPATCH 117/215 NFSD: Fix frame size warning in svc_export_parse()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 6939ace1f22681fface7841cdbf34d3204cc94b5 ]
fs/nfsd/export.c: In function 'svc_export_parse':fs/nfsd/export.c:737:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
737 | }
On my systems, svc_export_parse() has a stack frame of over 800 bytes, not 1040, but nonetheless, it could do with some reduction.
When a struct svc_export is on the stack, it's a temporary structure used as an argument, and not visible as an actual exported FS. No need to reserve space for export_stats in such cases.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/export.c | 32 +++++++++++++++++++++++--------- fs/nfsd/export.h | 4 ++-- fs/nfsd/stats.h | 12 ++++++------ 3 files changed, 31 insertions(+), 17 deletions(-)
fs/nfsd/export.c +23 -9
@@ -339,12 +339,16 @@ static int export_stats_init(struct expostatic void export_stats_reset (struct export_stats *stats) { -nfsd_percpu_counters_reset (stats->counter,EXP_STATS_COUNTERS_NUM ); +if (stats) +nfsd_percpu_counters_reset (stats->counter, +EXP_STATS_COUNTERS_NUM ); }static void export_stats_destroy (struct export_stats *stats) { -nfsd_percpu_counters_destroy (stats->counter,EXP_STATS_COUNTERS_NUM ); +if (stats) +nfsd_percpu_counters_destroy (stats->counter, +EXP_STATS_COUNTERS_NUM ); }static void svc_export_put (struct kref *ref)
@@ -353,7 +357,8 @@ static void svc_export_put(struct kref *path_put (&exp->ex_path);auth_domain_put (exp->ex_client);nfsd4_fslocs_free (&exp->ex_fslocs); -export_stats_destroy (&exp->ex_stats); +export_stats_destroy (exp->ex_stats); +kfree (exp->ex_stats);kfree (exp->ex_uuid);kfree_rcu (exp, ex_rcu); }
@@ -744,13 +749,15 @@ static int svc_export_show(struct seq_fiseq_putc (m,'\t' );seq_escape (m, exp->ex_client->name," \t\n\\" );if (export_stats) { -seq_printf (m,"\t%lld\n" , exp->ex_stats.start_time); +struct percpu_counter *counter = exp->ex_stats->counter; + +seq_printf (m,"\t%lld\n" , exp->ex_stats->start_time);seq_printf (m,"\tfh_stale: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_FH_STALE ])); +percpu_counter_sum_positive (&counter[EXP_STATS_FH_STALE ]));seq_printf (m,"\tio_read: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_READ ])); +percpu_counter_sum_positive (&counter[EXP_STATS_IO_READ ]));seq_printf (m,"\tio_write: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ])); +percpu_counter_sum_positive (&counter[EXP_STATS_IO_WRITE ]));seq_putc (m,'\n' );return 0 ; }
@@ -796,7 +803,7 @@ static void svc_export_init(struct cache new->ex_layout_types =0 ; new->ex_uuid =NULL ; new->cd = item->cd; -export_stats_reset (&new->ex_stats); +export_stats_reset (new->ex_stats); }static void export_update (struct cache_head *cnew,struct cache_head *citem)
@@ -832,7 +839,14 @@ static struct cache_head *svc_export_allif (!i)return NULL ; -if (export_stats_init (&i->ex_stats)) { + i->ex_stats =kmalloc (sizeof (*(i->ex_stats)),GFP_KERNEL ); +if (!i->ex_stats) { +kfree (i); +return NULL ; + } + +if (export_stats_init (i->ex_stats)) { +kfree (i->ex_stats);kfree (i);return NULL ; }
fs/nfsd/export.h +2 -2
@@ -64,10 +64,10 @@ struct svc_export {struct cache_head h;struct auth_domain * ex_client;int ex_flags; +int ex_fsid;struct path ex_path;kuid_t ex_anon_uid;kgid_t ex_anon_gid; -int ex_fsid;unsigned char * ex_uuid;/* 16 byte fsid */ struct nfsd4_fs_locations ex_fslocs;uint32_t ex_nflavors;
@@ -76,7 +76,7 @@ struct svc_export {struct nfsd4_deviceid_map *ex_devid_map;struct cache_detail *cd;struct rcu_head ex_rcu; -struct export_stats ex_stats; +struct export_stats *ex_stats; };/* an "export key" (expkey) maps a filehandlefragement to an
fs/nfsd/stats.h +6 -6
@@ -60,22 +60,22 @@ static inline void nfsd_stats_rc_nocachestatic inline void nfsd_stats_fh_stale_inc (struct svc_export *exp) {percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_FH_STALE ]); -if (exp) -percpu_counter_inc (&exp->ex_stats.counter[EXP_STATS_FH_STALE ]); +if (exp && exp->ex_stats) +percpu_counter_inc (&exp->ex_stats->counter[EXP_STATS_FH_STALE ]); }static inline void nfsd_stats_io_read_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_READ ], amount); -if (exp) -percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_READ ], amount); +if (exp && exp->ex_stats) +percpu_counter_add (&exp->ex_stats->counter[EXP_STATS_IO_READ ], amount); }static inline void nfsd_stats_io_write_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_WRITE ], amount); -if (exp) -percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ], amount); +if (exp && exp->ex_stats) +percpu_counter_add (&exp->ex_stats->counter[EXP_STATS_IO_WRITE ], amount); }static inline void nfsd_stats_payload_misses_inc (struct nfsd_net *nn)
Greg Kroah-Hartman
maintainerPATCH 118/215 sunrpc: dont change ->sv_stats if it doesnt exist
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit ab42f4d9a26f1723dcfd6c93fcf768032b2bb5e7 ]
We check for the existence of ->sv_stats elsewhere except in the core processing code. It appears that only nfsd actual exports these values anywhere, everybody else just has a write only copy of sv_stats in their svc_program. Add a check for ->sv_stats before every adjustment to allow us to eliminate the stats struct from all the users who don't report the stats.
--- net/sunrpc/svc.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
net/sunrpc/svc.c +16 -8
@@ -1357,7 +1357,8 @@ svc_process_common(struct svc_rqst *rqst goto err_bad_proc;/* Syntactic check complete */ - serv->sv_stats->rpccnt++; +if (serv->sv_stats) + serv->sv_stats->rpccnt++;trace_svc_process (rqstp, progp->pg_name);/* Build the reply header. */
@@ -1423,7 +1424,8 @@ err_short_len: goto close_xprt; err_bad_rpc: - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,1 );/* REJECT */ svc_putnl (resv,0 );/* RPC_MISMATCH */ svc_putnl (resv,2 );/* Only RPCv2 supported */
@@ -1436,7 +1438,8 @@ err_release_bad_auth: err_bad_auth:dprintk ("svc: authentication failed (%d)\n" ,be32_to_cpu (rqstp->rq_auth_stat)); - serv->sv_stats->rpcbadauth++; +if (serv->sv_stats) + serv->sv_stats->rpcbadauth++;/* Restore write pointer to location of accept status: */ xdr_ressize_check (rqstp, reply_statp);svc_putnl (resv,1 );/* REJECT */
@@ -1446,7 +1449,8 @@ err_bad_auth: err_bad_prog:dprintk ("svc: unknown program %d\n" , prog); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROG_UNAVAIL ); goto sendit;
@@ -1454,7 +1458,8 @@ err_bad_vers:svc_printk (rqstp,"unknown version (%d for prog %d, %s)\n" , rqstp->rq_vers, rqstp->rq_prog, progp->pg_name); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROG_MISMATCH );svc_putnl (resv, process.mismatch.lovers);svc_putnl (resv, process.mismatch.hivers);
@@ -1463,7 +1468,8 @@ err_bad_vers: err_bad_proc:svc_printk (rqstp,"unknown procedure (%d)\n" , rqstp->rq_proc); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROC_UNAVAIL ); goto sendit;
@@ -1472,7 +1478,8 @@ err_garbage: rpc_stat = rpc_garbage_args; err_bad: - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,ntohl (rpc_stat)); goto sendit; }
@@ -1513,7 +1520,8 @@ svc_process(struct svc_rqst *rqstp)if (dir !=0 ) {/* direction != CALL */ svc_printk (rqstp,"bad direction %d, dropping request\n" , dir); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++; goto out_drop; }
Greg Kroah-Hartman
maintainerPATCH 119/215 nfsd: stop setting ->pg_stats for unused stats
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit a2214ed588fb3c5b9824a21cff870482510372bb ]
A lot of places are setting a blank svc_stats in ->pg_stats and never utilizing these stats. Remove all of these extra structs as we're not reporting these stats anywhere.
--- fs/lockd/svc.c | 3 --- fs/nfs/callback.c | 3 --- fs/nfsd/nfssvc.c | 5 ----- 3 files changed, 11 deletions(-)
fs/lockd/svc.c +0 -3
@@ -759,8 +759,6 @@ static const struct svc_version *nlmsvc_#endif }; -static struct svc_stat nlmsvc_stats; -#define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)static struct svc_program nlmsvc_program = { .pg_prog =NLM_PROGRAM ,/* program number */
@@ -768,7 +766,6 @@ static struct svc_program nlmsvc_program .pg_vers = nlmsvc_version, /* version table */ .pg_name = "lockd", /* service name */ .pg_class = "nfsd", /* share authentication with nfsd */ - .pg_stats = &nlmsvc_stats, /* stats table */ .pg_authenticate = &lockd_authenticate, /* export authentication */ .pg_init_request = svc_generic_init_request, .pg_rpcbind_set = svc_generic_rpcbind_set,
fs/nfs/callback.c +0 -3
@@ -407,15 +407,12 @@ static const struct svc_version *nfs4_ca [4] = &nfs4_callback_version4, }; -static struct svc_stat nfs4_callback_stats; -static struct svc_program nfs4_callback_program = { .pg_prog =NFS4_CALLBACK ,/* RPC service number */ .pg_nvers =ARRAY_SIZE (nfs4_callback_version),/* Number of entries */ .pg_vers = nfs4_callback_version,/* version table */ .pg_name ="NFSv4 callback" ,/* service name */ .pg_class ="nfs" ,/* authentication class */ - .pg_stats = &nfs4_callback_stats, .pg_authenticate = nfs_callback_authenticate, .pg_init_request = svc_generic_init_request, .pg_rpcbind_set = svc_generic_rpcbind_set,
fs/nfsd/nfssvc.c +0 -5
@@ -89,7 +89,6 @@ unsigned long nfsd_drc_max_mem;unsigned long nfsd_drc_mem_used;#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL ) -static struct svc_stat nfsd_acl_svcstats;static const struct svc_version *nfsd_acl_version[] = { # if defined(CONFIG_NFSD_V2_ACL) [2] = &nfsd_acl_version2,
@@ -108,15 +107,11 @@ static struct svc_program nfsd_acl_progr .pg_vers = nfsd_acl_version, .pg_name = "nfsacl", .pg_class = "nfsd", - .pg_stats = &nfsd_acl_svcstats, .pg_authenticate = &svc_set_client, .pg_init_request = nfsd_acl_init_request, .pg_rpcbind_set = nfsd_acl_rpcbind_set, }; -static struct svc_stat nfsd_acl_svcstats = { - .program = &nfsd_acl_program, -};#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ static const struct svc_version *nfsd_version[] = {
Greg Kroah-Hartman
maintainerPATCH 120/215 sunrpc: pass in the sv_stats struct through svc_create_pooled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit f094323867668d50124886ad884b665de7319537 ]
Since only one service actually reports the rpc stats there's not much of a reason to have a pointer to it in the svc_program struct. Adjust the svc_create_pooled function to take the sv_stats as an argument and pass the struct through there as desired instead of getting it from the svc_program->pg_stats.
--- fs/nfsd/nfssvc.c | 3 ++- include/linux/sunrpc/svc.h | 4 +++- net/sunrpc/svc.c | 12 +++++++----- 3 files changed, 12 insertions(+), 7 deletions(-)
fs/nfsd/nfssvc.c +2 -1
@@ -665,7 +665,8 @@ int nfsd_create_serv(struct net *net)if (nfsd_max_blksize ==0 ) nfsd_max_blksize =nfsd_get_default_max_blksize ();nfsd_reset_versions (nn); - serv =svc_create_pooled (&nfsd_program, nfsd_max_blksize, nfsd); + serv =svc_create_pooled (&nfsd_program, &nfsd_svcstats, + nfsd_max_blksize, nfsd);if (serv ==NULL )return -ENOMEM ;
include/linux/sunrpc/svc.h +3 -1
@@ -483,7 +483,9 @@ void svc_rqst_replace_page(struct sv struct page *page);void svc_rqst_free (struct svc_rqst *);void svc_exit_thread (struct svc_rqst *); -struct svc_serv *svc_create_pooled (struct svc_program *,unsigned int , +struct svc_serv *svc_create_pooled (struct svc_program *prog, +struct svc_stat *stats, +unsigned int bufsize,int (*threadfn)(void *data));int svc_set_num_threads (struct svc_serv *,struct svc_pool *,int );int svc_pool_stats_open (struct svc_serv *serv,struct file *file);
net/sunrpc/svc.c +7 -5
@@ -447,8 +447,8 @@ __svc_init_bc(struct svc_serv *serv)* Create an RPC service */ static struct svc_serv * -__svc_create (struct svc_program *prog,unsigned int bufsize,int npools, -int (*threadfn)(void *data)) +__svc_create (struct svc_program *prog,struct svc_stat *stats, +unsigned int bufsize,int npools,int (*threadfn)(void *data)) {struct svc_serv *serv;unsigned int vers;
@@ -460,7 +460,7 @@ __svc_create(struct svc_program *prog, u serv->sv_name = prog->pg_name; serv->sv_program = prog;kref_init (&serv->sv_refcnt); - serv->sv_stats = prog->pg_stats; + serv->sv_stats = stats;if (bufsize >RPCSVC_MAXPAYLOAD ) bufsize =RPCSVC_MAXPAYLOAD ; serv->sv_max_payload = bufsize? bufsize :4096 ;
@@ -522,26 +522,28 @@ __svc_create(struct svc_program *prog, ustruct svc_serv *svc_create (struct svc_program *prog,unsigned int bufsize,int (*threadfn)(void *data)) { -return __svc_create (prog, bufsize,1 , threadfn); +return __svc_create (prog,NULL , bufsize,1 , threadfn); }EXPORT_SYMBOL_GPL (svc_create);/** * svc_create_pooled - Create an RPC service with pooled threads * @prog: the RPC program the new service will handle +* @stats: the stats struct if desired * @bufsize: maximum message size for @prog * @threadfn: a function to service RPC requests for @prog * * Returns an instantiated struct svc_serv object or NULL. */ struct svc_serv *svc_create_pooled (struct svc_program *prog, +struct svc_stat *stats,unsigned int bufsize,int (*threadfn)(void *data)) {struct svc_serv *serv;unsigned int npools =svc_pool_map_get (); - serv =__svc_create (prog, bufsize, npools, threadfn); + serv =__svc_create (prog, stats, bufsize, npools, threadfn);if (!serv) goto out_err;return serv;
Greg Kroah-Hartman
maintainerPATCH 121/215 sunrpc: remove ->pg_stats from svc_program
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 3f6ef182f144dcc9a4d942f97b6a8ed969f13c95 ]
Now that this isn't used anywhere, remove it.
--- fs/nfsd/nfssvc.c | 1 - include/linux/sunrpc/svc.h | 1 - 2 files changed, 2 deletions(-)
fs/nfsd/nfssvc.c +0 -1
@@ -136,7 +136,6 @@ struct svc_program nfsd_program = { .pg_vers = nfsd_version, /* version table */ .pg_name = "nfsd", /* program name */ .pg_class = "nfsd", /* authentication class */ - .pg_stats = &nfsd_svcstats, /* version table */ .pg_authenticate = &svc_set_client, /* export authentication */ .pg_init_request = nfsd_init_request, .pg_rpcbind_set = nfsd_rpcbind_set,
include/linux/sunrpc/svc.h +0 -1
@@ -409,7 +409,6 @@ struct svc_program {const struct svc_version **pg_vers;/* version array */ char * pg_name;/* service name */ char * pg_class;/* class name: services sharing authentication */ -struct svc_stat * pg_stats;/* rpc statistics */ int (*pg_authenticate)(struct svc_rqst *); __be32 (*pg_init_request)(struct svc_rqst *, const struct svc_program *,
Greg Kroah-Hartman
maintainerPATCH 122/215 sunrpc: use the struct net as the svc proc private
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 418b9687dece5bd763c09b5c27a801a7e3387be9 ]
nfsd is the only thing using this helper, and it doesn't use the private currently. When we switch to per-network namespace stats we will need the struct net * in order to get to the nfsd_net. Use the net as the proc private so we can utilize this when we make the switch over.
--- net/sunrpc/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/stats.c +1 -1
@@ -309,7 +309,7 @@ EXPORT_SYMBOL_GPL(rpc_proc_unregister);struct proc_dir_entry *svc_proc_register (struct net *net,struct svc_stat *statp,const struct proc_ops *proc_ops) { -return do_register (net, statp->program->pg_name, statp, proc_ops); +return do_register (net, statp->program->pg_name, net, proc_ops); }EXPORT_SYMBOL_GPL (svc_proc_register);
Greg Kroah-Hartman
maintainerPATCH 123/215 nfsd: rename NFSD_NET_* to NFSD_STATS_*
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit d98416cc2154053950610bb6880911e3dcbdf8c5 ]
We're going to merge the stats all into per network namespace in subsequent patches, rename these nn counters to be consistent with the rest of the stats.
--- fs/nfsd/netns.h | 4 ++-- fs/nfsd/nfscache.c | 4 ++-- fs/nfsd/stats.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/netns.h +2 -2
@@ -25,9 +25,9 @@ struct nfsd4_client_tracking_ops;enum {/* cache misses due only to checksum comparison failures */ -NFSD_NET_PAYLOAD_MISSES , +NFSD_STATS_PAYLOAD_MISSES ,/* amount of memory (in bytes) currently consumed by the DRC */ -NFSD_NET_DRC_MEM_USAGE , +NFSD_STATS_DRC_MEM_USAGE ,NFSD_NET_COUNTERS_NUM };
fs/nfsd/nfscache.c +2 -2
@@ -673,7 +673,7 @@ int nfsd_reply_cache_stats_show(struct s atomic_read(&nn->num_drc_entries));seq_printf (m,"hash buckets: %u\n" ,1 << nn->maskbits);seq_printf (m,"mem usage: %lld\n" , -percpu_counter_sum_positive (&nn->counter[NFSD_NET_DRC_MEM_USAGE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ]));seq_printf (m,"cache hits: %lld\n" ,percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ])); seq_printf(m, "cache misses: %lld\n",
@@ -681,7 +681,7 @@ int nfsd_reply_cache_stats_show(struct sseq_printf (m,"not cached: %lld\n" ,percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ]));seq_printf (m,"payload misses: %lld\n" , -percpu_counter_sum_positive (&nn->counter[NFSD_NET_PAYLOAD_MISSES ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]));seq_printf (m,"longest chain len: %u\n" , nn->longest_chain);seq_printf (m,"cachesize at longest: %u\n" , nn->longest_chain_cachesize);return 0 ;
fs/nfsd/stats.h +3 -3
@@ -80,17 +80,17 @@ static inline void nfsd_stats_io_write_astatic inline void nfsd_stats_payload_misses_inc (struct nfsd_net *nn) { -percpu_counter_inc (&nn->counter[NFSD_NET_PAYLOAD_MISSES ]); +percpu_counter_inc (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]); }static inline void nfsd_stats_drc_mem_usage_add (struct nfsd_net *nn,s64 amount) { -percpu_counter_add (&nn->counter[NFSD_NET_DRC_MEM_USAGE ], amount); +percpu_counter_add (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ], amount); }static inline void nfsd_stats_drc_mem_usage_sub (struct nfsd_net *nn,s64 amount) { -percpu_counter_sub (&nn->counter[NFSD_NET_DRC_MEM_USAGE ], amount); +percpu_counter_sub (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ], amount); }#endif /* _NFSD_STATS_H */
Greg Kroah-Hartman
maintainerPATCH 124/215 nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 93483ac5fec62cc1de166051b219d953bb5e4ef4 ]
We are running nfsd servers inside of containers with their own network namespace, and we want to monitor these services using the stats found in /proc. However these are not exposed in the proc inside of the container, so we have to bind mount the host /proc into our containers to get at this information.
Separate out the stat counters init and the proc registration, and move the proc registration into the pernet operations entry and exit points so that these stats can be exposed inside of network namespaces.
This is an intermediate step, this just exposes the global counters in the network namespace. Subsequent patches will move these counters into the per-network namespace container.
--- fs/nfsd/nfsctl.c | 8 +++++--- fs/nfsd/stats.c | 21 ++++++--------------- fs/nfsd/stats.h | 6 ++++-- 3 files changed, 15 insertions(+), 20 deletions(-)
fs/nfsd/nfsctl.c +5 -3
@@ -1466,6 +1466,7 @@ static __net_init int nfsd_init_net(strunfsd4_init_leases_net (nn);get_random_bytes (&nn->siphash_key,sizeof (nn->siphash_key));seqlock_init (&nn->writeverf_lock); +nfsd_proc_stat_init (net);return 0 ;
@@ -1481,6 +1482,7 @@ static __net_exit void nfsd_exit_net(str {struct nfsd_net *nn =net_generic (net, nfsd_net_id); +nfsd_proc_stat_shutdown (net);nfsd_net_reply_cache_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);
@@ -1504,7 +1506,7 @@ static int __init init_nfsd(void) retval =nfsd4_init_pnfs ();if (retval) goto out_free_slabs; - retval =nfsd_stat_init ();/* Statistics */ + retval =nfsd_stat_counters_init ();/* Statistics */ if (retval) goto out_free_pnfs; retval =nfsd_drc_slab_create ();
@@ -1540,7 +1542,7 @@ out_free_lockd:nfsd_lockd_shutdown ();nfsd_drc_slab_free (); out_free_stat: -nfsd_stat_shutdown (); +nfsd_stat_counters_destroy (); out_free_pnfs:nfsd4_exit_pnfs (); out_free_slabs:
@@ -1557,7 +1559,7 @@ static void __exit exit_nfsd(void)nfsd_drc_slab_free ();remove_proc_entry ("fs/nfs/exports" ,NULL );remove_proc_entry ("fs/nfs" ,NULL ); -nfsd_stat_shutdown (); +nfsd_stat_counters_destroy ();nfsd_lockd_shutdown ();nfsd4_free_slabs ();nfsd4_exit_pnfs ();
fs/nfsd/stats.c +6 -15
@@ -106,31 +106,22 @@ void nfsd_percpu_counters_destroy(structpercpu_counter_destroy (&counters[i]); } -static int nfsd_stat_counters_init (void ) +int nfsd_stat_counters_init (void ) {return nfsd_percpu_counters_init (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); } -static void nfsd_stat_counters_destroy (void ) +void nfsd_stat_counters_destroy (void ) {nfsd_percpu_counters_destroy (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); } -int nfsd_stat_init (void ) +void nfsd_proc_stat_init (struct net *net) { -int err; - - err =nfsd_stat_counters_init (); -if (err) -return err; - -svc_proc_register (&init_net, &nfsd_svcstats, &nfsd_proc_ops); - -return 0 ; +svc_proc_register (net, &nfsd_svcstats, &nfsd_proc_ops); } -void nfsd_stat_shutdown (void ) +void nfsd_proc_stat_shutdown (struct net *net) { -nfsd_stat_counters_destroy (); -svc_proc_unregister (&init_net,"nfsd" ); +svc_proc_unregister (net,"nfsd" ); }
fs/nfsd/stats.h +4 -2
@@ -39,8 +39,10 @@ extern struct svc_stat nfsd_svcstats;int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num);void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num); -int nfsd_stat_init (void ); -void nfsd_stat_shutdown (void ); +int nfsd_stat_counters_init (void ); +void nfsd_stat_counters_destroy (void ); +void nfsd_proc_stat_init (struct net *net); +void nfsd_proc_stat_shutdown (struct net *net);static inline void nfsd_stats_rc_hits_inc (void ) {
Greg Kroah-Hartman
maintainerPATCH 125/215 nfsd: make all of the nfsd stats per-network namespace
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 4b14885411f74b2b0ce0eb2b39d0fffe54e5ca0d ]
We have a global set of counters that we modify for all of the nfsd operations, but now that we're exposing these stats across all network namespaces we need to make the stats also be per-network namespace. We already have some caching stats that are per-network namespace, so move these definitions into the same counter and then adjust all the helpers and users of these stats to provide the appropriate nfsd_net struct so that the stats are maintained for the per-network namespace objects.
--- fs/nfsd/cache.h | 2 -- fs/nfsd/netns.h | 17 +++++++++++++++-- fs/nfsd/nfs4proc.c | 6 +++--- fs/nfsd/nfscache.c | 36 +++++++----------------------------- fs/nfsd/nfsctl.c | 12 +++--------- fs/nfsd/nfsfh.c | 3 ++- fs/nfsd/stats.c | 24 +++++++++++++----------- fs/nfsd/stats.h | 49 +++++++++++++++++-------------------------------- fs/nfsd/vfs.c | 6 ++++-- 9 files changed, 64 insertions(+), 91 deletions(-)
fs/nfsd/cache.h +0 -2
@@ -80,8 +80,6 @@ enum {int nfsd_drc_slab_create (void );void nfsd_drc_slab_free (void ); -int nfsd_net_reply_cache_init (struct nfsd_net *nn); -void nfsd_net_reply_cache_destroy (struct nfsd_net *nn);int nfsd_reply_cache_init (struct nfsd_net *);void nfsd_reply_cache_shutdown (struct nfsd_net *);int nfsd_cache_lookup (struct svc_rqst *);
fs/nfsd/netns.h +15 -2
@@ -10,6 +10,7 @@#include <net/net_namespace.h> #include <net/netns/generic.h> +#include <linux/nfs4.h> #include <linux/percpu_counter.h> #include <linux/siphash.h>
@@ -28,7 +29,19 @@ enum {NFSD_STATS_PAYLOAD_MISSES ,/* amount of memory (in bytes) currently consumed by the DRC */ NFSD_STATS_DRC_MEM_USAGE , - NFSD_NET_COUNTERS_NUM +NFSD_STATS_RC_HITS ,/* repcache hits */ +NFSD_STATS_RC_MISSES ,/* repcache misses */ +NFSD_STATS_RC_NOCACHE ,/* uncached reqs */ +NFSD_STATS_FH_STALE ,/* FH stale error */ +NFSD_STATS_IO_READ ,/* bytes returned to read requests */ +NFSD_STATS_IO_WRITE ,/* bytes passed in write requests */ +#ifdef CONFIG_NFSD_V4 +NFSD_STATS_FIRST_NFS4_OP ,/* count of individual nfsv4 operations */ +NFSD_STATS_LAST_NFS4_OP =NFSD_STATS_FIRST_NFS4_OP +LAST_NFS4_OP , +#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) +NFSD_STATS_WDELEG_GETATTR ,/* count of getattr conflict with wdeleg */ +#endif +NFSD_STATS_COUNTERS_NUM };/*
@@ -168,7 +181,7 @@ struct nfsd_net {atomic_t num_drc_entries;/* Per-netns stats counters */ -struct percpu_counter counter[NFSD_NET_COUNTERS_NUM ]; +struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM ];/* longest hash chain seen */ unsigned int longest_chain;
fs/nfsd/nfs4proc.c +3 -3
@@ -2435,10 +2435,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp)return rpc_success; } -static inline void nfsd4_increment_op_stats (u32 opnum) +static inline void nfsd4_increment_op_stats (struct nfsd_net *nn,u32 opnum) {if (opnum >=FIRST_NFS4_OP && opnum <=LAST_NFS4_OP ) -percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_NFS4_OP (opnum)]); +percpu_counter_inc (&nn->counter[NFSD_STATS_NFS4_OP (opnum)]); }static const struct nfsd4_operation nfsd4_ops[];
@@ -2713,7 +2713,7 @@ encode_op: status, nfsd4_op_name(op->opnum));nfsd4_cstate_clear_replay (cstate); -nfsd4_increment_op_stats (op->opnum); +nfsd4_increment_op_stats (nn, op->opnum); }fh_put (current_fh);
fs/nfsd/nfscache.c +7 -29
@@ -176,27 +176,6 @@ void nfsd_drc_slab_free(void)kmem_cache_destroy (drc_slab); } -/** -* nfsd_net_reply_cache_init - per net namespace reply cache set-up -* @nn: nfsd_net being initialized -* -* Returns zero on succes; otherwise a negative errno is returned. -*/ -int nfsd_net_reply_cache_init (struct nfsd_net *nn) -{ -return nfsd_percpu_counters_init (nn->counter,NFSD_NET_COUNTERS_NUM ); -} - -/** -* nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down -* @nn: nfsd_net being freed -* -*/ -void nfsd_net_reply_cache_destroy (struct nfsd_net *nn) -{ -nfsd_percpu_counters_destroy (nn->counter,NFSD_NET_COUNTERS_NUM ); -} -int nfsd_reply_cache_init (struct nfsd_net *nn) {unsigned int hashsize;
@@ -478,7 +457,7 @@ out:*/ int nfsd_cache_lookup (struct svc_rqst *rqstp) { -struct nfsd_net *nn; +struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);struct svc_cacherep *rp, *found;__wsum csum;struct nfsd_drc_bucket *b;
@@ -489,7 +468,7 @@ int nfsd_cache_lookup(struct svc_rqst *r rqstp->rq_cacherep =NULL ;if (type ==RC_NOCACHE ) { -nfsd_stats_rc_nocache_inc (); +nfsd_stats_rc_nocache_inc (nn); goto out; }
@@ -499,7 +478,6 @@ int nfsd_cache_lookup(struct svc_rqst *r* Since the common case is a cache miss followed by an insert, * preallocate an entry. */ - nn =net_generic (SVC_NET (rqstp), nfsd_net_id); rp =nfsd_cacherep_alloc (rqstp, csum, nn);if (!rp) goto out;
@@ -517,7 +495,7 @@ int nfsd_cache_lookup(struct svc_rqst *r freed =nfsd_cacherep_dispose (&dispose);trace_nfsd_drc_gc (nn, freed); -nfsd_stats_rc_misses_inc (); +nfsd_stats_rc_misses_inc (nn);atomic_inc (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_add (nn,sizeof (*rp)); goto out;
@@ -525,7 +503,7 @@ int nfsd_cache_lookup(struct svc_rqst *r found_entry:/* We found a matching entry which is either in progress or done. */ nfsd_reply_cache_free_locked (NULL , rp, nn); -nfsd_stats_rc_hits_inc (); +nfsd_stats_rc_hits_inc (nn); rtn =RC_DROPIT ; rp = found;
@@ -675,11 +653,11 @@ int nfsd_reply_cache_stats_show(struct sseq_printf (m,"mem usage: %lld\n" ,percpu_counter_sum_positive (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ]));seq_printf (m,"cache hits: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_HITS ]));seq_printf (m,"cache misses: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_MISSES ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_MISSES ]));seq_printf (m,"not cached: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_NOCACHE ]));seq_printf (m,"payload misses: %lld\n" ,percpu_counter_sum_positive (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]));seq_printf (m,"longest chain len: %u\n" , nn->longest_chain);
fs/nfsd/nfsctl.c +3 -9
@@ -1458,7 +1458,7 @@ static __net_init int nfsd_init_net(stru retval =nfsd_idmap_init (net);if (retval) goto out_idmap_error; - retval =nfsd_net_reply_cache_init (nn); + retval =nfsd_stat_counters_init (nn);if (retval) goto out_repcache_error; nn->nfsd_versions =NULL ;
@@ -1483,7 +1483,7 @@ static __net_exit void nfsd_exit_net(strstruct nfsd_net *nn =net_generic (net, nfsd_net_id);nfsd_proc_stat_shutdown (net); -nfsd_net_reply_cache_destroy (nn); +nfsd_stat_counters_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);nfsd_netns_free_versions (nn);
@@ -1506,12 +1506,9 @@ static int __init init_nfsd(void) retval =nfsd4_init_pnfs ();if (retval) goto out_free_slabs; - retval =nfsd_stat_counters_init ();/* Statistics */ -if (retval) - goto out_free_pnfs; retval =nfsd_drc_slab_create ();if (retval) - goto out_free_stat; + goto out_free_pnfs;nfsd_lockd_init ();/* lockd->nfsd callbacks */ retval =create_proc_exports_entry ();if (retval)
@@ -1541,8 +1538,6 @@ out_free_exports: out_free_lockd:nfsd_lockd_shutdown ();nfsd_drc_slab_free (); -out_free_stat: -nfsd_stat_counters_destroy (); out_free_pnfs:nfsd4_exit_pnfs (); out_free_slabs:
@@ -1559,7 +1554,6 @@ static void __exit exit_nfsd(void)nfsd_drc_slab_free ();remove_proc_entry ("fs/nfs/exports" ,NULL );remove_proc_entry ("fs/nfs" ,NULL ); -nfsd_stat_counters_destroy ();nfsd_lockd_shutdown ();nfsd4_free_slabs ();nfsd4_exit_pnfs ();
fs/nfsd/nfsfh.c +2 -1
@@ -327,6 +327,7 @@ out:__be32 fh_verify (struct svc_rqst *rqstp,struct svc_fh *fhp,umode_t type,int access) { +struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);struct svc_export *exp =NULL ;struct dentry *dentry;__be32 error;
@@ -395,7 +396,7 @@ skip_pseudoflavor_check: out:trace_nfsd_fh_verify_err (rqstp, fhp, type, access, error);if (error == nfserr_stale) -nfsd_stats_fh_stale_inc (exp); +nfsd_stats_fh_stale_inc (nn, exp);return error; }
fs/nfsd/stats.c +13 -11
@@ -34,15 +34,17 @@ struct svc_stat nfsd_svcstats = {static int nfsd_show (struct seq_file *seq,void *v) { +struct net *net =PDE_DATA (file_inode (seq->file)); +struct nfsd_net *nn =net_generic (net, nfsd_net_id);int i;seq_printf (seq,"rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_MISSES ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_FH_STALE ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_IO_READ ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_IO_WRITE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_HITS ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_MISSES ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_NOCACHE ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_FH_STALE ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_IO_READ ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_IO_WRITE ]));/* thread usage: */ seq_printf (seq,"th %u 0" ,atomic_read (&nfsdstats.th_cnt));
@@ -63,7 +65,7 @@ static int nfsd_show(struct seq_file *seseq_printf (seq,"proc4ops %u" ,LAST_NFS4_OP +1 );for (i =0 ; i <=LAST_NFS4_OP ; i++) {seq_printf (seq," %lld" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_NFS4_OP (i)])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_NFS4_OP (i)])); }seq_putc (seq,'\n' );
@@ -106,14 +108,14 @@ void nfsd_percpu_counters_destroy(structpercpu_counter_destroy (&counters[i]); } -int nfsd_stat_counters_init (void ) +int nfsd_stat_counters_init (struct nfsd_net *nn) { -return nfsd_percpu_counters_init (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); +return nfsd_percpu_counters_init (nn->counter,NFSD_STATS_COUNTERS_NUM ); } -void nfsd_stat_counters_destroy (void ) +void nfsd_stat_counters_destroy (struct nfsd_net *nn) { -nfsd_percpu_counters_destroy (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); +nfsd_percpu_counters_destroy (nn->counter,NFSD_STATS_COUNTERS_NUM ); }void nfsd_proc_stat_init (struct net *net)
fs/nfsd/stats.h +17 -32
85 lines not on this page · raw message
fs/nfsd/vfs.c +4 -2
@@ -984,7 +984,9 @@ static __be32 nfsd_finish_read(struct sv unsigned long *count, u32 *eof, ssize_t host_err) { if (host_err >= 0) { - nfsd_stats_io_read_add(fhp->fh_export, host_err); + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + +nfsd_stats_io_read_add (nn, fhp->fh_export, host_err); *eof =nfsd_eof_on_read (file, offset, host_err, *count); *count = host_err;fsnotify_access (file);
@@ -1127,7 +1129,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s goto out_nfserr; } *cnt = host_err; -nfsd_stats_io_write_add (exp, *cnt); +nfsd_stats_io_write_add (nn, exp, *cnt);fsnotify_modify (file); host_err =filemap_check_wb_err (file->f_mapping, since);if (host_err <0 )
Greg Kroah-Hartman
maintainerPATCH 126/215 nfsd: remove nfsd_stats, make th_cnt a global counter
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit e41ee44cc6a473b1f414031782c3b4283d7f3e5f ]
This is the last global stat, take it out of the nfsd_stats struct and make it a global part of nfsd, report it the same as always.
--- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfssvc.c | 5 +++-- fs/nfsd/stats.c | 3 +-- fs/nfsd/stats.h | 6 ------ 4 files changed, 5 insertions(+), 10 deletions(-)
fs/nfsd/nfsd.h +1 -0
@@ -69,6 +69,7 @@ extern struct mutex nfsd_mutex;extern spinlock_t nfsd_drc_lock;extern unsigned long nfsd_drc_max_mem;extern unsigned long nfsd_drc_mem_used; +extern atomic_t nfsd_th_cnt;/* number of available threads */ extern const struct seq_operations nfs_exports_op;
fs/nfsd/nfssvc.c +3 -2
@@ -34,6 +34,7 @@#define NFSDDBG_FACILITY NFSDDBG_SVC +atomic_t nfsd_th_cnt =ATOMIC_INIT (0 );extern struct svc_program nfsd_program;static int nfsd (void *vrqstp);#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )
@@ -941,7 +942,7 @@ nfsd(void *vrqstp) current->fs->umask =0 ; -atomic_inc (&nfsdstats.th_cnt); +atomic_inc (&nfsd_th_cnt);set_freezable ();
@@ -965,7 +966,7 @@ nfsd(void *vrqstp)validate_process_creds (); } -atomic_dec (&nfsdstats.th_cnt); +atomic_dec (&nfsd_th_cnt); out:/* Release the thread */
fs/nfsd/stats.c +1 -2
@@ -27,7 +27,6 @@#include "nfsd.h" -struct nfsd_stats nfsdstats;struct svc_stat nfsd_svcstats = { .program = &nfsd_program, };
@@ -47,7 +46,7 @@ static int nfsd_show(struct seq_file *se percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE]));/* thread usage: */ -seq_printf (seq,"th %u 0" ,atomic_read (&nfsdstats.th_cnt)); +seq_printf (seq,"th %u 0" ,atomic_read (&nfsd_th_cnt));/* deprecated thread usage histogram stats */ for (i =0 ; i <10 ; i++)
fs/nfsd/stats.h +0 -6
@@ -10,12 +10,6 @@#include <uapi/linux/nfsd/stats.h> #include <linux/percpu_counter.h> -struct nfsd_stats { -atomic_t th_cnt;/* number of available threads */ -}; - -extern struct nfsd_stats nfsdstats; -extern struct svc_stat nfsd_svcstats;int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);
Greg Kroah-Hartman
maintainerPATCH 127/215 nfsd: make svc_stat per-network namespace instead of global
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 16fb9808ab2c99979f081987752abcbc5b092eac ]
The final bit of stats that is global is the rpc svc_stat. Move this into the nfsd_net struct and use that everywhere instead of the global struct. Remove the unused global struct.
--- fs/nfsd/netns.h | 4 ++++ fs/nfsd/nfsctl.c | 2 ++ fs/nfsd/nfssvc.c | 2 +- fs/nfsd/stats.c | 10 ++++------ fs/nfsd/stats.h | 2 -- 5 files changed, 11 insertions(+), 9 deletions(-)
fs/nfsd/netns.h +4 -0
@@ -13,6 +13,7 @@#include <linux/nfs4.h> #include <linux/percpu_counter.h> #include <linux/siphash.h> +#include <linux/sunrpc/stats.h> /* Hash tables for nfs4_clientid state */ #define CLIENT_HASH_BITS 4
@@ -183,6 +184,9 @@ struct nfsd_net {/* Per-netns stats counters */ struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM ]; +/* sunrpc svc stats */ +struct svc_stat nfsd_svcstats; +/* longest hash chain seen */ unsigned int longest_chain;
fs/nfsd/nfsctl.c +2 -0
@@ -1461,6 +1461,8 @@ static __net_init int nfsd_init_net(stru retval =nfsd_stat_counters_init (nn);if (retval) goto out_repcache_error; +memset (&nn->nfsd_svcstats,0 ,sizeof (nn->nfsd_svcstats)); + nn->nfsd_svcstats.program = &nfsd_program; nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn);
fs/nfsd/nfssvc.c +1 -1
@@ -665,7 +665,7 @@ int nfsd_create_serv(struct net *net)if (nfsd_max_blksize ==0 ) nfsd_max_blksize =nfsd_get_default_max_blksize ();nfsd_reset_versions (nn); - serv =svc_create_pooled (&nfsd_program, &nfsd_svcstats, + serv =svc_create_pooled (&nfsd_program, &nn->nfsd_svcstats, nfsd_max_blksize, nfsd);if (serv ==NULL )return -ENOMEM ;
fs/nfsd/stats.c +4 -6
@@ -27,10 +27,6 @@#include "nfsd.h" -struct svc_stat nfsd_svcstats = { - .program = &nfsd_program, -}; -static int nfsd_show (struct seq_file *seq,void *v) {struct net *net =PDE_DATA (file_inode (seq->file));
@@ -56,7 +52,7 @@ static int nfsd_show(struct seq_file *seseq_puts (seq,"\nra 0 0 0 0 0 0 0 0 0 0 0 0\n" );/* show my rpc info */ -svc_seq_show (seq, &nfsd_svcstats); +svc_seq_show (seq, &nn->nfsd_svcstats);#ifdef CONFIG_NFSD_V4 /* Show count for individual nfsv4 operations */
@@ -119,7 +115,9 @@ void nfsd_stat_counters_destroy(struct nvoid nfsd_proc_stat_init (struct net *net) { -svc_proc_register (net, &nfsd_svcstats, &nfsd_proc_ops); +struct nfsd_net *nn =net_generic (net, nfsd_net_id); + +svc_proc_register (net, &nn->nfsd_svcstats, &nfsd_proc_ops); }void nfsd_proc_stat_shutdown (struct net *net)
fs/nfsd/stats.h +0 -2
@@ -10,8 +10,6 @@#include <uapi/linux/nfsd/stats.h> #include <linux/percpu_counter.h> -extern struct svc_stat nfsd_svcstats; -int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num);void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num);
Greg Kroah-Hartman
maintainerPATCH 128/215 media: solo6x10: replace max(a, min(b, c)) by clamp(b, a, c)
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Jarno <[email protected]>
commit 31e97d7c9ae3de072d7b424b2cf706a03ec10720 upstream.
This patch replaces max(a, min(b, c)) by clamp(b, a, c) in the solo6x10 driver. This improves the readability and more importantly, for the solo6x10-p2m.c file, this reduces on my system (x86-64, gcc 13):
- the preprocessed size from 121 MiB to 4.5 MiB;
- the build CPU time from 46.8 s to 1.6 s;
- the build memory from 2786 MiB to 98MiB.
In fine, this allows this relatively simple C file to be built on a 32-bit system.
--- drivers/media/pci/solo6x10/solo6x10-offsets.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/media/pci/solo6x10/solo6x10-offsets.h +5 -5
@@ -57,16 +57,16 @@#define SOLO_MP4E_EXT_ADDR (__solo) \ (SOLO_EREF_EXT_ADDR(__solo) + SOLO_EREF_EXT_AREA(__solo))#define SOLO_MP4E_EXT_SIZE (__solo) \ - max((__solo->nr_chans * 0x00080000), \ - min(((__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo)) - \ - __SOLO_JPEG_MIN_SIZE(__solo)), 0x00ff0000)) + clamp(__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo) - \ + __SOLO_JPEG_MIN_SIZE(__solo), \ + __solo->nr_chans * 0x00080000, 0x00ff0000)#define __SOLO_JPEG_MIN_SIZE (__solo) (__solo->nr_chans * 0x00080000)#define SOLO_JPEG_EXT_ADDR (__solo) \ (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo))#define SOLO_JPEG_EXT_SIZE (__solo) \ - max(__SOLO_JPEG_MIN_SIZE(__solo), \ - min((__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo)), 0x00ff0000)) + clamp(__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo), \ + __SOLO_JPEG_MIN_SIZE(__solo), 0x00ff0000)#define SOLO_SDRAM_END (__solo) \ (SOLO_JPEG_EXT_ADDR(__solo) + SOLO_JPEG_EXT_SIZE(__solo))
Greg Kroah-Hartman
maintainerPATCH 129/215 dm suspend: return -ERESTARTSYS instead of -EINTR
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
[ Upstream commit 1e1fd567d32fcf7544c6e09e0e5bc6c650da6e23 ]
This commit changes device mapper, so that it returns -ERESTARTSYS instead of -EINTR when it is interrupted by a signal (so that the ioctl can be restarted).
The manpage signal(7) says that the ioctl function should be restarted if the signal was handled with SA_RESTART.
--- drivers/md/dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/dm.c +2 -2
@@ -2255,7 +2255,7 @@ static int dm_wait_for_bios_completion(struct mapped_device *md, unsigned int tabreak ;if (signal_pending_state (task_state, current)) { - r = -EINTR ; + r = -ERESTARTSYS ;break ; }
@@ -2280,7 +2280,7 @@ static int dm_wait_for_completion(struct mapped_device *md, unsigned int task_stbreak ;if (signal_pending_state (task_state, current)) { - r = -EINTR ; + r = -ERESTARTSYS ;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 130/215 net: mana: Fix doorbell out of order violation and avoid unnecessary doorbell rings
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
[ Upstream commit 58a63729c957621f1990c3494c702711188ca347 ]
After napi_complete_done() is called when NAPI is polling in the current process context, another NAPI may be scheduled and start running in softirq on another CPU and may ring the doorbell before the current CPU does. When combined with unnecessary rings when there is no need to arm the CQ, it triggers error paths in the hardware.
This patch fixes this by calling napi_complete_done() after doorbell rings. It limits the number of unnecessary rings when there is no need to arm. MANA hardware specifies that there must be one doorbell ring every 8 CQ wraparounds. This driver guarantees one doorbell ring as soon as the number of consumed CQEs exceeds 4 CQ wraparounds. In practical workloads, the 4 CQ wraparounds proves to be big enough that it rarely exceeds this limit before all the napi weight is consumed.
To implement this, add a per-CQ counter cq->work_done_since_doorbell, and make sure the CQ is armed as soon as passing 4 wraparounds of the CQ.
--- drivers/net/ethernet/microsoft/mana/mana.h | 1 + drivers/net/ethernet/microsoft/mana/mana_en.c | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-)
drivers/net/ethernet/microsoft/mana/mana.h +1 -0
@@ -252,6 +252,7 @@ struct mana_cq {/* NAPI data */ struct napi_struct napi;int work_done; +int work_done_since_doorbell;int budget; };
drivers/net/ethernet/microsoft/mana/mana_en.c +15 -9
@@ -1074,7 +1074,6 @@ static void mana_poll_rx_cq(struct mana_cq *cq)static int mana_cq_handler (void *context,struct gdma_queue *gdma_queue) {struct mana_cq *cq = context; -u8 arm_bit;int w;WARN_ON_ONCE (cq->gdma_cq != gdma_queue);
@@ -1085,16 +1084,23 @@ static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)mana_poll_tx_cq (cq); w = cq->work_done; - -if (w < cq->budget && -napi_complete_done (&cq->napi, w)) { - arm_bit =SET_ARM_BIT ; - }else { - arm_bit =0 ; + cq->work_done_since_doorbell += w; + +if (w < cq->budget) { +mana_gd_ring_cq (gdma_queue,SET_ARM_BIT ); + cq->work_done_since_doorbell =0 ; +napi_complete_done (&cq->napi, w); + }else if (cq->work_done_since_doorbell > + cq->gdma_cq->queue_size /COMP_ENTRY_SIZE *4 ) { +/* MANA hardware requires at least one doorbell ring every 8 +* wraparounds of CQ even if there is no need to arm the CQ. +* This driver rings the doorbell as soon as we have exceeded +* 4 wraparounds. +*/ +mana_gd_ring_cq (gdma_queue,0 ); + cq->work_done_since_doorbell =0 ; } -mana_gd_ring_cq (gdma_queue, arm_bit); -return w; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 131/215 platform/surface: aggregator: Fix warning when controller is destroyed in probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilian Luz <[email protected]>
[ Upstream commit bc923d594db21bee0ead128eb4bb78f7e77467a4 ]
There is a small window in ssam_serial_hub_probe() where the controller is initialized but has not been started yet. Specifically, between ssam_controller_init() and ssam_controller_start(). Any failure in this window, for example caused by a failure of serdev_device_open(), currently results in an incorrect warning being emitted.
In particular, any failure in this window results in the controller being destroyed via ssam_controller_destroy(). This function checks the state of the controller and, in an attempt to validate that the controller has been cleanly shut down before we try and deallocate any resources, emits a warning if that state is not SSAM_CONTROLLER_STOPPED.
However, since we have only just initialized the controller and have not yet started it, its state is SSAM_CONTROLLER_INITIALIZED. Note that this is the only point at which the controller has this state, as it will change after we start the controller with ssam_controller_start() and never revert back. Further, at this point no communication has taken place and the sender and receiver threads have not been started yet (and we may not even have an open serdev device either).
Therefore, it is perfectly safe to call ssam_controller_destroy() with a state of SSAM_CONTROLLER_INITIALIZED. This, however, means that the warning currently being emitted is incorrect. Fix it by extending the check.
--- drivers/platform/surface/aggregator/controller.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/platform/surface/aggregator/controller.c +2 -1
@@ -1354,7 +1354,8 @@ void ssam_controller_destroy(struct ssam_controller *ctrl)if (ctrl->state ==SSAM_CONTROLLER_UNINITIALIZED )return ; -WARN_ON (ctrl->state !=SSAM_CONTROLLER_STOPPED ); +WARN_ON (ctrl->state !=SSAM_CONTROLLER_STOPPED && + ctrl->state !=SSAM_CONTROLLER_INITIALIZED );/* * Note: New events could still have been received after the previous
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 132/215 Bluetooth: hci_core: Fix LE quote calculation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 932021a11805b9da4bd6abf66fe233cccd59fe0e ]
Function hci_sched_le needs to update the respective counter variable inplace other the likes of hci_quote_sent would attempt to use the possible outdated value of conn->{le_cnt,acl_cnt}.
--- net/bluetooth/hci_core.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
net/bluetooth/hci_core.c +7 -12
@@ -4876,19 +4876,19 @@ static void hci_sched_le(struct hci_dev *hdev) {struct hci_chan *chan;struct sk_buff *skb; -int quote, cnt, tmp; +int quote, *cnt, tmp;BT_DBG ("%s" , hdev->name);if (!hci_conn_num (hdev,LE_LINK ))return ; - cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; + cnt = hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; -__check_timeout (hdev, cnt,LE_LINK ); +__check_timeout (hdev, *cnt,LE_LINK ); - tmp = cnt; -while (cnt && (chan =hci_chan_sent (hdev,LE_LINK , "e))) { + tmp = *cnt; +while (*cnt && (chan =hci_chan_sent (hdev,LE_LINK , "e))) {u32 priority = (skb_peek (&chan->data_q))->priority;while (quote-- && (skb =skb_peek (&chan->data_q))) { BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
@@ -4903,7 +4903,7 @@ static void hci_sched_le(struct hci_dev *hdev)hci_send_frame (hdev, skb); hdev->le_last_tx = jiffies; - cnt--; + (*cnt)--; chan->sent++; chan->conn->sent++;
@@ -4913,12 +4913,7 @@ static void hci_sched_le(struct hci_dev *hdev) } } -if (hdev->le_pkts) - hdev->le_cnt = cnt; -else - hdev->acl_cnt = cnt; - -if (cnt != tmp) +if (*cnt != tmp)hci_prio_recalculate (hdev,LE_LINK ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 133/215 Bluetooth: SMP: Fix assumption of Central always being Initiator
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 28cd47f75185c4818b0fb1b46f2f02faaba96376 ]
SMP initiator role shall be considered the one that initiates the pairing procedure with SMP_CMD_PAIRING_REQ:
BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part H page 1557:
Figure 2.1: LE pairing phases
Note that by sending SMP_CMD_SECURITY_REQ it doesn't change the role to be Initiator.
--- net/bluetooth/smp.c | 144 ++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 72 deletions(-)
net/bluetooth/smp.c +72 -72
@@ -913,7 +913,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,* Confirms and the responder Enters the passkey. */ if (smp->method ==OVERLAP ) { -if (hcon->role ==HCI_ROLE_MASTER ) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) smp->method =CFM_PASSKEY ;else smp->method =REQ_PASSKEY ;
@@ -963,7 +963,7 @@ static u8 smp_confirm(struct smp_chan *smp)smp_send_cmd (smp->conn,SMP_CMD_PAIRING_CONFIRM ,sizeof (cp), &cp); -if (conn->hcon->out) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags))SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_CONFIRM );else SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RANDOM );
@@ -979,7 +979,8 @@ static u8 smp_random(struct smp_chan *smp)int ret;bt_dev_dbg (conn->hcon->hdev,"conn %p %s" , conn, - conn->hcon->out ?"initiator" :"responder" ); +test_bit (SMP_FLAG_INITIATOR , &smp->flags) ?"initiator" : +"responder" ); ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, hcon->init_addr_type, &hcon->init_addr,
@@ -993,7 +994,7 @@ static u8 smp_random(struct smp_chan *smp)return SMP_CONFIRM_FAILED ; } -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {u8 stk[16 ];__le64 rand =0 ;__le16 ediv =0 ;
@@ -1250,14 +1251,15 @@ static void smp_distribute_keys(struct smp_chan *smp) rsp = (void *) &smp->prsp[1 ];/* The responder sends its keys first */ -if (hcon->out && (smp->remote_key_dist &KEY_DIST_MASK )) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags) && + (smp->remote_key_dist &KEY_DIST_MASK )) {smp_allow_key_dist (smp);return ; } req = (void *) &smp->preq[1 ]; -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { keydist = &rsp->init_key_dist; *keydist &= req->init_key_dist; }else {
@@ -1426,7 +1428,7 @@ static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])struct hci_conn *hcon = smp->conn->hcon;u8 *na, *nb, a[7 ], b[7 ]; -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { na = smp->prnd; nb = smp->rrnd; }else {
@@ -1454,7 +1456,7 @@ static void sc_dhkey_check(struct smp_chan *smp) a[6 ] = hcon->init_addr_type; b[6 ] = hcon->resp_addr_type; -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { local_addr = a; remote_addr = b;memcpy (io_cap, &smp->preq[1 ],3 );
@@ -1533,7 +1535,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)/* The round is only complete when the initiator * receives pairing random. */ -if (!hcon->out) { +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);if (smp->passkey_round ==20 )
@@ -1561,7 +1563,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RANDOM ); -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);return 0 ;
@@ -1572,7 +1574,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)case SMP_CMD_PUBLIC_KEY :default :/* Initiating device starts the round */ -if (!hcon->out) +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags))return 0 ; bt_dev_dbg(hdev, "Starting passkey round %u",
@@ -1617,7 +1619,7 @@ static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) }/* Initiator sends DHKey check first */ -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {sc_dhkey_check (smp);SMP_ALLOW_CMD (smp,SMP_CMD_DHKEY_CHECK ); }else if (test_and_clear_bit (SMP_FLAG_DHKEY_PENDING , &smp->flags)) {
@@ -1740,7 +1742,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)struct smp_cmd_pairing rsp, *req = (void *) skb->data;struct l2cap_chan *chan = conn->smp;struct hci_dev *hdev = conn->hcon->hdev; -struct smp_chan *smp; +struct smp_chan *smp = chan->data;u8 key_size, auth, sec_level;int ret;
@@ -1749,16 +1751,14 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)if (skb->len <sizeof (*req))return SMP_INVALID_PARAMS ; -if (conn->hcon->role !=HCI_ROLE_SLAVE ) +if (smp &&test_bit (SMP_FLAG_INITIATOR , &smp->flags))return SMP_CMD_NOTSUPP ; -if (!chan->data) +if (!smp) { smp =smp_chan_create (conn); -else - smp = chan->data; - -if (!smp) -return SMP_UNSPECIFIED ; +if (!smp) +return SMP_UNSPECIFIED ; + }/* We didn't start the pairing, so match remote */ auth = req->auth_req &AUTH_REQ_MASK (hdev);
@@ -1940,7 +1940,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)if (skb->len <sizeof (*rsp))return SMP_INVALID_PARAMS ; -if (conn->hcon->role !=HCI_ROLE_MASTER ) +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags))return SMP_CMD_NOTSUPP ;skb_pull (skb,sizeof (*rsp));
@@ -2035,7 +2035,7 @@ static u8 sc_check_confirm(struct smp_chan *smp)if (smp->method ==REQ_PASSKEY || smp->method ==DSP_PASSKEY )return sc_passkey_round (smp,SMP_CMD_PAIRING_CONFIRM ); -if (conn->hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RANDOM );
@@ -2057,7 +2057,7 @@ static int fixup_sc_false_positive(struct smp_chan *smp)u8 auth;/* The issue is only observed when we're in responder role */ -if (hcon->out) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags))return SMP_UNSPECIFIED ;if (hci_dev_test_flag (hdev,HCI_SC_ONLY )) {
@@ -2093,7 +2093,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)struct hci_dev *hdev = hcon->hdev;bt_dev_dbg (hdev,"conn %p %s" , conn, - hcon->out ?"initiator" :"responder" ); +test_bit (SMP_FLAG_INITIATOR , &smp->flags) ?"initiator" : +"responder" );if (skb->len <sizeof (smp->pcnf))return SMP_INVALID_PARAMS ;
@@ -2115,7 +2116,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)return ret; } -if (conn->hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RANDOM );
@@ -2150,7 +2151,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)if (!test_bit (SMP_FLAG_SC , &smp->flags))return smp_random (smp); -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { pkax = smp->local_pk; pkbx = smp->remote_pk; na = smp->prnd;
@@ -2163,7 +2164,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) }if (smp->method ==REQ_OOB ) { -if (!hcon->out) +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags))smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);SMP_ALLOW_CMD (smp,SMP_CMD_DHKEY_CHECK );
@@ -2174,7 +2175,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)if (smp->method ==REQ_PASSKEY || smp->method ==DSP_PASSKEY )return sc_passkey_round (smp,SMP_CMD_PAIRING_RANDOM ); -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {u8 cfm[16 ]; err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
@@ -2215,7 +2216,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)return SMP_UNSPECIFIED ;if (smp->method ==REQ_OOB ) { -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {sc_dhkey_check (smp);SMP_ALLOW_CMD (smp,SMP_CMD_DHKEY_CHECK ); }
@@ -2289,10 +2290,27 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,return false; } +static void smp_send_pairing_req (struct smp_chan *smp,__u8 auth) +{ +struct smp_cmd_pairing cp; + +if (smp->conn->hcon->type ==ACL_LINK ) +build_bredr_pairing_cmd (smp, &cp,NULL ); +else +build_pairing_cmd (smp->conn, &cp,NULL , auth); + + smp->preq[0 ] =SMP_CMD_PAIRING_REQ ; +memcpy (&smp->preq[1 ], &cp,sizeof (cp)); + +smp_send_cmd (smp->conn,SMP_CMD_PAIRING_REQ ,sizeof (cp), &cp); +SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RSP ); + +set_bit (SMP_FLAG_INITIATOR , &smp->flags); +} +static u8 smp_cmd_security_req (struct l2cap_conn *conn,struct sk_buff *skb) {struct smp_cmd_security_req *rp = (void *) skb->data; -struct smp_cmd_pairing cp;struct hci_conn *hcon = conn->hcon;struct hci_dev *hdev = hcon->hdev;struct smp_chan *smp;
@@ -2341,16 +2359,20 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)skb_pull (skb,sizeof (*rp)); -memset (&cp,0 ,sizeof (cp)); -build_pairing_cmd (conn, &cp,NULL , auth); +smp_send_pairing_req (smp, auth); - smp->preq[0 ] =SMP_CMD_PAIRING_REQ ; -memcpy (&smp->preq[1 ], &cp,sizeof (cp)); +return 0 ; +} -smp_send_cmd (conn,SMP_CMD_PAIRING_REQ ,sizeof (cp), &cp); -SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RSP ); +static void smp_send_security_req (struct smp_chan *smp,__u8 auth) +{ +struct smp_cmd_security_req cp; -return 0 ; + cp.auth_req = auth; +smp_send_cmd (smp->conn,SMP_CMD_SECURITY_REQ ,sizeof (cp), &cp); +SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_REQ ); + +clear_bit (SMP_FLAG_INITIATOR , &smp->flags); }int smp_conn_security (struct hci_conn *hcon,__u8 sec_level)
@@ -2421,23 +2443,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) authreq |=SMP_AUTH_MITM ; } -if (hcon->role ==HCI_ROLE_MASTER ) { -struct smp_cmd_pairing cp; - -build_pairing_cmd (conn, &cp,NULL , authreq); - smp->preq[0 ] =SMP_CMD_PAIRING_REQ ; -memcpy (&smp->preq[1 ], &cp,sizeof (cp)); - -smp_send_cmd (conn,SMP_CMD_PAIRING_REQ ,sizeof (cp), &cp); -SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RSP ); - }else { -struct smp_cmd_security_req cp; - cp.auth_req = authreq; -smp_send_cmd (conn,SMP_CMD_SECURITY_REQ ,sizeof (cp), &cp); -SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_REQ ); - } +if (hcon->role ==HCI_ROLE_MASTER ) +smp_send_pairing_req (smp, authreq); +else +smp_send_security_req (smp, authreq); -set_bit (SMP_FLAG_INITIATOR , &smp->flags); ret =0 ; unlock:
@@ -2688,8 +2698,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)static u8 sc_select_method (struct smp_chan *smp) { -struct l2cap_conn *conn = smp->conn; -struct hci_conn *hcon = conn->hcon;struct smp_cmd_pairing *local, *remote;u8 local_mitm, remote_mitm, local_io, remote_io, method;
@@ -2702,7 +2710,7 @@ static u8 sc_select_method(struct smp_chan *smp)* the "struct smp_cmd_pairing" from them we need to skip the * first byte which contains the opcode. */ -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { local = (void *) &smp->preq[1 ]; remote = (void *) &smp->prsp[1 ]; }else {
@@ -2771,7 +2779,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)/* Non-initiating device sends its public key after receiving * the key from the initiating device. */ -if (!hcon->out) { +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { err =sc_send_public_key (smp);if (err)return err;
@@ -2833,7 +2841,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) }if (smp->method ==REQ_OOB ) { -if (hcon->out) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags))smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);
@@ -2842,7 +2850,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)return 0 ; } -if (hcon->out) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags))SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_CONFIRM );if (smp->method ==REQ_PASSKEY ) {
@@ -2857,7 +2865,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)/* The Initiating device waits for the non-initiating device to * send the confirm value. */ -if (conn->hcon->out) +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags))return 0 ; err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
@@ -2891,7 +2899,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) a[6 ] = hcon->init_addr_type; b[6 ] = hcon->resp_addr_type; -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) { local_addr = a; remote_addr = b;memcpy (io_cap, &smp->prsp[1 ],3 );
@@ -2916,7 +2924,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)if (crypto_memneq (check->e, e,16 ))return SMP_DHKEY_CHECK_FAILED ; -if (!hcon->out) { +if (!test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {if (test_bit (SMP_FLAG_WAIT_USER , &smp->flags)) {set_bit (SMP_FLAG_DHKEY_PENDING , &smp->flags);return 0 ;
@@ -2928,7 +2936,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)sc_add_ltk (smp); -if (hcon->out) { +if (test_bit (SMP_FLAG_INITIATOR , &smp->flags)) {hci_le_start_enc (hcon,0 ,0 , smp->tk, smp->enc_key_size); hcon->enc_key_size = smp->enc_key_size; }
@@ -3077,7 +3085,6 @@ static void bredr_pairing(struct l2cap_chan *chan)struct l2cap_conn *conn = chan->conn;struct hci_conn *hcon = conn->hcon;struct hci_dev *hdev = hcon->hdev; -struct smp_cmd_pairing req;struct smp_chan *smp;bt_dev_dbg (hdev,"chan %p" , chan);
@@ -3129,14 +3136,7 @@ static void bredr_pairing(struct l2cap_chan *chan)bt_dev_dbg (hdev,"starting SMP over BR/EDR" ); -/* Prepare and send the BR/EDR SMP Pairing Request */ -build_bredr_pairing_cmd (smp, &req,NULL ); - - smp->preq[0 ] =SMP_CMD_PAIRING_REQ ; -memcpy (&smp->preq[1 ], &req,sizeof (req)); - -smp_send_cmd (conn,SMP_CMD_PAIRING_REQ ,sizeof (req), &req); -SMP_ALLOW_CMD (smp,SMP_CMD_PAIRING_RSP ); +smp_send_pairing_req (smp,0x00 ); }static void smp_resume_cb (struct l2cap_chan *chan)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 134/215 tc-testing: dont access non-existent variable on exception
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit a0c9fe5eecc97680323ee83780ea3eaf440ba1b7 ]
Since commit 255c1c7279ab ("tc-testing: Allow test cases to be skipped") the variable test_ordinal doesn't exist in call_pre_case(). So it should not be accessed when an exception occurs.
This resolves the following splat:
...
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../tdc.py", line 1028, in <module>
main()
File ".../tdc.py", line 1022, in main
set_operation_mode(pm, parser, args, remaining)
File ".../tdc.py", line 966, in set_operation_mode
catresults = test_runner_serial(pm, args, alltests)
File ".../tdc.py", line 642, in test_runner_serial
(index, tsr) = test_runner(pm, args, alltests)
File ".../tdc.py", line 536, in test_runner
res = run_one_test(pm, args, index, tidx)
File ".../tdc.py", line 419, in run_one_test
pm.call_pre_case(tidx)
File ".../tdc.py", line 146, in call_pre_case
print('test_ordinal is {}'.format(test_ordinal)) NameError: name 'test_ordinal' is not defined
--- tools/testing/selftests/tc-testing/tdc.py | 1 - 1 file changed, 1 deletion(-)
tools/testing/selftests/tc-testing/tdc.py +0 -1
@@ -129,7 +129,6 @@ class PluginMgr: except Exception as ee: print('exception {} in call to pre_case for {} plugin'. format(ee, pgn_inst.__class__)) - print('test_ordinal is {}'.format(test_ordinal)) print('testid is {}'.format(caseinfo['id'])) raise
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 135/215 kcm: Serialise kcm_sendmsg() for the same socket.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 807067bf014d4a3ae2cc55bd3de16f22a01eb580 ]
syzkaller reported UAF in kcm_release(). [0]
The scenario is
1. Thread A builds a skb with MSG_MORE and sets kcm->seq_skb.
2. Thread A resumes building skb from kcm->seq_skb but is blocked by sk_stream_wait_memory()
3. Thread B calls sendmsg() concurrently, finishes building kcm->seq_skb and puts the skb to the write queue
4. Thread A faces an error and finally frees skb that is already in the write queue
5. kcm_release() does double-free the skb in the write queue
When a thread is building a MSG_MORE skb, another thread must not touch it.
Let's add a per-sk mutex and serialise kcm_sendmsg().
[0]:
BUG: KASAN: slab-use-after-free in __skb_unlink include/linux/skbuff.h:2366 [inline] BUG: KASAN: slab-use-after-free in __skb_dequeue include/linux/skbuff.h:2385 [inline] BUG: KASAN: slab-use-after-free in __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline] BUG: KASAN: slab-use-after-free in __skb_queue_purge include/linux/skbuff.h:3181 [inline] BUG: KASAN: slab-use-after-free in kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691 Read of size 8 at addr ffff0000ced0fc80 by task syz-executor329/6167 CPU: 1 PID: 6167 Comm: syz-executor329 Tainted: G B 6.8.0-rc5-syzkaller-g9abbc24128bc #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024 Call trace: dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:291 show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:298 __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd0/0x124 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:377 [inline] print_report+0x178/0x518 mm/kasan/report.c:488 kasan_report+0xd8/0x138 mm/kasan/report.c:601 __asan_report_load8_noabort+0x20/0x2c mm/kasan/report_generic.c:381 __skb_unlink include/linux/skbuff.h:2366 [inline] __skb_dequeue include/linux/skbuff.h:2385 [inline] __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline] __skb_queue_purge include/linux/skbuff.h:3181 [inline] kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691 __sock_release net/socket.c:659 [inline] sock_close+0xa4/0x1e8 net/socket.c:1421 __fput+0x30c/0x738 fs/file_table.c:376 ____fput+0x20/0x30 fs/file_table.c:404 task_work_run+0x230/0x2e0 kernel/task_work.c:180 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0x618/0x1f64 kernel/exit.c:871 do_group_exit+0x194/0x22c kernel/exit.c:1020 get_signal+0x1500/0x15ec kernel/signal.c:2893 do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249 do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148 exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline] exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline] el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 Allocated by task 6166: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_alloc_info+0x70/0x84 mm/kasan/generic.c:626 unpoison_slab_object mm/kasan/common.c:314 [inline] __kasan_slab_alloc+0x74/0x8c mm/kasan/common.c:340 kasan_slab_alloc include/linux/kasan.h:201 [inline] slab_post_alloc_hook mm/slub.c:3813 [inline] slab_alloc_node mm/slub.c:3860 [inline] kmem_cache_alloc_node+0x204/0x4c0 mm/slub.c:3903 __alloc_skb+0x19c/0x3d8 net/core/skbuff.c:641 alloc_skb include/linux/skbuff.h:1296 [inline] kcm_sendmsg+0x1d3c/0x2124 net/kcm/kcmsock.c:783 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] sock_sendmsg+0x220/0x2c0 net/socket.c:768 splice_to_socket+0x7cc/0xd58 fs/splice.c:889 do_splice_from fs/splice.c:941 [inline] direct_splice_actor+0xec/0x1d8 fs/splice.c:1164 splice_direct_to_actor+0x438/0xa0c fs/splice.c:1108 do_splice_direct_actor fs/splice.c:1207 [inline] do_splice_direct+0x1e4/0x304 fs/splice.c:1233 do_sendfile+0x460/0xb3c fs/read_write.c:1295 __do_sys_sendfile64 fs/read_write.c:1362 [inline] __se_sys_sendfile64 fs/read_write.c:1348 [inline] __arm64_sys_sendfile64+0x160/0x3b4 fs/read_write.c:1348 __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 Freed by task 6167: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_free_info+0x5c/0x74 mm/kasan/generic.c:640 poison_slab_object+0x124/0x18c mm/kasan/common.c:241 __kasan_slab_free+0x3c/0x78 mm/kasan/common.c:257 kasan_slab_free include/linux/kasan.h:184 [inline] slab_free_hook mm/slub.c:2121 [inline] slab_free mm/slub.c:4299 [inline] kmem_cache_free+0x15c/0x3d4 mm/slub.c:4363 kfree_skbmem+0x10c/0x19c __kfree_skb net/core/skbuff.c:1109 [inline] kfree_skb_reason+0x240/0x6f4 net/core/skbuff.c:1144 kfree_skb include/linux/skbuff.h:1244 [inline] kcm_release+0x104/0x4c8 net/kcm/kcmsock.c:1685 __sock_release net/socket.c:659 [inline] sock_close+0xa4/0x1e8 net/socket.c:1421 __fput+0x30c/0x738 fs/file_table.c:376 ____fput+0x20/0x30 fs/file_table.c:404 task_work_run+0x230/0x2e0 kernel/task_work.c:180 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0x618/0x1f64 kernel/exit.c:871 do_group_exit+0x194/0x22c kernel/exit.c:1020 get_signal+0x1500/0x15ec kernel/signal.c:2893 do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249 do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148 exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline] exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline] el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 The buggy address belongs to the object at ffff0000ced0fc80 which belongs to the cache skbuff_head_cache of size 240
The buggy address is located 0 bytes inside of
freed 240-byte region [ffff0000ced0fc80, ffff0000ced0fd70)
The buggy address belongs to the physical page:
page:00000000d35f4ae4 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10ed0f
flags: 0x5ffc00000000800(slab|node=0|zone=2|lastcpupid=0x7ff)
page_type: 0xffffffff()
raw: 05ffc00000000800 ffff0000c1cbf640 fffffdffc3423100 dead000000000004
raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff0000ced0fb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff0000ced0fc00: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
>ffff0000ced0fc80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff0000ced0fd00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc
ffff0000ced0fd80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb--- include/net/kcm.h | 1 + net/kcm/kcmsock.c | 4 ++++ 2 files changed, 5 insertions(+)
include/net/kcm.h +1 -0
@@ -70,6 +70,7 @@ struct kcm_sock {struct work_struct tx_work;struct list_head wait_psock_list;struct sk_buff *seq_skb; +struct mutex tx_mutex; u32 tx_stopped : 1;/* Don't use bit fields here, these are set under different locks */
net/kcm/kcmsock.c +4 -0
@@ -911,6 +911,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) !(msg->msg_flags & MSG_MORE) : !!(msg->msg_flags & MSG_EOR);int err = -EPIPE ; +mutex_lock (&kcm->tx_mutex);lock_sock (sk);/* Per tcp_sendmsg this should be in poll */
@@ -1059,6 +1060,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)KCM_STATS_ADD (kcm->stats.tx_bytes, copied);release_sock (sk); +mutex_unlock (&kcm->tx_mutex);return copied; out_error:
@@ -1084,6 +1086,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) sk->sk_write_space (sk);release_sock (sk); +mutex_unlock (&kcm->tx_mutex);return err; }
@@ -1326,6 +1329,7 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux)spin_unlock_bh (&mux->lock);INIT_WORK (&kcm->tx_work, kcm_tx_work); +mutex_init (&kcm->tx_mutex);spin_lock_bh (&mux->rx_lock);kcm_rcv_ready (kcm);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 136/215 netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 1eacdd71b3436b54d5fc8218c4bb0187d92a6892 ]
The sequence counter nft_counter_seq is a per-CPU counter. There is no lock associated with it. nft_counter_do_eval() is using the same counter and disables BH which suggest that it can be invoked from a softirq. This in turn means that nft_counter_offload_stats(), which disables only preemption, can be interrupted by nft_counter_do_eval() leading to two writer for one seqcount_t.
This can lead to loosing stats or reading statistics while they are updated.
Disable BH during stats update in nft_counter_offload_stats() to ensure one writer at a time.
--- net/netfilter/nft_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nft_counter.c +2 -2
@@ -264,7 +264,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr,struct nft_counter *this_cpu;seqcount_t *myseq; -preempt_disable (); +local_bh_disable (); this_cpu =this_cpu_ptr (priv->counter); myseq =this_cpu_ptr (&nft_counter_seq);
@@ -272,7 +272,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr, this_cpu->packets += stats->pkts; this_cpu->bytes += stats->bytes;write_seqcount_end (myseq); -preempt_enable (); +local_bh_enable (); }static struct nft_expr_type nft_counter_type;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 137/215 netfilter: nft_counter: Synchronize nft_counter_reset() against reader.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit a0b39e2dc7017ac667b70bdeee5293e410fab2fb ]
nft_counter_reset() resets the counter by subtracting the previously retrieved value from the counter. This is a write operation on the counter and as such it requires to be performed with a write sequence of nft_counter_seq to serialize against its possible reader.
Update the packets/ bytes within write-sequence of nft_counter_seq.
--- net/netfilter/nft_counter.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netfilter/nft_counter.c +5 -0
@@ -106,11 +106,16 @@ static void nft_counter_reset(struct nft_counter_percpu_priv *priv, struct nft_counter *total) {struct nft_counter *this_cpu; +seqcount_t *myseq;local_bh_disable (); this_cpu =this_cpu_ptr (priv->counter); + myseq =this_cpu_ptr (&nft_counter_seq); + +write_seqcount_begin (myseq); this_cpu->packets -= total->packets; this_cpu->bytes -= total->bytes; +write_seqcount_end (myseq);local_bh_enable (); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 138/215 ip6_tunnel: Fix broken GRO
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Bogendoerfer <[email protected]>
[ Upstream commit 4b3e33fcc38f7750604b065c55a43e94c5bc3145 ]
GRO code checks for matching layer 2 headers to see, if packet belongs to the same flow and because ip6 tunnel set dev->hard_header_len this check fails in cases, where it shouldn't. To fix this don't set hard_header_len, but use needed_headroom like ipv4/ip_tunnel.c does.
--- net/ipv6/ip6_tunnel.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
net/ipv6/ip6_tunnel.c +7 -5
@@ -1501,7 +1501,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) tdev =__dev_get_by_index (t->net, p->link);if (tdev) { - dev->hard_header_len = tdev->hard_header_len + t_hlen; + dev->needed_headroom = tdev->hard_header_len + + tdev->needed_headroom + t_hlen; mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU); mtu = mtu - t_hlen;
@@ -1729,7 +1730,9 @@ ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr,int ip6_tnl_change_mtu (struct net_device *dev,int new_mtu) {struct ip6_tnl *tnl =netdev_priv (dev); +int t_hlen; + t_hlen = tnl->hlen +sizeof (struct ipv6hdr );if (tnl->parms.proto ==IPPROTO_IPV6 ) {if (new_mtu <IPV6_MIN_MTU )return -EINVAL ;
@@ -1738,10 +1741,10 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)return -EINVAL ; }if (tnl->parms.proto ==IPPROTO_IPV6 || tnl->parms.proto ==0 ) { -if (new_mtu >IP6_MAX_MTU - dev->hard_header_len) +if (new_mtu >IP6_MAX_MTU - dev->hard_header_len - t_hlen)return -EINVAL ; }else { -if (new_mtu >IP_MAX_MTU - dev->hard_header_len) +if (new_mtu >IP_MAX_MTU - dev->hard_header_len - t_hlen)return -EINVAL ; } dev->mtu = new_mtu;
@@ -1887,12 +1890,11 @@ ip6_tnl_dev_init_gen(struct net_device *dev) t_hlen = t->hlen +sizeof (struct ipv6hdr ); dev->type =ARPHRD_TUNNEL6 ; - dev->hard_header_len =LL_MAX_HEADER + t_hlen; dev->mtu =ETH_DATA_LEN - t_hlen;if (!(t->parms.flags &IP6_TNL_F_IGN_ENCAP_LIMIT )) dev->mtu -=8 ; dev->min_mtu =ETH_MIN_MTU ; - dev->max_mtu =IP6_MAX_MTU - dev->hard_header_len; + dev->max_mtu =IP6_MAX_MTU - dev->hard_header_len - t_hlen;dev_hold (dev);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 139/215 bonding: fix bond_ipsec_offload_ok return type
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit fc59b9a5f7201b9f7272944596113a82cc7773d5 ]
Fix the return type which should be bool.
--- drivers/net/bonding/bond_main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
drivers/net/bonding/bond_main.c +6 -12
@@ -592,34 +592,28 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)struct net_device *real_dev;struct slave *curr_active;struct bonding *bond; -int err; +bool ok = false; bond =netdev_priv (bond_dev);rcu_read_lock (); curr_active =rcu_dereference (bond->curr_active_slave); real_dev = curr_active->dev; -if (BOND_MODE (bond) !=BOND_MODE_ACTIVEBACKUP ) { - err = false; +if (BOND_MODE (bond) !=BOND_MODE_ACTIVEBACKUP ) goto out; - } -if (!xs->xso.real_dev) { - err = false; +if (!xs->xso.real_dev) goto out; - }if (!real_dev->xfrmdev_ops || !real_dev->xfrmdev_ops->xdo_dev_offload_ok || -netif_is_bond_master (real_dev)) { - err = false; +netif_is_bond_master (real_dev)) goto out; - } - err = real_dev->xfrmdev_ops->xdo_dev_offload_ok (skb, xs); + ok = real_dev->xfrmdev_ops->xdo_dev_offload_ok (skb, xs); out:rcu_read_unlock (); -return err; +return ok; }static const struct xfrmdev_ops bond_xfrmdev_ops = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 140/215 bonding: fix null pointer deref in bond_ipsec_offload_ok
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 95c90e4ad89d493a7a14fa200082e466e2548f9d ]
We must check if there is an active slave before dereferencing the pointer.
--- drivers/net/bonding/bond_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/bonding/bond_main.c +2 -0
@@ -597,6 +597,8 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) bond =netdev_priv (bond_dev);rcu_read_lock (); curr_active =rcu_dereference (bond->curr_active_slave); +if (!curr_active) + goto out; real_dev = curr_active->dev;if (BOND_MODE (bond) !=BOND_MODE_ACTIVEBACKUP )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 141/215 bonding: fix xfrm real_dev null pointer dereference
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit f8cde9805981c50d0c029063dc7d82821806fc44 ]
We shouldn't set real_dev to NULL because packets can be in transit and xfrm might call xdo_dev_offload_ok() in parallel. All callbacks assume real_dev is set.
Example trace:
kernel: BUG: unable to handle page fault for address: 0000000000001030
kernel: bond0: (slave eni0np1): making interface the new active one
kernel: #PF: supervisor write access in kernel mode
kernel: #PF: error_code(0x0002) - not-present page
kernel: PGD 0 P4D 0
kernel: Oops: 0002 [#1] PREEMPT SMP
kernel: CPU: 4 PID: 2237 Comm: ping Not tainted 6.7.7+ #12
kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014
kernel: RIP: 0010:nsim_ipsec_offload_ok+0xc/0x20 [netdevsim]
kernel: bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
kernel: Code: e0 0f 0b 48 83 7f 38 00 74 de 0f 0b 48 8b 47 08 48 8b 37 48 8b 78 40 e9 b2 e5 9a d7 66 90 0f 1f 44 00 00 48 8b 86 80 02 00 00 <83> 80 30 10 00 00 01 b8 01 00 00 00 c3 0f 1f 80 00 00 00 00 0f 1f
kernel: bond0: (slave eni0np1): making interface the new active one
kernel: RSP: 0018:ffffabde81553b98 EFLAGS: 00010246
kernel: bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
kernel:
kernel: RAX: 0000000000000000 RBX: ffff9eb404e74900 RCX: ffff9eb403d97c60
kernel: RDX: ffffffffc090de10 RSI: ffff9eb404e74900 RDI: ffff9eb3c5de9e00
kernel: RBP: ffff9eb3c0a42000 R08: 0000000000000010 R09: 0000000000000014
kernel: R10: 7974203030303030 R11: 3030303030303030 R12: 0000000000000000
kernel: R13: ffff9eb3c5de9e00 R14: ffffabde81553cc8 R15: ffff9eb404c53000
kernel: FS: 00007f2a77a3ad00(0000) GS:ffff9eb43bd00000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000001030 CR3: 00000001122ab000 CR4: 0000000000350ef0
kernel: bond0: (slave eni0np1): making interface the new active one
kernel: Call Trace:
kernel: <TASK>
kernel: ? __die+0x1f/0x60
kernel: bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
kernel: ? page_fault_oops+0x142/0x4c0 kernel: ? do_user_addr_fault+0x65/0x670 kernel: ? kvm_read_and_reset_apf_flags+0x3b/0x50 kernel: bond0: (slave eni0np1): making interface the new active one kernel: ? exc_page_fault+0x7b/0x180 kernel: ? asm_exc_page_fault+0x22/0x30 kernel: ? nsim_bpf_uninit+0x50/0x50 [netdevsim]
kernel: bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
kernel: ? nsim_ipsec_offload_ok+0xc/0x20 [netdevsim]
kernel: bond0: (slave eni0np1): making interface the new active one
kernel: bond_ipsec_offload_ok+0x7b/0x90 [bonding]
kernel: xfrm_output+0x61/0x3b0
kernel: bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
kernel: ip_push_pending_frames+0x56/0x80
--- drivers/net/bonding/bond_main.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/bonding/bond_main.c +0 -1
@@ -575,7 +575,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) }else { slave->dev->xfrmdev_ops->xdo_dev_state_delete (ipsec->xs); } - ipsec->xs->xso.real_dev =NULL ; }spin_unlock_bh (&bond->ipsec_lock);rcu_read_unlock ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 142/215 bonding: fix xfrm state handling when clearing active slave
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit c4c5c5d2ef40a9f67a9241dc5422eac9ffe19547 ]
If the active slave is cleared manually the xfrm state is not flushed. This leads to xfrm add/del imbalance and adding the same state multiple times. For example when the device cannot handle anymore states we get:
[ 1169.884811] bond0: (slave eni0np1): bond_ipsec_add_sa_all: failed to add SA
because it's filled with the same state after multiple active slave clearings. This change also has a few nice side effects: user-space gets a notification for the change, the old device gets its mac address and promisc/mcast adjusted properly.
--- drivers/net/bonding/bond_options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/bonding/bond_options.c +1 -1
@@ -893,7 +893,7 @@ static int bond_option_active_slave_set(struct bonding *bond,/* check to see if we are clearing active */ if (!slave_dev) {netdev_dbg (bond->dev,"Clearing current active slave\n" ); -RCU_INIT_POINTER (bond->curr_active_slave,NULL ); +bond_change_active_slave (bond,NULL );bond_select_active_slave (bond); }else {struct slave *old_active =rtnl_dereference (bond->curr_active_slave);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 143/215 ice: fix ICE_LAST_OFFSET formula
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej Fijalkowski <[email protected]>
[ Upstream commit b966ad832942b5a11e002f9b5ef102b08425b84a ]
For bigger PAGE_SIZE archs, ice driver works on 3k Rx buffers. Therefore, ICE_LAST_OFFSET should take into account ICE_RXBUF_3072, not ICE_RXBUF_2048.
--- drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_txrx.c +1 -1
@@ -765,7 +765,7 @@ ice_can_reuse_rx_page(struct ice_rx_buf *rx_buf, int rx_buf_pgcnt)return false;#else #define ICE_LAST_OFFSET \ - (SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_2048) + (SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_3072)if (rx_buf->page_offset >ICE_LAST_OFFSET )return false;#endif /* PAGE_SIZE < 8192) */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 144/215 dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit c50e7475961c36ec4d21d60af055b32f9436b431 ]
The dpaa2_switch_add_bufs() function returns the number of bufs that it was able to add. It returns BUFS_PER_CMD (7) for complete success or a smaller number if there are not enough pages available. However, the error checking is looking at the total number of bufs instead of the number which were added on this iteration. Thus the error checking only works correctly for the first iteration through the loop and subsequent iterations are always counted as a success.
Fix this by checking only the bufs added in the current iteration.
--- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +4 -3
@@ -2585,13 +2585,14 @@ static int dpaa2_switch_refill_bp(struct ethsw_core *ethsw)static int dpaa2_switch_seed_bp (struct ethsw_core *ethsw) { -int *count, i; +int *count, ret, i;for (i =0 ; i <DPAA2_ETHSW_NUM_BUFS ; i +=BUFS_PER_CMD ) { + ret =dpaa2_switch_add_bufs (ethsw, ethsw->bpid); count = ðsw->buf_count; - *count +=dpaa2_switch_add_bufs (ethsw, ethsw->bpid); + *count += ret; -if (unlikely (*count <BUFS_PER_CMD )) +if (unlikely (ret <BUFS_PER_CMD ))return -ENOMEM ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 145/215 net: dsa: mv88e6xxx: read FID when handling ATU violations
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans J. Schultz <[email protected]>
[ Upstream commit 4bf24ad09bc0b05e97fb48b962b2c9246fc76727 ]
When an ATU violation occurs, the switch uses the ATU FID register to report the FID of the MAC address that incurred the violation. It would be good for the driver to know the FID value for purposes such as logging and CPU-based authentication.
Up until now, the driver has been calling the mv88e6xxx_g1_atu_op() function to read ATU violations, but that doesn't do exactly what we want, namely it calls mv88e6xxx_g1_atu_fid_write() with FID 0. (side note, the documentation for the ATU Get/Clear Violation command says that writes to the ATU FID register have no effect before the operation starts, it's only that we disregard the value that this register provides once the operation completes)
So mv88e6xxx_g1_atu_fid_write() is not what we want, but rather mv88e6xxx_g1_atu_fid_read(). However, the latter doesn't exist, we need to write it.
The remainder of mv88e6xxx_g1_atu_op() except for mv88e6xxx_g1_atu_fid_write() is still needed, namely to send a GET_CLR_VIOLATION command to the ATU. In principle we could have still kept calling mv88e6xxx_g1_atu_op(), but the MDIO writes to the ATU FID register are pointless, but in the interest of doing less CPU work per interrupt, write a new function called mv88e6xxx_g1_read_atu_violation() and call it.
The FID will be the port default FID as set by mv88e6xxx_port_set_fid() if the VID from the packet cannot be found in the VTU. Otherwise it is the FID derived from the VTU entry associated with that VID.
Stable-dep-of: 528876d867a2 ("net: dsa: mv88e6xxx: Fix out-of-bound access")
--- drivers/net/dsa/mv88e6xxx/global1_atu.c | 72 +++++++++++++++++++++---- 1 file changed, 61 insertions(+), 11 deletions(-)
drivers/net/dsa/mv88e6xxx/global1_atu.c +61 -11
@@ -114,6 +114,19 @@ static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)return mv88e6xxx_g1_wait_bit (chip,MV88E6XXX_G1_ATU_OP , bit,0 ); } +static int mv88e6xxx_g1_read_atu_violation (struct mv88e6xxx_chip *chip) +{ +int err; + + err =mv88e6xxx_g1_write (chip,MV88E6XXX_G1_ATU_OP , +MV88E6XXX_G1_ATU_OP_BUSY | +MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION ); +if (err) +return err; + +return mv88e6xxx_g1_atu_op_wait (chip); +} +static int mv88e6xxx_g1_atu_op (struct mv88e6xxx_chip *chip,u16 fid,u16 op) {u16 val;
@@ -159,6 +172,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)return mv88e6xxx_g1_atu_op (chip, fid,MV88E6XXX_G1_ATU_OP_GET_NEXT_DB ); } +static int mv88e6xxx_g1_atu_fid_read (struct mv88e6xxx_chip *chip,u16 *fid) +{ +u16 val =0 , upper =0 , op =0 ; +int err = -EOPNOTSUPP ; + +if (mv88e6xxx_num_databases (chip) >256 ) { + err =mv88e6xxx_g1_read (chip,MV88E6352_G1_ATU_FID , &val); + val &=0xfff ; +if (err) +return err; + }else { + err =mv88e6xxx_g1_read (chip,MV88E6XXX_G1_ATU_OP , &op); +if (err) +return err; +if (mv88e6xxx_num_databases (chip) >64 ) { +/* ATU DBNum[7:4] are located in ATU Control 15:12 */ + err =mv88e6xxx_g1_read (chip,MV88E6XXX_G1_ATU_CTL , + &upper); +if (err) +return err; + + upper = (upper >>8 ) &0x00f0 ; + }else if (mv88e6xxx_num_databases (chip) >16 ) { +/* ATU DBNum[5:4] are located in ATU Operation 9:8 */ + upper = (op >>4 ) &0x30 ; + } + +/* ATU DBNum[3:0] are located in ATU Operation 3:0 */ + val = (op &0xf ) | upper; + } + *fid = val; + +return err; +} +/* Offset 0x0C: ATU Data Register */ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
@@ -353,14 +401,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id) {struct mv88e6xxx_chip *chip = dev_id;struct mv88e6xxx_atu_entry entry; -int spid; -int err; -u16 val; +int err, spid; +u16 val, fid;mv88e6xxx_reg_lock (chip); - err =mv88e6xxx_g1_atu_op (chip,0 , -MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION ); + err =mv88e6xxx_g1_read_atu_violation (chip);if (err) goto out;
@@ -368,6 +414,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)if (err) goto out; + err =mv88e6xxx_g1_atu_fid_read (chip, &fid); +if (err) + goto out; + err =mv88e6xxx_g1_atu_data_read (chip, &entry);if (err) goto out;
@@ -386,22 +436,22 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)if (val &MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU member violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU member violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_member_violation++; }if (val &MV88E6XXX_G1_ATU_OP_MISS_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU miss violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU miss violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_miss_violation++; }if (val &MV88E6XXX_G1_ATU_OP_FULL_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU full violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU full violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_full_violation++; }mv88e6xxx_reg_unlock (chip);
Signature · 1 line
2.43.0