6.18.14-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainercover 6.18.14-rc1 review
This is the start of the stable review cycle for the 6.18.14 release. There are 641 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 27 Feb 2026 01:22: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/v6.x/stable-review/patch-6.18.14-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.18.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.18.14-rc1
Huacai Chen <[email protected]>
net: stmmac: dwmac-loongson: Set clk_csr_i to 100-150MHz
Ivan Lipski <[email protected]>
drm/amd/display: Clear HDMI HPD pending work only if it is enabled
Martin KaFai Lau <[email protected]>
selftests/bpf: Test bpf_skb_check_mtu(BPF_MTU_CHK_SEGS) when transport_header is not set
Joanne Koong <[email protected]>
io_uring/rsrc: clean up buffer cloning arg validation
Jan Kiszka <[email protected]>
Drivers: hv: vmbus: Use kthread for vmbus interrupts on PREEMPT_RT
Jeongjun Park <[email protected]>
drm/exynos: vidi: fix to avoid directly dereferencing user pointer
Jeongjun Park <[email protected]>
drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl()
Lewis Mason <[email protected]>
ALSA: hda/realtek: Add quirk for Samsung Galaxy Book3 Pro 360 (NP965QFG)
Takashi Iwai <[email protected]>
ALSA: hda/conexant: Fix headphone jack handling on Acer Swift SF314
Eric Naim <[email protected]>
ALSA: hda/realtek: Add quirk for Gigabyte G5 KF5 (2023)
Shengjiu Wang <[email protected]>
ASoC: dt-bindings: asahi-kasei,ak5558: Fix the supply names
Shengjiu Wang <[email protected]>
ASoC: dt-bindings: asahi-kasei,ak4458: Fix the supply names
Shengjiu Wang <[email protected]>
ASoC: dt-bindings: asahi-kasei,ak4458: set unevaluatedProperties:false
Vikram Sharma <[email protected]>
dt-bindings: media: qcom,qcs8300-camss: Add missing power supplies
Abel Vesa <[email protected]>
dt-bindings: phy: qcom-edp: Add missing clock for X Elite
Daniel Hodges <[email protected]>
SUNRPC: fix gss_auth kref leak in gss_alloc_msg error path
Chuck Lever <[email protected]>
SUNRPC: auth_gss: fix memory leaks in XDR decoding error paths
Damien Le Moal <[email protected]>
ata: libata-scsi: avoid Non-NCQ command starvation
Damien Le Moal <[email protected]>
ata: libata-scsi: refactor ata_scsi_translate()
Linus Walleij <[email protected]>
ata: pata_ftide010: Fix some DMA timings
Jan Kara <[email protected]>
ext4: use optimized mballoc scanning regardless of inode format
Jan Kara <[email protected]>
ext4: always allocate blocks only from groups inode can use
Brian Foster <[email protected]>
ext4: fix dirtyclusters double decrement on fs shutdown
Yongjian Sun <[email protected]>
ext4: fix e4b bitmap inconsistency reports
Zilin Guan <[email protected]>
ext4: fix memory leak in ext4_ext_shift_extents()
Zhang Yi <[email protected]>
ext4: drop extent cache when splitting extent fails
Zhang Yi <[email protected]>
ext4: drop extent cache after doing PARTIAL_VALID1 zeroout
Zhang Yi <[email protected]>
ext4: don't cache extent during splitting extent
Zhang Yi <[email protected]>
ext4: don't zero the entire extent if EXT4_EXT_DATA_PARTIAL_VALID1
Zhang Yi <[email protected]>
ext4: subdivide EXT4_EXT_DATA_VALID1
Yao Zi <[email protected]>
MIPS: Work around LLVM bug when gp is used as global register variable
Thomas Richard (TI) <[email protected]>
usb: cdns3: fix role switching during resume
Mario Kleiner <[email protected]>
drm/amd/display: Use same max plane scaling limits for all 64 bpp formats
Detlev Casanova <[email protected]>
ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
Ethan Tidmore <[email protected]>
x86/hyperv: Fix error pointer dereference
Filipe Manana <[email protected]>
btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not found
Filipe Manana <[email protected]>
btrfs: use the correct type to initialize block reserve for delayed refs
Jiasheng Jiang <[email protected]>
btrfs: reset block group size class when it becomes empty
Filipe Manana <[email protected]>
btrfs: reduce block group critical section in btrfs_free_reserved_bytes()
Filipe Manana <[email protected]>
btrfs: remove fs_info argument from btrfs_try_granting_tickets()
Kiryl Shutsemau (Meta) <[email protected]>
efi: Fix reservation of unaccepted memory table
Dmitry Torokhov <[email protected]>
gpio: amd-fch: ionly return allowed values from amd_fch_gpio_get()
Raag Jadav <[email protected]>
drm/xe/bo: Redirect faults to dummy page for wedged device
Shuicheng Lin <[email protected]>
drm/xe: Make xe_modparam.force_vram_bar_size signed
Matt Roper <[email protected]>
drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138
Shuicheng Lin <[email protected]>
drm/xe/mmio: Avoid double-adjust in 64-bit reads
Michal Wajdeczko <[email protected]>
drm/xe/configfs: Fix 'parameter name omitted' errors
Alexander Egorenkov <[email protected]>
s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
Felix Gu <[email protected]>
spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()
Srinivasan Shanmugam <[email protected]>
drm/amd/display: Fix out-of-bounds stream encoder index v3
Timur Kristóf <[email protected]>
drm/amd/display: Reject cursor plane on DCE when scaled differently than primary
Srinivasan Shanmugam <[email protected]>
drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
Kai-Heng Feng <[email protected]>
PCI: Validate window resource type in pbus_select_window_for_type()
Alexandre Ferrieux <[email protected]>
ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init
Kaushlendra Kumar <[email protected]>
drm/i915/acpi: free _DSM package when no connectors
Ziyi Guo <[email protected]>
ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
Li RongQing <[email protected]>
mshv: fix SRCU protection in irqfd resampler ack handler
Alex Deucher <[email protected]>
drm/amdgpu/sdma6: enable queue resets unconditionally
Alex Deucher <[email protected]>
drm/amdgpu/sdma5.2: enable queue resets unconditionally
Alex Deucher <[email protected]>
drm/amdgpu/sdma5: enable queue resets unconditionally
Alex Deucher <[email protected]>
drm/amdgpu: move reset debug disable handling
Zilin Guan <[email protected]>
drm/amdgpu: Fix memory leak in amdgpu_ras_init()
Zilin Guan <[email protected]>
drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()
Zilin Guan <[email protected]>
drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc()
John Johansen <[email protected]>
apparmor: fix aa_label to return state from compount and component match
Georgia Garcia <[email protected]>
apparmor: fix invalid deref of rawdata when export_binary is unset
Zhengmian Hu <[email protected]>
apparmor: avoid per-cpu hold underflow in aa_get_buffer
John Johansen <[email protected]>
apparmor: make label_match return a consistent value
John Johansen <[email protected]>
apparmor: remove apply_modes_to_perms from label_match
John Johansen <[email protected]>
apparmor: fix rlimit for posix cpu timers
John Johansen <[email protected]>
apparmor: move check for aa_null file to cover all cases
Ryan Lee <[email protected]>
apparmor: account for in_atomic removal in common_file_perm
John Johansen <[email protected]>
apparmor: drop in_atomic flag in common_mmap, and common_file_perm
Ryan Lee <[email protected]>
apparmor: fix boolean argument in apparmor_mmap_file
Ryan Lee <[email protected]>
apparmor: return -ENOMEM in unpack_perms_table upon alloc failure
Helge Deller <[email protected]>
apparmor: Fix & Optimize table creation from possibly unaligned memory
Helge Deller <[email protected]>
AppArmor: Allow apparmor to handle unaligned dfa tables
John Johansen <[email protected]>
apparmor: fix NULL sock in aa_sock_file_perm
System Administrator <root@localhost>
apparmor: fix NULL pointer dereference in __unix_needs_revalidation
Cosmin Ratiu <[email protected]>
net/mlx5e: Use unsigned for mlx5e_get_max_num_channels
Cosmin Ratiu <[email protected]>
net/mlx5e: Fix deadlocks between devlink and netdev instance locks
Gal Pressman <[email protected]>
net/mlx5: Fix misidentification of write combining CQE during poll loop
Shay Drory <[email protected]>
net/mlx5: Fix multiport device check over light SFs
Hangbin Liu <[email protected]>
bonding: alb: fix UAF in rlb_arp_recv during bond up/down
Vikas Gupta <[email protected]>
bnge: fix reserving resources from FW
Dimitri Daskalakis <[email protected]>
eth: fbnic: Advertise supported XDP features.
Hariprasad Kelam <[email protected]>
octeontx2-af: Fix default entries mcam entry action
Eric Dumazet <[email protected]>
ipv6: icmp: remove obsolete code in icmpv6_xrlim_allow()
Eric Dumazet <[email protected]>
inet: move icmp_global_{credit,stamp} to a separate cache line
Eric Dumazet <[email protected]>
icmp: prevent possible overflow in icmp_global_allow()
Dimitri Daskalakis <[email protected]>
eth: fbnic: Add validation for MTU changes
Eric Dumazet <[email protected]>
macvlan: observe an RCU grace period in macvlan_common_newlink() error path
Jakub Kicinski <[email protected]>
selftests: tc_actions: don't dump 2MB of \0 to stdout
Eric Dumazet <[email protected]>
ping: annotate data-races in ping_lookup()
Arnd Bergmann <[email protected]>
net: psp: select CONFIG_SKB_EXTENSIONS
Jakub Kicinski <[email protected]>
bpftool: Fix truncated netlink dumps
Eric Dumazet <[email protected]>
ipv6: fix a race in ip6_sock_set_v6only()
Inseo An <[email protected]>
netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
Pablo Neira Ayuso <[email protected]>
net: remove WARN_ON_ONCE when accessing forward path array
Julian Anastasov <[email protected]>
ipvs: do not keep dest_dst if dev is going down
Florian Westphal <[email protected]>
netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
Aleksei Oladko <[email protected]>
selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with br_netfilter enabled
Aleksei Oladko <[email protected]>
selftests: forwarding: vxlan_bridge_1d: fix test failure with br_netfilter enabled
Nikolay Aleksandrov <[email protected]>
net: bridge: mcast: always update mdb_n_entries for vlan contexts
Allison Henderson <[email protected]>
net/rds: rds_sendmsg should not discard payload_len
Ziyi Guo <[email protected]>
xen-netback: reject zero-queue configuration from guest
Ziyi Guo <[email protected]>
net: usb: catc: enable basic endpoint checking
Antonio Quartulli <[email protected]>
ovpn: tcp - don't deref NULL sk_socket member after tcp_close()
Bobby Eshleman <[email protected]>
eth: fbnic: set DMA_HINT_L4 for all flows
Bobby Eshleman <[email protected]>
eth: fbnic: increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes
Bobby Eshleman <[email protected]>
eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0
Mohsin Bashir <[email protected]>
eth: fbnic: Configure RDE settings for pause frame
Anton Protopopov <[email protected]>
bpf: Add a map/btf from a fd array more consistently
Anton Protopopov <[email protected]>
bpf: Fix a potential use-after-free of BTF object
Amery Hung <[email protected]>
libbpf: Fix invalid write loop logic in bpf_linker__add_buf()
Chengfeng Ye <[email protected]>
fbnic: close fw_log race between users and teardown
Daniel Machon <[email protected]>
net: sparx5/lan969x: fix PTP clock max_adj value
Kuniyuki Iwashima <[email protected]>
ipv6: Fix out-of-bound access in fib6_add_rt2node().
Pin-yen Lin <[email protected]>
selftests: netconsole: Increase port listening timeout
Andre Carvalho <[email protected]>
selftests: netconsole: remove log noise due to socat exit
Ziyi Guo <[email protected]>
net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()
Ziyi Guo <[email protected]>
net: mscc: ocelot: split xmit into FDMA and register injection paths
Ziyi Guo <[email protected]>
net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
Daniel Machon <[email protected]>
net: sparx5/lan969x: fix DWRR cost max to match hardware register width
Jie Zhang <[email protected]>
net: stmmac: fix oops when split header is enabled
Russell King (Oracle) <[email protected]>
net: stmmac: replace has_xxxx with core_type
Russell King (Oracle) <[email protected]>
net: stmmac: remove broken PCS code
Yue Haibing <[email protected]>
selftests: net: lib: Fix jq parsing error
Ido Schimmel <[email protected]>
selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
Ralf Lici <[email protected]>
ovpn: fix VPN TX bytes counting
Ralf Lici <[email protected]>
ovpn: fix possible use-after-free in ovpn_net_xmit
Ralf Lici <[email protected]>
ovpn: set sk_user_data before overriding callbacks
Aboorva Devarajan <[email protected]>
cpuidle: Skip governor when only one idle state is available
Zhai Can <[email protected]>
ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
zhouwenhao <[email protected]>
objpool: fix the overestimation of object pooling metadata size
Aristeu Rozanski <[email protected]>
selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
Josh Poimboeuf <[email protected]>
kbuild: Add objtool to top-level clean target
Kuppuswamy Sathyanarayanan <[email protected]>
powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check
Sean V Kelley <[email protected]>
ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
Jiasheng Jiang <[email protected]>
fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
Edward Adam Davis <[email protected]>
fs/ntfs3: prevent infinite loops caused by the next valid being the same
Bartlomiej Kubik <[email protected]>
fs/ntfs3: Initialize new folios before use
Jens Axboe <[email protected]>
io_uring/cancel: de-unionize file and user_data in struct io_cancel_data
Pavel Begunkov <[email protected]>
io_uring: delay sqarray static branch disablement
Christoph Böhmwalder <[email protected]>
drbd: always set BLK_FEAT_STABLE_WRITES
Jared Kangas <[email protected]>
dmaengine: fsl-edma: don't explicitly disable clocks in .remove()
Barnabás Czémán <[email protected]>
backlight: qcom-wled: Change PM8950 WLED configurations
Barnabás Czémán <[email protected]>
backlight: qcom-wled: Support ovp values for PMI8994
Haotian Zhang <[email protected]>
leds: qcom-lpg: Check the return value of regmap_bulk_write()
Duje Mihanović <[email protected]>
leds: expresswire: Fix chip state breakage
Jiayu Du <[email protected]>
pinctrl: canaan: k230: Fix NULL pointer dereference when parsing devicetree
Wei Li <[email protected]>
pinctrl: single: fix refcount leak in pcs_add_gpio_func()
Felix Gu <[email protected]>
pinctrl: meson: amlogic-a4: Fix device node reference leak in bank helpers
Luca Weiss <[email protected]>
pinctrl: qcom: sm8250-lpass-lpi: Fix i2s2_data_groups definition
Luca Boccassi <[email protected]>
pidfs: return -EREMOTE when PIDFD_GET_INFO is called on another ns
Randy Dunlap <[email protected]>
mips: LOONGSON32: drop a dangling Kconfig symbol
Harshit Mogalapalli <[email protected]>
iio: sca3000: Fix a resource leak in sca3000_probe()
Qing Wang <[email protected]>
ovl: Fix uninit-value in ovl_fill_real
Felix Gu <[email protected]>
pinctrl: equilibrium: Fix device node reference leak in pinbank_init()
Jose Javier Rodriguez Barbarin <[email protected]>
mcb: fix incorrect sanity check
Randy Dunlap <[email protected]>
nvmem: an8855: drop an unused Kconfig symbol
Justin Chen <[email protected]>
usb: bdc: fix sleep during atomic
Svyatoslav Ryhel <[email protected]>
drivers: iio: mpu3050: use dev_err_probe for regulator request
Robert Marko <[email protected]>
mfd: simple-mfd-i2c: Add Delta TN48M CPLD support
Haotian Zhang <[email protected]>
mfd: arizona: Fix regulator resource leak on wm5102_clear_write_sequencer() failure
Greg Kroah-Hartman <[email protected]>
Revert "mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms"
Yicong Yang <[email protected]>
coresight: tmc-etr: Fix race condition between sysfs and perf mode
Thomas Richard <[email protected]>
phy: freescale: imx8qm-hsio: fix NULL pointer dereference
Antonio Borneo <[email protected]>
coresight: etm3x: Fix cpulocked warning on cpuhp
Kery Qi <[email protected]>
watchdog: starfive-wdt: Fix PM reference leak in probe error path
Petre Rodan <[email protected]>
iio: pressure: mprls0025pa: fix pressure calculation
Petre Rodan <[email protected]>
iio: pressure: mprls0025pa: fix scan_type struct
Petre Rodan <[email protected]>
iio: pressure: mprls0025pa: fix interrupt flag
Petre Rodan <[email protected]>
iio: pressure: mprls0025pa: fix SPI CS delay violation
Petre Rodan <[email protected]>
iio: pressure: mprls0025pa: fix spi_transfer struct initialisation
Matthew Schwartz <[email protected]>
mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
Zilin Guan <[email protected]>
gpib: Fix memory leak in ni_usb_init()
Dan Carpenter <[email protected]>
gpib: Fix error code in ni_usb_write_registers()
Dan Carpenter <[email protected]>
gpib: Fix error code in ibonline()
Randy Dunlap <[email protected]>
serial: SH_SCI: improve "DMA support" prompt
Randy Dunlap <[email protected]>
serial: imx: change SERIAL_IMX_CONSOLE to bool
Chaitanya Mishra <[email protected]>
staging: greybus: lights: avoid NULL deref
Randy Dunlap <[email protected]>
usb: typec: ucsi: drop an unused Kconfig symbol
Randy Dunlap <[email protected]>
iio: test: drop dangling symbol in gain-time-scale helpers
Arnd Bergmann <[email protected]>
soundwire: intel_ace2x: add SND_HDA_CORE dependency
Alper Ak <[email protected]>
char: misc: Use IS_ERR() for filp_open() return value
Cristian Ciocaltea <[email protected]>
phy: rockchip: samsung-hdptx: Pre-compute HDMI PLL config for 461.10125 MHz output
Nuno Sá <[email protected]>
dma: dma-axi-dmac: fix HW scatter-gather not looking at the queue
Nuno Sá <[email protected]>
dma: dma-axi-dmac: fix SW cyclic transfers
AngeloGioacchino Del Regno <[email protected]>
dmaengine: mediatek: uart-apdma: Fix above 4G addressing TX/RX
Nicolas Frattaroli <[email protected]>
interconnect: mediatek: Aggregate bandwidth with saturating add
Nicolas Frattaroli <[email protected]>
interconnect: mediatek: Don't hijack parent device
Krzysztof Kozlowski <[email protected]>
clk: zynqmp: pll: Fix zynqmp_clk_divider_determine_rate kerneldoc
Krzysztof Kozlowski <[email protected]>
clk: zynqmp: divider: Fix zynqmp_clk_divider_determine_rate kerneldoc
Haotian Zhang <[email protected]>
clk: mediatek: Fix error handling in runtime PM setup
Nicolas Frattaroli <[email protected]>
clk: mediatek: Add mfg_eb as parent to mt8196 mfgpll clocks
Sjoerd Simons <[email protected]>
clk: mediatek: Drop __initconst from gates
Brian Masney <[email protected]>
clk: zynqmp: divider: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: x86: cgu: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: versaclock3: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: stm32: stm32-core: convert from divider_round_rate_parent() to divider_determine_rate()
Brian Masney <[email protected]>
clk: stm32: stm32-core: convert from divider_ro_round_rate() to divider_ro_determine_rate()
Brian Masney <[email protected]>
clk: sprd: div: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: sophgo: sg2042-clkgen: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: nxp: lpc32xx: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: nuvoton: ma35d1-divider: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: milbeaut: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: loongson1: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: hisilicon: clkdivider-hi6220: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: bm1880: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: actions: owl-divider: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: actions: owl-composite: convert from owl_divider_helper_round_rate() to divider_determine_rate()
Dmitry Baryshkov <[email protected]>
clk: qcom: gfx3d: add parent to parent request map
David Heidelberg <[email protected]>
clk: qcom: dispcc-sm7150: Fix dispcc_mdss_pclk1_clk_src
Petr Hodina <[email protected]>
clk: qcom: dispcc-sdm845: Enable parents for pixel clocks
Brian Masney <[email protected]>
clk: qcom: regmap-divider: convert from divider_round_rate() to divider_determine_rate()
Brian Masney <[email protected]>
clk: qcom: regmap-divider: convert from divider_ro_round_rate() to divider_ro_determine_rate()
Geert Uytterhoeven <[email protected]>
clk: Move clk_{save,restore}_context() to COMMON_CLK section
Vladimir Zapolskiy <[email protected]>
Input: adp5589 - remove a leftover header file
Brian Masney <[email protected]>
clk: microchip: core: remove duplicate determine_rate on pic32_sclk_ops
Miaoqian Lin <[email protected]>
clk: rockchip: Fix error pointer check after rockchip_clk_register_gate_link()
Brian Masney <[email protected]>
clk: qcom: alpha-pll: convert from divider_round_rate() to divider_determine_rate()
George Moussalem <[email protected]>
clk: qcom: gcc-ipq5018: flag sleep clock as critical
Barnabás Czémán <[email protected]>
clk: qcom: gcc-msm8917: Remove ALWAYS_ON flag from cpp_gdsc
Barnabás Czémán <[email protected]>
clk: qcom: gcc-msm8953: Remove ALWAYS_ON flag from cpp_gdsc
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-glymur: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-qdu1000: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-x1e80100: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-milos: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-sdx75: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-sm4450: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-sm8750: Update the SDCC RCGs to use shared_floor_ops
Jagadeesh Kona <[email protected]>
clk: qcom: gcc-sm8450: Update the SDCC RCGs to use shared_floor_ops
Martin Blumenstingl <[email protected]>
clk: meson: g12a: Limit the HDMI PLL OD to /4
Martin Blumenstingl <[email protected]>
clk: meson: gxbb: Limit the HDMI PLL OD to /4 on GXL/GXM SoCs
Taniya Das <[email protected]>
clk: qcom: rcg2: compute 2d using duty fraction directly
Vladimir Zapolskiy <[email protected]>
clk: qcom: gcc-sm8650: Use floor ops for SDCC RCGs
Vladimir Zapolskiy <[email protected]>
clk: qcom: gcc-sm8550: Use floor ops for SDCC RCGs
Inochi Amaoto <[email protected]>
clk: spacemit: Respect Kconfig setting when building modules
Yao Zi <[email protected]>
clk: thead: th1520-ap: Poll for PLL lock and wait for stability
Felix Gu <[email protected]>
fbdev: au1200fb: Fix a memory leak in au1200fb_drv_probe()
Felix Gu <[email protected]>
fbdev: of_display_timing: Fix device node reference leak in of_get_display_timings()
Sudeep Holla <[email protected]>
Revert "mailbox/pcc: support mailbox management of the shared buffer"
Shengjiu Wang <[email protected]>
remoteproc: imx_dsp_rproc: Only reset carveout memory at RPROC_OFFLINE state
Steven Rostedt <[email protected]>
tracing: Remove duplicate ENABLE_EVENT_STR and DISABLE_EVENT_STR macros
Miaoqian Lin <[email protected]>
tracing: Properly process error handling in event_hist_trigger_parse()
Sagi Grimberg <[email protected]>
fs/nfs: Fix readdir slow-start regression
Li Chen <[email protected]>
nvdimm: virtio_pmem: serialize flush requests
Colin Ian King <[email protected]>
scsi: csiostor: Fix dereference of null pointer rn
Arnd Bergmann <[email protected]>
scsi: ufs: host: mediatek: Require CONFIG_PM
Zilin Guan <[email protected]>
scsi: smartpqi: Fix memory leak in pqi_report_phys_luns()
Olga Kornievskaia <[email protected]>
pNFS: fix a missing wake up while waiting on NFS_LAYOUT_DRAIN
Yi Liu <[email protected]>
RDMA/uverbs: Add __GFP_NOWARN to ib_uverbs_unmarshall_recv() kmalloc
Val Packett <[email protected]>
power: supply: qcom_battmgr: Recognize "LiP" as lithium-polymer
Waqar Hameed <[email protected]>
power: supply: pm8916_lbc: Fix use-after-free for extcon in IRQ handler
Weili Qian <[email protected]>
hisi_acc_vfio_pci: fix VF reset timeout issue
Miquel Raynal <[email protected]>
mtd: spinand: Fix kernel doc
Weigang He <[email protected]>
mtd: parsers: ofpart: fix OF node refcount leak in parse_fixed_partitions()
Yuxiong Wang <[email protected]>
cxl: Fix premature commit_end increment on decoder commit failure
Chuck Lever <[email protected]>
RDMA/core: add rdma_rw_max_sge() helper for SQ sizing
Li Zhijian <[email protected]>
RDMA/rxe: Fix race condition in QP timer handlers
Zilin Guan <[email protected]>
RDMA/mlx5: Fix memory leak in GET_DATA_DIRECT_SYSFS_PATH handler
Yi Liu <[email protected]>
RDMA/uverbs: Validate wqe_size before using it in ib_uverbs_post_send
Li Zhijian <[email protected]>
RDMA/rxe: Fix iova-to-va conversion for MR page sizes != PAGE_SIZE
Cheatham, Benjamin <[email protected]>
cxl/core: Fix cxl_dport debugfs EINJ entries
Mike Snitzer <[email protected]>
NFS/localio: remove -EAGAIN handling in nfs_local_doio()
Mike Snitzer <[email protected]>
NFS/localio: use GFP_NOIO and non-memreclaim workqueue in nfs_local_commit
Mike Snitzer <[email protected]>
NFS/localio: prevent direct reclaim recursion into NFS via nfs_writepages
Trond Myklebust <[email protected]>
NFS/localio: Handle short writes by retrying
Zilin Guan <[email protected]>
mtd: parsers: Fix memory leak in mtd_parser_tplink_safeloader_parse()
Mario Limonciello (AMD) <[email protected]>
crypto: ccp - Send PSP_CMD_TEE_RING_DESTROY when PSP_CMD_TEE_RING_INIT fails
Mario Limonciello (AMD) <[email protected]>
crypto: ccp - Factor out ring destroy handling to a helper
Mario Limonciello (AMD) <[email protected]>
crypto: ccp - Add an S4 restore flow
Mario Limonciello (AMD) <[email protected]>
crypto: ccp - Declare PSP dead if PSP_CMD_TEE_RING_INIT fails
Shyam Sundar S K <[email protected]>
platform/x86/amd/pmf: Prevent TEE errors after hibernate
Anthony Pighin (Nokia) <[email protected]>
vfio/pci: Lock upstream bridge for vfio_pci_core_disable()
Alexander Usyskin <[email protected]>
mtd: intel-dg: Fix accessing regions before setting nregions
Alok Tiwari <[email protected]>
mtd: rawnand: cadence: Fix return type of CDMA send-and-wait helper
Or Har-Toov <[email protected]>
IB/mlx5: Fix port speed query for representors
Chiara Meiohas <[email protected]>
RDMA/mlx5: Fix UMR hang in LAG error state unload
Malaya Kumar Rout <[email protected]>
tools/power/x86/intel-speed-select: Fix file descriptor leak in isolate_cpus()
Krishna Chomal <[email protected]>
platform/x86: hp-wmi: fix platform profile values for Omen 16-wf1xxx
Jacob Moroni <[email protected]>
RDMA/iwcm: Fix workqueue list corruption by removing work_list
Jiasheng Jiang <[email protected]>
RDMA/rxe: Fix double free in rxe_srq_from_init
Roman Penyaev <[email protected]>
RDMA/rtrs-srv: fix SG mapping
Waqar Hameed <[email protected]>
power: supply: wm97xx: Fix NULL pointer dereference in power_supply_changed()
Haotian Zhang <[email protected]>
power: supply: bq27xxx: fix wrong errno when bus ops are unsupported
Alexander Koskovich <[email protected]>
power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write
Waqar Hameed <[email protected]>
power: supply: sbs-battery: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: rt9455: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: pm8916_lbc: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: goldfish: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: cpcap-battery: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: bq25980: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: bq256xx: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: act8945a: Fix use-after-free in power_supply_changed()
Waqar Hameed <[email protected]>
power: supply: ab8500: Fix use-after-free in power_supply_changed()
Dan Williams <[email protected]>
cxl/mem: Fix devm_cxl_memdev_edac_release() confusion
Maher Sanalla <[email protected]>
RDMA/mlx5: Fix ucaps init error flow
Chengchang Tang <[email protected]>
RDMA/hns: Notify ULP of remaining soft-WCs during reset
Junxian Huang <[email protected]>
RDMA/hns: Fix RoCEv1 failure due to DSCP
Chengchang Tang <[email protected]>
RDMA/hns: Fix WQ_MEM_RECLAIM warning
Etienne AUJAMES <[email protected]>
IB/cache: update gid cache on client reregister event
Honggang LI <[email protected]>
RDMA/rtrs: server: remove dead code
Kuniyuki Iwashima <[email protected]>
af_unix: Fix memleak of newsk in unix_stream_connect().
Hariprasad Kelam <[email protected]>
octeontx2-pf: Unregister devlink on probe failure
Michael Dege <[email protected]>
net: renesas: rswitch: fix forwarding offload statemachine
Eric Joyner <[email protected]>
ionic: Rate limit unknown xcvr type messages
Vimlesh Kumar <[email protected]>
octeon_ep_vf: ensure dbell BADDR updation
Vimlesh Kumar <[email protected]>
octeon_ep: ensure dbell BADDR updation
Vimlesh Kumar <[email protected]>
octeon_ep: disable per ring interrupts
Jiayuan Chen <[email protected]>
serial: caif: fix use-after-free in caif_serial ldisc_close()
Jiayuan Chen <[email protected]>
xfrm: fix ip_rt_bug race in icmp_route_lookup reverse path
René Rebe <[email protected]>
net: sunhme: Fix sbus regression
Jiayuan Chen <[email protected]>
net: atm: fix crash due to unvalidated vcc pointer in sigd_send()
Stefan Metzmacher <[email protected]>
smb: client: correct value for smbd_max_fragmented_recv_size
Jinliang Zheng <[email protected]>
procfs: fix missing RCU protection when reading real_parent in do_task_stat()
Jian Shen <[email protected]>
net: hns3: fix double free issue for tx spare buffer
Ivan Vecera <[email protected]>
dpll: zl3073x: Fix output pin phase adjustment sign
Ivan Vecera <[email protected]>
dpll: zl3073x: Cache all output properties in zl3073x_out
Ivan Vecera <[email protected]>
dpll: zl3073x: Split ref, out, and synth logic from core
Ivan Vecera <[email protected]>
dpll: zl3073x: Store raw register values instead of parsed state
Ivan Vecera <[email protected]>
dpll: zl3073x: Specify phase adjustment granularity for pins
Ivan Vecera <[email protected]>
dpll: add phase-adjust-gran pin attribute
Nicolas Cavallari <[email protected]>
PCI: Add ACS quirk for Pericom PI7C9X2G404 switches [12d8:b404]
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: validate open interval overlap
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: validate element belonging to interval
Florian Westphal <[email protected]>
netfilter: nft_set_rbtree: don't gc elements on insert
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: remove seqcount_rwlock_t
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: use binary search array in get command
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: translate rbtree to array for binary search
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: check for partial overlaps in anonymous sets
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_rbtree: fix bogus EEXIST with NLM_F_CREATE with null interval
Anders Grahn <[email protected]>
netfilter: nft_counter: fix reset of counters on 32bit archs
Florian Westphal <[email protected]>
netfilter: nft_set_hash: fix get operation on big endian
Florian Westphal <[email protected]>
netfilter: nfnetlink_queue: do shared-unconfirmed check before segmentation
Scott Mitchell <[email protected]>
netfilter: nfnetlink_queue: optimize verdict lookup with hash table
Votokina Victoria <[email protected]>
nfc: hci: shdlc: Stop timers and work before freeing context
Eric Dumazet <[email protected]>
inet: RAW sockets using IPPROTO_RAW MUST drop incoming ICMP
Thomas Bogendoerfer <[email protected]>
bonding: only set speed/duplex to unknown, if getting speed failed
Anshumali Gaur <[email protected]>
octeontx2-af: Fix PF driver crash with kexec kernel booting
Paolo Abeni <[email protected]>
mptcp: fix receive space timestamp initialization
Paolo Abeni <[email protected]>
mptcp: do not account for OoO in mptcp_rcvbuf_grow()
Tuo Li <[email protected]>
of: unittest: fix possible null-pointer dereferences in of_unittest_property_copy()
Chia-Yu Chang <[email protected]>
tcp: accecn: handle unexpected AccECN negotiation feedback
Chia-Yu Chang <[email protected]>
tcp: disable RFC3168 fallback identifier for CC modules
Chia-Yu Chang <[email protected]>
tcp: ECT_1_NEGOTIATION and NEEDS_ACCECN identifiers
Arnd Bergmann <[email protected]>
jfs: avoid -Wtautological-constant-out-of-range-compare warning
Ondrej Mosnacek <[email protected]>
ucount: check for CAP_SYS_RESOURCE using ns_capable_noaudit()
Ondrej Mosnacek <[email protected]>
ipc: don't audit capability check in ipc_permissions()
Kevin Brodsky <[email protected]>
selftests/mm: fix faulting-in code in pagemap_ioctl test
Kevin Brodsky <[email protected]>
selftests/mm: fix usage of FORCE_READ() in cow tests
Håkon Bugge <[email protected]>
PCI/ACPI: Restrict program_hpx_type2() to AER bits
Håkon Bugge <[email protected]>
PCI: Initialize RCB from pci_configure_device()
Aaradhana Sahu <[email protected]>
wifi: ath12k: clear stale link mapping of ahvif->links_map
Aaradhana Sahu <[email protected]>
wifi: ath12k: Fix index decrement when array_len is zero
Miaoqing Pan <[email protected]>
wifi: ath11k: add usecase firmware handling based on device compatible
Ziyi Guo <[email protected]>
wifi: ath10k: sdio: add missing lock protection in ath10k_sdio_fw_crashed_dump()
Sergey Shtylyov <[email protected]>
PCI: Check parent for NULL in of_pci_bus_release_domain_nr()
Eric Dumazet <[email protected]>
tcp: tcp_tx_timestamp() must look at the rtx queue
Ilpo Järvinen <[email protected]>
PCI: Remove old_size limit from bridge window sizing
Ilpo Järvinen <[email protected]>
PCI: Stop over-estimating bridge window size
Ilpo Järvinen <[email protected]>
PCI: Rewrite bridge window head alignment function
Zhiyu Zhang <[email protected]>
fat: avoid parent link count underflow in rmdir
Alice Ryhl <[email protected]>
rust: task: restrict Task::group_leader() to current
Chaitanya Mishra <[email protected]>
lib/kstrtox: fix kstrtobool() docstring to mention enabled/disabled
Anthony Iliopoulos <[email protected]>
nfsd: never defer requests during idmap lookup
Chuck Lever <[email protected]>
xdrgen: Remove inclusion of nlm4.h header
Chuck Lever <[email protected]>
xdrgen: Initialize data pointer for zero-length items
Chuck Lever <[email protected]>
NFS: NFSERR_INVAL is not defined by NFSv2
Chuck Lever <[email protected]>
xdrgen: Fix struct prefix for typedef types in program wrappers
Mikulas Patocka <[email protected]>
dm: use bio_clone_blkg_association
Lu Baolu <[email protected]>
iommu/vt-d: Clear Present bit before tearing down context entry
Lu Baolu <[email protected]>
iommu/vt-d: Clear Present bit before tearing down PASID entry
Dmytro Maluka <[email protected]>
iommu/vt-d: Flush cache for PASID table before using it
Zilin Guan <[email protected]>
wifi: rtw89: debug: Fix memory leak in __print_txpwr_map()
Jörg Wedekind <[email protected]>
PCI: Mark 3ware-9650SA Root Port Extended Tags as broken
Petr Mladek <[email protected]>
kallsyms/ftrace: set module buildid in ftrace_mod_address_lookup()
Petr Mladek <[email protected]>
module: add helper function for reading module_buildid()
Petr Mladek <[email protected]>
kallsyms/bpf: rename __bpf_address_lookup() to bpf_address_lookup()
Fernando Fernandez Mancera <[email protected]>
netfilter: nf_conncount: fix tracking of connections from localhost
Florian Westphal <[email protected]>
netfilter: nft_compat: add more restrictions on netlink attributes
Fernando Fernandez Mancera <[email protected]>
netfilter: nf_conncount: increase the connection clean up limit to 64
Fernando Fernandez Mancera <[email protected]>
netfilter: nf_conncount: make nf_conncount_gc_list() to disable BH
Florian Westphal <[email protected]>
netfilter: nf_tables: reset table validation state on abort
Li Chen <[email protected]>
ext4: fast commit: make s_fc_lock reclaim-safe
Miri Korenblit <[email protected]>
wifi: cfg80211: stop NAN and P2P in cfg80211_leave
Matt Johnston <[email protected]>
mctp i2c: initialise event handler read bytes
Jian Zhang <[email protected]>
net: mctp-i2c: fix duplicate reception of old data
Abhishek Bapat <[email protected]>
quota: fix livelock between quotactl and freeze_super
Baochen Qiang <[email protected]>
wifi: ath12k: do WoW offloads only on primary link
Rosen Penev <[email protected]>
wifi: ath9k: add OF dependency to AHB
Alistair Popple <[email protected]>
PCI/P2PDMA: Reset page reference count when page mapping fails
Aadityarangan Shridhar Iyengar <[email protected]>
PCI/PTM: Fix pcie_ptm_create_debugfs() memory leak
Mikulas Patocka <[email protected]>
dm: use READ_ONCE in dm_blk_report_zones
Mikulas Patocka <[email protected]>
dm: fix unlocked test for dm_suspended_md
Uwe Kleine-König <[email protected]>
PCI/portdrv: Fix potential resource leak
Inochi Amaoto <[email protected]>
PCI: sophgo: Disable L0s and L1 on Sophgo 2044 PCIe Root Ports
Håkon Bugge <[email protected]>
PCI: Do not attempt to set ExtTag for VFs
Shuai Xue <[email protected]>
Documentation: tracing: Add PCI tracepoint documentation
Hou Tao <[email protected]>
PCI/P2PDMA: Fix p2pmem_alloc_mmap() warning condition
Hou Tao <[email protected]>
PCI/P2PDMA: Release per-CPU pgmap ref when vm_insert_page() fails
Huang Chenming <[email protected]>
wifi: cfg80211: Fix use_for flag update on BSS refresh
Brian Norris <[email protected]>
PCI/PM: Avoid redundant delays on D3hot->D3cold
Baruch Siach <[email protected]>
Documentation: PCI: endpoint: Fix ntb/vntb copy & paste errors
Haotian Zhang <[email protected]>
PCI: xilinx: Fix INTx IRQ domain leak in error paths
Haotian Zhang <[email protected]>
PCI: mediatek: Fix IRQ domain leak when MSI allocation fails
Carl Lee <[email protected]>
hwmon: (pmbus/mpq8785) fix VOUT_MODE mismatch during identification
Guenter Roeck <[email protected]>
Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
Francesco Lavra <[email protected]>
spi: tools: Add include folder to .gitignore
Charles Keepax <[email protected]>
ASoC: SDCA: Handle volatile controls correctly
Charles Keepax <[email protected]>
ASoC: SDCA: Force some SDCA Controls to be volatile
Charles Keepax <[email protected]>
ASoC: SDCA: Remove outdated todo comment
Lizhi Hou <[email protected]>
accel/amdxdna: Fix incorrect error code returned for failed chain command
Ryan Lin <[email protected]>
HID: intel-ish-hid: fix NULL-ptr-deref in ishtp_bus_remove_all_clients
Zishun Yi <[email protected]>
accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
Lizhi Hou <[email protected]>
accel/amdxdna: Stop job scheduling across aie2_release_resource()
Lizhi Hou <[email protected]>
accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()
Tzung-Bi Shih <[email protected]>
platform/chrome: cros_ec_lightbar: Fix response size initialization
Sheetal <[email protected]>
ASoC: tegra: Add AHUB writeable_reg for RX holes
Harry Yoo <[email protected]>
mm/slab: fix false lockdep warning in __kfree_rcu_sheaf()
Shuicheng Lin <[email protected]>
drm/xe: Unregister drm device on probe error
Vinay Belgaumkar <[email protected]>
drm/xe/ptl: Disable DCC on PTL
Roberto Sassu <[email protected]>
evm: Use ordered xattrs list to calculate HMAC in evm_init_hmac()
Ricardo Ribalda <[email protected]>
media: uvcvideo: Fix allocation for small frame sizes
Gokul Praveen <[email protected]>
pwm: tiehrpwm: Enable pwmchip's parent device before setting configuration
Andy Shevchenko <[email protected]>
platform/chrome: cros_typec_switch: Don't touch struct fwnode_handle::dev
Nathan Chancellor <[email protected]>
drm/msm/dp: Avoid division by zero in msm_dp_ctrl_config_msa()
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: program correct register for UBWC config on DPU 8.x+
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: offset HBB values written to DPU by -13
Dmitry Baryshkov <[email protected]>
drm/msm/mdss: correct HBB programmed on UBWC 5.x and 6.x devices
Cristian Ciocaltea <[email protected]>
drm/rockchip: dw_hdmi_qp: Fix RK3576 HPD interrupt handling
Baihan Li <[email protected]>
drm/hisilicon/hibmc: Adding reset colorbar cfg in dp init.
Baihan Li <[email protected]>
drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually
Baihan Li <[email protected]>
drm/hisilicon/hibmc: add dp mode valid check
Baihan Li <[email protected]>
drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq
Michał Grzelak <[email protected]>
drm/buddy: release free_trees array on buddy mm teardown
Dmitry Baryshkov <[email protected]>
drm/msm/a2xx: fix pixel shader start on A225
David Heidelberg <[email protected]>
media: ccs: Accommodate C-PHY into the calculation
Lizhi Hou <[email protected]>
accel/amdxdna: Fix notifier_wq flushing warning
Brian Masney <[email protected]>
drm/msm/dsi_phy_14nm: convert from divider_round_rate() to divider_determine_rate()
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: fix CMD panels on DPU 1.x - 3.x
Dmitry Baryshkov <[email protected]>
drm/msm/disp: set num_planes to 1 for interleaved YUV formats
Haotian Zhang <[email protected]>
HID: playstation: Add missing check for input_ff_create_memless
André Draszik <[email protected]>
regulator: core: move supply check earlier in set_machine_constraints()
Jani Nikula <[email protected]>
mei: late_bind: fix struct intel_lb_component_ops kernel-doc
Mani Chandana Ballary Kuntumalla <[email protected]>
drm/msm/dp: Update msm_dp_controller IDs for sa8775p
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: fix WD timer handling on DPU 8.x
Teguh Sobirin <[email protected]>
drm/msm/dpu: Set vsync source irrespective of mdp top support
Mahadevan P <[email protected]>
drm/msm/disp/dpu: add merge3d support for sc7280
Srinivasan Shanmugam <[email protected]>
drm/amdgpu: Use explicit VCN instance 0 in SR-IOV init
Srinivasan Shanmugam <[email protected]>
drm/amdkfd: Fix signal_eviction_fence() bool return value
Mario Limonciello (AMD) <[email protected]>
drm/amd: Drop "amdgpu kernel modesetting enabled" message
Zilin Guan <[email protected]>
media: chips-media: wave5: Fix memory leak on codec_info allocation failure
Cristian Ciocaltea <[email protected]>
ASoC: nau8821: Fixup nau8821_enable_jack_detect()
Konstantin Andreev <[email protected]>
smack: /smack/doi: accept previously used values
Konstantin Andreev <[email protected]>
smack: /smack/doi must be > 0
Ketil Johnsen <[email protected]>
drm/panthor: Evict groups before VM termination
Simon Trimmer <[email protected]>
ASoC: SDCA: Allow sample width wild cards in set_usage()
Takashi Iwai <[email protected]>
ALSA: vmaster: Relax __free() variable declarations
Takashi Iwai <[email protected]>
ALSA: pcm: Relax __free() variable declarations
David Heidelberg <[email protected]>
drm/panel: sw43408: Remove manual invocation of unprepare at remove
Lizhi Hou <[email protected]>
accel/amdxdna: Fix race where send ring appears full due to delayed head update
Boris Brezillon <[email protected]>
drm/panthor: Fix panthor_gpu_coherency_set()
Lai Jiangshan <[email protected]>
workqueue: Process rescuer work items one-by-one using a cursor
Lai Jiangshan <[email protected]>
workqueue: Only assign rescuer work when really needed
Lai Jiangshan <[email protected]>
workqueue: Factor out assign_rescuer_work()
Boris Brezillon <[email protected]>
drm/panthor: Make sure we resume the tick when new jobs are submitted
Boris Brezillon <[email protected]>
drm/panthor: Fix the logic that decides when to stop ticking
Boris Brezillon <[email protected]>
drm/panthor: Fix immediate ticking on a disabled tick
Boris Brezillon <[email protected]>
drm/panthor: Fix the group priority rotation logic
Boris Brezillon <[email protected]>
drm/panthor: Fix the full_tick check
Boris Brezillon <[email protected]>
drm/panthor: Recover from panthor_gpu_flush_caches() failures
Junhui Liu <[email protected]>
reset: canaan: k230: drop OF dependency and enable by default
Konrad Dybcio <[email protected]>
arm64: dts: qcom: sm6115: Add CX_MEM/DBGC GPU regions
Konrad Dybcio <[email protected]>
arm64: dts: qcom: agatti: Add CX_MEM/DBGC GPU regions
Viken Dadhaniya <[email protected]>
arm64: dts: qcom: talos: Drop opp-shared from QUP OPP table
Jonathan Marek <[email protected]>
arm64: dts: qcom: x1e: bus is 40-bits (fix 64GB models)
Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sdm845-db845c: specify power for WiFi CH1
Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sdm845-db845c: drop CS from SPIO0
Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: qrb4210-rb2: Fix UART3 wakeup IRQ storm
Jerome Brunet <[email protected]>
arm64: dts: amlogic: g12: assign the MMC A signal clock
Jerome Brunet <[email protected]>
arm64: dts: amlogic: g12: assign the MMC B and C signal clocks
Jerome Brunet <[email protected]>
arm64: dts: amlogic: gx: assign the MMC signal clocks
Jerome Brunet <[email protected]>
arm64: dts: amlogic: axg: assign the MMC signal clocks
Jerome Brunet <[email protected]>
arm64: dts: amlogic: c3: assign the MMC signal clocks
Haotian Zhang <[email protected]>
hwspinlock: omap: Handle devm_pm_runtime_enable() errors
Dmitry Baryshkov <[email protected]>
soc: qcom: ubwc: add missing include
Abhash Kumar Jha <[email protected]>
arm64: dts: ti: k3-j784s4-j742s2-main-common.dtsi: Refactor watchdog instances for j784s4
Abhash Kumar Jha <[email protected]>
arm64: dts: ti: k3-j784s4-main.dtsi: Move c71_3 node to appropriate order
Jerome Brunet <[email protected]>
arm64: dts: amlogic: s4: fix mmc clock assignment
Jerome Brunet <[email protected]>
arm64: dts: amlogic: s4: assign mmc b clock to 24MHz
AngeloGioacchino Del Regno <[email protected]>
arm64: dts: mediatek: mt8183-jacuzzi-pico6: Fix typo in pinmux node
Vladimir Zapolskiy <[email protected]>
arm: dts: lpc32xx: add clocks property to Motor Control PWM device tree node
Lad Prabhakar <[email protected]>
arm64: dts: renesas: rzt2h-n2h-evk-common: Use GPIO for SD0 write protect
Narayana Murty N <[email protected]>
powerpc/eeh: fix recursive pci_lock_rescan_remove locking in EEH event handling
Zilin Guan <[email protected]>
soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
Haotian Zhang <[email protected]>
soc: qcom: cmd-db: Use devm_memremap() to fix memory leak in cmd_db_dev_probe
Christophe Leroy <[email protected]>
powerpc/uaccess: Move barrier_nospec() out of allow_read_{from/write}_user()
Chen-Yu Tsai <[email protected]>
ARM: dts: allwinner: sun5i-a13-utoo-p66: delete "power-gpios" property
Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: msm8994-octagon: Fix Analog Devices vendor prefix of AD7147
Geert Uytterhoeven <[email protected]>
arm64: dts: renesas: r9a09g047e57-smarc: Remove duplicate SW_LCD_EN
Abel Vesa <[email protected]>
arm64: dts: qcom: x1e80100: Fix USB combo PHYs SS1 and SS2 ref clocks
Casey Connolly <[email protected]>
arm64: dts: qcom: sdm845-oneplus: Mark l14a regulator as boot-on
Casey Connolly <[email protected]>
arm64: dts: qcom: sdm845-oneplus: Don't keep panel regulator always on
Casey Connolly <[email protected]>
arm64: dts: qcom: sdm845-oneplus: Don't mark ts supply boot-on
Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sdm630: fix gpu_speed_bin size
Haotian Zhang <[email protected]>
clk: qcom: Return correct error code in qcom_cc_probe_by_index()
Alexander Stein <[email protected]>
arm64: dts: tqma8mpql-mba8mp-ras314: Fix HDMI CEC pad control settings
Alexander Stein <[email protected]>
arm64: dts: tqma8mpql-mba8mpxl: Fix HDMI CEC pad control settings
Sudeep Holla <[email protected]>
firmware: arm_ffa: Correct 32-bit response handling in NOTIFICATION_INFO_GET
Dan Carpenter <[email protected]>
EDAC/i5400: Fix snprintf() limit calculation in calculate_dimm_size()
Dan Carpenter <[email protected]>
EDAC/i5000: Fix snprintf() size calculation in calculate_dimm_size()
Jorge Ramirez-Ortiz <[email protected]>
soc: qcom: smem: handle ENOMEM error during probe
Sai Ritvik Tanksalkar <[email protected]>
pstore/ram: fix buffer overflow in persistent_ram_save_old()
Larysa Zaremba <[email protected]>
selftests/xsk: fix number of Tx frags in invalid packet
Larysa Zaremba <[email protected]>
selftests/xsk: properly handle batch ending in the middle of a packet
Bastien Curutchet (eBPF Foundation) <[email protected]>
selftests/bpf: test_xsk: Split xskxceiver
Lianjie Wang <[email protected]>
hwrng: core - use RCU and work_struct to fix race condition
Jonathan McDowell <[email protected]>
hwrng: core - Allow runtime disabling of the HW RNG
Zilin Guan <[email protected]>
crypto: starfive - Fix memory leak in starfive_aes_aead_do_one_req()
KP Singh <[email protected]>
bpf: Require frozen map for calculating map hash
KP Singh <[email protected]>
bpf: Limit bpf program signature size
Titouan Ameline de Cadeville <[email protected]>
fs/tests: exec: drop duplicate bprm_stack_limits test vectors
Chen Jinghuang <[email protected]>
sched/rt: Skip currently executing CPU in rto_next_cpu()
Joel Fernandes <[email protected]>
sched/deadline: Clear the defer params
Sebastian Andrzej Siewior <[email protected]>
media: pci: mg4b: Use IRQF_NO_THREAD
Sebastian Andrzej Siewior <[email protected]>
mfd: wm8350-core: Use IRQF_ONESHOT
Sebastian Andrzej Siewior <[email protected]>
rtc: amlogic-a4: Remove IRQF_ONESHOT
Sebastian Andrzej Siewior <[email protected]>
usb: typec: fusb302: Remove IRQF_ONESHOT
Sebastian Andrzej Siewior <[email protected]>
EDAC/altera: Remove IRQF_ONESHOT
Sebastian Andrzej Siewior <[email protected]>
scsi: efct: Use IRQF_ONESHOT and default primary handler
Sebastian Andrzej Siewior <[email protected]>
Bluetooth: btintel_pcie: Use IRQF_ONESHOT and default primary handler
Sebastian Andrzej Siewior <[email protected]>
iommu/amd: Use core's primary handler and set IRQF_ONESHOT
Sebastian Andrzej Siewior <[email protected]>
platform/x86: int0002: Remove IRQF_ONESHOT from request_irq()
Sebastian Andrzej Siewior <[email protected]>
genirq: Set IRQF_COND_ONESHOT in devm_request_irq().
Paul Chaignon <[email protected]>
bpf: Fix bpf_xdp_store_bytes proto for read-only arg
Jianpeng Chang <[email protected]>
crypto: caam - fix netdev memory leak in dpaa2_caam_probe
Weili Qian <[email protected]>
crypto: hisilicon/trng - support tfms sharing the device
Jiri Olsa <[email protected]>
selftests/bpf: Fix kprobe multi stacktrace_ips test
Jiri Olsa <[email protected]>
x86/fgraph,bpf: Switch kprobe_multi program stack unwind to hw_regs path
Jiri Olsa <[email protected]>
x86/fgraph: Fix return_to_handler regs.rsp value
Aleksander Jan Bajkowski <[email protected]>
crypto: inside-secure/eip93 - unregister only available algorithm
Ella Ma <[email protected]>
crypto: ccp - Fix a crash due to incorrect cleanup usage of kfree
Luis Gerhorst <[email protected]>
bpf: Fix verifier_bug_if to account for BPF_CALL
Guillaume Gonnet <[email protected]>
bpf: Fix tcx/netkit detach permissions when prog fd isn't given
Jiayuan Chen <[email protected]>
bpf, sockmap: Fix FIONREAD for sockmap
Jiayuan Chen <[email protected]>
bpf, sockmap: Fix incorrect copied_seq calculation
Kumar Kartikeya Dwivedi <[email protected]>
rqspinlock: Fix TAS fallback lock entry creation
Aleksander Jan Bajkowski <[email protected]>
hwrng: airoha - set rng quality to 900
Tycho Andersen (AMD) <[email protected]>
crypto: ccp - narrow scope of snp_range_list
Tom Lendacky <[email protected]>
crypto: ccp - Fix a case where SNP_SHUTDOWN is missed
Aleksander Jan Bajkowski <[email protected]>
crypto: inside-secure/eip93 - fix kernel panic in driver detach
Thomas Gleixner <[email protected]>
hrtimer: Fix trace oddity
Kery Qi <[email protected]>
selftests/bpf: Fix resource leak in serial_test_wq on attach failure
Zesen Liu <[email protected]>
bpf: Fix memory access flags in helper prototypes
Puranjay Mohan <[email protected]>
bpf: Preserve id of register in sync_linked_regs()
Chenghai Huang <[email protected]>
crypto: hisilicon/sgl - fix inconsistent map/unmap direction issue
Qi Tao <[email protected]>
crypto: hisilicon/sec2 - support skcipher/aead fallback for hardware queue unavailable
Weili Qian <[email protected]>
crypto: hisilicon/hpre - support the hpre algorithm fallback
Chenghai Huang <[email protected]>
crypto: hisilicon - consolidate qp creation and start in hisi_qm_alloc_qps_node
Chenghai Huang <[email protected]>
crypto: hisilicon/zip - support fallback for zip
Chenghai Huang <[email protected]>
crypto: hisilicon/qm - centralize the sending locks of each module into qm
Chenghai Huang <[email protected]>
crypto: hisilicon/qm - enhance the configuration of req_type in queue attributes
lizhi <[email protected]>
crypto: hisilicon/hpre: extend tag field to 64 bits for better performance
Chenghai Huang <[email protected]>
crypto: hisilicon/sec - move backlog management to qp and store sqe in qp for callback
Chenghai Huang <[email protected]>
crypto: hisilicon/zip - adjust the way to obtain the req in the callback function
Thomas Fourier <[email protected]>
crypto: octeontx - fix dma_free_coherent() size
Thomas Fourier <[email protected]>
crypto: cavium - fix dma_free_coherent() size
Gabriele Monaco <[email protected]>
sched: Fix build for modules using set_tsk_need_resched()
Thomas Gleixner <[email protected]>
time/sched_clock: Use ACCESS_PRIVATE() to evaluate hrtimer::function
Thomas Weißschuh <[email protected]>
ARM: VDSO: Patch out __vdso_clock_getres() if unavailable
Gabriele Monaco <[email protected]>
sched: Export hidden tracepoints to modules
Varun R Mallya <[email protected]>
libbpf: Fix OOB read in btf_dump_get_bitfield_value
Puranjay Mohan <[email protected]>
selftests/bpf: veristat: fix printing order in output_stats()
Giovanni Cabiddu <[email protected]>
crypto: qat - fix warning on adf_pfvf_pf_proto.c
Sandipan Das <[email protected]>
perf/x86/core: Do not set bit width for unavailable counters
Andrew Cooper <[email protected]>
x86/cpu/amd: Correct the microcode table for Zenbleed
Jens Axboe <[email protected]>
io_uring/kbuf: fix memory leak if io_buffer_add_list fails
Salah Triki <[email protected]>
s390/cio: Fix device lifecycle handling in css_alloc_subchannel()
Gui-Dong Han <[email protected]>
PM: sleep: wakeirq: harden dev_pm_clear_wake_irq() against races
Yaxiong Tian <[email protected]>
cpufreq: intel_pstate: Enable asym capacity only when CPU SMT is not possible
Leo Yan <[email protected]>
perf: arm_spe: Properly set hw.state on failures
Breno Leitao <[email protected]>
arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
Samuel Wu <[email protected]>
PM: wakeup: Handle empty list in wakeup_sources_walk_start()
Xiao Ni <[email protected]>
md: fix return value of mddev_trylock
Zilin Guan <[email protected]>
md/raid1: fix memory leak in raid1_run()
Roger Pau Monne <[email protected]>
Partial revert "x86/xen: fix balloon target initialization for PVH dom0"
Govindarajulu Varadarajan <[email protected]>
ublk: Validate SQE128 flag before accessing the cmd
Caleb Sander Mateos <[email protected]>
ublk: restore auto buf unregister refcount optimization
Felix Gu <[email protected]>
thermal/of: Fix reference leak in thermal_of_cm_lookup()
Christoph Hellwig <[email protected]>
iomap: fix submission side handling of completion side errors
Felix Gu <[email protected]>
cpufreq: scmi: Fix device_node reference leak in scmi_cpu_domain_id()
Aleks Todorov <[email protected]>
OPP: Return correct value in dev_pm_opp_get_level
Yu Kuai <[email protected]>
md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout
Yu Kuai <[email protected]>
md/raid5: fix IO hang with degraded array with llbitmap
Li Nan <[email protected]>
md/raid10: fix any_working flag handling in raid10_sync_request
Yu Kuai <[email protected]>
md/raid5: fix raid5_run() to return error when log_init() fails
Rafael J. Wysocki <[email protected]>
thermal: intel: x86_pkg_temp_thermal: Handle invalid temperature
Rafael J. Wysocki <[email protected]>
cpuidle: governors: menu: Always check timers with tick stopped
Jens Axboe <[email protected]>
io_uring/sync: validate passed in offset
Jens Axboe <[email protected]>
io_uring/eventfd: remove unused ctx->evfd_last_cq_tail member
Alexey Simakov <[email protected]>
ACPICA: Fix NULL pointer dereference in acpi_ev_address_space_dispatch()
Caleb Sander Mateos <[email protected]>
io_uring: use release-acquire ordering for IORING_SETUP_R_DISABLED
Teddy Astie <[email protected]>
xen/virtio: Don't use grant-dma-ops when running as Dom0
Rafael J. Wysocki <[email protected]>
ACPI: processor: Update cpuidle driver check in __acpi_processor_start()
Florian-Ewald Mueller <[email protected]>
rnbd-srv: Fix server side setting of bi_size for special IOs
Shyam Prasad N <[email protected]>
netfs: avoid double increment of retry_count in subreq
Paulo Alcantara <[email protected]>
smb: client: fix potential UAF and double free in smb2_open_file()
Gao Xiang <[email protected]>
erofs: fix inline data read failure for ztailpacking pclusters
Boris Burkov <[email protected]>
btrfs: fix EEXIST abort due to non-consecutive gaps in chunk allocation
Boris Burkov <[email protected]>
btrfs: fix block_group_tree dirty_list corruption
Filipe Manana <[email protected]>
btrfs: qgroup: return correct error when deleting qgroup relation item
Johannes Thumshirn <[email protected]>
btrfs: zoned: don't zone append to conventional zone
Josef Bacik <[email protected]>
btrfs: add orig_logical to btrfs_bio for encryption
Qu Wenruo <[email protected]>
btrfs: introduce btrfs_bio::async_csum
Qu Wenruo <[email protected]>
btrfs: make sure all btrfs_bio::end_io are called in task context
Qu Wenruo <[email protected]>
btrfs: remove btrfs_bio::fs_info by extracting it from btrfs_bio::inode
Qu Wenruo <[email protected]>
btrfs: headers cleanup to remove unnecessary local includes
Gao Xiang <[email protected]>
erofs: handle end of filesystem properly for file-backed mounts
Gao Xiang <[email protected]>
erofs: get rid of raw bi_end_io() usage
Alper Ak <[email protected]>
tpm: st33zp24: Fix missing cleanup on get_burstcount() error
Alper Ak <[email protected]>
tpm: tpm_i2c_infineon: Fix locality leak on get_burstcount() failure
Zilin Guan <[email protected]>
i3c: dw: Fix memory leak in dw_i3c_master_i2c_xfers()
Fredrik Markstrom <[email protected]>
i3c: dw: Initialize spinlock to avoid upsetting lockdep
Deepanshu Kartikey <[email protected]>
gfs2: Fix use-after-free in iomap inline data write path
Andreas Gruenbacher <[email protected]>
gfs2: Fix slab-use-after-free in qd_put
Andreas Gruenbacher <[email protected]>
gfs2: Retries missing in gfs2_{rename,exchange}Adrian Hunter <[email protected]>
i3c: master: Update hot-join flag only on success
Ben Dooks <[email protected]>
fs: add <linux/init_task.h> for 'init_fs'
Amir Goldstein <[email protected]>
fs: move initializing f_mode before file_ref_init()
Breno Leitao <[email protected]>
device_cgroup: remove branch hint after code refactor
Billy Tsai <[email protected]>
i3c: Move device name assignment after i3c_bus_init
Xiaochen Shen <[email protected]>
selftests/resctrl: Fix a division by zero error on Hygon
Ben Dooks <[email protected]>
audit: move the compat_xxx_class[] extern declarations to audit_arch.h
Yao Kai <[email protected]>
rcu: Fix rcu_read_unlock() deadloop due to softirq
Shardul Bankar <[email protected]>
hfsplus: return error when node already exists in hfs_bnode_create
Thomas Fourier <[email protected]>
auxdisplay: arm-charlcd: fix release_mem_region() size
YunJe Shin <[email protected]>
RDMA/umad: Reject negative data_len in ib_umad_write
YunJe Shin <[email protected]>
RDMA/siw: Fix potential NULL pointer dereference in header processing
-------------
Diffstat:
Documentation/PCI/endpoint/pci-vntb-howto.rst | 14 +- .../bindings/media/qcom,qcs8300-camss.yaml | 13 + .../devicetree/bindings/phy/qcom,edp-phy.yaml | 28 +- .../bindings/sound/asahi-kasei,ak4458.yaml | 6 +- .../bindings/sound/asahi-kasei,ak5558.yaml | 4 +- Documentation/driver-api/dpll.rst | 36 +- Documentation/netlink/specs/dpll.yaml | 7 + Documentation/networking/ip-sysctl.rst | 7 +- Documentation/trace/events-pci.rst | 74 + Documentation/trace/index.rst | 1 + Makefile | 15 +- arch/arm/boot/dts/allwinner/sun5i-a13-utoo-p66.dts | 1 + arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi | 1 + arch/arm/kernel/vdso.c | 1 + arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi | 7 + arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 + arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 9 + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 9 + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 9 + arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 13 +- .../freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts | 2 +- .../dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts | 2 +- .../dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts | 2 +- .../boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi | 2 +- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 8 +- arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 2 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 4 +- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 8 +- .../arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 3 +- arch/arm64/boot/dts/qcom/sm6115.dtsi | 8 +- arch/arm64/boot/dts/qcom/sm6150.dtsi | 1 - arch/arm64/boot/dts/qcom/x1e80100.dtsi | 8 +- arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts | 1 - .../boot/dts/renesas/rzt2h-n2h-evk-common.dtsi | 4 +- .../boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi | 36 - arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 58 +- arch/arm64/mm/gcs.c | 4 +- arch/arm64/net/bpf_jit_comp.c | 2 +- arch/loongarch/net/bpf_jit.c | 2 +- arch/mips/Kconfig | 1 - arch/mips/kernel/relocate.c | 13 + arch/powerpc/include/asm/eeh.h | 2 + arch/powerpc/include/asm/kup.h | 2 - arch/powerpc/include/asm/uaccess.h | 4 + arch/powerpc/kernel/eeh_driver.c | 11 +- arch/powerpc/kernel/eeh_pe.c | 74 +- arch/powerpc/net/bpf_jit_comp.c | 2 +- arch/s390/Kconfig | 3 +- arch/x86/events/core.c | 4 +- arch/x86/hyperv/hv_vtl.c | 8 +- arch/x86/include/asm/ftrace.h | 2 +- arch/x86/kernel/cpu/amd.c | 30 +- arch/x86/kernel/ftrace_64.S | 5 +- arch/x86/xen/enlighten.c | 2 +- drivers/accel/amdxdna/aie2_ctx.c | 8 +- drivers/accel/amdxdna/amdxdna_mailbox.c | 27 +- drivers/accel/amdxdna/amdxdna_pci_drv.c | 5 +- drivers/accel/amdxdna/amdxdna_pci_drv.h | 1 + drivers/accel/amdxdna/amdxdna_ubuf.c | 10 +- drivers/acpi/acpica/evregion.c | 4 +- drivers/acpi/cppc_acpi.c | 4 +- drivers/acpi/power.c | 13 + drivers/acpi/processor_driver.c | 2 +- drivers/ata/libata-core.c | 5 + drivers/ata/libata-eh.c | 6 + drivers/ata/libata-scsi.c | 174 +- drivers/ata/libata.h | 2 + drivers/ata/pata_ftide010.c | 6 +- drivers/auxdisplay/arm-charlcd.c | 2 +- drivers/base/power/wakeirq.c | 11 +- drivers/base/power/wakeup.c | 4 +- drivers/block/drbd/drbd_main.c | 3 - drivers/block/drbd/drbd_nl.c | 20 +- drivers/block/rnbd/rnbd-srv.c | 33 +- drivers/block/ublk_drv.c | 10 +- drivers/bluetooth/btintel_pcie.c | 9 +- drivers/char/hw_random/airoha-trng.c | 1 + drivers/char/hw_random/core.c | 173 +- drivers/char/misc_minor_kunit.c | 2 +- drivers/char/tpm/st33zp24/st33zp24.c | 6 +- drivers/char/tpm/tpm_i2c_infineon.c | 6 +- drivers/clk/actions/owl-composite.c | 11 +- drivers/clk/actions/owl-divider.c | 17 +- drivers/clk/actions/owl-divider.h | 5 - drivers/clk/clk-bm1880.c | 5 +- drivers/clk/clk-loongson1.c | 5 +- drivers/clk/clk-milbeaut.c | 5 +- drivers/clk/clk-versaclock3.c | 7 +- drivers/clk/hisilicon/clkdivider-hi6220.c | 6 +- drivers/clk/mediatek/clk-mt7981-eth.c | 6 +- drivers/clk/mediatek/clk-mt8196-mfg.c | 13 +- drivers/clk/mediatek/clk-mt8516.c | 2 +- drivers/clk/mediatek/clk-mtk.c | 12 +- drivers/clk/mediatek/clk-pll.c | 3 + drivers/clk/mediatek/clk-pll.h | 1 + drivers/clk/meson/g12a.c | 17 +- drivers/clk/meson/gxbb.c | 17 +- drivers/clk/microchip/clk-core.c | 10 - drivers/clk/nuvoton/clk-ma35d1-divider.c | 7 +- drivers/clk/nxp/clk-lpc32xx.c | 6 +- drivers/clk/qcom/clk-alpha-pll.c | 21 +- drivers/clk/qcom/clk-rcg2.c | 7 +- drivers/clk/qcom/clk-regmap-divider.c | 16 +- drivers/clk/qcom/common.c | 2 +- drivers/clk/qcom/dispcc-sdm845.c | 4 +- drivers/clk/qcom/dispcc-sm7150.c | 2 +- drivers/clk/qcom/gcc-glymur.c | 4 +- drivers/clk/qcom/gcc-ipq5018.c | 1 + drivers/clk/qcom/gcc-milos.c | 6 +- drivers/clk/qcom/gcc-msm8917.c | 1 - drivers/clk/qcom/gcc-msm8953.c | 1 - drivers/clk/qcom/gcc-qdu1000.c | 4 +- drivers/clk/qcom/gcc-sdx75.c | 4 +- drivers/clk/qcom/gcc-sm4450.c | 6 +- drivers/clk/qcom/gcc-sm8450.c | 4 +- drivers/clk/qcom/gcc-sm8550.c | 4 +- drivers/clk/qcom/gcc-sm8650.c | 4 +- drivers/clk/qcom/gcc-sm8750.c | 4 +- drivers/clk/qcom/gcc-x1e80100.c | 4 +- drivers/clk/rockchip/clk.c | 2 +- drivers/clk/sophgo/clk-sg2042-clkgen.c | 15 +- drivers/clk/spacemit/Makefile | 9 +- drivers/clk/spacemit/ccu-k1.c | 1 + drivers/clk/spacemit/ccu_common.c | 6 + drivers/clk/spacemit/ccu_ddn.c | 1 + drivers/clk/spacemit/ccu_mix.c | 9 + drivers/clk/spacemit/ccu_pll.c | 1 + drivers/clk/sprd/div.c | 6 +- drivers/clk/stm32/clk-stm32-core.c | 42 +- drivers/clk/thead/clk-th1520-ap.c | 34 +- drivers/clk/x86/clk-cgu.c | 6 +- drivers/clk/zynqmp/divider.c | 10 +- drivers/clk/zynqmp/pll.c | 5 +- drivers/cpufreq/intel_pstate.c | 2 +- drivers/cpufreq/scmi-cpufreq.c | 1 + drivers/cpuidle/cpuidle.c | 10 + drivers/cpuidle/governors/menu.c | 22 +- drivers/crypto/caam/caamalg_qi2.c | 27 +- drivers/crypto/caam/caamalg_qi2.h | 2 + drivers/crypto/cavium/cpt/cptvf_main.c | 3 +- drivers/crypto/ccp/ccp-ops.c | 2 +- drivers/crypto/ccp/psp-dev.c | 11 + drivers/crypto/ccp/sev-dev.c | 59 +- drivers/crypto/ccp/sp-dev.c | 12 + drivers/crypto/ccp/sp-dev.h | 3 + drivers/crypto/ccp/sp-pci.c | 16 +- drivers/crypto/ccp/tee-dev.c | 56 +- drivers/crypto/ccp/tee-dev.h | 1 + drivers/crypto/hisilicon/Kconfig | 1 + drivers/crypto/hisilicon/hpre/hpre.h | 5 +- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 418 ++-- drivers/crypto/hisilicon/hpre/hpre_main.c | 2 +- drivers/crypto/hisilicon/qm.c | 112 +- drivers/crypto/hisilicon/sec2/sec.h | 7 - drivers/crypto/hisilicon/sec2/sec_crypto.c | 163 +- drivers/crypto/hisilicon/sec2/sec_main.c | 21 +- drivers/crypto/hisilicon/sgl.c | 2 +- drivers/crypto/hisilicon/trng/trng.c | 123 +- drivers/crypto/hisilicon/zip/zip.h | 2 +- drivers/crypto/hisilicon/zip/zip_crypto.c | 133 +- drivers/crypto/hisilicon/zip/zip_main.c | 4 +- drivers/crypto/inside-secure/eip93/eip93-main.c | 94 +- .../intel/qat/qat_common/adf_pfvf_pf_proto.c | 10 + drivers/crypto/marvell/octeontx/otx_cptvf_main.c | 3 +- drivers/crypto/starfive/jh7110-aes.c | 9 +- drivers/cxl/core/edac.c | 64 +- drivers/cxl/core/hdm.c | 3 +- drivers/cxl/core/memdev.c | 1 - drivers/cxl/core/port.c | 8 +- drivers/cxl/cxlmem.h | 5 +- drivers/dma/dma-axi-dmac.c | 11 +- drivers/dma/fsl-edma-main.c | 1 - drivers/dma/mediatek/mtk-uart-apdma.c | 10 +- drivers/dpll/dpll_netlink.c | 12 +- drivers/dpll/zl3073x/Makefile | 3 +- drivers/dpll/zl3073x/core.c | 225 -- drivers/dpll/zl3073x/core.h | 167 +- drivers/dpll/zl3073x/dpll.c | 436 +--- drivers/dpll/zl3073x/out.c | 157 ++ drivers/dpll/zl3073x/out.h | 93 + drivers/dpll/zl3073x/prop.c | 19 +- drivers/dpll/zl3073x/ref.c | 112 + drivers/dpll/zl3073x/ref.h | 66 + drivers/dpll/zl3073x/synth.c | 87 + drivers/dpll/zl3073x/synth.h | 72 + drivers/edac/altera_edac.c | 11 +- drivers/edac/i5000_edac.c | 1 + drivers/edac/i5400_edac.c | 2 +- drivers/firmware/arm_ffa/driver.c | 33 +- drivers/firmware/efi/efi.c | 8 +- drivers/gpio/gpio-amd-fch.c | 7 +- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 - drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 6 +- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 6 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 8 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 14 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 20 +- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 14 +- drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 45 +- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 + .../display/dc/resource/dcn315/dcn315_resource.c | 8 +- .../display/dc/resource/dcn316/dcn316_resource.c | 8 +- .../amd/display/dc/resource/dcn32/dcn32_resource.c | 8 +- .../display/dc/resource/dcn321/dcn321_resource.c | 8 +- .../amd/display/dc/resource/dcn35/dcn35_resource.c | 8 +- .../display/dc/resource/dcn351/dcn351_resource.c | 8 +- drivers/gpu/drm/drm_buddy.c | 1 + drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 36 +- drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 + drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h | 2 + drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 38 +- drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 8 + drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 3 + drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 71 +- drivers/gpu/drm/i915/display/intel_acpi.c | 1 + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 5 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 18 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 7 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 49 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 35 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 7 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 7 + drivers/gpu/drm/msm/disp/mdp_format.c | 8 +- drivers/gpu/drm/msm/dp/dp_ctrl.c | 24 +- drivers/gpu/drm/msm/dp/dp_display.c | 4 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 7 +- drivers/gpu/drm/msm/msm_mdss.c | 2 +- drivers/gpu/drm/panel/panel-lg-sw43408.c | 4 - drivers/gpu/drm/panthor/panthor_gpu.c | 21 +- drivers/gpu/drm/panthor/panthor_mmu.c | 4 + drivers/gpu/drm/panthor/panthor_sched.c | 169 +- drivers/gpu/drm/panthor/panthor_sched.h | 1 + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 7 +- drivers/gpu/drm/xe/xe_bo.c | 2 +- drivers/gpu/drm/xe/xe_configfs.h | 12 +- drivers/gpu/drm/xe/xe_device.c | 1 + drivers/gpu/drm/xe/xe_guc_pc.c | 34 + drivers/gpu/drm/xe/xe_mmio.c | 10 +- drivers/gpu/drm/xe/xe_module.h | 2 +- drivers/gpu/drm/xe/xe_wa.c | 18 +- drivers/hid/hid-playstation.c | 4 +- drivers/hid/intel-ish-hid/ishtp/bus.c | 2 +- drivers/hv/mshv_eventfd.c | 5 +- drivers/hv/vmbus_drv.c | 66 +- drivers/hwmon/ibmpex.c | 9 +- drivers/hwmon/pmbus/mpq8785.c | 28 + drivers/hwspinlock/omap_hwspinlock.c | 4 +- drivers/hwtracing/coresight/coresight-etm3x-core.c | 12 +- drivers/hwtracing/coresight/coresight-tmc-etr.c | 13 + drivers/i3c/master.c | 6 +- drivers/i3c/master/dw-i3c-master.c | 3 + drivers/iio/accel/sca3000.c | 6 +- drivers/iio/gyro/mpu3050-core.c | 6 +- drivers/iio/pressure/mprls0025pa.c | 36 +- drivers/iio/pressure/mprls0025pa.h | 2 - drivers/iio/pressure/mprls0025pa_spi.c | 19 +- drivers/iio/test/Kconfig | 1 - drivers/infiniband/core/cache.c | 3 +- drivers/infiniband/core/iwcm.c | 56 +- drivers/infiniband/core/iwcm.h | 1 - drivers/infiniband/core/rw.c | 53 +- drivers/infiniband/core/user_mad.c | 8 +- drivers/infiniband/core/uverbs_cmd.c | 7 +- drivers/infiniband/hw/hns/hns_roce_ah.c | 23 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 54 +- drivers/infiniband/hw/mlx5/main.c | 101 +- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 + drivers/infiniband/hw/mlx5/std_types.c | 4 +- drivers/infiniband/sw/rxe/rxe_comp.c | 3 + drivers/infiniband/sw/rxe/rxe_mr.c | 285 ++- drivers/infiniband/sw/rxe/rxe_req.c | 3 + drivers/infiniband/sw/rxe/rxe_srq.c | 6 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 10 +- drivers/infiniband/sw/siw/siw_qp_rx.c | 3 +- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 33 +- drivers/interconnect/mediatek/icc-emi.c | 9 +- drivers/iommu/amd/amd_iommu.h | 1 - drivers/iommu/amd/init.c | 12 +- drivers/iommu/amd/iommu.c | 5 - drivers/iommu/intel/iommu.c | 4 +- drivers/iommu/intel/iommu.h | 21 +- drivers/iommu/intel/pasid.c | 18 +- drivers/iommu/intel/pasid.h | 14 + drivers/leds/leds-expresswire.c | 24 +- drivers/leds/rgb/leds-qcom-lpg.c | 8 +- drivers/mailbox/pcc.c | 102 +- drivers/mcb/mcb-core.c | 9 +- drivers/md/dm-zone.c | 11 +- drivers/md/dm.c | 2 + drivers/md/md-llbitmap.c | 4 +- drivers/md/md.h | 4 +- drivers/md/raid1.c | 1 + drivers/md/raid10.c | 2 +- drivers/md/raid5.c | 10 +- drivers/media/i2c/ccs/ccs-core.c | 16 +- drivers/media/pci/mgb4/mgb4_trigger.c | 2 +- .../platform/chips-media/wave5/wave5-vpu-dec.c | 4 +- .../platform/chips-media/wave5/wave5-vpu-enc.c | 4 +- drivers/media/usb/uvc/uvc_video.c | 3 +- drivers/mfd/Kconfig | 11 + drivers/mfd/arizona-core.c | 2 +- drivers/mfd/simple-mfd-i2c.c | 1 + drivers/mtd/devices/mtd_intel_dg.c | 9 +- drivers/mtd/nand/raw/cadence-nand-controller.c | 2 +- drivers/mtd/parsers/ofpart_core.c | 16 +- drivers/mtd/parsers/tplink_safeloader.c | 1 + drivers/net/bonding/bond_main.c | 21 +- drivers/net/caif/caif_serial.c | 5 +- drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 11 +- .../net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c | 21 +- .../net/ethernet/marvell/octeon_ep/octep_cnxk_pf.c | 64 +- .../net/ethernet/marvell/octeon_ep/octep_main.h | 2 +- .../marvell/octeon_ep/octep_regs_cn9k_pf.h | 1 + .../marvell/octeon_ep/octep_regs_cnxk_pf.h | 1 + drivers/net/ethernet/marvell/octeon_ep/octep_rx.c | 8 +- .../ethernet/marvell/octeon_ep_vf/octep_vf_cn9k.c | 3 +- .../ethernet/marvell/octeon_ep_vf/octep_vf_cnxk.c | 39 +- .../ethernet/marvell/octeon_ep_vf/octep_vf_main.h | 2 +- .../ethernet/marvell/octeon_ep_vf/octep_vf_rx.c | 8 +- drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 11 + .../net/ethernet/marvell/octeontx2/af/rvu_npc.c | 41 +- .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 +- drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 14 - .../ethernet/mellanox/mlx5/core/en/reporter_rx.c | 13 + .../ethernet/mellanox/mlx5/core/en/reporter_tx.c | 52 +- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 40 - drivers/net/ethernet/mellanox/mlx5/core/wc.c | 14 +- drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 + drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c | 3 - drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 20 + drivers/net/ethernet/meta/fbnic/fbnic_netdev.h | 2 + drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 19 +- drivers/net/ethernet/meta/fbnic/fbnic_phylink.c | 3 + drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 5 +- drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 43 +- drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 3 +- drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- drivers/net/ethernet/mscc/ocelot_net.c | 89 +- .../net/ethernet/pensando/ionic/ionic_ethtool.c | 7 +- drivers/net/ethernet/renesas/rswitch_l2.c | 15 +- drivers/net/ethernet/stmicro/stmmac/common.h | 5 + .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 5 +- .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +- .../net/ethernet/stmicro/stmmac/dwmac-loongson.c | 6 +- .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +- .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +- drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c | 2 +- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.c | 73 +- drivers/net/ethernet/stmicro/stmmac/stmmac_est.c | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 68 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 63 +- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 14 +- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 9 +- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 4 +- drivers/net/ethernet/sun/sunhme.c | 3 + drivers/net/macvlan.c | 5 + drivers/net/mctp/mctp-i2c.c | 9 + drivers/net/ovpn/io.c | 57 +- drivers/net/ovpn/socket.c | 41 +- drivers/net/ovpn/tcp.c | 23 +- drivers/net/ovpn/udp.c | 1 + drivers/net/usb/catc.c | 37 +- drivers/net/wireless/ath/ath10k/sdio.c | 6 + drivers/net/wireless/ath/ath11k/core.c | 27 + drivers/net/wireless/ath/ath11k/core.h | 4 + .../net/wireless/ath/ath12k/debugfs_htt_stats.c | 8 +- drivers/net/wireless/ath/ath12k/mac.c | 4 +- drivers/net/wireless/ath/ath12k/wow.c | 16 + drivers/net/wireless/ath/ath9k/Kconfig | 2 +- drivers/net/wireless/realtek/rtw89/debug.c | 8 +- drivers/net/xen-netback/xenbus.c | 5 +- drivers/nvdimm/nd_virtio.c | 3 +- drivers/nvdimm/virtio_pmem.c | 1 + drivers/nvdimm/virtio_pmem.h | 4 + drivers/nvmem/Kconfig | 2 +- drivers/of/unittest.c | 6 +- drivers/opp/core.c | 2 +- drivers/pci/controller/dwc/pcie-sophgo.c | 18 + drivers/pci/controller/pcie-mediatek.c | 4 +- drivers/pci/controller/pcie-xilinx.c | 9 +- drivers/pci/p2pdma.c | 10 +- drivers/pci/pci-acpi.c | 59 +- drivers/pci/pci.c | 5 +- drivers/pci/pci.h | 3 + drivers/pci/pcie/aer.c | 3 - drivers/pci/pcie/portdrv.c | 6 +- drivers/pci/pcie/ptm.c | 5 +- drivers/pci/probe.c | 35 +- drivers/pci/quirks.c | 5 + drivers/pci/setup-bus.c | 138 +- drivers/perf/arm_spe_pmu.c | 18 +- drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 2 +- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 + drivers/pinctrl/meson/pinctrl-amlogic-a4.c | 10 +- drivers/pinctrl/pinctrl-equilibrium.c | 1 + drivers/pinctrl/pinctrl-k230.c | 7 +- drivers/pinctrl/pinctrl-single.c | 2 + drivers/pinctrl/qcom/pinctrl-sm8250-lpass-lpi.c | 2 +- drivers/platform/chrome/cros_ec_lightbar.c | 2 +- drivers/platform/chrome/cros_typec_switch.c | 6 +- drivers/platform/x86/amd/pmf/core.c | 62 +- drivers/platform/x86/amd/pmf/pmf.h | 10 + drivers/platform/x86/amd/pmf/tee-if.c | 12 +- drivers/platform/x86/hp/hp-wmi.c | 179 +- drivers/platform/x86/intel/int0002_vgpio.c | 4 +- drivers/power/reset/nvmem-reboot-mode.c | 15 +- drivers/power/supply/ab8500_charger.c | 40 +- drivers/power/supply/act8945a_charger.c | 16 +- drivers/power/supply/bq256xx_charger.c | 12 +- drivers/power/supply/bq25980_charger.c | 12 +- drivers/power/supply/bq27xxx_battery.c | 6 +- drivers/power/supply/cpcap-battery.c | 8 +- drivers/power/supply/goldfish_battery.c | 12 +- drivers/power/supply/pm8916_bms_vm.c | 18 +- drivers/power/supply/pm8916_lbc.c | 18 +- drivers/power/supply/qcom_battmgr.c | 3 +- drivers/power/supply/rt9455_charger.c | 17 +- drivers/power/supply/sbs-battery.c | 36 +- drivers/power/supply/wm97xx_battery.c | 34 +- drivers/powercap/intel_rapl_tpmi.c | 2 +- drivers/pwm/pwm-tiehrpwm.c | 6 +- drivers/regulator/core.c | 55 +- drivers/remoteproc/imx_dsp_rproc.c | 8 +- drivers/reset/Kconfig | 2 +- drivers/rtc/rtc-amlogic-a4.c | 2 +- drivers/s390/cio/css.c | 2 +- drivers/scsi/csiostor/csio_scsi.c | 3 +- drivers/scsi/elx/efct/efct_driver.c | 8 +- drivers/scsi/smartpqi/smartpqi_init.c | 13 +- drivers/soc/mediatek/mtk-svs.c | 5 +- drivers/soc/qcom/cmd-db.c | 7 +- drivers/soc/qcom/smem.c | 4 +- drivers/soundwire/Kconfig | 1 + drivers/spi/spi-wpcm-fiu.c | 2 +- drivers/staging/gpib/common/iblib.c | 5 +- drivers/staging/gpib/ni_usb/ni_usb_gpib.c | 14 +- drivers/staging/greybus/light.c | 8 +- drivers/thermal/intel/x86_pkg_temp_thermal.c | 3 + drivers/thermal/thermal_of.c | 4 +- drivers/tty/serial/Kconfig | 8 +- drivers/ufs/host/Kconfig | 1 + drivers/ufs/host/ufs-mediatek.c | 12 +- drivers/usb/cdns3/core.c | 2 +- drivers/usb/gadget/udc/bdc/bdc_core.c | 4 +- drivers/usb/typec/tcpm/fusb302.c | 3 +- drivers/usb/typec/ucsi/Kconfig | 1 - drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 24 + drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h | 2 + drivers/vfio/pci/vfio_pci_core.c | 17 +- drivers/video/backlight/qcom-wled.c | 42 +- drivers/video/fbdev/au1200fb.c | 6 +- drivers/video/of_display_timing.c | 6 +- drivers/watchdog/starfive-wdt.c | 2 +- drivers/xen/balloon.c | 19 +- drivers/xen/grant-dma-ops.c | 3 +- drivers/xen/unpopulated-alloc.c | 3 + fs/btrfs/accessors.h | 1 + fs/btrfs/bio.c | 167 +- fs/btrfs/bio.h | 30 +- fs/btrfs/block-group.c | 31 +- fs/btrfs/block-rsv.c | 9 +- fs/btrfs/btrfs_inode.h | 8 +- fs/btrfs/compression.c | 6 +- fs/btrfs/compression.h | 6 +- fs/btrfs/ctree.h | 2 - fs/btrfs/defrag.c | 1 + fs/btrfs/dir-item.c | 1 + fs/btrfs/direct-io.c | 6 +- fs/btrfs/disk-io.c | 1 + fs/btrfs/disk-io.h | 3 +- fs/btrfs/extent-tree.c | 1 + fs/btrfs/extent_io.c | 22 +- fs/btrfs/extent_io.h | 1 - fs/btrfs/extent_map.h | 3 +- fs/btrfs/file-item.c | 64 +- fs/btrfs/file-item.h | 4 +- fs/btrfs/inode.c | 8 +- fs/btrfs/qgroup.c | 15 +- fs/btrfs/scrub.c | 51 +- fs/btrfs/space-info.c | 15 +- fs/btrfs/space-info.h | 5 +- fs/btrfs/subpage.h | 1 - fs/btrfs/transaction.c | 11 +- fs/btrfs/transaction.h | 4 - fs/btrfs/tree-log.c | 1 + fs/btrfs/tree-log.h | 3 +- fs/btrfs/volumes.c | 243 +- fs/btrfs/zoned.c | 4 +- fs/btrfs/zoned.h | 1 - fs/erofs/fileio.c | 22 +- fs/erofs/fscache.c | 4 +- fs/erofs/zdata.c | 30 +- fs/ext4/ext4.h | 16 + fs/ext4/extents.c | 54 +- fs/ext4/fast_commit.c | 51 +- fs/ext4/mballoc-test.c | 2 +- fs/ext4/mballoc.c | 73 +- fs/fat/namei_msdos.c | 7 +- fs/fat/namei_vfat.c | 7 +- fs/file_table.c | 10 +- fs/fs_struct.c | 1 + fs/gfs2/bmap.c | 13 +- fs/gfs2/glock.c | 36 +- fs/gfs2/glock.h | 3 +- fs/gfs2/inode.c | 18 +- fs/gfs2/quota.c | 1 + fs/hfsplus/bnode.c | 2 +- fs/iomap/direct-io.c | 10 +- fs/jfs/jfs_dtree.c | 4 +- fs/netfs/write_retry.c | 1 - fs/nfs/dir.c | 4 +- fs/nfs/localio.c | 92 +- fs/nfs/pnfs.c | 3 +- fs/nfsd/nfs2acl.c | 2 +- fs/nfsd/nfs4idmap.c | 48 +- fs/nfsd/nfs4proc.c | 2 - fs/nfsd/nfs4xdr.c | 16 + fs/nfsd/nfsproc.c | 2 +- fs/ntfs3/file.c | 10 +- fs/ntfs3/fslog.c | 3 + fs/overlayfs/readdir.c | 2 +- fs/pidfs.c | 2 +- fs/proc/array.c | 2 +- fs/pstore/ram_core.c | 11 + fs/quota/quota.c | 1 + fs/smb/client/smb2file.c | 2 + fs/smb/client/smbdirect.c | 19 +- fs/tests/exec_kunit.c | 6 - include/acpi/pcc.h | 29 - include/asm-generic/rqspinlock.h | 2 +- include/drm/intel/intel_lb_mei_interface.h | 3 +- include/linux/audit.h | 6 - include/linux/audit_arch.h | 7 + include/linux/bpf.h | 5 + include/linux/bpf_mprog.h | 10 + include/linux/capability.h | 6 + include/linux/clk.h | 48 +- include/linux/device_cgroup.h | 2 +- include/linux/dpll.h | 1 + include/linux/filter.h | 26 +- include/linux/ftrace.h | 6 +- include/linux/hisi_acc_qm.h | 13 +- include/linux/hw_random.h | 2 + include/linux/input/adp5589.h | 180 -- include/linux/interrupt.h | 2 +- include/linux/io_uring_types.h | 7 +- include/linux/leds-expresswire.h | 3 - include/linux/libata.h | 3 + include/linux/mfd/wm8350/core.h | 2 +- include/linux/mlx5/driver.h | 4 +- include/linux/module.h | 9 + include/linux/mtd/spinand.h | 2 +- include/linux/psp.h | 1 + include/linux/skmsg.h | 70 +- include/linux/soc/qcom/ubwc.h | 1 + include/linux/stmmac.h | 12 +- include/linux/sunrpc/xdrgen/_builtins.h | 20 +- include/linux/u64_stats_sync.h | 10 + include/net/inet_ecn.h | 20 +- include/net/ipv6.h | 11 +- include/net/netfilter/nf_conntrack_count.h | 1 + include/net/netfilter/nf_queue.h | 4 + include/net/netfilter/nf_tables.h | 4 + include/net/netns/ipv4.h | 9 +- include/net/tcp.h | 31 +- include/net/tcp_ecn.h | 66 +- include/rdma/rw.h | 2 + include/sound/sdca_function.h | 1 + include/uapi/linux/dpll.h | 1 + include/uapi/linux/nfs.h | 2 +- include/ufs/ufshcd.h | 4 - include/xen/xen.h | 2 + io_uring/cancel.h | 6 +- io_uring/io_uring.c | 14 +- io_uring/kbuf.c | 5 +- io_uring/msg_ring.c | 12 +- io_uring/register.c | 3 +- io_uring/rsrc.c | 27 +- io_uring/sync.c | 2 + ipc/ipc_sysctl.c | 2 +- kernel/bpf/core.c | 4 +- kernel/bpf/helpers.c | 2 +- kernel/bpf/rqspinlock.c | 7 +- kernel/bpf/syscall.c | 19 +- kernel/bpf/verifier.c | 66 +- kernel/kallsyms.c | 9 +- kernel/module/kallsyms.c | 9 +- kernel/rcu/tree.h | 2 +- kernel/rcu/tree_plugin.h | 15 +- kernel/sched/core.c | 4 + kernel/sched/deadline.c | 3 + kernel/sched/rt.c | 5 + kernel/time/hrtimer.c | 2 +- kernel/time/sched_clock.c | 2 +- kernel/trace/bpf_trace.c | 6 +- kernel/trace/ftrace.c | 5 +- kernel/trace/trace_events.c | 5 - kernel/trace/trace_events_hist.c | 2 +- kernel/ucount.c | 2 +- kernel/workqueue.c | 92 +- lib/kstrtox.c | 4 +- lib/objpool.c | 2 +- mm/slub.c | 20 + net/atm/signaling.c | 56 +- net/bridge/br_multicast.c | 45 +- net/core/dev.c | 2 +- net/core/filter.c | 22 +- net/core/skmsg.c | 30 +- net/ipv4/icmp.c | 32 +- net/ipv4/ping.c | 33 +- net/ipv4/tcp.c | 3 + net/ipv4/tcp_bpf.c | 25 +- net/ipv4/tcp_cong.c | 5 +- net/ipv4/tcp_input.c | 5 +- net/ipv4/tcp_minisocks.c | 7 +- net/ipv4/udp_bpf.c | 23 +- net/ipv6/af_inet6.c | 2 +- net/ipv6/icmp.c | 13 +- net/ipv6/ip6_fib.c | 2 +- net/mptcp/protocol.c | 14 +- net/mptcp/protocol.h | 5 + net/netfilter/ipvs/ip_vs_xmit.c | 46 +- net/netfilter/nf_conncount.c | 54 +- net/netfilter/nf_conntrack_h323_main.c | 10 +- net/netfilter/nf_tables_api.c | 34 +- net/netfilter/nfnetlink_queue.c | 267 ++- net/netfilter/nft_compat.c | 13 +- net/netfilter/nft_connlimit.c | 7 +- net/netfilter/nft_counter.c | 4 +- net/netfilter/nft_set_hash.c | 9 +- net/netfilter/nft_set_rbtree.c | 794 +++++-- net/nfc/hci/llc_shdlc.c | 8 + net/psp/Kconfig | 1 + net/rds/send.c | 6 +- net/sunrpc/auth_gss/auth_gss.c | 3 + net/sunrpc/auth_gss/gss_rpc_xdr.c | 82 +- net/sunrpc/xprtrdma/svc_rdma_transport.c | 8 +- net/unix/af_unix.c | 11 +- net/wireless/core.c | 4 +- net/wireless/scan.c | 2 +- rust/kernel/task.rs | 24 +- security/apparmor/apparmorfs.c | 9 + security/apparmor/file.c | 15 +- security/apparmor/include/match.h | 12 +- security/apparmor/label.c | 33 +- security/apparmor/lsm.c | 33 +- security/apparmor/match.c | 22 +- security/apparmor/net.c | 6 +- security/apparmor/policy_unpack.c | 6 +- security/apparmor/resource.c | 5 + security/integrity/evm/evm_crypto.c | 14 +- security/smack/smackfs.c | 79 +- sound/core/pcm.c | 4 +- sound/core/pcm_compat.c | 9 +- sound/core/pcm_native.c | 50 +- sound/core/vmaster.c | 12 +- sound/hda/codecs/conexant.c | 10 + sound/hda/codecs/realtek/alc269.c | 2 + sound/soc/codecs/aw88261.c | 3 +- sound/soc/codecs/nau8821.c | 5 + sound/soc/codecs/nau8821.h | 1 + sound/soc/fsl/fsl_xcvr.c | 3 - sound/soc/rockchip/rockchip_i2s_tdm.c | 10 + sound/soc/sdca/sdca_asoc.c | 54 +- sound/soc/sdca/sdca_functions.c | 62 +- sound/soc/sdca/sdca_regmap.c | 9 +- sound/soc/tegra/tegra210_ahub.c | 57 + sound/soc/tegra/tegra210_ahub.h | 30 + tools/bpf/bpftool/net.c | 5 +- tools/lib/bpf/btf_dump.c | 9 + tools/lib/bpf/linker.c | 2 +- tools/lib/bpf/netlink.c | 4 +- tools/net/sunrpc/xdrgen/generators/__init__.py | 3 +- .../xdrgen/templates/C/program/decoder/argument.j2 | 4 + .../xdrgen/templates/C/program/encoder/result.j2 | 6 + .../sunrpc/xdrgen/templates/C/source_top/client.j2 | 1 - tools/objtool/Makefile | 2 + tools/power/x86/intel-speed-select/isst-config.c | 2 + tools/spi/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/prog_tests/check_mtu.c | 23 +- .../selftests/bpf/prog_tests/stacktrace_ips.c | 19 +- tools/testing/selftests/bpf/prog_tests/wq.c | 5 +- tools/testing/selftests/bpf/progs/test_check_mtu.c | 12 + tools/testing/selftests/bpf/test_xsk.c | 2422 +++++++++++++++++++ tools/testing/selftests/bpf/test_xsk.h | 297 +++ tools/testing/selftests/bpf/veristat.c | 2 +- tools/testing/selftests/bpf/xskxceiver.c | 2497 +------------------- tools/testing/selftests/bpf/xskxceiver.h | 156 -- .../selftests/drivers/net/lib/sh/lib_netcons.sh | 6 +- .../selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 +- tools/testing/selftests/memfd/memfd_test.c | 113 +- tools/testing/selftests/mm/cow.c | 16 +- tools/testing/selftests/mm/pagemap_ioctl.c | 9 +- .../testing/selftests/net/forwarding/tc_actions.sh | 2 +- .../selftests/net/forwarding/vxlan_bridge_1d.sh | 26 +- .../net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- tools/testing/selftests/net/lib.sh | 2 +- tools/testing/selftests/resctrl/resctrlfs.c | 10 + 723 files changed, 11582 insertions(+), 7566 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/641 RDMA/siw: Fix potential NULL pointer dereference in header processing
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: YunJe Shin <[email protected]>
commit 14ab3da122bd18920ad57428f6cf4fade8385142 upstream.
If siw_get_hdr() returns -EINVAL before set_rx_fpdu_context(), qp->rx_fpdu can be NULL. The error path in siw_tcp_rx_data() dereferences qp->rx_fpdu->more_ddp_segs without checking, which may lead to a NULL pointer deref. Only check more_ddp_segs when rx_fpdu is present.
KASAN splat:
[ 101.384271] KASAN: null-ptr-deref in range [0x00000000000000c0-0x00000000000000c7] [ 101.385869] RIP: 0010:siw_tcp_rx_data+0x13ad/0x1e50
--- drivers/infiniband/sw/siw/siw_qp_rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/sw/siw/siw_qp_rx.c +2 -1
@@ -1435,7 +1435,8 @@ int siw_tcp_rx_data(read_descriptor_t *r }if (unlikely (rv !=0 && rv != -EAGAIN )) {if ((srx->state >SIW_GET_HDR || - qp->rx_fpdu->more_ddp_segs) && run_completion) + (qp->rx_fpdu && qp->rx_fpdu->more_ddp_segs)) && + run_completion)siw_rdmap_complete (qp, rv); siw_dbg_qp(qp, "rx error %d, rx state %d\n", rv,
Greg Kroah-Hartman
maintainerPATCH 2/641 RDMA/umad: Reject negative data_len in ib_umad_write
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: YunJe Shin <[email protected]>
commit 5551b02fdbfd85a325bb857f3a8f9c9f33397ed2 upstream.
ib_umad_write computes data_len from user-controlled count and the MAD header sizes. With a mismatched user MAD header size and RMPP header length, data_len can become negative and reach ib_create_send_mad(). This can make the padding calculation exceed the segment size and trigger an out-of-bounds memset in alloc_send_rmpp_list().
Add an explicit check to reject negative data_len before creating the send buffer.
KASAN splat:
[ 211.363464] BUG: KASAN: slab-out-of-bounds in ib_create_send_mad+0xa01/0x11b0 [ 211.364077] Write of size 220 at addr ffff88800c3fa1f8 by task spray_thread/102 [ 211.365867] ib_create_send_mad+0xa01/0x11b0 [ 211.365887] ib_umad_write+0x853/0x1c80
--- drivers/infiniband/core/user_mad.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/infiniband/core/user_mad.c +6 -2
@@ -514,7 +514,8 @@ static ssize_t ib_umad_write(struct filestruct rdma_ah_attr ah_attr;struct ib_ah *ah;__be64 *tid; -int ret, data_len, hdr_len, copy_offset, rmpp_active; +int ret, hdr_len, copy_offset, rmpp_active; +size_t data_len;u8 base_version;if (count <hdr_size (file) +IB_MGMT_RMPP_HDR )
@@ -588,7 +589,10 @@ static ssize_t ib_umad_write(struct file } base_version = ((struct ib_mad_hdr *)&packet->mad.data)->base_version; - data_len = count -hdr_size (file) - hdr_len; +if (check_sub_overflow (count,hdr_size (file) + hdr_len, &data_len)) { + ret = -EINVAL ; + goto err_ah; + } packet->msg = ib_create_send_mad(agent, be32_to_cpu(packet->mad.hdr.qpn), packet->mad.hdr.pkey_index, rmpp_active,
Greg Kroah-Hartman
maintainerPATCH 3/641 auxdisplay: arm-charlcd: fix release_mem_region() size
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit b5c23a4d291d2ac1dfdd574a68a3a68c8da3069e ]
It seems like, after the request_mem_region(), the corresponding release_mem_region() must take the same size. This was done in (now removed due to previous refactoring) charlcd_remove() but not in the error path in charlcd_probe().
--- drivers/auxdisplay/arm-charlcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/auxdisplay/arm-charlcd.c +1 -1
@@ -323,7 +323,7 @@ static int __init charlcd_probe(struct platform_device *pdev) out_no_irq:iounmap (lcd->virtbase); out_no_memregion: -release_mem_region (lcd->phybase,SZ_4K ); +release_mem_region (lcd->phybase, lcd->physize); out_no_resource:kfree (lcd);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 4/641 hfsplus: return error when node already exists in hfs_bnode_create
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shardul Bankar <[email protected]>
[ Upstream commit d8a73cc46c8462a969a7516131feb3096f4c49d3 ]
When hfs_bnode_create() finds that a node is already hashed (which should not happen in normal operation), it currently returns the existing node without incrementing its reference count. This causes a reference count inconsistency that leads to a kernel panic when the node is later freed in hfs_bnode_put():
kernel BUG at fs/hfsplus/bnode.c:676!
BUG_ON(!atomic_read(&node->refcnt))
This scenario can occur when hfs_bmap_alloc() attempts to allocate a node that is already in use (e.g., when node 0's bitmap bit is incorrectly unset), or due to filesystem corruption.
Returning an existing node from a create path is not normal operation.
Fix this by returning ERR_PTR(-EEXIST) instead of the node when it's already hashed. This properly signals the error condition to callers, which already check for IS_ERR() return values.
--- fs/hfsplus/bnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/hfsplus/bnode.c +1 -1
@@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)if (node) {pr_crit ("new node %u already hashed?\n" , num);WARN_ON (1 ); -return node; +return ERR_PTR (-EEXIST ); } node =__hfs_bnode_create (tree, num);if (!node)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 5/641 rcu: Fix rcu_read_unlock() deadloop due to softirq
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Kai <[email protected]>
[ Upstream commit d41e37f26b3157b3f1d10223863519a943aa239b ]
Commit 5f5fa7ea89dc ("rcu: Don't use negative nesting depth in __rcu_read_unlock()") removes the recursion-protection code from __rcu_read_unlock(). Therefore, we could invoke the deadloop in raise_softirq_irqoff() with ftrace enabled as follows:
WARNING: CPU: 0 PID: 0 at kernel/trace/trace.c:3021 __ftrace_trace_stack.constprop.0+0x172/0x180 Modules linked in: my_irq_work(O) CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G O 6.18.0-rc7-dirty #23 PREEMPT(full) Tainted: [O]=OOT_MODULE Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:__ftrace_trace_stack.constprop.0+0x172/0x180 RSP: 0018:ffffc900000034a8 EFLAGS: 00010002 RAX: 0000000000000000 RBX: 0000000000000004 RCX: 0000000000000000 RDX: 0000000000000003 RSI: ffffffff826d7b87 RDI: ffffffff826e9329 RBP: 0000000000090009 R08: 0000000000000005 R09: ffffffff82afbc4c R10: 0000000000000008 R11: 0000000000011d7a R12: 0000000000000000 R13: ffff888003874100 R14: 0000000000000003 R15: ffff8880038c1054 FS: 0000000000000000(0000) GS:ffff8880fa8ea000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055b31fa7f540 CR3: 00000000078f4005 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <IRQ> trace_buffer_unlock_commit_regs+0x6d/0x220 trace_event_buffer_commit+0x5c/0x260 trace_event_raw_event_softirq+0x47/0x80 raise_softirq_irqoff+0x6e/0xa0 rcu_read_unlock_special+0xb1/0x160 unwind_next_frame+0x203/0x9b0 __unwind_start+0x15d/0x1c0 arch_stack_walk+0x62/0xf0 stack_trace_save+0x48/0x70 __ftrace_trace_stack.constprop.0+0x144/0x180 trace_buffer_unlock_commit_regs+0x6d/0x220 trace_event_buffer_commit+0x5c/0x260 trace_event_raw_event_softirq+0x47/0x80 raise_softirq_irqoff+0x6e/0xa0 rcu_read_unlock_special+0xb1/0x160 unwind_next_frame+0x203/0x9b0 __unwind_start+0x15d/0x1c0 arch_stack_walk+0x62/0xf0 stack_trace_save+0x48/0x70 __ftrace_trace_stack.constprop.0+0x144/0x180 trace_buffer_unlock_commit_regs+0x6d/0x220 trace_event_buffer_commit+0x5c/0x260 trace_event_raw_event_softirq+0x47/0x80 raise_softirq_irqoff+0x6e/0xa0 rcu_read_unlock_special+0xb1/0x160 unwind_next_frame+0x203/0x9b0 __unwind_start+0x15d/0x1c0 arch_stack_walk+0x62/0xf0 stack_trace_save+0x48/0x70 __ftrace_trace_stack.constprop.0+0x144/0x180 trace_buffer_unlock_commit_regs+0x6d/0x220 trace_event_buffer_commit+0x5c/0x260 trace_event_raw_event_softirq+0x47/0x80 raise_softirq_irqoff+0x6e/0xa0 rcu_read_unlock_special+0xb1/0x160 __is_insn_slot_addr+0x54/0x70 kernel_text_address+0x48/0xc0 __kernel_text_address+0xd/0x40 unwind_get_return_address+0x1e/0x40 arch_stack_walk+0x9c/0xf0 stack_trace_save+0x48/0x70 __ftrace_trace_stack.constprop.0+0x144/0x180 trace_buffer_unlock_commit_regs+0x6d/0x220 trace_event_buffer_commit+0x5c/0x260 trace_event_raw_event_softirq+0x47/0x80 __raise_softirq_irqoff+0x61/0x80 __flush_smp_call_function_queue+0x115/0x420 __sysvec_call_function_single+0x17/0xb0 sysvec_call_function_single+0x8c/0xc0 </IRQ>
Commit b41642c87716 ("rcu: Fix rcu_read_unlock() deadloop due to IRQ work") fixed the infinite loop in rcu_read_unlock_special() for IRQ work by setting a flag before calling irq_work_queue_on(). We fix this issue by setting the same flag before calling raise_softirq_irqoff() and rename the flag to defer_qs_pending for more common.
--- kernel/rcu/tree.h | 2 +- kernel/rcu/tree_plugin.h | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-)
kernel/rcu/tree.h +1 -1
@@ -203,7 +203,7 @@ struct rcu_data {/* during and after the last grace */ /* period it is aware of. */ struct irq_work defer_qs_iw;/* Obtain later scheduler attention. */ -int defer_qs_iw_pending;/* Scheduler attention pending? */ +int defer_qs_pending;/* irqwork or softirq pending? */ struct work_struct strict_work;/* Schedule readers for strict GPs. */ /* 2) batch handling */
kernel/rcu/tree_plugin.h +9 -6
@@ -487,8 +487,8 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)union rcu_special special; rdp =this_cpu_ptr (&rcu_data); -if (rdp->defer_qs_iw_pending ==DEFER_QS_PENDING ) - rdp->defer_qs_iw_pending =DEFER_QS_IDLE ; +if (rdp->defer_qs_pending ==DEFER_QS_PENDING ) + rdp->defer_qs_pending =DEFER_QS_IDLE ;/* * If RCU core is waiting for this CPU to exit its critical section,
@@ -645,7 +645,7 @@ static void rcu_preempt_deferred_qs_handler(struct irq_work *iwp)* 5. Deferred QS reporting does not happen. */ if (rcu_preempt_depth () >0 ) -WRITE_ONCE (rdp->defer_qs_iw_pending,DEFER_QS_IDLE ); +WRITE_ONCE (rdp->defer_qs_pending,DEFER_QS_IDLE ); }/*
@@ -747,7 +747,10 @@ static void rcu_read_unlock_special(struct task_struct *t)// Using softirq, safe to awaken, and either the // wakeup is free or there is either an expedited // GP in flight or a potential need to deboost. -raise_softirq_irqoff (RCU_SOFTIRQ ); +if (rdp->defer_qs_pending !=DEFER_QS_PENDING ) { + rdp->defer_qs_pending =DEFER_QS_PENDING ; +raise_softirq_irqoff (RCU_SOFTIRQ ); + } }else {// Enabling BH or preempt does reschedule, so... // Also if no expediting and no possible deboosting,
@@ -756,11 +759,11 @@ static void rcu_read_unlock_special(struct task_struct *t)set_tsk_need_resched (current);set_preempt_need_resched ();if (IS_ENABLED (CONFIG_IRQ_WORK ) && irqs_were_disabled && - needs_exp && rdp->defer_qs_iw_pending !=DEFER_QS_PENDING && + needs_exp && rdp->defer_qs_pending !=DEFER_QS_PENDING &&cpu_online (rdp->cpu)) {// Get scheduler to re-evaluate and call hooks. // If !IRQ_WORK, FQS scan will eventually IPI. - rdp->defer_qs_iw_pending =DEFER_QS_PENDING ; + rdp->defer_qs_pending =DEFER_QS_PENDING ;irq_work_queue_on (&rdp->defer_qs_iw, rdp->cpu); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 6/641 audit: move the compat_xxx_class[] extern declarations to audit_arch.h
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <[email protected]>
[ Upstream commit 76489955c6d4a065ca69dc88faf7a50a59b66f35 ]
The comapt_xxx_class symbols aren't declared in anything that lib/comapt_audit.c is including (arm64 build) which is causing the following sparse warnings:
lib/compat_audit.c:7:10: warning: symbol 'compat_dir_class'
was not declared. Should it be static?lib/compat_audit.c:12:10: warning: symbol 'compat_read_class'
was not declared. Should it be static?lib/compat_audit.c:17:10: warning: symbol 'compat_write_class'
was not declared. Should it be static?lib/compat_audit.c:22:10: warning: symbol 'compat_chattr_class'
was not declared. Should it be static?lib/compat_audit.c:27:10: warning: symbol 'compat_signal_class'
was not declared. Should it be static?
Trying to fix this by chaning compat_audit.c to inclde <linux/audit.h> does not work on arm64 due to compile errors with the extra includes that changing this header makes. The simpler thing would be just to move the definitons of these symbols out of <linux/audit.h> into <linux/audit_arch.h> which is included.
--- include/linux/audit.h | 6 ------ include/linux/audit_arch.h | 7 +++++++ 2 files changed, 7 insertions(+), 6 deletions(-)
include/linux/audit.h +0 -6
@@ -128,12 +128,6 @@ enum audit_nfcfgop {extern int __init audit_register_class (int class,unsigned *list);extern int audit_classify_syscall (int abi,unsigned syscall);extern int audit_classify_arch (int arch); -/* only for compat system calls */ -extern unsigned compat_write_class[]; -extern unsigned compat_read_class[]; -extern unsigned compat_dir_class[]; -extern unsigned compat_chattr_class[]; -extern unsigned compat_signal_class[];/* audit_names->type values */ #define AUDIT_TYPE_UNKNOWN 0/* we don't know yet */
include/linux/audit_arch.h +7 -0
@@ -23,4 +23,11 @@ enum auditsc_class_t {extern int audit_classify_compat_syscall (int abi,unsigned syscall); +/* only for compat system calls */ +extern unsigned compat_write_class[]; +extern unsigned compat_read_class[]; +extern unsigned compat_dir_class[]; +extern unsigned compat_chattr_class[]; +extern unsigned compat_signal_class[]; +#endif
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 7/641 selftests/resctrl: Fix a division by zero error on Hygon
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaochen Shen <[email protected]>
[ Upstream commit 671ef08d9455f5754d1fc96f5a14e357d6b80936 ]
Change to adjust effective L3 cache size with SNC enabled change introduced the snc_nodes_per_l3_cache() function to detect the Intel Sub-NUMA Clustering (SNC) feature by comparing #CPUs in node0 with #CPUs sharing LLC with CPU0. The function was designed to return:
(1) >1: SNC mode is enabled.
(2) 1: SNC mode is not enabled or not supported.
However, on certain Hygon CPUs, #CPUs sharing LLC with CPU0 is actually less than #CPUs in node0. This results in snc_nodes_per_l3_cache() returning 0 (calculated as cache_cpus / node_cpus).
This leads to a division by zero error in get_cache_size():
*cache_size /= snc_nodes_per_l3_cache();
Causing the resctrl selftest to fail with:
"Floating point exception (core dumped)"
Fix the issue by ensuring snc_nodes_per_l3_cache() returns 1 when SNC mode is not supported on the platform.
Updated commit log to fix commit has issues:
Shuah Khan <[email protected]>
--- tools/testing/selftests/resctrl/resctrlfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/testing/selftests/resctrl/resctrlfs.c +10 -0
@@ -243,6 +243,16 @@ int snc_nodes_per_l3_cache(void) } snc_mode = cache_cpus / node_cpus; +/* +* On some platforms (e.g. Hygon), +* cache_cpus < node_cpus, the calculated snc_mode is 0. +* +* Set snc_mode = 1 to indicate that SNC mode is not +* supported on the platform. +*/ +if (!snc_mode) + snc_mode =1 ; +if (snc_mode >1 )ksft_print_msg ("SNC-%d mode discovered.\n" , snc_mode); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 8/641 i3c: Move device name assignment after i3c_bus_init
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Billy Tsai <[email protected]>
[ Upstream commit 3502cea99c7ceb331458cbd34ef6792c83144687 ]
Move device name initialization to occur after i3c_bus_init() so that i3cbus->id is guaranteed to be assigned before it is used.
--- drivers/i3c/master.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/i3c/master.c +2 -1
@@ -2884,7 +2884,6 @@ int i3c_master_register(struct i3c_master_controller *master,INIT_LIST_HEAD (&master->boardinfo.i3c);device_initialize (&master->dev); -dev_set_name (&master->dev,"i3c-%d" , i3cbus->id); master->dev.dma_mask = parent->dma_mask; master->dev.coherent_dma_mask = parent->coherent_dma_mask;
@@ -2894,6 +2893,8 @@ int i3c_master_register(struct i3c_master_controller *master,if (ret) goto err_put_dev; +dev_set_name (&master->dev,"i3c-%d" , i3cbus->id); + ret =of_populate_i3c_bus (master);if (ret) goto err_put_dev;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 9/641 device_cgroup: remove branch hint after code refactor
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 6784f274722559c0cdaaa418bc8b7b1d61c314f9 ]
commit 4ef4ac360101 ("device_cgroup: avoid access to ->i_rdev in the common case in devcgroup_inode_permission()") reordered the checks in devcgroup_inode_permission() to check the inode mode before checking i_rdev, for better cache behavior.
However, the likely() annotation on the i_rdev check was not updated to reflect the new code flow. Originally, when i_rdev was checked first, likely(!inode->i_rdev) made sense because most inodes were(?) regular files/directories, thus i_rdev == 0.
After the reorder, by the time we reach the i_rdev check, we have already confirmed the inode IS a block or character device. Block and character special files are precisely defined by having a device number (i_rdev), so !inode->i_rdev is now the rare edge case, not the common case.
Branch profiling confirmed this is 100% mispredicted:
correct incorrect % Function File Line
------- --------- - -------- ---- ----
0 2631904 100 devcgroup_inode_permission device_cgroup.h 24Remove likely() to avoid giving the wrong hint to the CPU.
--- include/linux/device_cgroup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/device_cgroup.h +1 -1
@@ -21,7 +21,7 @@ static inline int devcgroup_inode_permission(struct inode *inode, int mask)if (likely (!S_ISBLK (inode->i_mode) && !S_ISCHR (inode->i_mode)))return 0 ; -if (likely (!inode->i_rdev)) +if (!inode->i_rdev)return 0 ;if (S_ISBLK (inode->i_mode))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 10/641 fs: move initializing f_mode before file_ref_init()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 1219e0feaefc9697f738b223540e8e8906291cb3 ]
The comment above file_ref_init() says:
"We're SLAB_TYPESAFE_BY_RCU so initialize f_ref last." but file_set_fsnotify_mode() was added after file_ref_init().
Move it right after setting f_mode, where it makes more sense.
--- fs/file_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/file_table.c +5 -5
@@ -176,6 +176,11 @@ static int init_file(struct file *f, int flags, const struct cred *cred) f->f_flags = flags; f->f_mode =OPEN_FMODE (flags); +/* +* Disable permission and pre-content events for all files by default. +* They may be enabled later by fsnotify_open_perm_and_set_mode(). +*/ +file_set_fsnotify_mode (f,FMODE_NONOTIFY_PERM ); f->f_op =NULL ; f->f_mapping =NULL ;
@@ -197,11 +202,6 @@ static int init_file(struct file *f, int flags, const struct cred *cred)* refcount bumps we should reinitialize the reused file first. */ file_ref_init (&f->f_ref,1 ); -/* -* Disable permission and pre-content events for all files by default. -* They may be enabled later by fsnotify_open_perm_and_set_mode(). -*/ -file_set_fsnotify_mode (f,FMODE_NONOTIFY_PERM );return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 11/641 fs: add <linux/init_task.h> for init_fs
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <[email protected]>
[ Upstream commit 589cff4975afe1a4eaaa1d961652f50b1628d78d ]
The init_fs symbol is defined in <linux/init_task.h> but was not included in fs/fs_struct.c so fix by adding the include.
Fixes the following sparse warning:fs/fs_struct.c:150:18: warning: symbol 'init_fs' was not declared. Should it be static?
--- fs/fs_struct.c | 1 + 1 file changed, 1 insertion(+)
fs/fs_struct.c +1 -0
@@ -6,6 +6,7 @@#include <linux/path.h> #include <linux/slab.h> #include <linux/fs_struct.h> +#include <linux/init_task.h> #include "internal.h" /*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 12/641 i3c: master: Update hot-join flag only on success
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
[ Upstream commit f0775157b9f9a28ae3eabc8d05b0bc52e8056c80 ]
To prevent inconsistent state when an error occurs, ensure the hot-join flag is updated only when enabling or disabling hot-join succeeds.
--- drivers/i3c/master.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/i3c/master.c +2 -1
@@ -620,7 +620,8 @@ static int i3c_set_hotjoin(struct i3c_master_controller *master, bool enable)else ret = master->ops->disable_hotjoin (master); - master->hotjoin = enable; +if (!ret) + master->hotjoin = enable;i3c_bus_normaluse_unlock (&master->bus);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 13/641 gfs2: Retries missing in gfs2_{rename,exchange}
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 11d763f0b0afc2cf5f92f4adae5dbbbbef712f8f ]
Fix a bug in gfs2's asynchronous glock handling for rename and exchange operations. The original async implementation from commit ad26967b9afa ("gfs2: Use async glocks for rename") mentioned that retries were needed but never implemented them, causing operations to fail with -ESTALE instead of retrying on timeout.
Also makes the waiting interruptible.
In addition, the timeouts used were too high for situations in which timing out is a rare but expected scenario. Switch to shorter timeouts with randomization and exponentional backoff.
--- fs/gfs2/glock.c | 36 +++++++++++++++++++++++++++--------- fs/gfs2/glock.h | 3 ++- fs/gfs2/inode.c | 18 ++++++++++++++---- 3 files changed, 43 insertions(+), 14 deletions(-)
fs/gfs2/glock.c +27 -9
@@ -1354,31 +1354,45 @@ static int glocks_pending(unsigned int num_gh, struct gfs2_holder *ghs)* gfs2_glock_async_wait - wait on multiple asynchronous glock acquisitions * @num_gh: the number of holders in the array * @ghs: the glock holder array +* @retries: number of retries attempted so far * * Returns: 0 on success, meaning all glocks have been granted and are held. * -ESTALE if the request timed out, meaning all glocks were released, * and the caller should retry the operation. */ -int gfs2_glock_async_wait (unsigned int num_gh,struct gfs2_holder *ghs) +int gfs2_glock_async_wait (unsigned int num_gh,struct gfs2_holder *ghs, +unsigned int retries) {struct gfs2_sbd *sdp = ghs[0 ].gh_gl->gl_name.ln_sbd; -int i, ret =0 , timeout =0 ;unsigned long start_time = jiffies; +int i, ret =0 ; +long timeout;might_sleep (); -/* -* Total up the (minimum hold time * 2) of all glocks and use that to -* determine the max amount of time we should wait. -*/ -for (i =0 ; i < num_gh; i++) - timeout += ghs[i].gh_gl->gl_hold_time <<1 ; -if (!wait_event_timeout (sdp->sd_async_glock_wait, + timeout =GL_GLOCK_MIN_HOLD ; +if (retries) { +unsigned int max_shift; +long incr; + +/* Add a random delay and increase the timeout exponentially. */ + max_shift =BITS_PER_LONG -2 -__fls (GL_GLOCK_HOLD_INCR ); + incr =min (GL_GLOCK_HOLD_INCR <<min (retries -1 , max_shift), +10 *HZ -GL_GLOCK_MIN_HOLD ); +schedule_timeout_interruptible (get_random_long () % (incr /3 )); +if (signal_pending (current)) + goto interrupted; + timeout += (incr /3 ) +get_random_long () % (incr /3 ); + } + +if (!wait_event_interruptible_timeout (sdp->sd_async_glock_wait, !glocks_pending (num_gh, ghs), timeout)) { ret = -ESTALE ;/* request timed out. */ goto out; } +if (signal_pending (current)) + goto interrupted;for (i =0 ; i < num_gh; i++) {struct gfs2_holder *gh = &ghs[i];
@@ -1402,6 +1416,10 @@ int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs) } }return ret; + +interrupted: + ret = -EINTR ; + goto out; }/**
fs/gfs2/glock.h +2 -1
@@ -204,7 +204,8 @@ int gfs2_glock_poll(struct gfs2_holder *gh);int gfs2_instantiate (struct gfs2_holder *gh);int gfs2_glock_holder_ready (struct gfs2_holder *gh);int gfs2_glock_wait (struct gfs2_holder *gh); -int gfs2_glock_async_wait (unsigned int num_gh,struct gfs2_holder *ghs); +int gfs2_glock_async_wait (unsigned int num_gh,struct gfs2_holder *ghs, +unsigned int retries);void gfs2_glock_dq (struct gfs2_holder *gh);void gfs2_glock_dq_wait (struct gfs2_holder *gh);void gfs2_glock_dq_uninit (struct gfs2_holder *gh);
fs/gfs2/inode.c +14 -4
@@ -1495,7 +1495,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,unsigned int num_gh;int dir_rename =0 ;struct gfs2_diradd da = { .nr_blocks =0 , .save_loc =0 , }; -unsigned int x; +unsigned int retries =0 , x;int error;gfs2_holder_mark_uninitialized (&r_gh);
@@ -1545,12 +1545,17 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, num_gh++; } +again:for (x =0 ; x < num_gh; x++) { error =gfs2_glock_nq (ghs + x);if (error) goto out_gunlock; } - error =gfs2_glock_async_wait (num_gh, ghs); + error =gfs2_glock_async_wait (num_gh, ghs, retries); +if (error == -ESTALE ) { + retries++; + goto again; + }if (error) goto out_gunlock;
@@ -1739,7 +1744,7 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,struct gfs2_sbd *sdp =GFS2_SB (odir);struct gfs2_holder ghs[4 ], r_gh;unsigned int num_gh; -unsigned int x; +unsigned int retries =0 , x;umode_t old_mode = oip->i_inode.i_mode;umode_t new_mode = nip->i_inode.i_mode;int error;
@@ -1783,13 +1788,18 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,gfs2_holder_init (nip->i_gl,LM_ST_EXCLUSIVE ,GL_ASYNC , ghs + num_gh); num_gh++; +again:for (x =0 ; x < num_gh; x++) { error =gfs2_glock_nq (ghs + x);if (error) goto out_gunlock; } - error =gfs2_glock_async_wait (num_gh, ghs); + error =gfs2_glock_async_wait (num_gh, ghs, retries); +if (error == -ESTALE ) { + retries++; + goto again; + }if (error) goto out_gunlock;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 14/641 gfs2: Fix slab-use-after-free in qd_put
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 22150a7d401d9e9169b9b68e05bed95f7f49bf69 ]
Commit a475c5dd16e5 ("gfs2: Free quota data objects synchronously") started freeing quota data objects during filesystem shutdown instead of putting them back onto the LRU list, but it failed to remove these objects from the LRU list, causing LRU list corruption. This caused use-after-free when the shrinker (gfs2_qd_shrink_scan) tried to access already-freed objects on the LRU list.
Fix this by removing qd objects from the LRU list before freeing them in qd_put().
Initial fix from Deepanshu Kartikey <[email protected]>.
--- fs/gfs2/quota.c | 1 + 1 file changed, 1 insertion(+)
fs/gfs2/quota.c +1 -0
@@ -334,6 +334,7 @@ static void qd_put(struct gfs2_quota_data *qd)lockref_mark_dead (&qd->qd_lockref);spin_unlock (&qd->qd_lockref.lock); +list_lru_del_obj (&gfs2_qd_lru, &qd->qd_lru);gfs2_qd_dispose (qd);return ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 15/641 gfs2: Fix use-after-free in iomap inline data write path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
[ Upstream commit faddeb848305e79db89ee0479bb0e33380656321 ]
The inline data buffer head (dibh) is being released prematurely in gfs2_iomap_begin() via release_metapath() while iomap->inline_data still points to dibh->b_data. This causes a use-after-free when iomap_write_end_inline() later attempts to write to the inline data area.
The bug sequence:
1. gfs2_iomap_begin() calls gfs2_meta_inode_buffer() to read inode metadata into dibh
2. Sets iomap->inline_data = dibh->b_data + sizeof(struct gfs2_dinode)
3. Calls release_metapath() which calls brelse(dibh), dropping refcount to 0
4. kswapd reclaims the page (~39ms later in the syzbot report)
5. iomap_write_end_inline() tries to memcpy() to iomap->inline_data
6. KASAN detects use-after-free write to freed memory
Fix by storing dibh in iomap->private and incrementing its refcount with get_bh() in gfs2_iomap_begin(). The buffer is then properly released in gfs2_iomap_end() after the inline write completes, ensuring the page stays alive for the entire iomap operation.
Note: A C reproducer is not available for this issue. The fix is based on analysis of the KASAN report and code review showing the buffer head is freed before use.
[agruenba: Take buffer head reference in gfs2_iomap_begin() to avoid leaks in gfs2_iomap_get() and gfs2_iomap_alloc().]
--- fs/gfs2/bmap.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
fs/gfs2/bmap.c +12 -1
@@ -1127,10 +1127,18 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, goto out_unlock;break ;default : - goto out_unlock; + goto out; } ret =gfs2_iomap_begin_write (inode, pos, length, flags, iomap, &mp); +if (ret) + goto out_unlock; + +out: +if (iomap->type ==IOMAP_INLINE ) { + iomap->private =metapath_dibh (&mp); +get_bh (iomap->private); + } out_unlock:release_metapath (&mp);
@@ -1144,6 +1152,9 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,struct gfs2_inode *ip =GFS2_I (inode);struct gfs2_sbd *sdp =GFS2_SB (inode); +if (iomap->private) +brelse (iomap->private); +switch (flags & (IOMAP_WRITE |IOMAP_ZERO )) {case IOMAP_WRITE :if (flags &IOMAP_DIRECT )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 16/641 i3c: dw: Initialize spinlock to avoid upsetting lockdep
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fredrik Markstrom <[email protected]>
[ Upstream commit b58eaa4761ab02fc38c39d674a6bcdd55e00f388 ]
The devs_lock spinlock introduced when adding support for ibi:s was never initialized.
--- drivers/i3c/master/dw-i3c-master.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i3c/master/dw-i3c-master.c +2 -0
@@ -1563,6 +1563,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,spin_lock_init (&master->xferqueue.lock);INIT_LIST_HEAD (&master->xferqueue.list); +spin_lock_init (&master->devs_lock); +writel (INTR_ALL , master->regs +INTR_STATUS ); irq =platform_get_irq (pdev,0 ); ret = devm_request_irq(&pdev->dev, irq,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 17/641 i3c: dw: Fix memory leak in dw_i3c_master_i2c_xfers()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 2537089413514caaa9a5fdeeac3a34d45100f747 ]
The dw_i3c_master_i2c_xfers() function allocates memory for the xfer structure using dw_i3c_master_alloc_xfer(). If pm_runtime_resume_and_get() fails, the function returns without freeing the allocated xfer, resulting in a memory leak.
Add a dw_i3c_master_free_xfer() call to the error path to ensure the allocated memory is properly freed.
Compile tested only. Issue found using a prototype static analysis tool and code review.
--- drivers/i3c/master/dw-i3c-master.c | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/master/dw-i3c-master.c +1 -0
@@ -1094,6 +1094,7 @@ static int dw_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,dev_err (master->dev,"<%s> cannot resume i3c bus master, err: %d\n" , __func__, ret); +dw_i3c_master_free_xfer (xfer);return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 18/641 tpm: tpm_i2c_infineon: Fix locality leak on get_burstcount() failure
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alper Ak <[email protected]>
[ Upstream commit bbd6e97c836cbeb9606d7b7e5dcf8a1d89525713 ]
get_burstcount() can return -EBUSY on timeout. When this happens, the function returns directly without releasing the locality that was acquired at the beginning of tpm_tis_i2c_send().
Use goto out_err to ensure proper cleanup when get_burstcount() fails.
--- drivers/char/tpm/tpm_i2c_infineon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/char/tpm/tpm_i2c_infineon.c +4 -2
@@ -544,8 +544,10 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, burstcnt =get_burstcount (chip);/* burstcnt < 0 = TPM is busy */ -if (burstcnt <0 ) -return burstcnt; +if (burstcnt <0 ) { + rc = burstcnt; + goto out_err; + }if (burstcnt > (len -1 - count)) burstcnt = len -1 - count;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 19/641 tpm: st33zp24: Fix missing cleanup on get_burstcount() error
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alper Ak <[email protected]>
[ Upstream commit 3e91b44c93ad2871f89fc2a98c5e4fe6ca5db3d9 ]
get_burstcount() can return -EBUSY on timeout. When this happens, st33zp24_send() returns directly without releasing the locality acquired earlier.
Use goto out_err to ensure proper cleanup when get_burstcount() fails.
--- drivers/char/tpm/st33zp24/st33zp24.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/char/tpm/st33zp24/st33zp24.c +4 -2
@@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,for (i =0 ; i < len -1 ;) { burstcnt =get_burstcount (chip); -if (burstcnt <0 ) -return burstcnt; +if (burstcnt <0 ) { + ret = burstcnt; + goto out_err; + } size =min_t (int, len - i -1 , burstcnt); ret = tpm_dev->ops->send (tpm_dev->phy_id,TPM_DATA_FIFO , buf + i, size);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 20/641 erofs: get rid of raw bi_end_io() usage
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit 80d0c27a0a4af8e0678d7412781482e6f73c22c7 ]
These BIOs are actually harmless in practice, as they are all pseudo BIOs and do not use advanced features like chaining. Using the BIO interface is a more friendly and unified approach for both bdev and and file-backed I/Os (compared to awkward bvec interfaces).
Let's use bio_endio() instead.
Stable-dep-of: bc804a8d7e86 ("erofs: handle end of filesystem properly for file-backed mounts")
--- fs/erofs/fileio.c | 2 +- fs/erofs/fscache.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
fs/erofs/fileio.c +1 -1
@@ -35,13 +35,13 @@ static void erofs_fileio_ki_complete(struct kiocb *iocb, long ret)if (rq->bio.bi_end_io) {if (ret <0 && !rq->bio.bi_status) rq->bio.bi_status =errno_to_blk_status (ret); - rq->bio.bi_end_io (&rq->bio); }else {bio_for_each_folio_all (fi, &rq->bio) {DBG_BUGON (folio_test_uptodate (fi.folio));erofs_onlinefolio_end (fi.folio, ret, false); } } +bio_endio (&rq->bio);bio_uninit (&rq->bio);if (refcount_dec_and_test (&rq->ref))kfree (rq);
fs/erofs/fscache.c +2 -2
@@ -185,7 +185,7 @@ static void erofs_fscache_bio_endio(void *priv, ssize_t transferred_or_error)if (IS_ERR_VALUE (transferred_or_error)) io->bio.bi_status =errno_to_blk_status (transferred_or_error); - io->bio.bi_end_io (&io->bio); +bio_endio (&io->bio);BUILD_BUG_ON (offsetof(struct erofs_fscache_bio , io) !=0 );erofs_fscache_io_put (&io->io); }
@@ -216,7 +216,7 @@ void erofs_fscache_submit_bio(struct bio *bio)if (!ret)return ; bio->bi_status =errno_to_blk_status (ret); - bio->bi_end_io (bio); +bio_endio (bio); }static int erofs_fscache_meta_read_folio (struct file *data,struct folio *folio)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 21/641 erofs: handle end of filesystem properly for file-backed mounts
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit bc804a8d7e865ef47fb7edcaf5e77d18bf444ebc ]
I/O requests beyond the end of the filesystem should be zeroed out, similar to loopback devices and that is what we expect.
--- fs/erofs/fileio.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
fs/erofs/fileio.c +8 -12
@@ -25,21 +25,17 @@ static void erofs_fileio_ki_complete(struct kiocb *iocb, long ret) container_of(iocb, struct erofs_fileio_rq, iocb);struct folio_iter fi; -if (ret >0 ) { -if (ret != rq->bio.bi_iter.bi_size) { -bio_advance (&rq->bio, ret); -zero_fill_bio (&rq->bio); - } - ret =0 ; +if (ret >=0 && ret != rq->bio.bi_iter.bi_size) { +bio_advance (&rq->bio, ret); +zero_fill_bio (&rq->bio); } -if (rq->bio.bi_end_io) { -if (ret <0 && !rq->bio.bi_status) - rq->bio.bi_status =errno_to_blk_status (ret); - }else { +if (!rq->bio.bi_end_io) {bio_for_each_folio_all (fi, &rq->bio) {DBG_BUGON (folio_test_uptodate (fi.folio)); -erofs_onlinefolio_end (fi.folio, ret, false); +erofs_onlinefolio_end (fi.folio, ret <0 , false); } + }else if (ret <0 && !rq->bio.bi_status) { + rq->bio.bi_status =errno_to_blk_status (ret); }bio_endio (&rq->bio);bio_uninit (&rq->bio);
@@ -51,7 +47,7 @@ static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq) {const struct cred *old_cred;struct iov_iter iter; -int ret; +ssize_t ret;if (!rq)return ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 22/641 btrfs: headers cleanup to remove unnecessary local includes
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit c5667f9c8eb90293dfa4e52c65eb89fe39f5652d ]
[BUG]
When I tried to remove btrfs_bio::fs_info and use btrfs_bio::inode to grab the fs_info, the header "btrfs_inode.h" is needed to access the full btrfs_inode structure.
Then btrfs will fail to compile.
[CAUSE]
There is a recursive including chain:
"bio.h" -> "btrfs_inode.h" -> "extent_map.h" -> "compression.h" -> "bio.h"
That recursive including is causing problems for btrfs.
[ENHANCEMENT]
To reduce the risk of recursive including:
- Remove unnecessary local includes from btrfs headers Either the included header is pulled in by other headers, or is completely unnecessary.
- Remove btrfs local includes if the header only requires a pointer In that case let the implementing C file to pull the required header.
This is especially important for headers like "btrfs_inode.h" which pulls in a lot of other btrfs headers, thus it's a mine field of recursive including.
- Remove unnecessary temporary structure definition Either if we have included the header defining the structure, or completely unused.
Now including "btrfs_inode.h" inside "bio.h" is completely fine, although "btrfs_inode.h" still includes "extent_map.h", but that header only includes "fs.h", no more chain back to "bio.h".
Stable-dep-of: b39b26e017c7 ("btrfs: zoned: don't zone append to conventional zone")
--- fs/btrfs/accessors.h | 1 + fs/btrfs/btrfs_inode.h | 8 ++++---- fs/btrfs/compression.h | 3 --- fs/btrfs/ctree.h | 2 -- fs/btrfs/defrag.c | 1 + fs/btrfs/dir-item.c | 1 + fs/btrfs/direct-io.c | 2 ++ fs/btrfs/disk-io.c | 1 + fs/btrfs/disk-io.h | 3 ++- fs/btrfs/extent-tree.c | 1 + fs/btrfs/extent_io.h | 1 - fs/btrfs/extent_map.h | 3 +-- fs/btrfs/file-item.h | 2 +- fs/btrfs/inode.c | 1 + fs/btrfs/space-info.c | 1 + fs/btrfs/subpage.h | 1 - fs/btrfs/transaction.c | 2 ++ fs/btrfs/transaction.h | 4 ---- fs/btrfs/tree-log.c | 1 + fs/btrfs/tree-log.h | 3 +-- fs/btrfs/zoned.h | 1 - 21 files changed, 21 insertions(+), 22 deletions(-)
fs/btrfs/accessors.h +1 -0
@@ -12,6 +12,7 @@#include <linux/string.h> #include <linux/mm.h> #include <uapi/linux/btrfs_tree.h> +#include "fs.h" #include "extent_io.h" struct extent_buffer ;
fs/btrfs/btrfs_inode.h +4 -4
@@ -18,20 +18,20 @@#include <linux/lockdep.h> #include <uapi/linux/btrfs_tree.h> #include <trace/events/btrfs.h> +#include "ctree.h" #include "block-rsv.h" #include "extent_map.h" -#include "extent_io.h" #include "extent-io-tree.h" -#include "ordered-data.h" -#include "delayed-inode.h" -struct extent_state ;struct posix_acl ;struct iov_iter ;struct writeback_control ;struct btrfs_root ;struct btrfs_fs_info ;struct btrfs_trans_handle ; +struct btrfs_bio ; +struct btrfs_file_extent ; +struct btrfs_delayed_node ;/* * Since we search a directory based on f_pos (struct dir_context::pos) we have
fs/btrfs/compression.h +0 -3
@@ -14,14 +14,11 @@#include <linux/pagemap.h> #include "bio.h" #include "fs.h" -#include "messages.h" struct address_space ; -struct page ;struct inode ;struct btrfs_inode ;struct btrfs_ordered_extent ; -struct btrfs_bio ;/* * We want to make sure that amount of RAM required to uncompress an extent is
fs/btrfs/ctree.h +0 -2
@@ -17,9 +17,7 @@#include <linux/refcount.h> #include <uapi/linux/btrfs_tree.h> #include "locking.h" -#include "fs.h" #include "accessors.h" -#include "extent-io-tree.h" struct extent_buffer ;struct btrfs_block_rsv ;
fs/btrfs/defrag.c +1 -0
@@ -15,6 +15,7 @@#include "defrag.h" #include "file-item.h" #include "super.h" +#include "compression.h" static struct kmem_cache *btrfs_inode_defrag_cachep;
fs/btrfs/dir-item.c +1 -0
@@ -9,6 +9,7 @@#include "transaction.h" #include "accessors.h" #include "dir-item.h" +#include "delayed-inode.h" /* * insert a name into a directory, doing overflow properly if there is a hash
fs/btrfs/direct-io.c +2 -0
@@ -10,6 +10,8 @@#include "fs.h" #include "transaction.h" #include "volumes.h" +#include "bio.h" +#include "ordered-data.h" struct btrfs_dio_data {ssize_t submitted;
fs/btrfs/disk-io.c +1 -0
@@ -50,6 +50,7 @@#include "relocation.h" #include "scrub.h" #include "super.h" +#include "delayed-inode.h" #define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\ BTRFS_HEADER_FLAG_RELOC |\
fs/btrfs/disk-io.h +2 -1
@@ -9,7 +9,8 @@#include <linux/sizes.h> #include <linux/compiler_types.h> #include "ctree.h" -#include "fs.h" +#include "bio.h" +#include "ordered-data.h" struct block_device ;struct super_block ;
fs/btrfs/extent-tree.c +1 -0
@@ -40,6 +40,7 @@#include "orphan.h" #include "tree-checker.h" #include "raid-stripe-tree.h" +#include "delayed-inode.h" #undef SCRAMBLE_DELAYED_REFS
fs/btrfs/extent_io.h +0 -1
@@ -12,7 +12,6 @@#include <linux/rwsem.h> #include <linux/list.h> #include <linux/slab.h> -#include "compression.h" #include "messages.h" #include "ulist.h" #include "misc.h"
fs/btrfs/extent_map.h +1 -2
@@ -8,8 +8,7 @@#include <linux/rbtree.h> #include <linux/list.h> #include <linux/refcount.h> -#include "misc.h" -#include "compression.h" +#include "fs.h" struct btrfs_inode ;struct btrfs_fs_info ;
fs/btrfs/file-item.h +1 -1
@@ -7,7 +7,7 @@#include <linux/list.h> #include <uapi/linux/btrfs_tree.h> #include "ctree.h" -#include "accessors.h" +#include "ordered-data.h" struct extent_map ;struct btrfs_file_extent_item ;
fs/btrfs/inode.c +1 -0
@@ -71,6 +71,7 @@#include "backref.h" #include "raid-stripe-tree.h" #include "fiemap.h" +#include "delayed-inode.h" #define COW_FILE_RANGE_KEEP_LOCKED (1UL << 0)#define COW_FILE_RANGE_NO_INLINE (1UL << 1)
fs/btrfs/space-info.c +1 -0
@@ -15,6 +15,7 @@#include "accessors.h" #include "extent-tree.h" #include "zoned.h" +#include "delayed-inode.h" /* * HOW DOES SPACE RESERVATION WORK
fs/btrfs/subpage.h +0 -1
@@ -7,7 +7,6 @@#include <linux/atomic.h> #include <linux/sizes.h> #include "btrfs_inode.h" -#include "fs.h" struct address_space ;struct folio ;
fs/btrfs/transaction.c +2 -0
@@ -32,6 +32,8 @@#include "ioctl.h" #include "relocation.h" #include "scrub.h" +#include "ordered-data.h" +#include "delayed-inode.h" static struct kmem_cache *btrfs_trans_handle_cachep;
fs/btrfs/transaction.h +0 -4
@@ -14,10 +14,6 @@#include <linux/wait.h> #include "btrfs_inode.h" #include "delayed-ref.h" -#include "extent-io-tree.h" -#include "block-rsv.h" -#include "messages.h" -#include "misc.h" struct dentry ;struct inode ;
fs/btrfs/tree-log.c +1 -0
@@ -29,6 +29,7 @@#include "orphan.h" #include "print-tree.h" #include "tree-checker.h" +#include "delayed-inode.h" #define MAX_CONFLICT_INODES 10
fs/btrfs/tree-log.h +1 -2
@@ -8,8 +8,7 @@#include <linux/list.h> #include <linux/fs.h> -#include "messages.h" -#include "ctree.h" +#include <linux/fscrypt.h> #include "transaction.h" struct inode ;
fs/btrfs/zoned.h +0 -1
@@ -15,7 +15,6 @@#include "disk-io.h" #include "block-group.h" #include "btrfs_inode.h" -#include "fs.h" struct block_device ;struct extent_buffer ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 23/641 btrfs: remove btrfs_bio::fs_info by extracting it from btrfs_bio::inode
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 81cea6cd7041ebd42281e0517f856d88527d3326 ]
Currently there is only one caller which doesn't populate btrfs_bio::inode, and that's scrub.
The idea is scrub doesn't want any automatic csum verification nor read-repair, as everything will be handled by scrub itself.
However that behavior is really no different than metadata inode, thus we can reuse btree_inode as btrfs_bio::inode for scrub.
The only exception is in btrfs_submit_chunk() where if a bbio is from scrub or data reloc inode, we set rst_search_commit_root to true. This means we still need a way to distinguish scrub from metadata, but that can be done by a new flag inside btrfs_bio.
Now btrfs_bio::inode is a mandatory parameter, we can extract fs_info from that inode thus can remove btrfs_bio::fs_info to save 8 bytes from btrfs_bio structure.
Stable-dep-of: b39b26e017c7 ("btrfs: zoned: don't zone append to conventional zone")
--- fs/btrfs/bio.c | 53 ++++++++++++++++++++++-------------------- fs/btrfs/bio.h | 18 +++++++++----- fs/btrfs/compression.c | 6 ++--- fs/btrfs/compression.h | 3 ++- fs/btrfs/direct-io.c | 4 +--- fs/btrfs/extent_io.c | 22 +++++++----------- fs/btrfs/inode.c | 7 ++---- fs/btrfs/scrub.c | 51 ++++++++++++++++++++++------------------ fs/btrfs/zoned.c | 4 ++-- 9 files changed, 87 insertions(+), 81 deletions(-)
fs/btrfs/bio.c +28 -25
@@ -41,13 +41,17 @@ static bool bbio_has_ordered_extent(const struct btrfs_bio *bbio)* Initialize a btrfs_bio structure. This skips the embedded bio itself as it * is already initialized by the block layer. */ -void btrfs_bio_init (struct btrfs_bio *bbio,struct btrfs_fs_info *fs_info, +void btrfs_bio_init (struct btrfs_bio *bbio,struct btrfs_inode *inode,u64 file_offset,btrfs_bio_end_io_t end_io,void *private) { +/* @inode parameter is mandatory. */ +ASSERT (inode); +memset (bbio,0 , offsetof(struct btrfs_bio , bio)); - bbio->fs_info = fs_info; + bbio->inode = inode; bbio->end_io = end_io; bbio->private = private; + bbio->file_offset = file_offset;atomic_set (&bbio->pending_ios,1 );WRITE_ONCE (bbio->status,BLK_STS_OK ); }
@@ -60,7 +64,7 @@ void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_fs_info *fs_info,* a mempool. */ struct btrfs_bio *btrfs_bio_alloc (unsigned int nr_vecs,blk_opf_t opf, -struct btrfs_fs_info *fs_info, +struct btrfs_inode *inode,u64 file_offset,btrfs_bio_end_io_t end_io,void *private) {struct btrfs_bio *bbio;
@@ -68,7 +72,7 @@ struct btrfs_bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf, bio =bio_alloc_bioset (NULL , nr_vecs, opf,GFP_NOFS , &btrfs_bioset); bbio =btrfs_bio (bio); -btrfs_bio_init (bbio, fs_info, end_io, private); +btrfs_bio_init (bbio, inode, file_offset, end_io, private);return bbio; }
@@ -85,9 +89,7 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,return ERR_CAST (bio); bbio =btrfs_bio (bio); -btrfs_bio_init (bbio, fs_info,NULL , orig_bbio); - bbio->inode = orig_bbio->inode; - bbio->file_offset = orig_bbio->file_offset; +btrfs_bio_init (bbio, orig_bbio->inode, orig_bbio->file_offset,NULL , orig_bbio); orig_bbio->file_offset += map_length;if (bbio_has_ordered_extent (bbio)) {refcount_inc (&orig_bbio->ordered->refs);
@@ -244,9 +246,8 @@ static struct btrfs_failed_bio *repair_one_sector(struct btrfs_bio *failed_bbio,bio_add_folio_nofail (repair_bio, folio, sectorsize, foff); repair_bbio =btrfs_bio (repair_bio); -btrfs_bio_init (repair_bbio, fs_info,NULL , fbio); - repair_bbio->inode = failed_bbio->inode; - repair_bbio->file_offset = failed_bbio->file_offset + bio_offset; +btrfs_bio_init (repair_bbio, failed_bbio->inode, failed_bbio->file_offset + bio_offset, +NULL , fbio); mirror =next_repair_mirror (fbio, failed_bbio->mirror_num);btrfs_debug (fs_info,"submitting repair read to mirror %d" , mirror);
@@ -332,7 +333,7 @@ static void btrfs_simple_end_io(struct bio *bio) {struct btrfs_bio *bbio =btrfs_bio (bio);struct btrfs_device *dev = bio->bi_private; -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;btrfs_bio_counter_dec (fs_info);
@@ -581,10 +582,11 @@ static void run_one_async_done(struct btrfs_work *work, bool do_free)static bool should_async_write (struct btrfs_bio *bbio) { +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;bool auto_csum_mode = true;#ifdef CONFIG_BTRFS_EXPERIMENTAL -struct btrfs_fs_devices *fs_devices = bbio->fs_info->fs_devices; +struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;enum btrfs_offload_csum_mode csum_mode =READ_ONCE (fs_devices->offload_csum_mode);if (csum_mode ==BTRFS_OFFLOAD_CSUM_FORCE_OFF )
@@ -594,7 +596,7 @@ static bool should_async_write(struct btrfs_bio *bbio)#endif /* Submit synchronously if the checksum implementation is fast. */ -if (auto_csum_mode &&test_bit (BTRFS_FS_CSUM_IMPL_FAST , &bbio->fs_info->flags)) +if (auto_csum_mode &&test_bit (BTRFS_FS_CSUM_IMPL_FAST , &fs_info->flags))return false;/*
@@ -605,7 +607,7 @@ static bool should_async_write(struct btrfs_bio *bbio)return false;/* Zoned devices require I/O to be submitted in order. */ -if ((bbio->bio.bi_opf &REQ_META ) &&btrfs_is_zoned (bbio->fs_info)) +if ((bbio->bio.bi_opf &REQ_META ) &&btrfs_is_zoned (fs_info))return false;return true;
@@ -620,7 +622,7 @@ static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio,struct btrfs_io_context *bioc, struct btrfs_io_stripe *smap, int mirror_num) { - struct btrfs_fs_info *fs_info = bbio->fs_info; + struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;struct async_submit_bio *async; async =kmalloc (sizeof (*async),GFP_NOFS );
@@ -639,11 +641,12 @@ static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio,static u64 btrfs_append_map_length (struct btrfs_bio *bbio,u64 map_length) { +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;unsigned int nr_segs;int sector_offset; - map_length =min (map_length, bbio->fs_info->max_zone_append_size); - sector_offset =bio_split_rw_at (&bbio->bio, &bbio->fs_info->limits, + map_length =min (map_length, fs_info->max_zone_append_size); + sector_offset =bio_split_rw_at (&bbio->bio, &fs_info->limits, &nr_segs, map_length);if (sector_offset) {/*
@@ -651,7 +654,7 @@ static u64 btrfs_append_map_length(struct btrfs_bio *bbio, u64 map_length)* sectorsize and thus cause unaligned I/Os. Fix that by * always rounding down to the nearest boundary. */ -return ALIGN_DOWN (sector_offset <<SECTOR_SHIFT , bbio->fs_info->sectorsize); +return ALIGN_DOWN (sector_offset <<SECTOR_SHIFT , fs_info->sectorsize); }return map_length; }
@@ -659,7 +662,7 @@ static u64 btrfs_append_map_length(struct btrfs_bio *bbio, u64 map_length)static bool btrfs_submit_chunk (struct btrfs_bio *bbio,int mirror_num) {struct btrfs_inode *inode = bbio->inode; -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = inode->root->fs_info;struct bio *bio = &bbio->bio;u64 logical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ;u64 length = bio->bi_iter.bi_size;
@@ -670,7 +673,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)blk_status_t status;int ret; -if (!bbio->inode ||btrfs_is_data_reloc_root (inode->root)) +if (bbio->is_scrub ||btrfs_is_data_reloc_root (inode->root)) smap.rst_search_commit_root = true;else smap.rst_search_commit_root = false;
@@ -734,7 +737,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)* Csum items for reloc roots have already been cloned at this * point, so they are handled as part of the no-checksum case. */ -if (inode && !(inode->flags &BTRFS_INODE_NODATASUM ) && +if (!(inode->flags &BTRFS_INODE_NODATASUM ) && !test_bit (BTRFS_FS_STATE_NO_DATA_CSUMS , &fs_info->fs_state) && !btrfs_is_data_reloc_root (inode->root)) { if (should_async_write(bbio) &&
@@ -782,7 +785,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)static void assert_bbio_alignment (struct btrfs_bio *bbio) {#ifdef CONFIG_BTRFS_ASSERT -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;struct bio_vec bvec;struct bvec_iter iter;const u32 blocksize = fs_info->sectorsize;
@@ -885,16 +888,16 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,*/ void btrfs_submit_repair_write (struct btrfs_bio *bbio,int mirror_num,bool dev_replace) { -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;u64 logical = bbio->bio.bi_iter.bi_sector <<SECTOR_SHIFT ;u64 length = bbio->bio.bi_iter.bi_size;struct btrfs_io_stripe smap = {0 };int ret; -ASSERT (fs_info);ASSERT (mirror_num >0 );ASSERT (btrfs_op (&bbio->bio) ==BTRFS_MAP_WRITE ); -ASSERT (!bbio->inode); +ASSERT (!is_data_inode (bbio->inode)); +ASSERT (bbio->is_scrub);btrfs_bio_counter_inc_blocked (fs_info); ret =btrfs_map_repair_block (fs_info, &smap, logical, length, mirror_num);
fs/btrfs/bio.h +12 -6
@@ -34,7 +34,10 @@ typedef void (*btrfs_bio_end_io_t)(struct btrfs_bio *bbio);struct btrfs_bio {/* * Inode and offset into it that this I/O operates on. -* Only set for data I/O. +* +* If the inode is a data one, csum verification and read-repair +* will be done automatically. +* If the inode is a metadata one, everything is handled by the caller. */ struct btrfs_inode *inode;u64 file_offset;
@@ -76,14 +79,17 @@ struct btrfs_bio {atomic_t pending_ios;struct work_struct end_io_work; -/* File system that this I/O operates on. */ -struct btrfs_fs_info *fs_info; -/* Save the first error status of split bio. */ blk_status_t status;/* Use the commit root to look up csums (data read bio only). */ bool csum_search_commit_root; + +/* +* Since scrub will reuse btree inode, we need this flag to distinguish +* scrub bios. +*/ +bool is_scrub;/* * This member must come last, bio_alloc_bioset will allocate enough * bytes for entire btrfs_bio but relies on bio being last.
@@ -99,10 +105,10 @@ static inline struct btrfs_bio *btrfs_bio(struct bio *bio)int __init btrfs_bioset_init (void );void __cold btrfs_bioset_exit (void ); -void btrfs_bio_init (struct btrfs_bio *bbio,struct btrfs_fs_info *fs_info, +void btrfs_bio_init (struct btrfs_bio *bbio,struct btrfs_inode *inode,u64 file_offset,btrfs_bio_end_io_t end_io,void *private);struct btrfs_bio *btrfs_bio_alloc (unsigned int nr_vecs,blk_opf_t opf, -struct btrfs_fs_info *fs_info, +struct btrfs_inode *inode,u64 file_offset,btrfs_bio_end_io_t end_io,void *private);void btrfs_bio_end_io (struct btrfs_bio *bbio,blk_status_t status);
fs/btrfs/compression.c +2 -4
@@ -67,9 +67,7 @@ static struct compressed_bio *alloc_compressed_bio(struct btrfs_inode *inode, bbio =btrfs_bio (bio_alloc_bioset (NULL ,BTRFS_MAX_COMPRESSED_PAGES , op,GFP_NOFS , &btrfs_compressed_bioset)); -btrfs_bio_init (bbio, inode->root->fs_info, end_io,NULL ); - bbio->inode = inode; - bbio->file_offset = start; +btrfs_bio_init (bbio, inode, start, end_io,NULL );return to_compressed_bio (bbio); }
@@ -354,7 +352,7 @@ static void end_bbio_compressed_write(struct btrfs_bio *bbio)static void btrfs_add_compressed_bio_folios (struct compressed_bio *cb) { -struct btrfs_fs_info *fs_info = cb->bbio.fs_info; +struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;struct bio *bio = &cb->bbio.bio;u32 offset =0 ;
fs/btrfs/compression.h +2 -1
@@ -14,6 +14,7 @@#include <linux/pagemap.h> #include "bio.h" #include "fs.h" +#include "btrfs_inode.h" struct address_space ;struct inode ;
@@ -74,7 +75,7 @@ struct compressed_bio {static inline struct btrfs_fs_info *cb_to_fs_info (const struct compressed_bio *cb) { -return cb->bbio.fs_info; +return cb->bbio.inode->root->fs_info; }/* @range_end must be exclusive. */
fs/btrfs/direct-io.c +1 -3
@@ -715,10 +715,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, container_of(bbio, struct btrfs_dio_private, bbio);struct btrfs_dio_data *dio_data = iter->private; -btrfs_bio_init (bbio,BTRFS_I (iter->inode)->root->fs_info, +btrfs_bio_init (bbio,BTRFS_I (iter->inode), file_offset, btrfs_dio_end_io, bio->bi_private); - bbio->inode =BTRFS_I (iter->inode); - bbio->file_offset = file_offset; dip->file_offset = file_offset; dip->bytes = bio->bi_iter.bi_size;
fs/btrfs/extent_io.c +9 -13
@@ -518,7 +518,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le*/ static void end_bbio_data_write (struct btrfs_bio *bbio) { -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;struct bio *bio = &bbio->bio;int error =blk_status_to_errno (bio->bi_status);struct folio_iter fi;
@@ -574,7 +574,7 @@ static void begin_folio_read(struct btrfs_fs_info *fs_info, struct folio *folio)*/ static void end_bbio_data_read (struct btrfs_bio *bbio) { -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;struct bio *bio = &bbio->bio;struct folio_iter fi;
@@ -739,12 +739,10 @@ static void alloc_new_bio(struct btrfs_inode *inode,struct btrfs_fs_info *fs_info = inode->root->fs_info;struct btrfs_bio *bbio; - bbio =btrfs_bio_alloc (BIO_MAX_VECS , bio_ctrl->opf, fs_info, - bio_ctrl->end_io_func,NULL ); + bbio =btrfs_bio_alloc (BIO_MAX_VECS , bio_ctrl->opf, inode, + file_offset, bio_ctrl->end_io_func,NULL ); bbio->bio.bi_iter.bi_sector = disk_bytenr >>SECTOR_SHIFT ; bbio->bio.bi_write_hint = inode->vfs_inode.i_write_hint; - bbio->inode = inode; - bbio->file_offset = file_offset; bio_ctrl->bbio = bbio; bio_ctrl->len_to_oe_boundary =U32_MAX ; bio_ctrl->next_file_offset = file_offset;
@@ -2223,12 +2221,11 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb, bbio =btrfs_bio_alloc (INLINE_EXTENT_BUFFER_PAGES ,REQ_OP_WRITE |REQ_META |wbc_to_write_flags (wbc), - eb->fs_info, end_bbio_meta_write, eb); +BTRFS_I (fs_info->btree_inode), eb->start, + end_bbio_meta_write, eb); bbio->bio.bi_iter.bi_sector = eb->start >>SECTOR_SHIFT ;bio_set_dev (&bbio->bio, fs_info->fs_devices->latest_dev->bdev);wbc_init_bio (wbc, &bbio->bio); - bbio->inode =BTRFS_I (eb->fs_info->btree_inode); - bbio->file_offset = eb->start;for (int i =0 ; i <num_extent_folios (eb); i++) {struct folio *folio = eb->folios[i];u64 range_start =max_t (u64, eb->start,folio_pos (folio));
@@ -3842,6 +3839,7 @@ static void end_bbio_meta_read(struct btrfs_bio *bbio)int read_extent_buffer_pages_nowait (struct extent_buffer *eb,int mirror_num,const struct btrfs_tree_parent_check *check) { +struct btrfs_fs_info *fs_info = eb->fs_info;struct btrfs_bio *bbio;if (test_bit (EXTENT_BUFFER_UPTODATE , &eb->bflags))
@@ -3875,11 +3873,9 @@ int read_extent_buffer_pages_nowait(struct extent_buffer *eb, int mirror_num,refcount_inc (&eb->refs); bbio =btrfs_bio_alloc (INLINE_EXTENT_BUFFER_PAGES , -REQ_OP_READ |REQ_META , eb->fs_info, - end_bbio_meta_read, eb); +REQ_OP_READ |REQ_META ,BTRFS_I (fs_info->btree_inode), + eb->start, end_bbio_meta_read, eb); bbio->bio.bi_iter.bi_sector = eb->start >>SECTOR_SHIFT ; - bbio->inode =BTRFS_I (eb->fs_info->btree_inode); - bbio->file_offset = eb->start;memcpy (&bbio->parent_check, check,sizeof (*check));for (int i =0 ; i <num_extent_folios (eb); i++) {struct folio *folio = eb->folios[i];
fs/btrfs/inode.c +2 -5
@@ -9423,7 +9423,6 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode, u64 disk_bytenr, u64 disk_io_size, struct page **pages, void *uring_ctx) { - struct btrfs_fs_info *fs_info = inode->root->fs_info; struct btrfs_encoded_read_private *priv, sync_priv;struct completion sync_reads;unsigned long i =0 ;
@@ -9448,10 +9447,9 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode, priv->status =0 ; priv->uring_ctx = uring_ctx; - bbio =btrfs_bio_alloc (BIO_MAX_VECS ,REQ_OP_READ , fs_info, + bbio =btrfs_bio_alloc (BIO_MAX_VECS ,REQ_OP_READ , inode,0 , btrfs_encoded_read_endio, priv); bbio->bio.bi_iter.bi_sector = disk_bytenr >>SECTOR_SHIFT ; - bbio->inode = inode; do { size_t bytes = min_t(u64, disk_io_size, PAGE_SIZE);
@@ -9460,10 +9458,9 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,refcount_inc (&priv->pending_refs);btrfs_submit_bbio (bbio,0 ); - bbio =btrfs_bio_alloc (BIO_MAX_VECS ,REQ_OP_READ , fs_info, + bbio =btrfs_bio_alloc (BIO_MAX_VECS ,REQ_OP_READ , inode,0 , btrfs_encoded_read_endio, priv); bbio->bio.bi_iter.bi_sector = disk_bytenr >>SECTOR_SHIFT ; - bbio->inode = inode;continue ; }
fs/btrfs/scrub.c +29 -22
90 lines not on this page · raw message
fs/btrfs/zoned.c +2 -2
@@ -1809,14 +1809,14 @@ bool btrfs_use_zone_append(struct btrfs_bio *bbio) {u64 start = (bbio->bio.bi_iter.bi_sector <<SECTOR_SHIFT );struct btrfs_inode *inode = bbio->inode; -struct btrfs_fs_info *fs_info = bbio->fs_info; +struct btrfs_fs_info *fs_info = inode->root->fs_info;struct btrfs_block_group *cache;bool ret = false;if (!btrfs_is_zoned (fs_info))return false; -if (!inode || !is_data_inode (inode)) +if (!is_data_inode (inode))return false;if (btrfs_op (&bbio->bio) !=BTRFS_MAP_WRITE )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 24/641 btrfs: make sure all btrfs_bio::end_io are called in task context
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 4591c3ef751d861d7dd95ff4d2aadb1b5e95854e ]
[BACKGROUND]
Btrfs has a lot of different bi_end_io functions, to handle different raid profiles. But they introduced a lot of different contexts for btrfs_bio::end_io() calls:
- Simple read bios
Run in task context, backed by either endio_meta_workers or endio_workers.
- Simple write bios
Run in IRQ context.
- RAID56 write or rebuild bios
Run in task context, backed by rmw_workers.
- Mirrored write bios
Run in irq context.
This is inconsistent, and contributes to the number of workqueues used in btrfs.
[ENHANCEMENT]
Make all the above bios call their btrfs_bio::end_io() in task context, backed by either endio_meta_workers for metadata, or endio_workers for data.
For simple write bios, merge the handling into simple_end_io_work().
For mirrored write bios, it will be a little more complex, since both the original or the cloned bios can run the final btrfs_bio::end_io().
Here we make sure the cloned bios are using btrfs_bioset, to reuse the end_io_work, and run both original and cloned work inside the workqueue.
Add extra ASSERT()s to make sure btrfs_bio_end_io() is running in task context.
This not only unifies the context for btrfs_bio::end_io() functions, but also opens a new door for further btrfs_bio::end_io() related cleanups.
Stable-dep-of: b39b26e017c7 ("btrfs: zoned: don't zone append to conventional zone")
--- fs/btrfs/bio.c | 64 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 18 deletions(-)
fs/btrfs/bio.c +46 -18
@@ -102,6 +102,9 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,void btrfs_bio_end_io (struct btrfs_bio *bbio,blk_status_t status) { +/* Make sure we're already in task context. */ +ASSERT (in_task ()); + bbio->bio.bi_status = status;if (bbio->bio.bi_pool == &btrfs_clone_bioset) {struct btrfs_bio *orig_bbio = bbio->private;
@@ -318,15 +321,20 @@ static struct workqueue_struct *btrfs_end_io_wq(const struct btrfs_fs_info *fs_ireturn fs_info->endio_workers; } -static void btrfs_end_bio_work (struct work_struct *work) +static void simple_end_io_work (struct work_struct *work) { struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work); +struct bio *bio = &bbio->bio; -/* Metadata reads are checked and repaired by the submitter. */ -if (is_data_bbio (bbio)) -btrfs_check_read_bio (bbio, bbio->bio.bi_private); -else -btrfs_bio_end_io (bbio, bbio->bio.bi_status); +if (bio_op (bio) ==REQ_OP_READ ) { +/* Metadata reads are checked and repaired by the submitter. */ +if (is_data_bbio (bbio)) +return btrfs_check_read_bio (bbio, bbio->bio.bi_private); +return btrfs_bio_end_io (bbio, bbio->bio.bi_status); + } +if (bio_is_zone_append (bio) && !bio->bi_status) +btrfs_record_physical_zoned (bbio); +btrfs_bio_end_io (bbio, bbio->bio.bi_status); }static void btrfs_simple_end_io (struct bio *bio)
@@ -340,14 +348,8 @@ static void btrfs_simple_end_io(struct bio *bio)if (bio->bi_status)btrfs_log_dev_io_error (bio, dev); -if (bio_op (bio) ==REQ_OP_READ ) { -INIT_WORK (&bbio->end_io_work, btrfs_end_bio_work); -queue_work (btrfs_end_io_wq (fs_info, bio), &bbio->end_io_work); - }else { -if (bio_is_zone_append (bio) && !bio->bi_status) -btrfs_record_physical_zoned (bbio); -btrfs_bio_end_io (bbio, bbio->bio.bi_status); - } +INIT_WORK (&bbio->end_io_work, simple_end_io_work); +queue_work (btrfs_end_io_wq (fs_info, bio), &bbio->end_io_work); }static void btrfs_raid56_end_io (struct bio *bio)
@@ -355,6 +357,9 @@ static void btrfs_raid56_end_io(struct bio *bio)struct btrfs_io_context *bioc = bio->bi_private;struct btrfs_bio *bbio =btrfs_bio (bio); +/* RAID56 endio is always handled in workqueue. */ +ASSERT (in_task ()); +btrfs_bio_counter_dec (bioc->fs_info); bbio->mirror_num = bioc->mirror_num;if (bio_op (bio) ==REQ_OP_READ &&is_data_bbio (bbio))
@@ -365,11 +370,12 @@ static void btrfs_raid56_end_io(struct bio *bio)btrfs_put_bioc (bioc); } -static void btrfs_orig_write_end_io (struct bio *bio) +static void orig_write_end_io_work (struct work_struct *work) { + struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work); +struct bio *bio = &bbio->bio;struct btrfs_io_stripe *stripe = bio->bi_private;struct btrfs_io_context *bioc = stripe->bioc; -struct btrfs_bio *bbio =btrfs_bio (bio);btrfs_bio_counter_dec (bioc->fs_info);
@@ -394,8 +400,18 @@ static void btrfs_orig_write_end_io(struct bio *bio)btrfs_put_bioc (bioc); } -static void btrfs_clone_write_end_io (struct bio *bio) +static void btrfs_orig_write_end_io (struct bio *bio) +{ +struct btrfs_bio *bbio =btrfs_bio (bio); + +INIT_WORK (&bbio->end_io_work, orig_write_end_io_work); +queue_work (btrfs_end_io_wq (bbio->inode->root->fs_info, bio), &bbio->end_io_work); +} + +static void clone_write_end_io_work (struct work_struct *work) { + struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work); +struct bio *bio = &bbio->bio;struct btrfs_io_stripe *stripe = bio->bi_private;if (bio->bi_status) {
@@ -410,6 +426,14 @@ static void btrfs_clone_write_end_io(struct bio *bio)bio_put (bio); } +static void btrfs_clone_write_end_io (struct bio *bio) +{ +struct btrfs_bio *bbio =btrfs_bio (bio); + +INIT_WORK (&bbio->end_io_work, clone_write_end_io_work); +queue_work (btrfs_end_io_wq (bbio->inode->root->fs_info, bio), &bbio->end_io_work); +} +static void btrfs_submit_dev_bio (struct btrfs_device *dev,struct bio *bio) { if (!dev || !dev->bdev ||
@@ -456,6 +480,7 @@ static void btrfs_submit_dev_bio(struct btrfs_device *dev, struct bio *bio)static void btrfs_submit_mirrored_bio (struct btrfs_io_context *bioc,int dev_nr) {struct bio *orig_bio = bioc->orig_bio, *bio; +struct btrfs_bio *orig_bbio =btrfs_bio (orig_bio);ASSERT (bio_op (orig_bio) !=REQ_OP_READ );
@@ -464,8 +489,11 @@ static void btrfs_submit_mirrored_bio(struct btrfs_io_context *bioc, int dev_nr) bio = orig_bio; bio->bi_end_io = btrfs_orig_write_end_io; }else { - bio =bio_alloc_clone (NULL , orig_bio,GFP_NOFS , &fs_bio_set); +/* We need to use endio_work to run end_io in task context. */ + bio =bio_alloc_clone (NULL , orig_bio,GFP_NOFS , &btrfs_bioset);bio_inc_remaining (orig_bio); +btrfs_bio_init (btrfs_bio (bio), orig_bbio->inode, + orig_bbio->file_offset,NULL ,NULL ); bio->bi_end_io = btrfs_clone_write_end_io; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 25/641 btrfs: introduce btrfs_bio::async_csum
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit dd57c78aec398717a2fa6488d87b1a6cd43c7d0d ]
[ENHANCEMENT]
Btrfs currently calculates data checksums then submits the bio.
But after commit 968f19c5b1b7 ("btrfs: always fallback to buffered write if the inode requires checksum"), any writes with data checksum will fallback to buffered IO, meaning the content will not change during writeback.
This means we're safe to calculate the data checksum and submit the bio in parallel, and only need the following new behavior:
- Wait the csum generation to finish before calling btrfs_bio::end_io() Or this can lead to use-after-free for the csum generation worker.
- Save the current bi_iter for csum_one_bio()
As the submission part can advance btrfs_bio::bio.bi_iter, if not saved csum_one_bio() may got an empty bi_iter and do not generate any checksum.
Unfortunately this means we have to increase the size of btrfs_bio for 16 bytes, but this is still acceptable.
As usual, such new feature is hidden behind the experimental flag.
[THEORETIC ANALYZE]
Consider the following theoretic hardware performance, which should be more or less close to modern mainstream hardware:
Memory bandwidth: 50GiB/s
CRC32C bandwidth: 45GiB/s
SSD bandwidth: 8GiB/s
Then write bandwidth with data checksum before the patch is:
1 / ( 1 / 50 + 1 / 45 + 1 / 8) = 5.98 GiB/s
After the patch, the bandwidth is:
1 / ( 1 / 50 + max( 1 / 45 + 1 / 8)) = 6.90 GiB/s
The difference is 15.32% improvement.
[REAL WORLD BENCHMARK]
I'm using a Zen5 (HX 370) as the host, the VM has 4GiB memory, 10 vCPUs, the storage is backed by a PCIe gen3 x4 NVMe.
The test is a direct IO write, with 1MiB block size, write 7GiB data into a btrfs mount with data checksum. Thus the direct write will fallback to buffered one:
Vanilla Datasum: 1619.97 GiB/s
Patched Datasum: 1792.26 GiB/s
Diff +10.6 %
In my case, the bottleneck is the storage, thus the improvement is not reaching the theoretic one, but still some observable improvement.
Stable-dep-of: b39b26e017c7 ("btrfs: zoned: don't zone append to conventional zone")
--- fs/btrfs/bio.c | 21 ++++++++++++---- fs/btrfs/bio.h | 7 ++++++ fs/btrfs/file-item.c | 60 +++++++++++++++++++++++++++++++------------- fs/btrfs/file-item.h | 2 +- 4 files changed, 67 insertions(+), 23 deletions(-)
fs/btrfs/bio.c +16 -5
@@ -105,6 +105,9 @@ void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)/* Make sure we're already in task context. */ ASSERT (in_task ()); +if (bbio->async_csum) +wait_for_completion (&bbio->csum_done); + bbio->bio.bi_status = status;if (bbio->bio.bi_pool == &btrfs_clone_bioset) {struct btrfs_bio *orig_bbio = bbio->private;
@@ -538,7 +541,11 @@ static int btrfs_bio_csum(struct btrfs_bio *bbio) {if (bbio->bio.bi_opf &REQ_META )return btree_csum_one_bio (bbio); -return btrfs_csum_one_bio (bbio); +#ifdef CONFIG_BTRFS_EXPERIMENTAL +return btrfs_csum_one_bio (bbio, true); +#else +return btrfs_csum_one_bio (bbio, false); +#endif }/*
@@ -617,10 +624,14 @@ static bool should_async_write(struct btrfs_bio *bbio)struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;enum btrfs_offload_csum_mode csum_mode =READ_ONCE (fs_devices->offload_csum_mode); -if (csum_mode ==BTRFS_OFFLOAD_CSUM_FORCE_OFF ) -return false; - - auto_csum_mode = (csum_mode ==BTRFS_OFFLOAD_CSUM_AUTO ); +if (csum_mode ==BTRFS_OFFLOAD_CSUM_FORCE_ON ) +return true; +/* +* Write bios will calculate checksum and submit bio at the same time. +* Unless explicitly required don't offload serial csum calculate and bio +* submit into a workqueue. +*/ +return false;#endif /* Submit synchronously if the checksum implementation is fast. */
fs/btrfs/bio.h +7 -0
@@ -63,6 +63,9 @@ struct btrfs_bio {struct {struct btrfs_ordered_extent *ordered;struct btrfs_ordered_sum *sums; +struct work_struct csum_work; +struct completion csum_done; +struct bvec_iter csum_saved_iter;u64 orig_physical; };
@@ -90,6 +93,10 @@ struct btrfs_bio {* scrub bios. */ bool is_scrub; + +/* Whether the csum generation for data write is async. */ +bool async_csum; +/* * This member must come last, bio_alloc_bioset will allocate enough * bytes for entire btrfs_bio but relies on bio being last.
fs/btrfs/file-item.c +43 -17
91 lines not on this page · raw message
fs/btrfs/file-item.h +1 -1
@@ -64,7 +64,7 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,int btrfs_csum_file_blocks (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct btrfs_ordered_sum *sums); -int btrfs_csum_one_bio (struct btrfs_bio *bbio); +int btrfs_csum_one_bio (struct btrfs_bio *bbio,bool async);int btrfs_alloc_dummy_sum (struct btrfs_bio *bbio); int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, struct list_head *list, int search_commit,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 26/641 btrfs: add orig_logical to btrfs_bio for encryption
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit bd45e9e3f6232f76fa9bd0e40c1e3409e4449f5e ]
When checksumming the encrypted bio on writes we need to know which logical address this checksum is for. At the point where we get the encrypted bio the bi_sector is the physical location on the target disk, so we need to save the original logical offset in the btrfs_bio. Then we can use this when checksumming the bio instead of the bio->iter.bi_sector.
Note: The patch was taken from v5 of fscrypt patchset
(https://lore.kernel.org/linux-btrfs/[email protected]/)
which was handled over time by various people: Omar Sandoval, Sweet Tea Dorminy, Josef Bacik.
Stable-dep-of: b39b26e017c7 ("btrfs: zoned: don't zone append to conventional zone")
--- fs/btrfs/bio.c | 10 ++++++++++ fs/btrfs/bio.h | 2 ++ fs/btrfs/file-item.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-)
fs/btrfs/bio.c +10 -0
@@ -94,6 +94,8 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,if (bbio_has_ordered_extent (bbio)) {refcount_inc (&orig_bbio->ordered->refs); bbio->ordered = orig_bbio->ordered; + bbio->orig_logical = orig_bbio->orig_logical; + orig_bbio->orig_logical += map_length; } bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;atomic_inc (&orig_bbio->pending_ios);
@@ -726,6 +728,14 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) goto end_bbio; } +/* +* For fscrypt writes we will get the encrypted bio after we've remapped +* our bio to the physical disk location, so we need to save the +* original bytenr so we know what we're checksumming. +*/ +if (bio_op (bio) ==REQ_OP_WRITE &&is_data_bbio (bbio)) + bbio->orig_logical = logical; + map_length =min (map_length, length);if (use_append) map_length =btrfs_append_map_length (bbio, map_length);
fs/btrfs/bio.h +2 -0
@@ -59,6 +59,7 @@ struct btrfs_bio {* - pointer to the checksums for this bio * - original physical address from the allocator * (for zone append only) +* - original logical address, used for checksumming fscrypt bios */ struct {struct btrfs_ordered_extent *ordered;
@@ -67,6 +68,7 @@ struct btrfs_bio {struct completion csum_done;struct bvec_iter csum_saved_iter;u64 orig_physical; +u64 orig_logical; };/* For metadata reads: parentness verification. */
fs/btrfs/file-item.c +1 -1
@@ -815,7 +815,7 @@ int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async)if (!sums)return -ENOMEM ; - sums->logical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ; + sums->logical = bbio->orig_logical; sums->len = bio->bi_iter.bi_size;INIT_LIST_HEAD (&sums->list); bbio->sums = sums;
Signature · 1 line
2.51.0
Re: [PATCH 6.18 026/641] btrfs: add orig_logical to btrfs_bio for encryption
Quoted 2 lines · Greg Kroah-Hartman
6.18-stable review patch. If anyone has any objections, please let me know.
Hi Greg,
This one is a preparation for new feature development, it's not really worth the stable branch. Backporting it makes no sense.
Have a nice day,
Daniel
Quoted 97 lines
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit
bd45e9e3f6232f76fa9bd0e40c1e3409e4449f5e]When checksumming the encrypted bio on writes we need to know which logical address this checksum is for. At the point where we get the encrypted bio the
bi_sectoris the physical location on the target disk, so we need to save the original logical offset in thebtrfs_bio. Then we can use this when checksumming the bio instead of thebio->iter.bi_sector.Note: The patch was taken from v5 of fscrypt patchset
(https://lore.kernel.org/linux-btrfs/[email protected]/)
which was handled over time by various people: Omar Sandoval, Sweet Tea Dorminy, Josef Bacik.Signed-off-by Josef Bacik <[email protected]>Signed-off-by Daniel Vacek <[email protected]>Reviewed-by David Sterba <[email protected]>[ add note ]Signed-off-by David Sterba <[email protected]>Stable-dep-of:
b39b26e017c7("btrfs: zoned: don't zone append to conventional zone")Signed-off-by Sasha Levin <[email protected]>--- fs/btrfs/bio.c | 10 ++++++++++ fs/btrfs/bio.h | 2 ++ fs/btrfs/file-item.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-)fs/btrfs/bio.c +10
-0@@ -94,6 +94,8 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,if (bbio_has_ordered_extent (bbio)) {refcount_inc (&orig_bbio->ordered->refs); bbio->ordered = orig_bbio->ordered; + bbio->orig_logical = orig_bbio->orig_logical; + orig_bbio->orig_logical += map_length; } bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;atomic_inc (&orig_bbio->pending_ios);@@ -726,6 +728,14 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) goto end_bbio; } +/* +* For fscrypt writes we will get the encrypted bio after we've remapped +* our bio to the physical disk location, so we need to save the +* original bytenr so we know what we're checksumming. +*/ +if (bio_op (bio) ==REQ_OP_WRITE &&is_data_bbio (bbio)) + bbio->orig_logical = logical; + map_length =min (map_length, length);if (use_append) map_length =btrfs_append_map_length (bbio, map_length);fs/btrfs/bio.h +2
-0@@ -59,6 +59,7 @@ struct btrfs_bio {* - pointer to the checksums for this bio * - original physical address from the allocator * (for zone append only) +* - original logical address, used for checksumming fscrypt bios */ struct {struct btrfs_ordered_extent *ordered;@@ -67,6 +68,7 @@ struct btrfs_bio {struct completion csum_done;struct bvec_iter csum_saved_iter;u64 orig_physical; +u64 orig_logical; };/* For metadata reads: parentness verification. */ fs/btrfs/file-item.c +1
-2@@ -815,7 +815,7 @@ int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async)if (!sums)return -ENOMEM ; - sums->logical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ; + sums->logical = bbio->orig_logical; sums->len = bio->bi_iter.bi_size;INIT_LIST_HEAD (&sums->list); bbio->sums = sums; --2.51.0
Greg Kroah-Hartman
maintainerRe: [PATCH 6.18 026/641] btrfs: add orig_logical to btrfs_bio for encryption
Quoted 5 lines · Daniel Vacek
Quoted 2 lines · Greg Kroah-Hartman
6.18-stable review patch. If anyone has any objections, please let me know.
Quoted 32 lines
Hi Greg,
This one is a preparation for new feature development, it's not really worth the stable branch. Backporting it makes no sense.
Have a nice day,
DanielQuoted 24 lines
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit
bd45e9e3f6232f76fa9bd0e40c1e3409e4449f5e]When checksumming the encrypted bio on writes we need to know which logical address this checksum is for. At the point where we get the encrypted bio the
bi_sectoris the physical location on the target disk, so we need to save the original logical offset in thebtrfs_bio. Then we can use this when checksumming the bio instead of thebio->iter.bi_sector.Note: The patch was taken from v5 of fscrypt patchset
(https://lore.kernel.org/linux-btrfs/[email protected]/)
which was handled over time by various people: Omar Sandoval, Sweet Tea Dorminy, Josef Bacik.Signed-off-by Josef Bacik <[email protected]>Signed-off-by Daniel Vacek <[email protected]>Reviewed-by David Sterba <[email protected]>[ add note ]Signed-off-by David Sterba <[email protected]>Stable-dep-of:
b39b26e017c7("btrfs: zoned: don't zone append to conventional zone")
It was added because of the requirement for this backport. Let me see if that can't be done without this change first...
yup, that still worked, just a bit of fuzz, now dropped, thanks!
greg k-h
Greg Kroah-Hartman
maintainerPATCH 27/641 btrfs: zoned: dont zone append to conventional zone
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Thumshirn <[email protected]>
[ Upstream commit b39b26e017c7889181cb84032e22bef72e81cf29 ]
In case of a zoned RAID, it can happen that a data write is targeting a sequential write required zone and a conventional zone. In this case the bio will be marked as REQ_OP_ZONE_APPEND but for the conventional zone, this needs to be REQ_OP_WRITE.
The setting of REQ_OP_ZONE_APPEND is deferred to the last possible time in btrfs_submit_dev_bio(), but the decision if we can use zone append is cached in btrfs_bio.
--- fs/btrfs/bio.c | 19 +++++++++---------- fs/btrfs/bio.h | 3 +++ 2 files changed, 12 insertions(+), 10 deletions(-)
fs/btrfs/bio.c +9 -10
@@ -441,6 +441,8 @@ static void btrfs_clone_write_end_io(struct bio *bio)static void btrfs_submit_dev_bio (struct btrfs_device *dev,struct bio *bio) { +u64 physical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ; + if (!dev || !dev->bdev || test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) || (btrfs_op(bio) == BTRFS_MAP_WRITE &&
@@ -455,12 +457,13 @@ static void btrfs_submit_dev_bio(struct btrfs_device *dev, struct bio *bio)* For zone append writing, bi_sector must point the beginning of the * zone */ -if (bio_op (bio) ==REQ_OP_ZONE_APPEND ) { -u64 physical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ; +if (btrfs_bio (bio)->can_use_append &&btrfs_dev_is_sequential (dev, physical)) {u64 zone_start =round_down (physical, dev->fs_info->zone_size);ASSERT (btrfs_dev_is_sequential (dev, physical)); bio->bi_iter.bi_sector = zone_start >>SECTOR_SHIFT ; + bio->bi_opf &= ~REQ_OP_WRITE ; + bio->bi_opf |=REQ_OP_ZONE_APPEND ; } btrfs_debug(dev->fs_info, "%s: rw %d 0x%x, sector=%llu, dev=%lu (%s id %llu), size=%u",
@@ -708,7 +711,6 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)u64 logical = bio->bi_iter.bi_sector <<SECTOR_SHIFT ;u64 length = bio->bi_iter.bi_size;u64 map_length = length; -bool use_append =btrfs_use_zone_append (bbio);struct btrfs_io_context *bioc =NULL ;struct btrfs_io_stripe smap;blk_status_t status;
@@ -736,8 +738,10 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)if (bio_op (bio) ==REQ_OP_WRITE &&is_data_bbio (bbio)) bbio->orig_logical = logical; + bbio->can_use_append =btrfs_use_zone_append (bbio); + map_length =min (map_length, length); -if (use_append) +if (bbio->can_use_append) map_length =btrfs_append_map_length (bbio, map_length);if (map_length < length) {
@@ -766,11 +770,6 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) }if (btrfs_op (bio) ==BTRFS_MAP_WRITE ) { -if (use_append) { - bio->bi_opf &= ~REQ_OP_WRITE ; - bio->bi_opf |=REQ_OP_ZONE_APPEND ; - } -if (is_data_bbio (bbio) && bioc && bioc->use_rst) {/* * No locking for the list update, as we only add to
@@ -797,7 +796,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) status =errno_to_blk_status (ret);if (status) goto fail; - }else if (use_append || + }else if (bbio->can_use_append || (btrfs_is_zoned (fs_info) && inode && inode->flags &BTRFS_INODE_NODATASUM )) { ret =btrfs_alloc_dummy_sum (bbio);
fs/btrfs/bio.h +3 -0
@@ -99,6 +99,9 @@ struct btrfs_bio {/* Whether the csum generation for data write is async. */ bool async_csum; +/* Whether the bio is written using zone append. */ +bool can_use_append; +/* * This member must come last, bio_alloc_bioset will allocate enough * bytes for entire btrfs_bio but relies on bio being last.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 28/641 btrfs: qgroup: return correct error when deleting qgroup relation item
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 51b1fcf71c88c3c89e7dcf07869c5de837b1f428 ]
If we fail to delete the second qgroup relation item, we end up returning success or -ENOENT in case the first item does not exist, instead of returning the error from the second item deletion.
--- fs/btrfs/qgroup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/qgroup.c +3 -1
@@ -1627,8 +1627,10 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,if (ret <0 && ret != -ENOENT ) goto out; ret2 =del_qgroup_relation_item (trans, dst, src); -if (ret2 <0 && ret2 != -ENOENT ) +if (ret2 <0 && ret2 != -ENOENT ) { + ret = ret2; goto out; + }/* At least one deletion succeeded, return 0 */ if (!ret || !ret2)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 29/641 btrfs: fix block_group_tree dirty_list corruption
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
[ Upstream commit 3a1f4264daed4b419c325a7fe35e756cada3cf82 ]
When the incompat flag EXTENT_TREE_V2 is set, we unconditionally add the block group tree to the switch_commits list before calling switch_commit_roots, as we do for the tree root and the chunk root. However, the block group tree uses normal root dirty tracking and in any transaction that does an allocation and dirties a block group, the block group root will already be linked to a list by the dirty_list field and this use of list_add_tail() is invalid and corrupts the prev/next members of block_group_root->dirty_list.
This is apparent on a subsequent list_del on the prev if we enable CONFIG_DEBUG_LIST:
[32.1571] ------------[ cut here ]------------ [32.1572] list_del corruption. next->prev should beffff958890202538, but was ffff9588992bd538. (next=ffff958890201538) [32.1575] WARNING: lib/list_debug.c:65 at 0x0, CPU#3: sync/607 [32.1583] CPU: 3 UID: 0 PID: 607 Comm: sync Not tainted 6.18.0 #24PREEMPT(none) [32.1585] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS1.17.0-4.fc41 04/01/2014 [32.1587] RIP: 0010:__list_del_entry_valid_or_report+0x108/0x120 [32.1593] RSP: 0018:ffffaa288287fdd0 EFLAGS: 00010202 [32.1594] RAX: 0000000000000001 RBX: ffff95889326e800 RCX:ffff958890201538 [32.1596] RDX: ffff9588992bd538 RSI: ffff958890202538 RDI:ffffffff82a41e00 [32.1597] RBP: ffff958890202538 R08: ffffffff828fc1e8 R09:00000000ffffefff [32.1599] R10: ffffffff8288c200 R11: ffffffff828e4200 R12:ffff958890201538 [32.1601] R13: ffff95889326e958 R14: ffff958895c24000 R15:ffff958890202538 [32.1603] FS: 00007f0c28eb5740(0000) GS:ffff958af2bd2000(0000)knlGS:0000000000000000 [32.1605] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [32.1607] CR2: 00007f0c28e8a3cc CR3: 0000000109942005 CR4:0000000000370ef0 [32.1609] Call Trace: [32.1610] <TASK> [32.1611] switch_commit_roots+0x82/0x1d0 [btrfs] [32.1615] btrfs_commit_transaction+0x968/0x1550 [btrfs] [32.1618] ? btrfs_attach_transaction_barrier+0x23/0x60 [btrfs] [32.1621] __iterate_supers+0xe8/0x190 [32.1622] ? __pfx_sync_fs_one_sb+0x10/0x10 [32.1623] ksys_sync+0x63/0xb0 [32.1624] __do_sys_sync+0xe/0x20 [32.1625] do_syscall_64+0x73/0x450 [32.1626] entry_SYSCALL_64_after_hwframe+0x76/0x7e [32.1627] RIP: 0033:0x7f0c28d05d2b [32.1632] RSP: 002b:00007ffc9d988048 EFLAGS: 00000246 ORIG_RAX:00000000000000a2 [32.1634] RAX: ffffffffffffffda RBX: 00007ffc9d988228 RCX:00007f0c28d05d2b [32.1636] RDX: 00007f0c28e02301 RSI: 00007ffc9d989b21 RDI:00007f0c28dba90d [32.1637] RBP: 0000000000000001 R08: 0000000000000001 R09:0000000000000000 [32.1639] R10: 0000000000000000 R11: 0000000000000246 R12:000055b96572cb80 [32.1641] R13: 000055b96572b19f R14: 00007f0c28dfa434 R15:000055b96572b034 [32.1643] </TASK> [32.1644] irq event stamp: 0 [32.1644] hardirqs last enabled at (0): [<0000000000000000>] 0x0 [32.1646] hardirqs last disabled at (0): [<ffffffff81298817>]copy_process+0xb37/0x2260 [32.1648] softirqs last enabled at (0): [<ffffffff81298817>]copy_process+0xb37/0x2260 [32.1650] softirqs last disabled at (0): [<0000000000000000>] 0x0 [32.1652] ---[ end trace 0000000000000000 ]---
Furthermore, this list corruption eventually (when we happen to add a new block group) results in getting the switch_commits and dirty_cowonly_roots lists mixed up and attempting to call update_root on the tree root which can't be found in the tree root, resulting in a transaction abort:
[87.8269] BTRFS critical (device nvme1n1): unable to find root key (1 0 0) in tree 1 [87.8272] ------------[ cut here ]------------ [87.8274] BTRFS: Transaction aborted (error -117) [87.8275] WARNING: fs/btrfs/root-tree.c:153 at 0x0, CPU#4: sync/703 [87.8285] CPU: 4 UID: 0 PID: 703 Comm: sync Not tainted 6.18.0 #25 PREEMPT(none) [87.8287] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-4.fc41 04/01/2014 [87.8289] RIP: 0010:btrfs_update_root+0x296/0x790 [btrfs] [87.8295] RSP: 0018:ffffa58d035dfd60 EFLAGS: 00010282 [87.8297] RAX: ffff9a59126ddb68 RBX: ffff9a59126dc000 RCX: 0000000000000000 [87.8299] RDX: 0000000000000000 RSI: 00000000ffffff8b RDI: ffffffffc0b28270 [87.8301] RBP: ffff9a5904aec000 R08: 0000000000000000 R09: 00000000ffffefff [87.8303] R10: ffffffff9ac8c200 R11: ffffffff9ace4200 R12: 0000000000000001 [87.8305] R13: ffff9a59041740e8 R14: ffff9a5904aec1f7 R15: ffff9a590fdefaf0 [87.8307] FS: 00007f54cde6b740(0000) GS:ffff9a5b5a81c000(0000) knlGS:0000000000000000 [87.8309] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [87.8310] CR2: 00007f54cde403cc CR3: 0000000112902004 CR4: 0000000000370ef0 [87.8312] Call Trace: [87.8313] <TASK> [87.8314] ? _raw_spin_unlock+0x23/0x40 [87.8315] commit_cowonly_roots+0x1ad/0x250 [btrfs] [87.8317] ? btrfs_commit_transaction+0x79b/0x1560 [btrfs] [87.8320] btrfs_commit_transaction+0x8aa/0x1560 [btrfs] [87.8322] ? btrfs_attach_transaction_barrier+0x23/0x60 [btrfs] [87.8325] __iterate_supers+0xf1/0x170 [87.8326] ? __pfx_sync_fs_one_sb+0x10/0x10 [87.8327] ksys_sync+0x63/0xb0 [87.8328] __do_sys_sync+0xe/0x20 [87.8329] do_syscall_64+0x73/0x450 [87.8330] entry_SYSCALL_64_after_hwframe+0x76/0x7e [87.8331] RIP: 0033:0x7f54cdd05d2b [87.8336] RSP: 002b:00007fff1b58ff78 EFLAGS: 00000246 ORIG_RAX: 00000000000000a2 [87.8338] RAX: ffffffffffffffda RBX: 00007fff1b590158 RCX: 00007f54cdd05d2b [87.8340] RDX: 00007f54cde02301 RSI: 00007fff1b592b66 RDI: 00007f54cddba90d [87.8342] RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000000 [87.8344] R10: 0000000000000000 R11: 0000000000000246 R12: 000055e07ca96b80 [87.8346] R13: 000055e07ca9519f R14: 00007f54cddfa434 R15: 000055e07ca95034 [87.8348] </TASK> [87.8348] irq event stamp: 0 [87.8349] hardirqs last enabled at (0): [<0000000000000000>] 0x0 [87.8351] hardirqs last disabled at (0): [<ffffffff99698797>] copy_process+0xb37/0x21e0 [87.8353] softirqs last enabled at (0): [<ffffffff99698797>] copy_process+0xb37/0x21e0 [87.8355] softirqs last disabled at (0): [<0000000000000000>] 0x0 [87.8357] ---[ end trace 0000000000000000 ]--- [87.8358] BTRFS: error (device nvme1n1 state A) in btrfs_update_root:153: errno=-117 Filesystem corrupted [87.8360] BTRFS info (device nvme1n1 state EA): forced readonly [87.8362] BTRFS warning (device nvme1n1 state EA): Skipping commit of aborted transaction. [87.8364] BTRFS: error (device nvme1n1 state EA) in cleanup_transaction:2037: errno=-117 Filesystem corrupted
Since the block group tree was pulled out of the extent tree and uses normal root dirty tracking, remove the offending extra list_add. This fixes the list corruption and the resulting fs corruption.
--- fs/btrfs/transaction.c | 7 ------- 1 file changed, 7 deletions(-)
fs/btrfs/transaction.c +0 -7
@@ -2484,13 +2484,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)list_add_tail (&fs_info->chunk_root->dirty_list, &cur_trans->switch_commits); -if (btrfs_fs_incompat (fs_info,EXTENT_TREE_V2 )) { -btrfs_set_root_node (&fs_info->block_group_root->root_item, - fs_info->block_group_root->node); -list_add_tail (&fs_info->block_group_root->dirty_list, - &cur_trans->switch_commits); - } -switch_commit_roots (trans);ASSERT (list_empty (&cur_trans->dirty_bgs));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 30/641 btrfs: fix EEXIST abort due to non-consecutive gaps in chunk allocation
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
[ Upstream commit b14c5e04bd0f722ed631845599d52d03fcae1bc1 ]
I have been observing a number of systems aborting at insert_dev_extents() in btrfs_create_pending_block_groups(). The following is a sample stack trace of such an abort coming from forced chunk allocation (typically behind CONFIG_BTRFS_EXPERIMENTAL) but this can theoretically happen to any DUP chunk allocation.
[81.801] ------------[ cut here ]------------ [81.801] BTRFS: Transaction aborted (error -17) [81.801] WARNING: fs/btrfs/block-group.c:2876 at btrfs_create_pending_block_groups+0x721/0x770 [btrfs], CPU#1: bash/319 [81.802] Modules linked in: virtio_net btrfs xor zstd_compress raid6_pq null_blk [81.803] CPU: 1 UID: 0 PID: 319 Comm: bash Kdump: loaded Not tainted 6.19.0-rc6+ #319 NONE [81.803] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014 [81.804] RIP: 0010:btrfs_create_pending_block_groups+0x723/0x770 [btrfs] [81.806] RSP: 0018:ffffa36241a6bce8 EFLAGS: 00010282 [81.806] RAX: 000000000000000d RBX: ffff8e699921e400 RCX: 0000000000000000 [81.807] RDX: 0000000002040001 RSI: 00000000ffffffef RDI: ffffffffc0608bf0 [81.807] RBP: 00000000ffffffef R08: ffff8e69830f6000 R09: 0000000000000007 [81.808] R10: ffff8e699921e5e8 R11: 0000000000000000 R12: ffff8e6999228000 [81.808] R13: ffff8e6984d82000 R14: ffff8e69966a69c0 R15: ffff8e69aa47b000 [81.809] FS: 00007fec6bdd9740(0000) GS:ffff8e6b1b379000(0000) knlGS:0000000000000000 [81.809] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [81.810] CR2: 00005604833670f0 CR3: 0000000116679000 CR4: 00000000000006f0 [81.810] Call Trace: [81.810] <TASK> [81.810] __btrfs_end_transaction+0x3e/0x2b0 [btrfs] [81.811] btrfs_force_chunk_alloc_store+0xcd/0x140 [btrfs] [81.811] kernfs_fop_write_iter+0x15f/0x240 [81.812] vfs_write+0x264/0x500 [81.812] ksys_write+0x6c/0xe0 [81.812] do_syscall_64+0x66/0x770 [81.812] entry_SYSCALL_64_after_hwframe+0x76/0x7e [81.813] RIP: 0033:0x7fec6be66197 [81.814] RSP: 002b:00007fffb159dd30 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [81.815] RAX: ffffffffffffffda RBX: 00007fec6bdd9740 RCX: 00007fec6be66197 [81.815] RDX: 0000000000000002 RSI: 0000560483374f80 RDI: 0000000000000001 [81.816] RBP: 0000560483374f80 R08: 0000000000000000 R09: 0000000000000000 [81.816] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000002 [81.817] R13: 00007fec6bfb85c0 R14: 00007fec6bfb5ee0 R15: 00005604833729c0 [81.817] </TASK> [81.817] irq event stamp: 20039 [81.818] hardirqs last enabled at (20047): [<ffffffff99a68302>] __up_console_sem+0x52/0x60 [81.818] hardirqs last disabled at (20056): [<ffffffff99a682e7>] __up_console_sem+0x37/0x60 [81.819] softirqs last enabled at (19470): [<ffffffff999d2b46>] __irq_exit_rcu+0x96/0xc0 [81.819] softirqs last disabled at (19463): [<ffffffff999d2b46>] __irq_exit_rcu+0x96/0xc0 [81.820] ---[ end trace 0000000000000000 ]--- [81.820] BTRFS: error (device dm-7 state A) in btrfs_create_pending_block_groups:2876: errno=-17 Object already exists
Inspecting these aborts with drgn, I observed a pattern of overlapping chunk_maps. Note how stripe 1 of the first chunk overlaps in physical address with stripe 0 of the second chunk.
Physical Start Physical End Length Logical Type Stripe
----------------------------------------------------------------------------------------------------
0x0000000102500000 0x0000000142500000 1.0G 0x0000000641d00000 META|DUP 0/2 0x0000000142500000 0x0000000182500000 1.0G 0x0000000641d00000 META|DUP 1/2 0x0000000142500000 0x0000000182500000 1.0G 0x0000000601d00000 META|DUP 0/2 0x0000000182500000 0x00000001c2500000 1.0G 0x0000000601d00000 META|DUP 1/2
Now how could this possibly happen? All chunk allocation is protected by the chunk_mutex so racing allocations should see a consistent view of the CHUNK_ALLOCATED bit in the chunk allocation extent-io-tree (device->alloc_state as set by chunk_map_device_set_bits()) The tree itself is protected by a spin lock, and clearing/setting the bits is always protected by fs_info->mapping_tree_lock, so no race is apparent.
It turns out that there is a subtle bug in the logic regarding chunk allocations that have happened in the current transaction, known as "pending extents". The chunk allocation as defined in find_free_dev_extent() is a loop which searches the commit root of the dev_root and looks for gaps between DEV_EXTENT items. For those gaps, it then checks alloc_state bitmap for any pending extents and adjusts the hole that it finds accordingly. However, the logic in that adjustment assumes that the first pending extent is the only one in that range.
e.g., given a layout with two non-consecutive pending extents in a hole passed to dev_extent_hole_check() via *hole_start and *hole_size:
|----pending A----| real hole |----pending B----|
| candidate hole |
*hole_start *hole_start + *hole_sizethe code incorrectly returns a "hole" from the end of pending extent A until the passed in hole end, failing to account for pending B.
However, it is not entirely obvious that it is actually possible to produce such a layout. I was able to reproduce it, but with some
contortions: I continued to use the force chunk allocation sysfs file and I introduced a long delay (10 seconds) into the start of the cleaner thread. I also prevented the unused bgs cleaning logic from ever deleting metadata bgs. These help make it easier to deterministically produce the condition but shouldn't really matter if you imagine the conditions happening by race/luck. Allocations/frees can happen concurrently with the cleaner thread preparing to process an unused extent and both create some used chunks with an unused chunk interleaved, all during one transaction. Then btrfs_delete_unused_bgs() sees the unused one and clears it, leaving a range with several pending chunk allocations and a gap in the middle.
The basic idea is that the unused_bgs cleanup work happens on a worker so if we allocate 3 block groups in one transaction, then the cleaner work kicked off by the previous transaction comes through and deletes the middle one of the 3, then the commit root shows no dev extents and we have the bad pattern in the extent-io-tree. One final consideration is that the code happens to loop to the next hole if there are no more extents at all, so we need one more dev extent way past the area we are working in. Something like the following demonstrates the technique:
# push the BG frontier out to 20G fallocate -l 20G $mnt/foo # allocate one more that will prevent the "no more dev extents" luck fallocate -l 1G $mnt/sticky # sync sync # clear out the allocation area rm $mnt/foo sync _cleaner # let everything quiesce sleep 20 sync
# dev tree should have one bg 20G out and the rest at the beginning.. # sort of like an empty FS but with a random sticky chunk.
# kick off the cleaner in the background, remember it will sleep 10s # before doing interesting work _cleaner &
sleep 3
# create 3 trivial block groups, all empty, all immediately marked as unused. echo 1 > "$(_btrfs_sysfs_space_info $dev metadata)/force_chunk_alloc" echo 1 > "$(_btrfs_sysfs_space_info $dev data)/force_chunk_alloc" echo 1 > "$(_btrfs_sysfs_space_info $dev metadata)/force_chunk_alloc"
# let the cleaner thread definitely finish, it will remove the data bg sleep 10
# this allocation sees the non-consecutive pending metadata chunks with # data chunk gap of 1G and allocates a 2G extent in that hole. ENOSPC! echo 1 > "$(_btrfs_sysfs_space_info $dev metadata)/force_chunk_alloc"
As for the fix, it is not that obvious. I could not see a trivial way to do it even by adding backup loops into find_free_dev_extent(), so I opted to change the semantics of dev_extent_hole_check() to not stop looping until it finds a sufficiently big hole. For clarity, this also required changing the helper function contains_pending_extent() into two new helpers which find the first pending extent and the first suitable hole in a range.
I attempted to clean up the documentation and range calculations to be as consistent and clear as possible for the future.
I also looked at the zoned case and concluded that the loop there is different and not to be unified with this one. As far as I can tell, the zoned check will only further constrain the hole so looping back to find more holes is acceptable. Though given that zoned really only appends, I find it highly unlikely that it is susceptible to this bug.
--- fs/btrfs/volumes.c | 243 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 183 insertions(+), 60 deletions(-)
fs/btrfs/volumes.c +183 -60
@@ -1506,30 +1506,158 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, }/* -* Try to find a chunk that intersects [start, start + len] range and when one -* such is found, record the end of it in *start +* Find the first pending extent intersecting a range. +* +* @device: the device to search +* @start: start of the range to check +* @len: length of the range to check +* @pending_start: output pointer for the start of the found pending extent +* @pending_end: output pointer for the end of the found pending extent (inclusive) +* +* Search for a pending chunk allocation that intersects the half-open range +* [start, start + len). +* +* Return: true if a pending extent was found, false otherwise. +* If the return value is true, store the first pending extent in +* [*pending_start, *pending_end]. Otherwise, the two output variables +* may still be modified, to something outside the range and should not +* be used. */ -static bool contains_pending_extent (struct btrfs_device *device,u64 *start, -u64 len) +static bool first_pending_extent (struct btrfs_device *device,u64 start,u64 len, +u64 *pending_start,u64 *pending_end) { -u64 physical_start, physical_end; -lockdep_assert_held (&device->fs_info->chunk_mutex); -if (btrfs_find_first_extent_bit (&device->alloc_state, *start, - &physical_start, &physical_end, +if (btrfs_find_first_extent_bit (&device->alloc_state, start, + pending_start, pending_end,CHUNK_ALLOCATED ,NULL )) { -if (in_range (physical_start, *start, len) || -in_range (*start, physical_start, - physical_end +1 - physical_start)) { - *start = physical_end +1 ; +if (in_range (*pending_start, start, len) || +in_range (start, *pending_start, *pending_end +1 - *pending_start)) {return true; } }return false; } +/* +* Find the first real hole accounting for pending extents. +* +* @device: the device containing the candidate hole +* @start: input/output pointer for the hole start position +* @len: input/output pointer for the hole length +* @min_hole_size: the size of hole we are looking for +* +* Given a potential hole specified by [*start, *start + *len), check for pending +* chunk allocations within that range. If pending extents are found, the hole is +* adjusted to represent the first true free space that is large enough when +* accounting for pending chunks. +* +* Note that this function must handle various cases involving non consecutive +* pending extents. +* +* Returns: true if a suitable hole was found and false otherwise. +* If the return value is true, then *start and *len are set to represent the hole. +* If the return value is false, then *start is set to the largest hole we +* found and *len is set to its length. +* If there are no holes at all, then *start is set to the end of the range and +* *len is set to 0. +*/ +static bool find_hole_in_pending_extents (struct btrfs_device *device,u64 *start, +u64 *len,u64 min_hole_size) +{ +u64 pending_start, pending_end; +u64 end; +u64 max_hole_start =0 ; +u64 max_hole_len =0 ; + +lockdep_assert_held (&device->fs_info->chunk_mutex); + +if (*len ==0 ) +return false; + + end = *start + *len -1 ; + +/* +* Loop until we either see a large enough hole or check every pending +* extent overlapping the candidate hole. +* At every hole that we observe, record it if it is the new max. +* At the end of the iteration, set the output variables to the max hole. +*/ +while (true) { +if (first_pending_extent (device, *start, *len, &pending_start, &pending_end)) { +/* +* Case 1: the pending extent overlaps the start of +* candidate hole. That means the true hole is after the +* pending extent, but we need to find the next pending +* extent to properly size the hole. In the next loop, +* we will reduce to case 2 or 3. +* e.g., +* +* |----pending A----| real hole |----pending B----| +* | candidate hole | +* *start end +*/ +if (pending_start <= *start) { + *start = pending_end +1 ; + goto next; + } +/* +* Case 2: The pending extent starts after *start (and overlaps +* [*start, end), so the first hole just goes up to the start +* of the pending extent. +* e.g., +* +* | real hole |----pending A----| +* | candidate hole | +* *start end +*/ + *len = pending_start - *start; +if (*len > max_hole_len) { + max_hole_start = *start; + max_hole_len = *len; + } +if (*len >= min_hole_size) +break ; +/* +* If the hole wasn't big enough, then we advance past +* the pending extent and keep looking. +*/ + *start = pending_end +1 ; + goto next; + }else { +/* +* Case 3: There is no pending extent overlapping the +* range [*start, *start + *len - 1], so the only remaining +* hole is the remaining range. +* e.g., +* +* | candidate hole | +* | real hole | +* *start end +*/ + +if (*len > max_hole_len) { + max_hole_start = *start; + max_hole_len = *len; + } +break ; + } +next: +if (*start > end) +break ; + *len = end - *start +1 ; + } +if (max_hole_len) { + *start = max_hole_start; + *len = max_hole_len; + }else { + *start = end +1 ; + *len =0 ; + } +return max_hole_len >= min_hole_size; +} +static u64 dev_extent_search_start (struct btrfs_device *device) {switch (device->fs_devices->chunk_alloc_policy) {
@@ -1594,59 +1722,57 @@ static bool dev_extent_hole_check_zoned(struct btrfs_device *device, }/* -* Check if specified hole is suitable for allocation. +* Validate and adjust a hole for chunk allocation +* +* @device: the device containing the candidate hole +* @hole_start: input/output pointer for the hole start position +* @hole_size: input/output pointer for the hole size +* @num_bytes: minimum allocation size required * -* @device: the device which we have the hole -* @hole_start: starting position of the hole -* @hole_size: the size of the hole -* @num_bytes: the size of the free space that we need +* Check if the specified hole is suitable for allocation and adjust it if +* necessary. The hole may be modified to skip over pending chunk allocations +* and to satisfy stricter zoned requirements on zoned filesystems. * -* This function may modify @hole_start and @hole_size to reflect the suitable -* position for allocation. Returns 1 if hole position is updated, 0 otherwise. +* For regular (non-zoned) allocation, if the hole after adjustment is smaller +* than @num_bytes, the search continues past additional pending extents until +* either a sufficiently large hole is found or no more pending extents exist. +* +* Return: true if a suitable hole was found and false otherwise. +* If the return value is true, then *hole_start and *hole_size are set to +* represent the hole we found. +* If the return value is false, then *hole_start is set to the largest +* hole we found and *hole_size is set to its length. +* If there are no holes at all, then *hole_start is set to the end of the range +* and *hole_size is set to 0. */ static bool dev_extent_hole_check (struct btrfs_device *device,u64 *hole_start,u64 *hole_size,u64 num_bytes) { -bool changed = false; -u64 hole_end = *hole_start + *hole_size; +bool found = false; +const u64 hole_end = *hole_start + *hole_size -1 ; -for (;;) { -/* -* Check before we set max_hole_start, otherwise we could end up -* sending back this offset anyway. -*/ -if (contains_pending_extent (device, hole_start, *hole_size)) { -if (hole_end >= *hole_start) - *hole_size = hole_end - *hole_start; -else - *hole_size =0 ; - changed = true; - } +ASSERT (*hole_size >0 ); -switch (device->fs_devices->chunk_alloc_policy) { -default : -btrfs_warn_unknown_chunk_allocation (device->fs_devices->chunk_alloc_policy); - fallthrough; -case BTRFS_CHUNK_ALLOC_REGULAR : -/* No extra check */ -break ; -case BTRFS_CHUNK_ALLOC_ZONED : -if (dev_extent_hole_check_zoned (device, hole_start, - hole_size, num_bytes)) { - changed = true; -/* -* The changed hole can contain pending extent. -* Loop again to check that. -*/ -continue ; - } -break ; - } +again: + *hole_size = hole_end - *hole_start +1 ; + found =find_hole_in_pending_extents (device, hole_start, hole_size, num_bytes); +if (!found) +return found; +ASSERT (*hole_size >= num_bytes); +switch (device->fs_devices->chunk_alloc_policy) { +default : +btrfs_warn_unknown_chunk_allocation (device->fs_devices->chunk_alloc_policy); + fallthrough; +case BTRFS_CHUNK_ALLOC_REGULAR : +return found; +case BTRFS_CHUNK_ALLOC_ZONED : +if (dev_extent_hole_check_zoned (device, hole_start, hole_size, num_bytes)) + goto again;break ; } -return changed; +return found; }/*
@@ -1705,7 +1831,7 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, ret = -ENOMEM ; goto out; } -again: +if (search_start >= search_end ||test_bit (BTRFS_DEV_STATE_REPLACE_TGT , &device->dev_state)) { ret = -ENOSPC ;
@@ -1792,11 +1918,7 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,*/ if (search_end > search_start) { hole_size = search_end - search_start; -if (dev_extent_hole_check (device, &search_start, &hole_size, - num_bytes)) { -btrfs_release_path (path); - goto again; - } +dev_extent_hole_check (device, &search_start, &hole_size, num_bytes);if (hole_size > max_hole_size) { max_hole_start = search_start;
@@ -4882,6 +5004,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)u64 diff;u64 start;u64 free_diff =0 ; +u64 pending_start, pending_end; new_size =round_down (new_size, fs_info->sectorsize); start = new_size;
@@ -4927,7 +5050,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)* in-memory chunks are synced to disk so that the loop below sees them * and relocates them accordingly. */ -if (contains_pending_extent (device, &start, diff)) { +if (first_pending_extent (device, start, diff, &pending_start, &pending_end)) {mutex_unlock (&fs_info->chunk_mutex); ret =btrfs_commit_transaction (trans);if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 31/641 erofs: fix inline data read failure for ztailpacking pclusters
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit c134a40f86efb8d6b5a949ef70e06d5752209be5 ]
Compressed folios for ztailpacking pclusters must be valid before adding these pclusters to I/O chains. Otherwise, z_erofs_decompress_pcluster() may assume they are already valid and then trigger a NULL pointer dereference.
It is somewhat hard to reproduce because the inline data is in the same block as the tail of the compressed indexes, which are usually read just before. However, it may still happen if a fatal signal arrives while read_mapping_folio() is running, as shown below:
erofs: (device dm-1): z_erofs_pcluster_begin: failed to get inline data -4
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
...
pc : z_erofs_decompress_queue+0x4c8/0xa14 lr : z_erofs_decompress_queue+0x160/0xa14 sp : ffffffc08b3eb3a0 x29: ffffffc08b3eb570 x28: ffffffc08b3eb418 x27: 0000000000001000 x26: ffffff8086ebdbb8 x25: ffffff8086ebdbb8 x24: 0000000000000001 x23: 0000000000000008 x22: 00000000fffffffb x21: dead000000000700 x20: 00000000000015e7 x19: ffffff808babb400 x18: ffffffc089edc098 x17: 00000000c006287d x16: 00000000c006287d x15: 0000000000000004 x14: ffffff80ba8f8000 x13: 0000000000000004 x12: 00000006589a77c9 x11: 0000000000000015 x10: 0000000000000000 x9 : 0000000000000000 x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000000000003f x5 : 0000000000000040 x4 : ffffffffffffffe0 x3 : 0000000000000020 x2 : 0000000000000008 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: z_erofs_decompress_queue+0x4c8/0xa14 z_erofs_runqueue+0x908/0x97c z_erofs_read_folio+0x128/0x228 filemap_read_folio+0x68/0x128 filemap_get_pages+0x44c/0x8b4 filemap_read+0x12c/0x5b8 generic_file_read_iter+0x4c/0x15c do_iter_readv_writev+0x188/0x1e0 vfs_iter_read+0xac/0x1a4 backing_file_read_iter+0x170/0x34c ovl_read_iter+0xf0/0x140 vfs_read+0x28c/0x344 ksys_read+0x80/0xf0 __arm64_sys_read+0x24/0x34 invoke_syscall+0x60/0x114 el0_svc_common+0x88/0xe4 do_el0_svc+0x24/0x30 el0_svc+0x40/0xa8 el0t_64_sync_handler+0x70/0xbc el0t_64_sync+0x1bc/0x1c0
Fix this by reading the inline data before allocating and adding the pclusters to the I/O chains.
--- fs/erofs/zdata.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
fs/erofs/zdata.c +16 -14
@@ -805,14 +805,26 @@ static int z_erofs_pcluster_begin(struct z_erofs_frontend *fe)struct erofs_map_blocks *map = &fe->map;struct super_block *sb = fe->inode->i_sb;struct z_erofs_pcluster *pcl =NULL ; -void *ptr; +void *ptr =NULL ;int ret;DBG_BUGON (fe->pcl);/* must be Z_EROFS_PCLUSTER_TAIL or pointed to previous pcluster */ DBG_BUGON (!fe->head); -if (!(map->m_flags &EROFS_MAP_META )) { +if (map->m_flags &EROFS_MAP_META ) { + ret =erofs_init_metabuf (&map->buf, sb, +erofs_inode_in_metabox (fe->inode)); +if (ret) +return ret; + ptr =erofs_bread (&map->buf, map->m_pa, false); +if (IS_ERR (ptr)) { +erofs_err (sb,"failed to read inline data %pe @ pa %llu of nid %llu" , + ptr, map->m_pa,EROFS_I (fe->inode)->nid); +return PTR_ERR (ptr); + } + ptr = map->buf.page; + }else {while (1 ) {rcu_read_lock (); pcl =xa_load (&EROFS_SB (sb)->managed_pslots, map->m_pa);
@@ -852,18 +864,8 @@ static int z_erofs_pcluster_begin(struct z_erofs_frontend *fe)/* bind cache first when cached decompression is preferred */ z_erofs_bind_cache (fe); }else { - ret =erofs_init_metabuf (&map->buf, sb, -erofs_inode_in_metabox (fe->inode)); -if (ret) -return ret; - ptr =erofs_bread (&map->buf, map->m_pa, false); -if (IS_ERR (ptr)) { - ret =PTR_ERR (ptr); -erofs_err (sb,"failed to get inline folio %d" , ret); -return ret; - } -folio_get (page_folio (map->buf.page)); -WRITE_ONCE (fe->pcl->compressed_bvecs[0 ].page, map->buf.page); +folio_get (page_folio ((struct page *)ptr)); +WRITE_ONCE (fe->pcl->compressed_bvecs[0 ].page, ptr); fe->pcl->pageofs_in = map->m_pa & ~PAGE_MASK ; fe->mode =Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 32/641 smb: client: fix potential UAF and double free in smb2_open_file()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
[ Upstream commit ebbbc4bfad4cb355d17c671223d0814ee3ef4eda ]
Zero out @err_iov and @err_buftype before retrying SMB2_open() to prevent an UAF bug if @data != NULL, otherwise a double free.
--- fs/smb/client/smb2file.c | 2 ++ 1 file changed, 2 insertions(+)
fs/smb/client/smb2file.c +2 -0
@@ -178,6 +178,8 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 &err_buftype);if (rc == -EACCES && retry_without_read_attributes) {free_rsp_buf (err_buftype, err_iov.iov_base); +memset (&err_iov,0 ,sizeof (err_iov)); + err_buftype =CIFS_NO_BUFFER ; oparms->desired_access &= ~FILE_READ_ATTRIBUTES ; rc =SMB2_open (xid, oparms, smb2_path, &smb2_oplock, smb2_data,NULL , &err_iov, &err_buftype);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 33/641 netfs: avoid double increment of retry_count in subreq
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
[ Upstream commit a5ca32d031bbba5160e1f555aabb75a3f40f918d ]
This change fixes the instance of double incrementing of retry_count. The increment of this count already happens when netfs_reissue_write gets called. Incrementing this value before is not necessary.
--- fs/netfs/write_retry.c | 1 - 1 file changed, 1 deletion(-)
fs/netfs/write_retry.c +0 -1
@@ -98,7 +98,6 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq, subreq->start = start; subreq->len = len;__clear_bit (NETFS_SREQ_NEED_RETRY , &subreq->flags); - subreq->retry_count++;trace_netfs_sreq (subreq, netfs_sreq_trace_retry);/* Renegotiate max_len (wsize) */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 34/641 rnbd-srv: Fix server side setting of bi_size for special IOs
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian-Ewald Mueller <[email protected]>
[ Upstream commit 4ac9690d4b9456ca1d5276d86547fa2e7cd47684 ]
On rnbd-srv, the bi_size of the bio is set during the bio_add_page function, to which datalen is passed. But for special IOs like DISCARD and WRITE_ZEROES, datalen is 0, since there is no data to write. For these special IOs, use the bi_size of the rnbd_msg_io.
--- drivers/block/rnbd/rnbd-srv.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
drivers/block/rnbd/rnbd-srv.c +23 -10
@@ -145,18 +145,30 @@ static int process_rdma(struct rnbd_srv_session *srv_sess, priv->sess_dev = sess_dev; priv->id = id; - bio =bio_alloc (file_bdev (sess_dev->bdev_file),1 , + bio =bio_alloc (file_bdev (sess_dev->bdev_file), !!datalen,rnbd_to_bio_flags (le32_to_cpu (msg->rw)),GFP_KERNEL ); -bio_add_virt_nofail (bio, data, datalen); - - bio->bi_opf =rnbd_to_bio_flags (le32_to_cpu (msg->rw)); -if (bio_has_data (bio) && - bio->bi_iter.bi_size !=le32_to_cpu (msg->bi_size)) { -rnbd_srv_err_rl (sess_dev,"Datalen mismatch: bio bi_size (%u), bi_size (%u)\n" , - bio->bi_iter.bi_size, msg->bi_size); - err = -EINVAL ; - goto bio_put; +if (unlikely (!bio)) { + err = -ENOMEM ; + goto put_sess_dev; } + +if (!datalen) { +/* +* For special requests like DISCARD and WRITE_ZEROES, the datalen is zero. +*/ + bio->bi_iter.bi_size =le32_to_cpu (msg->bi_size); + }else { +bio_add_virt_nofail (bio, data, datalen); + bio->bi_opf =rnbd_to_bio_flags (le32_to_cpu (msg->rw)); +if (bio->bi_iter.bi_size !=le32_to_cpu (msg->bi_size)) { +rnbd_srv_err_rl (sess_dev, +"Datalen mismatch: bio bi_size (%u), bi_size (%u)\n" , + bio->bi_iter.bi_size, msg->bi_size); + err = -EINVAL ; + goto bio_put; + } + } + bio->bi_end_io = rnbd_dev_bi_end_io; bio->bi_private = priv; bio->bi_iter.bi_sector =le64_to_cpu (msg->sector);
@@ -170,6 +182,7 @@ static int process_rdma(struct rnbd_srv_session *srv_sess, bio_put:bio_put (bio); +put_sess_dev:rnbd_put_sess_dev (sess_dev); err:kfree (priv);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 35/641 ACPI: processor: Update cpuidle driver check in __acpi_processor_start()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 0089ce1c056aee547115bdc25c223f8f88c08498 ]
Commit 7a8c994cbb2d ("ACPI: processor: idle: Optimize ACPI idle driver registration") moved the ACPI idle driver registration to acpi_processor_driver_init() and acpi_processor_power_init() does not register an idle driver any more.
Accordingly, the cpuidle driver check in __acpi_processor_start() needs to be updated to avoid calling acpi_processor_power_init() without a cpuidle driver, in which case the registration of the cpuidle device in that function would lead to a NULL pointer dereference in __cpuidle_register_device().
--- drivers/acpi/processor_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/processor_driver.c +1 -1
@@ -166,7 +166,7 @@ static int __acpi_processor_start(struct acpi_device *device)if (result && !IS_ENABLED (CONFIG_ACPI_CPU_FREQ_PSS ))dev_dbg (&device->dev,"CPPC data invalid or not present\n" ); -if (!cpuidle_get_driver () ||cpuidle_get_driver () == &acpi_idle_driver) +if (cpuidle_get_driver () == &acpi_idle_driver)acpi_processor_power_init (pr);acpi_pss_perf_init (pr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 36/641 xen/virtio: Dont use grant-dma-ops when running as Dom0
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Teddy Astie <[email protected]>
[ Upstream commit dc8ea8714311e549ee93a2b0bdd5487d20bfadbf ]
Dom0 inherit devices from the machine and is usually in PV mode. If we are running in a virtual that has virtio devices, these devices would be considered as using grants with Dom0 as backend, while being the said Dom0 itself, while we want to use these devices like regular PCI devices.
Fix this by preventing grant-dma-ops from being used when running as Dom0 (initial domain). We still keep the device-tree logic as-is.
Message-ID: <6698564dd2270a9f7377b78ebfb20cb425cabbe8.1767720955.git.teddy.astie@vates.tech>
--- drivers/xen/grant-dma-ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/xen/grant-dma-ops.c +2 -1
@@ -362,7 +362,8 @@ static int xen_grant_init_backend_domid(struct device *dev,if (np) { ret =xen_dt_grant_init_backend_domid (dev, np, backend_domid);of_node_put (np); - }else if (IS_ENABLED (CONFIG_XEN_VIRTIO_FORCE_GRANT ) ||xen_pv_domain ()) { + }else if (!xen_initial_domain () && + (IS_ENABLED (CONFIG_XEN_VIRTIO_FORCE_GRANT ) ||xen_pv_domain ())) {dev_info (dev,"Using dom0 as backend\n" ); *backend_domid =0 ; ret =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 37/641 io_uring: use release-acquire ordering for IORING_SETUP_R_DISABLED
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos <[email protected]>
[ Upstream commit 7a8737e1132ff07ca225aa7a4008f87319b5b1ca ]
io_uring_enter(), __io_msg_ring_data(), and io_msg_send_fd() read ctx->flags and ctx->submitter_task without holding the ctx's uring_lock. This means they may race with the assignment to ctx->submitter_task and the clearing of IORING_SETUP_R_DISABLED from ctx->flags in io_register_enable_rings(). Ensure the correct ordering of the ctx->flags and ctx->submitter_task memory accesses by storing to ctx->flags using release ordering and loading it using acquire ordering.
--- io_uring/io_uring.c | 6 +++++- io_uring/msg_ring.c | 12 ++++++++++-- io_uring/register.c | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-)
io_uring/io_uring.c +5 -1
@@ -3490,7 +3490,11 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, ctx = file->private_data; ret = -EBADFD ; -if (unlikely (ctx->flags &IORING_SETUP_R_DISABLED )) +/* +* Keep IORING_SETUP_R_DISABLED check before submitter_task load +* in io_uring_add_tctx_node() -> __io_uring_add_tctx_node_from_submit() +*/ +if (unlikely (smp_load_acquire (&ctx->flags) &IORING_SETUP_R_DISABLED )) goto out;/*
io_uring/msg_ring.c +10 -2
@@ -124,7 +124,11 @@ static int __io_msg_ring_data(struct io_ring_ctx *target_ctx,return -EINVAL ;if (!(msg->flags &IORING_MSG_RING_FLAGS_PASS ) && msg->dst_fd)return -EINVAL ; -if (target_ctx->flags &IORING_SETUP_R_DISABLED ) +/* +* Keep IORING_SETUP_R_DISABLED check before submitter_task load +* in io_msg_data_remote() -> io_msg_remote_post() +*/ +if (smp_load_acquire (&target_ctx->flags) &IORING_SETUP_R_DISABLED )return -EBADFD ;if (io_msg_need_remote (target_ctx))
@@ -244,7 +248,11 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)return -EINVAL ;if (target_ctx == ctx)return -EINVAL ; -if (target_ctx->flags &IORING_SETUP_R_DISABLED ) +/* +* Keep IORING_SETUP_R_DISABLED check before submitter_task load +* in io_msg_fd_remote() +*/ +if (smp_load_acquire (&target_ctx->flags) &IORING_SETUP_R_DISABLED )return -EBADFD ;if (!msg->src_file) {int ret =io_msg_grab_file (req, issue_flags);
io_uring/register.c +2 -1
@@ -193,7 +193,8 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx)if (ctx->restrictions.registered) ctx->restricted =1 ; - ctx->flags &= ~IORING_SETUP_R_DISABLED ; +/* Keep submitter_task store before clearing IORING_SETUP_R_DISABLED */ +smp_store_release (&ctx->flags, ctx->flags & ~IORING_SETUP_R_DISABLED );if (ctx->sq_data &&wq_has_sleeper (&ctx->sq_data->wait))wake_up (&ctx->sq_data->wait);return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 38/641 ACPICA: Fix NULL pointer dereference in acpi_ev_address_space_dispatch()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Simakov <[email protected]>
[ Upstream commit f851e03bce968ff9b3faad1b616062e1244fd38d ]
Cover a missed execution path with a new check.
--- drivers/acpi/acpica/evregion.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/acpi/acpica/evregion.c +3 -1
@@ -163,7 +163,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,return_ACPI_STATUS (AE_NOT_EXIST ); } -if (region_obj->region.space_id ==ACPI_ADR_SPACE_PLATFORM_COMM ) { +if (field_obj + && region_obj->region.space_id == +ACPI_ADR_SPACE_PLATFORM_COMM ) {struct acpi_pcc_info *ctx = handler_desc->address_space.context;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 39/641 io_uring/eventfd: remove unused ctx->evfd_last_cq_tail member
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit 07f3c3a1cd56c2048a92dad0c11f15e4ac3888c1 ]
A previous commit got rid of any use of this member, but forgot to remove it. Kill it.
--- include/linux/io_uring_types.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
include/linux/io_uring_types.h +3 -4
@@ -439,6 +439,9 @@ struct io_ring_ctx {struct list_head defer_list;unsigned nr_drained; +/* protected by ->completion_lock */ +unsigned nr_req_allocated; +#ifdef CONFIG_NET_RX_BUSY_POLL struct list_head napi_list;/* track busy poll napi_id */ spinlock_t napi_lock;/* napi_list lock */
@@ -451,10 +454,6 @@ struct io_ring_ctx {DECLARE_HASHTABLE (napi_ht,4 );#endif -/* protected by ->completion_lock */ -unsigned evfd_last_cq_tail; -unsigned nr_req_allocated; -/* * Protection for resize vs mmap races - both the mmap and resize * side will need to grab this lock, to prevent either side from
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 40/641 io_uring/sync: validate passed in offset
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit 649dd18f559891bdafc5532d737c7dfb56060a6d ]
Check if the passed in offset is negative once cast to sync->off. This ensures that -EINVAL is returned for that case, like it would be for sync_file_range(2).
--- io_uring/sync.c | 2 ++ 1 file changed, 2 insertions(+)
io_uring/sync.c +2 -0
@@ -62,6 +62,8 @@ int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)return -EINVAL ; sync->off =READ_ONCE (sqe->off); +if (sync->off <0 ) +return -EINVAL ; sync->len =READ_ONCE (sqe->len); req->flags |=REQ_F_FORCE_ASYNC ;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 41/641 cpuidle: governors: menu: Always check timers with tick stopped
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 80606f4eb8d7484ab7f7d6f0fd30d71e6fbcf328 ]
After commit 5484e31bbbff ("cpuidle: menu: Skip tick_nohz_get_sleep_length() call in some cases"), if the return value of get_typical_interval() multiplied by NSEC_PER_USEC is not greater than RESIDENCY_THRESHOLD_NS, the menu governor will skip computing the time till the closest timer. If that happens when the tick has been stopped already, the selected idle state may be too deep due to the subsequent check comparing predicted_ns with TICK_NSEC and causing its value to be replaced with the expected time till the closest timer, which is KTIME_MAX in that case. That will cause the deepest enabled idle state to be selected, but the time till the closest timer very well may be shorter than the target residency of that state, in which case a shallower state should be used.
Address this by making menu_select() always compute the time till the closest timer when the tick has been stopped.
Also move the predicted_ns check mentioned above into the branch in which the time till the closest timer is determined because it only needs to be done in that case.
--- drivers/cpuidle/governors/menu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/cpuidle/governors/menu.c +11 -11
@@ -239,7 +239,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,/* Find the shortest expected idle interval. */ predicted_ns =get_typical_interval (data) *NSEC_PER_USEC ; -if (predicted_ns >RESIDENCY_THRESHOLD_NS ) { +if (predicted_ns >RESIDENCY_THRESHOLD_NS ||tick_nohz_tick_stopped ()) {unsigned int timer_us;/* Determine the time till the closest timer. */
@@ -259,6 +259,16 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, RESOLUTION * DECAY * NSEC_PER_USEC);/* Use the lowest expected idle interval to pick the idle state. */ predicted_ns =min ((u64 )timer_us *NSEC_PER_USEC , predicted_ns); +/* +* If the tick is already stopped, the cost of possible short +* idle duration misprediction is much higher, because the CPU +* may be stuck in a shallow idle state for a long time as a +* result of it. In that case, say we might mispredict and use +* the known time till the closest timer event for the idle +* state selection. +*/ +if (tick_nohz_tick_stopped () && predicted_ns <TICK_NSEC ) + predicted_ns = data->next_timer_ns; }else {/* * Because the next timer event is not going to be determined
@@ -284,16 +294,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,return 0 ; } -/* -* If the tick is already stopped, the cost of possible short idle -* duration misprediction is much higher, because the CPU may be stuck -* in a shallow idle state for a long time as a result of it. In that -* case, say we might mispredict and use the known time till the closest -* timer event for the idle state selection. -*/ -if (tick_nohz_tick_stopped () && predicted_ns <TICK_NSEC ) - predicted_ns = data->next_timer_ns; -/* * Find the idle state with the lowest power while satisfying * our constraints.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 42/641 thermal: intel: x86_pkg_temp_thermal: Handle invalid temperature
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 9635c586a559ba0e45b2bfbff79c937ddbaf1a62 ]
After commit be0a3600aa1e ("thermal: sysfs: Rework the handling of trip point updates"), THERMAL_TEMP_INVALID can be passed to sys_set_trip_temp() and it is treated as a regular temperature value there, so the sysfs write fails even though it is expected to succeed and disable the given trip point.
Address this by making sys_set_trip_temp() clear its temp variable when it is equal to THERMAL_TEMP_INVALID.
--- drivers/thermal/intel/x86_pkg_temp_thermal.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/thermal/intel/x86_pkg_temp_thermal.c +3 -0
@@ -128,6 +128,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd,u32 l, h, mask, shift, intr;int tj_max, val, ret; +if (temp ==THERMAL_TEMP_INVALID ) + temp =0 ; + tj_max =intel_tcc_get_tjmax (zonedev->cpu);if (tj_max <0 )return tj_max;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 43/641 md/raid5: fix raid5_run() to return error when log_init() fails
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 2d9f7150ac197ce79c9c917a004d4cf0b26ad7e0 ]
Since commit f63f17350e53 ("md/raid5: use the atomic queue limit update APIs"), the abort path in raid5_run() returns 'ret' instead of -EIO. However, if log_init() fails, 'ret' is still 0 from the previous successful call, causing raid5_run() to return success despite the failure.
Fix this by capturing the return value from log_init().
--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/raid5.c +2 -1
@@ -8056,7 +8056,8 @@ static int raid5_run(struct mddev *mddev) goto abort; } -if (log_init (conf, journal_dev,raid5_has_ppl (conf))) + ret =log_init (conf, journal_dev,raid5_has_ppl (conf)); +if (ret) goto abort;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 44/641 md/raid10: fix any_working flag handling in raid10_sync_request
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Nan <[email protected]>
[ Upstream commit 99582edb3f62e8ee6c34512021368f53f9b091f2 ]
In raid10_sync_request(), 'any_working' indicates if any IO will be submitted. When there's only one In_sync disk with badblocks, 'any_working' might be set to 1 but no IO is submitted. Fix it by setting 'any_working' after badblock checks.
--- drivers/md/raid10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/raid10.c +1 -1
@@ -3402,7 +3402,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, !test_bit(In_sync, &rdev->flags))continue ;/* This is where we read from */ - any_working =1 ; sector = r10_bio->devs[j].addr; if (is_badblock(rdev, sector, max_sync,
@@ -3417,6 +3416,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,continue ; } } + any_working =1 ; bio = r10_bio->devs[0 ].bio; bio->bi_next = biolist; biolist = bio;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 45/641 md/raid5: fix IO hang with degraded array with llbitmap
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit cd1635d844d26471c56c0a432abdee12fc9ad735 ]
When llbitmap bit state is still unwritten, any new write should force rcw, as bitmap_ops->blocks_synced() is checked in handle_stripe_dirtying(). However, later the same check is missing in need_this_block(), causing stripe to deadloop during handling because handle_stripe() will decide to go to handle_stripe_fill(), meanwhile need_this_block() always return 0 and nothing is handled.
--- drivers/md/raid5.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/md/raid5.c +6 -1
@@ -3751,9 +3751,14 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,struct r5dev *dev = &sh->dev[disk_idx];struct r5dev *fdev[2 ] = { &sh->dev[s->failed_num[0 ]], &sh->dev[s->failed_num[1 ]] }; +struct mddev *mddev = sh->raid_conf->mddev; +bool force_rcw = false;int i; -bool force_rcw = (sh->raid_conf->rmw_level ==PARITY_DISABLE_RMW ); +if (sh->raid_conf->rmw_level ==PARITY_DISABLE_RMW || + (mddev->bitmap_ops && mddev->bitmap_ops->blocks_synced && + !mddev->bitmap_ops->blocks_synced (mddev, sh->sector))) + force_rcw = true;if (test_bit (R5_LOCKED , &dev->flags) ||test_bit (R5_UPTODATE , &dev->flags))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 46/641 md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit d119bd2e1643cc023210ff3c6f0657e4f914e71d ]
When llbitmap_suspend_timeout() times out waiting for percpu_ref to become zero, it returns -ETIMEDOUT without resurrecting the percpu_ref. The caller (md_llbitmap_daemon_fn) then continues to the next page without calling llbitmap_resume(), leaving the percpu_ref in a killed state permanently.
Fix this by resurrecting the percpu_ref before returning the error, ensuring the page control structure remains usable for subsequent operations.
--- drivers/md/md-llbitmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/md-llbitmap.c +3 -1
@@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)percpu_ref_kill (&pctl->active);if (!wait_event_timeout (pctl->wait,percpu_ref_is_zero (&pctl->active), - llbitmap->mddev->bitmap_info.daemon_sleep *HZ )) + llbitmap->mddev->bitmap_info.daemon_sleep *HZ )) { +percpu_ref_resurrect (&pctl->active);return -ETIMEDOUT ; + }return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 47/641 OPP: Return correct value in dev_pm_opp_get_level
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleks Todorov <[email protected]>
[ Upstream commit 0b7277e02dabba2a9921a7f4761ae6e627e7297a ]
Commit 073d3d2ca7d4 ("OPP: Level zero is valid") modified the documentation for this function to indicate that errors should return a non-zero value to avoid colliding with the OPP level zero, however forgot to actually update the return.
No in-tree kernel code depends on the error value being 0.
--- drivers/opp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/opp/core.c +1 -1
@@ -241,7 +241,7 @@ unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp) {if (IS_ERR_OR_NULL (opp) || !opp->available) {pr_err ("%s: Invalid parameters\n" , __func__); -return 0 ; +return U32_MAX ; }return opp->level;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 48/641 cpufreq: scmi: Fix device_node reference leak in scmi_cpu_domain_id()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 0b7fbf9333fa4699a53145bad8ce74ea986caa13 ]
When calling of_parse_phandle_with_args(), the caller is responsible to call of_node_put() to release the reference of device node. In scmi_cpu_domain_id(), it does not release the reference.
--- drivers/cpufreq/scmi-cpufreq.c | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/scmi-cpufreq.c +1 -0
@@ -101,6 +101,7 @@ static int scmi_cpu_domain_id(struct device *cpu_dev)return -EINVAL ; } +of_node_put (domain_id.np);return domain_id.args[0 ]; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 49/641 iomap: fix submission side handling of completion side errors
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 4ad357e39b2ecd5da7bcc7e840ee24d179593cd5 ]
The "if (dio->error)" in iomap_dio_bio_iter exists to stop submitting more bios when a completion already return an error. Commit cfe057f7db1f ("iomap_dio_actor(): fix iov_iter bugs") made it revert the iov by "copied", which is very wrong given that we've already consumed that range and submitted a bio for it.
--- fs/iomap/direct-io.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/iomap/direct-io.c +7 -3
@@ -429,9 +429,13 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio) nr_pages =bio_iov_vecs_to_alloc (dio->submit.iter,BIO_MAX_VECS ); do { size_t n; - if (dio->error) { - iov_iter_revert(dio->submit.iter, copied); - copied = ret = 0; + + /* + * If completions already occurred and reported errors, give up now and + * don't bother submitting more bios. + */ + if (unlikely(data_race(dio->error))) { + ret = 0; goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 50/641 thermal/of: Fix reference leak in thermal_of_cm_lookup()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit a1fe789a96fe47733c133134fd264cb7ca832395 ]
In thermal_of_cm_lookup(), tr_np is obtained via of_parse_phandle(), but never released.
Use the __free(device_node) cleanup attribute to automatically release the node and fix the leak.
--- drivers/thermal/thermal_of.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/thermal/thermal_of.c +2 -2
@@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np, struct cooling_spec *c) {for_each_child_of_node_scoped (cm_np, child) { -struct device_node *tr_np;int count, i; - tr_np =of_parse_phandle (child,"trip" ,0 ); + struct device_node *tr_np __free(device_node) = +of_parse_phandle (child,"trip" ,0 );if (tr_np != trip->priv)continue ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 51/641 ublk: restore auto buf unregister refcount optimization
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos <[email protected]>
[ Upstream commit ad5f2e2908c9b79a86529281a48e94d644d43dc7 ]
Commit 1ceeedb59749 ("ublk: optimize UBLK_IO_UNREGISTER_IO_BUF on daemon task") optimized ublk request buffer unregistration to use a non-atomic reference count decrement when performed on the ublk_io's daemon task. The optimization applied to auto buffer unregistration, which happens as part of handling UBLK_IO_COMMIT_AND_FETCH_REQ on the daemon task. However, commit b749965edda8 ("ublk: remove ublk_commit_and_fetch()") reordered the ublk_sub_req_ref() for the completed request before the io_buffer_unregister_bvec() call. As a result, task_registered_buffers is already 0 when io_buffer_unregister_bvec() calls ublk_io_release() and the non-atomic refcount optimization doesn't apply.
Move the io_buffer_unregister_bvec() call back to before ublk_need_complete_req() to restore the reference counting optimization.
--- drivers/block/ublk_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/block/ublk_drv.c +2 -2
@@ -2526,11 +2526,11 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, io->res = result; req =ublk_fill_io_cmd (io, cmd); ret =ublk_config_io_buf (ub, io, cmd, addr, &buf_idx); +if (buf_idx !=UBLK_INVALID_BUF_IDX ) +io_buffer_unregister_bvec (cmd, buf_idx, issue_flags); compl =ublk_need_complete_req (ub, io);/* can't touch 'ublk_io' any more */ -if (buf_idx !=UBLK_INVALID_BUF_IDX ) -io_buffer_unregister_bvec (cmd, buf_idx, issue_flags);if (req_op (req) ==REQ_OP_ZONE_APPEND ) req->__sector = addr;if (compl)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 52/641 ublk: Validate SQE128 flag before accessing the cmd
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Govindarajulu Varadarajan <[email protected]>
[ Upstream commit da7e4b75e50c087d2031a92f6646eb90f7045a67 ]
ublk_ctrl_cmd_dump() accesses (header *)sqe->cmd before IO_URING_F_SQE128 flag check. This could cause out of boundary memory access.
Move the SQE128 flag check earlier in ublk_ctrl_uring_cmd() to return -EINVAL immediately if the flag is not set.
--- drivers/block/ublk_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/block/ublk_drv.c +3 -3
@@ -3841,10 +3841,10 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,if (issue_flags &IO_URING_F_NONBLOCK )return -EAGAIN ; -ublk_ctrl_cmd_dump (cmd); -if (!(issue_flags &IO_URING_F_SQE128 )) - goto out; +return -EINVAL ; + +ublk_ctrl_cmd_dump (cmd); ret =ublk_check_cmd_op (cmd_op);if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 53/641 Partial revert "x86/xen: fix balloon target initialization for PVH dom0"
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Pau Monne <[email protected]>
[ Upstream commit 0949c646d64697428ff6257d52efa5093566868d ]
This partially reverts commit 87af633689ce16ddb166c80f32b120e50b1295de so the current memory target for PV guests is still fetched from start_info->nr_pages, which matches exactly what the toolstack sets the initial memory target to.
Using get_num_physpages() is possible on PV also, but needs adjusting to take into account the ISA hole and the PFN at 0 not considered usable memory despite being populated, and hence would need extra adjustments. Instead of carrying those extra adjustments switch back to the previous code. That leaves Linux with a difference in how current memory target is obtained for HVM vs PV, but that's better than adding extra logic just for PV.
However if switching to start_info->nr_pages for PV domains we need to differentiate between released pages (freed back to the hypervisor) as opposed to pages in the physmap which are not populated to start with. Introduce a new xen_unpopulated_pages to account for papges that have never been populated, and hence in the PV case don't need subtracting.
Message-ID: <[email protected]>
--- arch/x86/xen/enlighten.c | 2 +- drivers/xen/balloon.c | 19 +++++++++++++++---- drivers/xen/unpopulated-alloc.c | 3 +++ include/xen/xen.h | 2 ++ 4 files changed, 21 insertions(+), 5 deletions(-)
arch/x86/xen/enlighten.c +1 -1
@@ -470,7 +470,7 @@ int __init arch_xen_unpopulated_init(struct resource **res)* driver to know how much of the physmap is unpopulated and * set an accurate initial memory target. */ - xen_released_pages += xen_extra_mem[i].n_pfns; + xen_unpopulated_pages += xen_extra_mem[i].n_pfns;/* Zero so region is not also added to the balloon driver. */ xen_extra_mem[i].n_pfns =0 ; }
drivers/xen/balloon.c +15 -4
@@ -724,6 +724,7 @@ static int __init balloon_add_regions(void)static int __init balloon_init (void ) {struct task_struct *task; +unsigned long current_pages;int rc;if (!xen_domain ())
@@ -731,12 +732,18 @@ static int __init balloon_init(void)pr_info ("Initialising balloon driver\n" ); -if (xen_released_pages >=get_num_physpages ()) { -WARN (1 ,"Released pages underflow current target" ); -return -ERANGE ; +if (xen_pv_domain ()) { +if (xen_released_pages >= xen_start_info->nr_pages) + goto underflow; + current_pages =min (xen_start_info->nr_pages - + xen_released_pages, max_pfn); + }else { +if (xen_unpopulated_pages >=get_num_physpages ()) + goto underflow; + current_pages =get_num_physpages () - xen_unpopulated_pages; } - balloon_stats.current_pages =get_num_physpages () - xen_released_pages; + balloon_stats.current_pages = current_pages; balloon_stats.target_pages = balloon_stats.current_pages; balloon_stats.balloon_low =0 ; balloon_stats.balloon_high =0 ;
@@ -767,6 +774,10 @@ static int __init balloon_init(void)xen_balloon_init ();return 0 ; + + underflow: +WARN (1 ,"Released pages underflow current target" ); +return -ERANGE ; }subsys_initcall (balloon_init);
drivers/xen/unpopulated-alloc.c +3 -0
@@ -18,6 +18,9 @@ static unsigned int list_count;static struct resource *target_resource; +/* Pages to subtract from the memory count when setting balloon target. */ +unsigned long xen_unpopulated_pages__initdata ; +/* * If arch is not happy with system "iomem_resource" being used for * the region allocation it can provide it's own view by creating specific
include/xen/xen.h +2 -0
@@ -69,11 +69,13 @@ extern u64 xen_saved_max_mem_size;#endif #ifdef CONFIG_XEN_UNPOPULATED_ALLOC +extern unsigned long xen_unpopulated_pages;int xen_alloc_unpopulated_pages (unsigned int nr_pages,struct page **pages);void xen_free_unpopulated_pages (unsigned int nr_pages,struct page **pages);#include <linux/ioport.h> int arch_xen_unpopulated_init (struct resource **res);#else +#define xen_unpopulated_pages 0UL#include <xen/balloon.h> static inline int xen_alloc_unpopulated_pages (unsigned int nr_pages,struct page **pages)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 54/641 md/raid1: fix memory leak in raid1_run()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 6abc7d5dcf0ee0f85e16e41c87fbd06231f28753 ]
raid1_run() calls setup_conf() which registers a thread via md_register_thread(). If raid1_set_limits() fails, the previously registered thread is not unregistered, resulting in a memory leak of the md_thread structure and the thread resource itself.
Add md_unregister_thread() to the error path to properly cleanup the thread, which aligns with the error handling logic of other paths in this function.
Compile tested only. Issue found using a prototype static analysis tool and code review.
--- drivers/md/raid1.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/raid1.c +1 -0
@@ -3253,6 +3253,7 @@ static int raid1_run(struct mddev *mddev)if (!mddev_is_dm (mddev)) { ret =raid1_set_limits (mddev);if (ret) { +md_unregister_thread (mddev, &conf->thread);if (!mddev->private)raid1_free (mddev, conf);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 55/641 md: fix return value of mddev_trylock
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiao Ni <[email protected]>
[ Upstream commit 05c8de4f09b08e97c6ecb190dcec0e68b167cb03 ]
A return value of 0 is treaded as successful lock acquisition. In fact, a return value of 1 means getting the lock successfully.
--- drivers/md/md.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/md.h +2 -2
@@ -736,8 +736,8 @@ static inline int mddev_trylock(struct mddev *mddev)int ret; ret =mutex_trylock (&mddev->reconfig_mutex); -if (!ret &&test_bit (MD_DELETED , &mddev->flags)) { - ret = -ENODEV ; +if (ret &&test_bit (MD_DELETED , &mddev->flags)) { + ret =0 ;mutex_unlock (&mddev->reconfig_mutex); }return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 56/641 PM: wakeup: Handle empty list in wakeup_sources_walk_start()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Wu <[email protected]>
[ Upstream commit 75ce02f4bc9a8b8350b6b1b01872467b0cc960cc ]
In the case of an empty wakeup_sources list, wakeup_sources_walk_start() will return an invalid but non-NULL address. This also affects wrappers of the aforementioned function, like for_each_wakeup_source().
Update wakeup_sources_walk_start() to return NULL in case of an empty list.
--- drivers/base/power/wakeup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/base/power/wakeup.c +1 -3
@@ -276,9 +276,7 @@ EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);*/ struct wakeup_source *wakeup_sources_walk_start (void ) { -struct list_head *ws_head = &wakeup_sources; - - return list_entry_rcu(ws_head->next, struct wakeup_source, entry); + return list_first_or_null_rcu(&wakeup_sources, struct wakeup_source, entry); }EXPORT_SYMBOL_GPL (wakeup_sources_walk_start);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 57/641 arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 53c998527ffa60f9deda8974a11ad39790684159 ]
alloc_gcs() returns an error-encoded pointer on failure, which comes from do_mmap(), not NULL.
The current NULL check fails to detect errors, which could lead to using an invalid GCS address.
Use IS_ERR_VALUE() to properly detect errors, consistent with the check in gcs_alloc_thread_stack().
--- arch/arm64/mm/gcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/mm/gcs.c +2 -2
@@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size =gcs_size (0 ); gcs =alloc_gcs (0 , size); -if (!gcs) -return -ENOMEM ; +if (IS_ERR_VALUE (gcs)) +return gcs; task->thread.gcspr_el0 = gcs + size -sizeof (u64); task->thread.gcs_base = gcs;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 58/641 perf: arm_spe: Properly set hw.state on failures
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yan <[email protected]>
[ Upstream commit 283182c1c239f6873d1a50e9e710c1a699f2256b ]
When arm_spe_pmu_next_off() fails to calculate a valid limit, it returns zero to indicate that tracing should not start. However, the caller arm_spe_perf_aux_output_begin() does not propagate this failure by updating hwc->state, cause the error to be silently ignored by upper layers.
Because hwc->state remains zero after a failure, arm_spe_pmu_start() continues to programs filter registers unnecessarily. The driver still reports success to the perf core, so the core assumes the SPE event was enabled and proceeds to enable other events. This breaks event group semantics: SPE is already stopped while other events in the same group are enabled.
Fix this by updating arm_spe_perf_aux_output_begin() to return a status code indicating success (0) or failure (-EIO). Both the interrupt handler and arm_spe_pmu_start() check the return value and call arm_spe_pmu_stop() to set PERF_HES_STOPPED in hwc->state.
In the interrupt handler, the period (e.g., period_left) needs to be updated, so PERF_EF_UPDATE is passed to arm_spe_pmu_stop(). When the error occurs during event start, the trace unit is not yet enabled, so a flag '0' is used to drain buffer and update state only.
--- drivers/perf/arm_spe_pmu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/perf/arm_spe_pmu.c +12 -6
@@ -105,6 +105,8 @@ struct arm_spe_pmu {/* Keep track of our dynamic hotplug state */ static enum cpuhp_state arm_spe_pmu_online; +static void arm_spe_pmu_stop (struct perf_event *event,int flags); +enum arm_spe_pmu_buf_fault_action {SPE_PMU_BUF_FAULT_ACT_SPURIOUS ,SPE_PMU_BUF_FAULT_ACT_FATAL ,
@@ -582,8 +584,8 @@ static u64 arm_spe_pmu_next_off(struct perf_output_handle *handle)return limit; } -static void arm_spe_perf_aux_output_begin (struct perf_output_handle *handle, -struct perf_event *event) +static int arm_spe_perf_aux_output_begin (struct perf_output_handle *handle, +struct perf_event *event) {u64 base, limit;struct arm_spe_pmu_buf *buf;
@@ -597,7 +599,6 @@ static void arm_spe_perf_aux_output_begin(struct perf_output_handle *handle,/* Start a new aux session */ buf =perf_aux_output_begin (handle, event);if (!buf) { - event->hw.state |=PERF_HES_STOPPED ;/* * We still need to clear the limit pointer, since the * profiler might only be disabled by virtue of a fault.
@@ -617,6 +618,7 @@ static void arm_spe_perf_aux_output_begin(struct perf_output_handle *handle, out_write_limit:write_sysreg_s (limit,SYS_PMBLIMITR_EL1 ); +return (limit &PMBLIMITR_EL1_E ) ?0 : -EIO ; }static void arm_spe_perf_aux_output_end (struct perf_output_handle *handle)
@@ -756,7 +758,10 @@ static irqreturn_t arm_spe_pmu_irq_handler(int irq, void *dev)* when we get to it. */ if (!(handle->aux_flags &PERF_AUX_FLAG_TRUNCATED )) { -arm_spe_perf_aux_output_begin (handle, event); +if (arm_spe_perf_aux_output_begin (handle, event)) { +arm_spe_pmu_stop (event,PERF_EF_UPDATE ); +break ; + }isb (); }break ;
@@ -851,9 +856,10 @@ static void arm_spe_pmu_start(struct perf_event *event, int flags)struct perf_output_handle *handle =this_cpu_ptr (spe_pmu->handle); hwc->state =0 ; -arm_spe_perf_aux_output_begin (handle, event); -if (hwc->state) +if (arm_spe_perf_aux_output_begin (handle, event)) { +arm_spe_pmu_stop (event,0 );return ; + } reg =arm_spe_event_to_pmsfcr (event);write_sysreg_s (reg,SYS_PMSFCR_EL1 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 59/641 cpufreq: intel_pstate: Enable asym capacity only when CPU SMT is not possible
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yaxiong Tian <[email protected]>
[ Upstream commit 1fedbb589448bee9f20bb2ed9c850d1d2cf9963c ]
According to the description in the intel_pstate.rst documentation, Capacity-Aware Scheduling and Energy-Aware Scheduling are only supported on a hybrid processor without SMT. Previously, the system used sched_smt_active() for judgment, which is not a strict condition because users can switch it on or off via /sys at any time.
This could lead to incorrect driver settings in certain scenarios. For example, on a CPU that supports SMT, a user can disable SMT via the nosmt parameter to enable asym capacity, and then re-enable SMT via /sys. In such cases, some settings in the driver would no longer be correct.
To address this issue, replace sched_smt_active() with cpu_smt_possible(), and only enable asym capacity when CPU SMT is not possible.
--- drivers/cpufreq/intel_pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/intel_pstate.c +1 -1
@@ -1152,7 +1152,7 @@ static void hybrid_init_cpu_capacity_scaling(bool refresh)* the capacity of SMT threads is not deterministic even approximately, * do not do that when SMT is in use. */ -if (hwp_is_hybrid && !sched_smt_active () &&arch_enable_hybrid_capacity_scale ()) { +if (hwp_is_hybrid && !cpu_smt_possible () &&arch_enable_hybrid_capacity_scale ()) {hybrid_refresh_cpu_capacity_scaling ();/* * Disabling ITMT causes sched domains to be rebuilt to disable asym
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 60/641 PM: sleep: wakeirq: harden dev_pm_clear_wake_irq() against races
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
[ Upstream commit 5c9ecd8e6437cd55a38ea4f1e1d19cee8e226cb8 ]
dev_pm_clear_wake_irq() currently uses a dangerous pattern where dev->power.wakeirq is read and checked for NULL outside the lock. If two callers invoke this function concurrently, both might see a valid pointer and proceed. This could result in a double-free when the second caller acquires the lock and tries to release the same object.
Address this by removing the lockless check of dev->power.wakeirq. Instead, acquire dev->power.lock immediately to ensure the check and the subsequent operations are atomic. If dev->power.wakeirq is NULL under the lock, simply unlock and return. This guarantees that concurrent calls cannot race to free the same object.
Based on a quick scan of current users, I did not find an actual bug as drivers seem to rely on their own synchronization. However, since asynchronous usage patterns exist (e.g., in drivers/net/wireless/ti/wlcore), I believe a race is theoretically possible if the API is used less carefully in the future. This change hardens the API to be robust against such cases.
--- drivers/base/power/wakeirq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/base/power/wakeirq.c +6 -3
@@ -83,13 +83,16 @@ EXPORT_SYMBOL_GPL(dev_pm_set_wake_irq);*/ void dev_pm_clear_wake_irq (struct device *dev) { -struct wake_irq *wirq = dev->power.wakeirq; +struct wake_irq *wirq;unsigned long flags; -if (!wirq) +spin_lock_irqsave (&dev->power.lock, flags); + wirq = dev->power.wakeirq; +if (!wirq) { +spin_unlock_irqrestore (&dev->power.lock, flags);return ; + } -spin_lock_irqsave (&dev->power.lock, flags);device_wakeup_detach_irq (dev); dev->power.wakeirq =NULL ;spin_unlock_irqrestore (&dev->power.lock, flags);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 61/641 s390/cio: Fix device lifecycle handling in css_alloc_subchannel()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
[ Upstream commit f65c75b0b9b5a390bc3beadcde0a6fbc3ad118f7 ]
css_alloc_subchannel() calls device_initialize() before setting up the DMA masks. If dma_set_coherent_mask() or dma_set_mask() fails, the error path frees the subchannel structure directly, bypassing the device model reference counting.
Once device_initialize() has been called, the embedded struct device must be released via put_device(), allowing the release callback to free the container structure.
Fix the error path by dropping the initial device reference with put_device() instead of calling kfree() directly.
This ensures correct device lifetime handling and avoids potential use-after-free or double-free issues.
--- drivers/s390/cio/css.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/cio/css.c +1 -1
@@ -236,7 +236,7 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,return sch; err: -kfree (sch); +put_device (&sch->dev);return ERR_PTR (ret); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 62/641 io_uring/kbuf: fix memory leak if io_buffer_add_list fails
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit 442ae406603a94f1a263654494f425302ceb0445 ]
io_register_pbuf_ring() ignores the return value of io_buffer_add_list(), which can fail if xa_store() returns an error (e.g., -ENOMEM). When this happens, the function returns 0 (success) to the caller, but the io_buffer_list structure is neither added to the xarray nor freed.
In practice this requires failure injection to hit, hence not a real issue. But it should get fixed up none the less.
--- io_uring/kbuf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
io_uring/kbuf.c +3 -2
@@ -669,8 +669,9 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg) bl->buf_ring = br;if (reg.flags &IOU_PBUF_RING_INC ) bl->flags |=IOBL_INC ; -io_buffer_add_list (ctx, bl, reg.bgid); -return 0 ; + ret =io_buffer_add_list (ctx, bl, reg.bgid); +if (!ret) +return 0 ; fail:io_free_region (ctx, &bl->region);kfree (bl);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 63/641 x86/cpu/amd: Correct the microcode table for Zenbleed
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Cooper <[email protected]>
[ Upstream commit fb7bfa31b8e8569f154f2fe0ea6c2f03c0f087aa ]
The good revisions are tied to exact steppings, meaning it's not valid to match on model number alone, let alone a range.
This is probably only a latent issue. From public microcode archives, the following CPUs exist 17-30-00, 17-60-00, 17-70-00 and would be captured by the model ranges. They're likely pre-production steppings, and likely didn't get Zenbleed microcode, but it's still incorrect to compare them to a different steppings revision.
Either way, convert the logic to use x86_match_min_microcode_rev(), which is the preferred mechanism.
--- arch/x86/kernel/cpu/amd.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
arch/x86/kernel/cpu/amd.c +9 -21
@@ -951,26 +951,14 @@ static void init_amd_zen1(struct cpuinfo_x86 *c) } } -static bool cpu_has_zenbleed_microcode (void ) -{ -u32 good_rev =0 ; - -switch (boot_cpu_data.x86_model) { - case 0x30 ... 0x3f: good_rev = 0x0830107b; break; - case 0x60 ... 0x67: good_rev = 0x0860010c; break; - case 0x68 ... 0x6f: good_rev = 0x08608107; break; - case 0x70 ... 0x7f: good_rev = 0x08701033; break; - case 0xa0 ... 0xaf: good_rev = 0x08a00009; break; - -default : -return false; - } - -if (boot_cpu_data.microcode < good_rev) -return false; - -return true; -} +static const struct x86_cpu_id amd_zenbleed_microcode[] = { +ZEN_MODEL_STEP_UCODE (0x17 ,0x31 ,0x0 ,0x0830107b ), +ZEN_MODEL_STEP_UCODE (0x17 ,0x60 ,0x1 ,0x0860010c ), +ZEN_MODEL_STEP_UCODE (0x17 ,0x68 ,0x1 ,0x08608107 ), +ZEN_MODEL_STEP_UCODE (0x17 ,0x71 ,0x0 ,0x08701033 ), +ZEN_MODEL_STEP_UCODE (0x17 ,0xa0 ,0x0 ,0x08a00009 ), + {} +};static void zen2_zenbleed_check (struct cpuinfo_x86 *c) {
@@ -980,7 +968,7 @@ static void zen2_zenbleed_check(struct cpuinfo_x86 *c)if (!cpu_has (c,X86_FEATURE_AVX ))return ; -if (!cpu_has_zenbleed_microcode ()) { +if (!x86_match_min_microcode_rev (amd_zenbleed_microcode)) {pr_notice_once ("Zenbleed: please update your microcode for the most optimal fix\n" );msr_set_bit (MSR_AMD64_DE_CFG ,MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT ); }else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 64/641 perf/x86/core: Do not set bit width for unavailable counters
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sandipan Das <[email protected]>
[ Upstream commit b456a6ba5756b6fb7e651775343e713bd08418e7 ]
Not all x86 processors have fixed counters. It may also be the case that a processor has only fixed counters and no general-purpose counters. Set the bit widths corresponding to each counter type only if such counters are available.
--- arch/x86/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/events/core.c +2 -2
@@ -3101,8 +3101,8 @@ void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap) cap->version = x86_pmu.version; cap->num_counters_gp =x86_pmu_num_counters (NULL ); cap->num_counters_fixed =x86_pmu_num_counters_fixed (NULL ); - cap->bit_width_gp = x86_pmu.cntval_bits; - cap->bit_width_fixed = x86_pmu.cntval_bits; + cap->bit_width_gp = cap->num_counters_gp ? x86_pmu.cntval_bits :0 ; + cap->bit_width_fixed = cap->num_counters_fixed ? x86_pmu.cntval_bits :0 ; cap->events_mask = (unsigned int )x86_pmu.events_maskl; cap->events_mask_len = x86_pmu.events_mask_len; cap->pebs_ept = x86_pmu.pebs_ept;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 65/641 crypto: qat - fix warning on adf_pfvf_pf_proto.c
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giovanni Cabiddu <[email protected]>
[ Upstream commit 994689b8f91b02fdb5f64cba2412cde5ef3084b5 ]
Building the QAT driver with -Wmaybe-uninitialized triggers warnings in qat_common/adf_pfvf_pf_proto.c. Specifically, the variables blk_type, blk_byte, and byte_max may be used uninitialized in handle_blkmsg_req():
make M=drivers/crypto/intel/qat W=1 C=2 "KCFLAGS=-Werror" \
KBUILD_CFLAGS_KERNEL=-Wmaybe-uninitialized \
CFLAGS_MODULE=-Wmaybe-uninitialized ...
warning: ‘byte_max’ may be used uninitialized [-Wmaybe-uninitialized]
warning: ‘blk_type’ may be used uninitialized [-Wmaybe-uninitialized]
warning: ‘blk_byte’ may be used uninitialized [-Wmaybe-uninitialized]
Although the caller of handle_blkmsg_req() always provides a req.type that is handled by the switch, the compiler cannot guarantee this.
Add a default case to the switch statement to handle an invalid req.type.
--- .../crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c +10 -0
@@ -148,6 +148,16 @@ static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info, blk_byte =FIELD_GET (ADF_VF2PF_SMALL_BLOCK_BYTE_MASK , req.data); byte_max =ADF_VF2PF_SMALL_BLOCK_BYTE_MAX ;break ; +default : +dev_err (&GET_DEV (vf_info->accel_dev), +"Invalid BlockMsg type 0x%.4x received from VF%u\n" , + req.type, vf_info->vf_nr); + resp.type =ADF_PF2VF_MSGTYPE_BLKMSG_RESP ; + resp.data =FIELD_PREP (ADF_PF2VF_BLKMSG_RESP_TYPE_MASK , +ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR ) | +FIELD_PREP (ADF_PF2VF_BLKMSG_RESP_DATA_MASK , +ADF_PF2VF_UNSPECIFIED_ERROR ); +return resp; }/* Is this a request for CRC or data? */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 66/641 selftests/bpf: veristat: fix printing order in output_stats()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Puranjay Mohan <[email protected]>
[ Upstream commit c286e7e9d1f1f3d90ad11c37e896f582b02d19c4 ]
The order of the variables in the printf() doesn't match the text and therefore veristat prints something like this:
Done. Processed 24 files, 0 programs. Skipped 62 files, 0 programs.
When it should print:
Done. Processed 24 files, 62 programs. Skipped 0 files, 0 programs.
Fix the order of variables in the printf() call.
--- tools/testing/selftests/bpf/veristat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/bpf/veristat.c +1 -1
@@ -2580,7 +2580,7 @@ static void output_stats(const struct verif_stats *s, enum resfmt fmt, bool lastif (last && fmt ==RESFMT_TABLE ) {output_header_underlines ();printf ("Done. Processed %d files, %d programs. Skipped %d files, %d programs.\n" , - env.files_processed, env.files_skipped, env.progs_processed, env.progs_skipped); + env.files_processed, env.progs_processed, env.files_skipped, env.progs_skipped); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 67/641 libbpf: Fix OOB read in btf_dump_get_bitfield_value
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varun R Mallya <[email protected]>
[ Upstream commit 5714ca8cba5ed736f3733663c446cbee63a10a64 ]
When dumping bitfield data, btf_dump_get_bitfield_value() reads data based on the underlying type's size (t->size). However, it does not verify that the provided data buffer (data_sz) is large enough to contain these bytes.
If btf_dump__dump_type_data() is called with a buffer smaller than the type's size, this leads to an out-of-bounds read. This was confirmed by AddressSanitizer in the linked issue.
Fix this by ensuring we do not read past the provided data_sz limit.
--- tools/lib/bpf/btf_dump.c | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/lib/bpf/btf_dump.c +9 -0
@@ -1762,9 +1762,18 @@ static int btf_dump_get_bitfield_value(struct btf_dump *d,__u16 left_shift_bits, right_shift_bits;const __u8 *bytes = data;__u8 nr_copy_bits; +__u8 start_bit, nr_bytes;__u64 num =0 ;int i; +/* Calculate how many bytes cover the bitfield */ + start_bit = bits_offset %8 ; + nr_bytes = (start_bit + bit_sz +7 ) /8 ; + +/* Bound check */ +if (data + nr_bytes > d->typed_dump->data_end) +return -E2BIG ; +/* Maximum supported bitfield size is 64 bits */ if (t->size >8 ) {pr_warn ("unexpected bitfield size %d\n" , t->size);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 68/641 sched: Export hidden tracepoints to modules
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriele Monaco <[email protected]>
[ Upstream commit 6c125b85f3c87b4bf7dba91af6f27d9600b9dba0 ]
The tracepoints sched_entry, sched_exit and sched_set_need_resched are not exported to tracefs as trace events, this allows only kernel code to access them. Helper modules like [1] can be used to still have the tracepoints available to ftrace for debugging purposes, but they do rely on the tracepoints being exported.
Export the 3 not exported tracepoints.
Note that sched_set_state is already exported as the macro is called from modules.
[1] - https://github.com/qais-yousef/sched_tp.git
--- kernel/sched/core.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/sched/core.c +3 -0
@@ -119,6 +119,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_cfs_tp);EXPORT_TRACEPOINT_SYMBOL_GPL (sched_util_est_se_tp);EXPORT_TRACEPOINT_SYMBOL_GPL (sched_update_nr_running_tp);EXPORT_TRACEPOINT_SYMBOL_GPL (sched_compute_energy_tp); +EXPORT_TRACEPOINT_SYMBOL_GPL (sched_entry_tp); +EXPORT_TRACEPOINT_SYMBOL_GPL (sched_exit_tp); +EXPORT_TRACEPOINT_SYMBOL_GPL (sched_set_need_resched_tp); DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); DEFINE_PER_CPU(struct rnd_state, sched_rnd_state);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 69/641 ARM: VDSO: Patch out __vdso_clock_getres() if unavailable
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit b9fecf0dddfc55cd7d02b0011494da3c613f7cde ]
The vDSO code hides symbols which are non-functional. __vdso_clock_getres() was not added to this list when it got introduced.
--- arch/arm/kernel/vdso.c | 1 + 1 file changed, 1 insertion(+)
arch/arm/kernel/vdso.c +1 -0
@@ -161,6 +161,7 @@ static void __init patch_vdso(void *ehdr)vdso_nullpatch_one (&einfo,"__vdso_gettimeofday" );vdso_nullpatch_one (&einfo,"__vdso_clock_gettime" );vdso_nullpatch_one (&einfo,"__vdso_clock_gettime64" ); +vdso_nullpatch_one (&einfo,"__vdso_clock_getres" ); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 70/641 time/sched_clock: Use ACCESS_PRIVATE() to evaluate hrtimer::function
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 3db5306b0bd562ac0fe7eddad26c60ebb6f5fdd4 ]
This dereference of sched_clock_timer::function was missed when the hrtimer callback function pointer was marked private.
--- kernel/time/sched_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/sched_clock.c +1 -1
@@ -215,7 +215,7 @@ void sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)update_clock_read_data (&rd); -if (sched_clock_timer.function !=NULL ) { +if (ACCESS_PRIVATE (&sched_clock_timer, function) !=NULL ) {/* update timeout for clock wrap */ hrtimer_start (&sched_clock_timer, cd.wrap_kt,HRTIMER_MODE_REL_HARD );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 71/641 sched: Fix build for modules using set_tsk_need_resched()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriele Monaco <[email protected]>
[ Upstream commit 8d737320166bd145af70a3133a9964b00ca81cba ]
Commit adcc3bfa8806 ("sched: Adapt sched tracepoints for RV task model") added a tracepoint to the need_resched action that can be triggered also by set_tsk_need_resched.
This function was previously accessible from out-of-tree modules but it's no longer available because the __trace_set_need_resched() symbol is not exported (together with the tracepoint itself, which was exported in a separate patch) and building such modules fails.
Export __trace_set_need_resched to modules to fix those build issues.
--- kernel/sched/core.c | 1 + 1 file changed, 1 insertion(+)
kernel/sched/core.c +1 -0
@@ -1139,6 +1139,7 @@ void __trace_set_need_resched(struct task_struct *curr, int tif) {trace_sched_set_need_resched_tp (curr,smp_processor_id (), tif); } +EXPORT_SYMBOL_GPL (__trace_set_need_resched);void resched_curr (struct rq *rq) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 72/641 crypto: cavium - fix dma_free_coherent() size
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit 941676c30ba5b40a01bed92448f457ce62fd1f07 ]
The size of the buffer in alloc_command_queues() is curr->size + CPT_NEXT_CHUNK_PTR_SIZE, so used that length for dma_free_coherent().
--- drivers/crypto/cavium/cpt/cptvf_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/crypto/cavium/cpt/cptvf_main.c +2 -1
@@ -180,7 +180,8 @@ static void free_command_queues(struct cpt_vf *cptvf,hlist_for_each_entry_safe (chunk, node, &cqinfo->queue[i].chead, nextchunk) { -dma_free_coherent (&pdev->dev, chunk->size, +dma_free_coherent (&pdev->dev, + chunk->size +CPT_NEXT_CHUNK_PTR_SIZE , chunk->head, chunk->dma_addr); chunk->head =NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 73/641 crypto: octeontx - fix dma_free_coherent() size
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit 624a6760bf8464965c17c8df10b40b557eaa3002 ]
The size of the buffer in alloc_command_queues() is curr->size + OTX_CPT_NEXT_CHUNK_PTR_SIZE, so used that length for dma_free_coherent().
--- drivers/crypto/marvell/octeontx/otx_cptvf_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/crypto/marvell/octeontx/otx_cptvf_main.c +2 -1
@@ -168,7 +168,8 @@ static void free_command_queues(struct otx_cptvf *cptvf, chunk =list_first_entry (&cqinfo->queue[i].chead, struct otx_cpt_cmd_chunk, nextchunk); -dma_free_coherent (&pdev->dev, chunk->size, +dma_free_coherent (&pdev->dev, + chunk->size +OTX_CPT_NEXT_CHUNK_PTR_SIZE , chunk->head, chunk->dma_addr); chunk->head =NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 74/641 crypto: hisilicon/zip - adjust the way to obtain the req in the callback function
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 19c2475ce1984cf675ebfbbeaa5509b2fb1887d6 ]
In the shared queue design, multiple tfms use same qp, and one qp need to corresponds to multiple qp_ctx. So use tag to obtain the req virtual address. Build a one-to-one relationship between tfm and qp_ctx. finaly remove the old get_tag operation.
--- drivers/crypto/hisilicon/zip/zip_crypto.c | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-)
drivers/crypto/hisilicon/zip/zip_crypto.c +9 -15
@@ -39,6 +39,7 @@ enum { HZIP_CTX_Q_NUM }; +#define GET_REQ_FROM_SQE (sqe) ((u64)(sqe)->dw26 | (u64)(sqe)->dw27 << 32)#define COMP_NAME_TO_TYPE (alg_name) \ (!strcmp((alg_name), "deflate") ? HZIP_ALG_TYPE_DEFLATE : 0)
@@ -48,6 +49,7 @@ struct hisi_zip_req {struct hisi_acc_hw_sgl *hw_dst;dma_addr_t dma_src;dma_addr_t dma_dst; +struct hisi_zip_qp_ctx *qp_ctx;u16 req_id; };
@@ -74,7 +76,6 @@ struct hisi_zip_sqe_ops {void (*fill_req_type)(struct hisi_zip_sqe *sqe,u8 req_type);void (*fill_tag)(struct hisi_zip_sqe *sqe,struct hisi_zip_req *req);void (*fill_sqe_type)(struct hisi_zip_sqe *sqe,u8 sqe_type); -u32 (*get_tag)(struct hisi_zip_sqe *sqe);u32 (*get_status)(struct hisi_zip_sqe *sqe);u32 (*get_dstlen)(struct hisi_zip_sqe *sqe); };
@@ -131,6 +132,7 @@ static struct hisi_zip_req *hisi_zip_create_req(struct hisi_zip_qp_ctx *qp_ctx, req_cache = q + req_id; req_cache->req_id = req_id; req_cache->req = req; + req_cache->qp_ctx = qp_ctx;return req_cache; }
@@ -181,7 +183,8 @@ static void hisi_zip_fill_req_type(struct hisi_zip_sqe *sqe, u8 req_type)static void hisi_zip_fill_tag (struct hisi_zip_sqe *sqe,struct hisi_zip_req *req) { - sqe->dw26 = req->req_id; + sqe->dw26 =lower_32_bits ((u64 )req); + sqe->dw27 =upper_32_bits ((u64 )req); }static void hisi_zip_fill_sqe_type (struct hisi_zip_sqe *sqe,u8 sqe_type)
@@ -237,7 +240,7 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx, &req->dma_dst, DMA_FROM_DEVICE);if (IS_ERR (req->hw_dst)) { ret =PTR_ERR (req->hw_dst); -dev_err (dev,"failed to map the dst buffer to hw slg (%d)!\n" , +dev_err (dev,"failed to map the dst buffer to hw sgl (%d)!\n" , ret); goto err_unmap_input; }
@@ -265,11 +268,6 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx,return ret; } -static u32 hisi_zip_get_tag (struct hisi_zip_sqe *sqe) -{ -return sqe->dw26; -} -static u32 hisi_zip_get_status (struct hisi_zip_sqe *sqe) {return sqe->dw3 &HZIP_BD_STATUS_M ;
@@ -282,14 +280,12 @@ static u32 hisi_zip_get_dstlen(struct hisi_zip_sqe *sqe)static void hisi_zip_acomp_cb (struct hisi_qp *qp,void *data) { -struct hisi_zip_qp_ctx *qp_ctx = qp->qp_ctx; +struct hisi_zip_sqe *sqe = data; +struct hisi_zip_req *req = (struct hisi_zip_req *)GET_REQ_FROM_SQE (sqe); +struct hisi_zip_qp_ctx *qp_ctx = req->qp_ctx;const struct hisi_zip_sqe_ops *ops = qp_ctx->ctx->ops;struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx; -struct hisi_zip_req_q *req_q = &qp_ctx->req_q;struct device *dev = &qp->qm->pdev->dev; -struct hisi_zip_sqe *sqe = data; -u32 tag = ops->get_tag (sqe); -struct hisi_zip_req *req = req_q->q + tag;struct acomp_req *acomp_req = req->req;int err =0 ;u32 status;
@@ -393,7 +389,6 @@ static const struct hisi_zip_sqe_ops hisi_zip_ops = { .fill_req_type = hisi_zip_fill_req_type, .fill_tag = hisi_zip_fill_tag, .fill_sqe_type = hisi_zip_fill_sqe_type, - .get_tag = hisi_zip_get_tag, .get_status = hisi_zip_get_status, .get_dstlen = hisi_zip_get_dstlen, };
@@ -581,7 +576,6 @@ static void hisi_zip_acomp_exit(struct crypto_acomp *tfm) {struct hisi_zip_ctx *ctx =crypto_tfm_ctx (&tfm->base); -hisi_zip_set_acomp_cb (ctx,NULL );hisi_zip_release_sgl_pool (ctx);hisi_zip_release_req_q (ctx);hisi_zip_ctx_exit (ctx);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 75/641 crypto: hisilicon/sec - move backlog management to qp and store sqe in qp for callback
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 08eb67d23e5172a5d1e60f1f0acccee569fe10ba ]
When multiple tfm use a same qp, the backlog data should be managed centrally by the qp, rather than in the qp_ctx of each req.
Additionally, since SEC_BD_TYPE1 and SEC_BD_TYPE2 cannot use the tag of the sqe to carry the virtual address of the req, the sent sqe is stored in the qp. This allows the callback function to get the req address. To handle the differences between hardware types, the callback functions are split into two separate implementations.
--- drivers/crypto/hisilicon/qm.c | 20 ++++- drivers/crypto/hisilicon/sec2/sec.h | 7 -- drivers/crypto/hisilicon/sec2/sec_crypto.c | 88 +++++++++++----------- include/linux/hisi_acc_qm.h | 8 ++ 4 files changed, 69 insertions(+), 54 deletions(-)
drivers/crypto/hisilicon/qm.c +16 -4
@@ -2210,6 +2210,7 @@ static void qp_stop_fail_cb(struct hisi_qp *qp)for (i =0 ; i < qp_used; i++) { pos = (i + cur_head) % sq_depth; qp->req_cb (qp, qp->sqe + (u32)(qm->sqe_size * pos)); +qm_cq_head_update (qp);atomic_dec (&qp->qp_status.used); } }
@@ -2374,6 +2375,7 @@ int hisi_qp_send(struct hisi_qp *qp, const void *msg)return -EBUSY ;memcpy (sqe, msg, qp->qm->sqe_size); + qp->msg[sq_tail] = msg;qm_db (qp->qm, qp->qp_id,QM_DOORBELL_CMD_SQ , sq_tail_next,0 );atomic_inc (&qp->qp_status.used);
@@ -2907,12 +2909,13 @@ EXPORT_SYMBOL_GPL(hisi_qm_wait_task_finish);static void hisi_qp_memory_uninit (struct hisi_qm *qm,int num) {struct device *dev = &qm->pdev->dev; -struct qm_dma *qdma; +struct hisi_qp *qp;int i;for (i = num -1 ; i >=0 ; i--) { - qdma = &qm->qp_array[i].qdma; -dma_free_coherent (dev, qdma->size, qdma->va, qdma->dma); + qp = &qm->qp_array[i]; +dma_free_coherent (dev, qp->qdma.size, qp->qdma.va, qp->qdma.dma); +kfree (qp->msg);kfree (qm->poll_data[i].qp_finish_id); }
@@ -2934,10 +2937,14 @@ static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id,return -ENOMEM ; qp = &qm->qp_array[id]; + qp->msg =kmalloc_array (sq_depth,sizeof (void *),GFP_KERNEL ); +if (!qp->msg) + goto err_free_qp_finish_id; + qp->qdma.va =dma_alloc_coherent (dev, dma_size, &qp->qdma.dma,GFP_KERNEL );if (!qp->qdma.va) - goto err_free_qp_finish_id; + goto err_free_qp_msg; qp->sqe = qp->qdma.va; qp->sqe_dma = qp->qdma.dma;
@@ -2949,8 +2956,13 @@ static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id, qp->qm = qm; qp->qp_id = id; +spin_lock_init (&qp->backlog.lock); +INIT_LIST_HEAD (&qp->backlog.list); +return 0 ; +err_free_qp_msg: +kfree (qp->msg); err_free_qp_finish_id:kfree (qm->poll_data[id].qp_finish_id);return ret;
drivers/crypto/hisilicon/sec2/sec.h +0 -7
@@ -82,11 +82,6 @@ struct sec_aead_req {__u8 out_mac_buf[SEC_MAX_MAC_LEN ]; }; -struct sec_instance_backlog { -struct list_head list; -spinlock_t lock; -}; -/* SEC request of Crypto */ struct sec_req { union {
@@ -112,7 +107,6 @@ struct sec_req {bool use_pbuf;struct list_head list; -struct sec_instance_backlog *backlog;struct sec_request_buf buf; };
@@ -172,7 +166,6 @@ struct sec_qp_ctx {spinlock_t id_lock;struct hisi_acc_sgl_pool *c_in_pool;struct hisi_acc_sgl_pool *c_out_pool; -struct sec_instance_backlog backlog;u16 send_head; };
drivers/crypto/hisilicon/sec2/sec_crypto.c +45 -43
190 lines not on this page · raw message
include/linux/hisi_acc_qm.h +8 -0
@@ -444,6 +444,11 @@ struct hisi_qp_ops {int (*fill_sqe)(void *sqe,void *q_parm,void *d_parm); }; +struct instance_backlog { +struct list_head list; +spinlock_t lock; +}; +struct hisi_qp {u32 qp_id;u16 sq_depth;
@@ -468,6 +473,9 @@ struct hisi_qp {bool is_in_kernel;u16 pasid;struct uacce_queue *uacce_q; + +struct instance_backlog backlog; +const void **msg; };static inline int vfs_num_set (const char *val,const struct kernel_param *kp)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 76/641 crypto: hisilicon/hpre: extend tag field to 64 bits for better performance
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: lizhi <[email protected]>
[ Upstream commit 3a1984758197f7fd4c557dd98090e8e0cf9f498e ]
This commit expands the tag field in hpre_sqe structure from 16-bit to 64-bit. The change enables storing request addresses directly in the tag field, allowing callback functions to access request messages without the previous indirection mechanism.
By eliminating the need for lookup tables, this modification reduces lock contention and associated overhead, leading to improved efficiency and simplified code.
--- drivers/crypto/hisilicon/hpre/hpre.h | 5 +- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 142 ++++---------------- 2 files changed, 25 insertions(+), 122 deletions(-)
drivers/crypto/hisilicon/hpre/hpre.h +2 -3
@@ -94,9 +94,8 @@ struct hpre_sqe {__le64 key;__le64 in;__le64 out; -__le16 tag; -__le16 resv2; -#define _HPRE_SQE_ALIGN_EXT 7 +__le64 tag; +#define _HPRE_SQE_ALIGN_EXT 6__le32 rsvd1[_HPRE_SQE_ALIGN_EXT]; };
drivers/crypto/hisilicon/hpre/hpre_crypto.c +23 -119
272 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 77/641 crypto: hisilicon/qm - enhance the configuration of req_type in queue attributes
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 21452eaa06edb5f6038720e643aed0bbfffad9c3 ]
Originally, when a queue was requested, it could only be configured with the default algorithm type of 0. Now, when multiple tfms use the same queue, the queue must be selected based on its attributes to meet the requirements of tfm tasks. So the algorithm type attribute of queue need to be distinguished. Just like a queue used for compression in ZIP cannot be used for decompression tasks.
--- drivers/crypto/hisilicon/hpre/hpre_main.c | 2 +- drivers/crypto/hisilicon/qm.c | 8 ++++---- drivers/crypto/hisilicon/sec2/sec_crypto.c | 1 - drivers/crypto/hisilicon/sec2/sec_main.c | 21 ++++++++++++++++----- drivers/crypto/hisilicon/zip/zip.h | 2 +- drivers/crypto/hisilicon/zip/zip_crypto.c | 13 +++++++++---- drivers/crypto/hisilicon/zip/zip_main.c | 4 ++-- include/linux/hisi_acc_qm.h | 3 +-- 8 files changed, 34 insertions(+), 20 deletions(-)
drivers/crypto/hisilicon/hpre/hpre_main.c +1 -1
@@ -465,7 +465,7 @@ struct hisi_qp *hpre_create_qp(u8 type)* type: 0 - RSA/DH. algorithm supported in V2, * 1 - ECC algorithm in V3. */ - ret =hisi_qm_alloc_qps_node (&hpre_devices,1 , type, node, &qp); + ret =hisi_qm_alloc_qps_node (&hpre_devices,1 , &type, node, &qp);if (!ret)return qp;
drivers/crypto/hisilicon/qm.c +4 -4
@@ -3583,7 +3583,7 @@ static int hisi_qm_sort_devices(int node, struct list_head *head,* not meet the requirements will return error. */ int hisi_qm_alloc_qps_node (struct hisi_qm_list *qm_list,int qp_num, -u8 alg_type,int node,struct hisi_qp **qps) +u8 *alg_type,int node,struct hisi_qp **qps) {struct hisi_qm_resource *tmp;int ret = -ENODEV ;
@@ -3601,7 +3601,7 @@ int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,list_for_each_entry (tmp, &head, list) {for (i =0 ; i < qp_num; i++) { - qps[i] =hisi_qm_create_qp (tmp->qm, alg_type); + qps[i] =hisi_qm_create_qp (tmp->qm, alg_type[i]);if (IS_ERR (qps[i])) {hisi_qm_free_qps (qps, i);break ;
@@ -3616,8 +3616,8 @@ int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,mutex_unlock (&qm_list->lock);if (ret) -pr_info ("Failed to create qps, node[%d], alg[%u], qp[%d]!\n" , - node, alg_type, qp_num); +pr_info ("Failed to create qps, node[%d], qp[%d]!\n" , + node, qp_num); err:free_list (&head);
drivers/crypto/hisilicon/sec2/sec_crypto.c +0 -1
@@ -626,7 +626,6 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id) qp_ctx = &ctx->qp_ctx[qp_ctx_id]; qp = ctx->qps[qp_ctx_id]; - qp->req_type =0 ; qp->qp_ctx = qp_ctx; qp_ctx->qp = qp; qp_ctx->ctx = ctx;
drivers/crypto/hisilicon/sec2/sec_main.c +16 -5
@@ -417,18 +417,29 @@ struct hisi_qp **sec_create_qps(void)int node =cpu_to_node (raw_smp_processor_id ());u32 ctx_num = ctx_q_num;struct hisi_qp **qps; +u8 *type;int ret; qps =kcalloc (ctx_num,sizeof (struct hisi_qp *),GFP_KERNEL );if (!qps)return NULL ; - ret =hisi_qm_alloc_qps_node (&sec_devices, ctx_num,0 , node, qps); -if (!ret) -return qps; +/* The type of SEC is all 0, so just allocated by kcalloc */ + type =kcalloc (ctx_num,sizeof (u8),GFP_KERNEL ); +if (!type) { +kfree (qps); +return NULL ; + } -kfree (qps); -return NULL ; + ret =hisi_qm_alloc_qps_node (&sec_devices, ctx_num, type, node, qps); +if (ret) { +kfree (type); +kfree (qps); +return NULL ; + } + +kfree (type); +return qps; }u64 sec_get_alg_bitmap (struct hisi_qm *qm,u32 high,u32 low)
drivers/crypto/hisilicon/zip/zip.h +1 -1
@@ -99,7 +99,7 @@ enum zip_cap_table_type { ZIP_CORE5_BITMAP, }; -int zip_create_qps (struct hisi_qp **qps,int qp_num,int node); +int zip_create_qps (struct hisi_qp **qps,int qp_num,int node,u8 *alg_type);int hisi_zip_register_to_crypto (struct hisi_qm *qm);void hisi_zip_unregister_from_crypto (struct hisi_qm *qm);bool hisi_zip_alg_support (struct hisi_qm *qm,u32 alg);
drivers/crypto/hisilicon/zip/zip_crypto.c +9 -4
@@ -66,6 +66,7 @@ struct hisi_zip_qp_ctx {struct hisi_acc_sgl_pool *sgl_pool;struct hisi_zip *zip_dev;struct hisi_zip_ctx *ctx; +u8 req_type; };struct hisi_zip_sqe_ops {
@@ -245,7 +246,7 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx, goto err_unmap_input; } -hisi_zip_fill_sqe (qp_ctx->ctx, &zip_sqe, qp->req_type, req); +hisi_zip_fill_sqe (qp_ctx->ctx, &zip_sqe, qp_ctx->req_type, req);/* send command to start a task */ atomic64_inc (&dfx->send_cnt);
@@ -360,7 +361,6 @@ static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *qp_ctx,struct device *dev = &qp->qm->pdev->dev;int ret; - qp->req_type = req_type; qp->alg_type = alg_type; qp->qp_ctx = qp_ctx;
@@ -397,10 +397,15 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int {struct hisi_qp *qps[HZIP_CTX_Q_NUM ] = {NULL };struct hisi_zip_qp_ctx *qp_ctx; +u8 alg_type[HZIP_CTX_Q_NUM ];struct hisi_zip *hisi_zip;int ret, i, j; - ret =zip_create_qps (qps,HZIP_CTX_Q_NUM , node); +/* alg_type = 0 for compress, 1 for decompress in hw sqe */ +for (i =0 ; i <HZIP_CTX_Q_NUM ; i++) + alg_type[i] = i; + + ret =zip_create_qps (qps,HZIP_CTX_Q_NUM , node, alg_type);if (ret) {pr_err ("failed to create zip qps (%d)!\n" , ret);return -ENODEV ;
@@ -409,7 +414,6 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);for (i =0 ; i <HZIP_CTX_Q_NUM ; i++) { -/* alg_type = 0 for compress, 1 for decompress in hw sqe */ qp_ctx = &hisi_zip_ctx->qp_ctx[i]; qp_ctx->ctx = hisi_zip_ctx; ret =hisi_zip_start_qp (qps[i], qp_ctx, i, req_type);
@@ -422,6 +426,7 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int } qp_ctx->zip_dev = hisi_zip; + qp_ctx->req_type = req_type; } hisi_zip_ctx->ops = &hisi_zip_ops;
drivers/crypto/hisilicon/zip/zip_main.c +2 -2
@@ -446,12 +446,12 @@ static const struct pci_device_id hisi_zip_dev_ids[] = { };MODULE_DEVICE_TABLE (pci, hisi_zip_dev_ids); -int zip_create_qps (struct hisi_qp **qps,int qp_num,int node) +int zip_create_qps (struct hisi_qp **qps,int qp_num,int node,u8 *alg_type) {if (node ==NUMA_NO_NODE ) node =cpu_to_node (raw_smp_processor_id ()); -return hisi_qm_alloc_qps_node (&zip_devices, qp_num,0 , node, qps); +return hisi_qm_alloc_qps_node (&zip_devices, qp_num, alg_type, node, qps); }bool hisi_zip_alg_support (struct hisi_qm *qm,u32 alg)
include/linux/hisi_acc_qm.h +1 -2
@@ -454,7 +454,6 @@ struct hisi_qp {u16 sq_depth;u16 cq_depth;u8 alg_type; -u8 req_type;struct qm_dma qdma;void *sqe;
@@ -580,7 +579,7 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,void hisi_acc_free_sgl_pool (struct device *dev,struct hisi_acc_sgl_pool *pool);int hisi_qm_alloc_qps_node (struct hisi_qm_list *qm_list,int qp_num, -u8 alg_type,int node,struct hisi_qp **qps); +u8 *alg_type,int node,struct hisi_qp **qps);void hisi_qm_free_qps (struct hisi_qp **qps,int qp_num);void hisi_qm_dev_shutdown (struct pci_dev *pdev);void hisi_qm_wait_task_finish (struct hisi_qm *qm,struct hisi_qm_list *qm_list);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 78/641 crypto: hisilicon/qm - centralize the sending locks of each module into qm
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 8cd9b608ee8dea78cac3f373bd5e3b3de2755d46 ]
When a single queue used by multiple tfms, the protection of shared resources by individual module driver programs is no longer sufficient. The hisi_qp_send needs to be ensured by the lock in qp.
--- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 4 ---- drivers/crypto/hisilicon/qm.c | 16 ++++++++++++---- drivers/crypto/hisilicon/zip/zip_crypto.c | 3 --- include/linux/hisi_acc_qm.h | 1 + 4 files changed, 13 insertions(+), 11 deletions(-)
drivers/crypto/hisilicon/hpre/hpre_crypto.c +0 -4
@@ -109,7 +109,6 @@ struct hpre_ctx {struct hisi_qp *qp;struct device *dev;struct hpre *hpre; -spinlock_t req_lock;unsigned int key_sz;bool crt_g2_mode;union {
@@ -410,7 +409,6 @@ static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type) qp->qp_ctx = ctx; qp->req_cb = hpre_alg_cb; -spin_lock_init (&ctx->req_lock); ctx->qp = qp; ctx->dev = &qp->qm->pdev->dev; hpre = container_of(ctx->qp->qm, struct hpre, qm);
@@ -478,9 +476,7 @@ static int hpre_send(struct hpre_ctx *ctx, struct hpre_sqe *msg) do { atomic64_inc(&dfx[HPRE_SEND_CNT].value); - spin_lock_bh(&ctx->req_lock); ret = hisi_qp_send(ctx->qp, msg); - spin_unlock_bh(&ctx->req_lock); if (ret != -EBUSY) break; atomic64_inc(&dfx[HPRE_SEND_BUSY_CNT].value);
drivers/crypto/hisilicon/qm.c +12 -4
@@ -2360,26 +2360,33 @@ EXPORT_SYMBOL_GPL(hisi_qm_stop_qp);int hisi_qp_send (struct hisi_qp *qp,const void *msg) {struct hisi_qp_status *qp_status = &qp->qp_status; -u16 sq_tail = qp_status->sq_tail; -u16 sq_tail_next = (sq_tail +1 ) % qp->sq_depth; -void *sqe =qm_get_avail_sqe (qp); +u16 sq_tail, sq_tail_next; +void *sqe; +spin_lock_bh (&qp->qp_lock);if (unlikely (atomic_read (&qp->qp_status.flags) ==QP_STOP ||atomic_read (&qp->qm->status.flags) ==QM_STOP || qp->is_resetting)) { +spin_unlock_bh (&qp->qp_lock);dev_info_ratelimited (&qp->qm->pdev->dev,"QP is stopped or resetting\n" );return -EAGAIN ; } -if (!sqe) + sqe =qm_get_avail_sqe (qp); +if (!sqe) { +spin_unlock_bh (&qp->qp_lock);return -EBUSY ; + } + sq_tail = qp_status->sq_tail; + sq_tail_next = (sq_tail +1 ) % qp->sq_depth;memcpy (sqe, msg, qp->qm->sqe_size); qp->msg[sq_tail] = msg;qm_db (qp->qm, qp->qp_id,QM_DOORBELL_CMD_SQ , sq_tail_next,0 );atomic_inc (&qp->qp_status.used); qp_status->sq_tail = sq_tail_next; +spin_unlock_bh (&qp->qp_lock);return 0 ; }
@@ -2956,6 +2963,7 @@ static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id, qp->qm = qm; qp->qp_id = id; +spin_lock_init (&qp->qp_lock);spin_lock_init (&qp->backlog.lock);INIT_LIST_HEAD (&qp->backlog.list);
drivers/crypto/hisilicon/zip/zip_crypto.c +0 -3
@@ -217,7 +217,6 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx, {struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx; -struct hisi_zip_req_q *req_q = &qp_ctx->req_q;struct acomp_req *a_req = req->req;struct hisi_qp *qp = qp_ctx->qp;struct device *dev = &qp->qm->pdev->dev;
@@ -250,9 +249,7 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx,/* send command to start a task */ atomic64_inc (&dfx->send_cnt); -spin_lock_bh (&req_q->req_lock); ret =hisi_qp_send (qp, &zip_sqe); -spin_unlock_bh (&req_q->req_lock);if (unlikely (ret <0 )) {atomic64_inc (&dfx->send_busy_cnt); ret = -EAGAIN ;
include/linux/hisi_acc_qm.h +1 -0
@@ -473,6 +473,7 @@ struct hisi_qp {u16 pasid;struct uacce_queue *uacce_q; +spinlock_t qp_lock;struct instance_backlog backlog;const void **msg; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 79/641 crypto: hisilicon/zip - support fallback for zip
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 73398f85a430cfebc2ff06ab836d6d9eb1484c79 ]
When the hardware queue resource busy(no shareable queue) or memery alloc fail in initialization of acomp_alg, use soft algorithm to complete the work.
--- drivers/crypto/hisilicon/Kconfig | 1 + drivers/crypto/hisilicon/zip/zip_crypto.c | 50 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 8 deletions(-)
drivers/crypto/hisilicon/Kconfig +1 -0
@@ -57,6 +57,7 @@ config CRYPTO_DEV_HISI_ZIP depends on UACCE || UACCE=n depends on ACPI select CRYPTO_DEV_HISI_QM + select CRYPTO_DEFLATE help Support for HiSilicon ZIP Driver
drivers/crypto/hisilicon/zip/zip_crypto.c +42 -8
104 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 80/641 crypto: hisilicon - consolidate qp creation and start in hisi_qm_alloc_qps_node
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 72f3bbebff15e87171271d643ee2672fb8e92031 ]
Consolidate the creation and start of qp into the function hisi_qm_alloc_qps_node. This change eliminates the need for each module to perform these steps in two separate phases (creation and start).
Stable-dep-of: 6aff4d977e2d ("crypto: hisilicon/hpre - support the hpre algorithm fallback")
--- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 40 ++---------- drivers/crypto/hisilicon/qm.c | 70 ++++++++++++++++----- drivers/crypto/hisilicon/sec2/sec_crypto.c | 8 --- drivers/crypto/hisilicon/zip/zip_crypto.c | 43 ++----------- include/linux/hisi_acc_qm.h | 1 - 5 files changed, 66 insertions(+), 96 deletions(-)
drivers/crypto/hisilicon/hpre/hpre_crypto.c +4 -36
@@ -156,27 +156,6 @@ static void hpre_dfx_add_req_time(struct hpre_asym_request *hpre_req)ktime_get_ts64 (&hpre_req->req_time); } -static struct hisi_qp *hpre_get_qp_and_start (u8 type) -{ -struct hisi_qp *qp; -int ret; - - qp =hpre_create_qp (type); -if (!qp) { -pr_err ("Can not create hpre qp!\n" ); -return ERR_PTR (-ENODEV ); - } - - ret =hisi_qm_start_qp (qp,0 ); -if (ret <0 ) { -hisi_qm_free_qps (&qp,1 ); -pci_err (qp->qm->pdev,"Can not start qp!\n" ); -return ERR_PTR (-EINVAL ); - } - -return qp; -} -static int hpre_get_data_dma_addr (struct hpre_asym_request *hpre_req,struct scatterlist *data,unsigned int len,int is_src,dma_addr_t *tmp)
@@ -316,9 +295,8 @@ static int hpre_alg_res_post_hf(struct hpre_ctx *ctx, struct hpre_sqe *sqe,static void hpre_ctx_clear (struct hpre_ctx *ctx,bool is_clear_all) { -if (is_clear_all) { +if (is_clear_all)hisi_qm_free_qps (&ctx->qp,1 ); - } ctx->crt_g2_mode = false; ctx->key_sz =0 ;
@@ -403,11 +381,10 @@ static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type)struct hisi_qp *qp;struct hpre *hpre; - qp =hpre_get_qp_and_start (type); -if (IS_ERR (qp)) -return PTR_ERR (qp); + qp =hpre_create_qp (type); +if (!qp) +return -ENODEV ; - qp->qp_ctx = ctx; qp->req_cb = hpre_alg_cb; ctx->qp = qp; ctx->dev = &qp->qm->pdev->dev;
@@ -597,9 +574,6 @@ static void hpre_dh_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)struct device *dev = ctx->dev;unsigned int sz = ctx->key_sz; -if (is_clear_all) -hisi_qm_stop_qp (ctx->qp); -if (ctx->dh.g) {dma_free_coherent (dev, sz, ctx->dh.g, ctx->dh.dma_g); ctx->dh.g =NULL ;
@@ -940,9 +914,6 @@ static void hpre_rsa_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)unsigned int half_key_sz = ctx->key_sz >>1 ;struct device *dev = ctx->dev; -if (is_clear_all) -hisi_qm_stop_qp (ctx->qp); -if (ctx->rsa.pubkey) {dma_free_coherent (dev, ctx->key_sz <<1 , ctx->rsa.pubkey, ctx->rsa.dma_pubkey);
@@ -1112,9 +1083,6 @@ static void hpre_ecc_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)unsigned int sz = ctx->key_sz;unsigned int shift = sz <<1 ; -if (is_clear_all) -hisi_qm_stop_qp (ctx->qp); -if (ctx->ecdh.p) {/* ecdh: p->a->k->b */ memzero_explicit (ctx->ecdh.p + shift, sz);
drivers/crypto/hisilicon/qm.c +56 -14
101 lines not on this page · raw message
drivers/crypto/hisilicon/sec2/sec_crypto.c +0 -8
@@ -626,7 +626,6 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id) qp_ctx = &ctx->qp_ctx[qp_ctx_id]; qp = ctx->qps[qp_ctx_id]; - qp->qp_ctx = qp_ctx; qp_ctx->qp = qp; qp_ctx->ctx = ctx;
@@ -644,14 +643,8 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id)if (ret) goto err_destroy_idr; - ret =hisi_qm_start_qp (qp,0 ); -if (ret <0 ) - goto err_resource_free; -return 0 ; -err_resource_free: -sec_free_qp_ctx_resource (ctx, qp_ctx); err_destroy_idr:idr_destroy (&qp_ctx->req_idr);return ret;
@@ -660,7 +653,6 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id)static void sec_release_qp_ctx (struct sec_ctx *ctx,struct sec_qp_ctx *qp_ctx) { -hisi_qm_stop_qp (qp_ctx->qp);sec_free_qp_ctx_resource (ctx, qp_ctx);idr_destroy (&qp_ctx->req_idr); }
drivers/crypto/hisilicon/zip/zip_crypto.c +6 -37
72 lines not on this page · raw message
include/linux/hisi_acc_qm.h +0 -1
@@ -463,7 +463,6 @@ struct hisi_qp {struct hisi_qp_status qp_status;struct hisi_qp_ops *hw_ops; -void *qp_ctx;void (*req_cb)(struct hisi_qp *qp,void *data);void (*event_cb)(struct hisi_qp *qp);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 81/641 crypto: hisilicon/hpre - support the hpre algorithm fallback
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weili Qian <[email protected]>
[ Upstream commit 6aff4d977e2d582c5d6ff6afd5646c1a459490fa ]
When all hardware queues are busy and no shareable queue, new processes fail to apply for queues. To avoid affecting tasks, support fallback mechanism when hardware queues are unavailable.
HPRE driver supports DH algorithm, limited to prime numbers up to 4K. It supports prime numbers larger than 4K via fallback mechanism.
--- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 238 ++++++++++++++++---- 1 file changed, 199 insertions(+), 39 deletions(-)
drivers/crypto/hisilicon/hpre/hpre_crypto.c +199 -39
@@ -93,6 +93,7 @@ struct hpre_dh_ctx {char *g;/* m */ dma_addr_t dma_g; +struct crypto_kpp *soft_tfm; };struct hpre_ecdh_ctx {
@@ -103,6 +104,7 @@ struct hpre_ecdh_ctx {/* low address: x->y */ unsigned char *g;dma_addr_t dma_g; +struct crypto_kpp *soft_tfm; };struct hpre_ctx {
@@ -120,6 +122,7 @@ struct hpre_ctx {unsigned int curve_id;/* for high performance core */ u8 enable_hpcore; +bool fallback; };struct hpre_asym_request {
@@ -382,8 +385,10 @@ static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type)struct hpre *hpre; qp =hpre_create_qp (type); -if (!qp) +if (!qp) { + ctx->qp =NULL ;return -ENODEV ; + } qp->req_cb = hpre_alg_cb; ctx->qp = qp;
@@ -509,6 +514,48 @@ static int hpre_dh_compute_value(struct kpp_request *req)return ret; } +static struct kpp_request *hpre_dh_prepare_fb_req (struct kpp_request *req) +{ +struct kpp_request *fb_req =kpp_request_ctx (req); +struct crypto_kpp *tfm =crypto_kpp_reqtfm (req); +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); + +kpp_request_set_tfm (fb_req, ctx->dh.soft_tfm); +kpp_request_set_callback (fb_req, req->base.flags, req->base.complete, req->base.data); +kpp_request_set_input (fb_req, req->src, req->src_len); +kpp_request_set_output (fb_req, req->dst, req->dst_len); + +return fb_req; +} + +static int hpre_dh_generate_public_key (struct kpp_request *req) +{ +struct crypto_kpp *tfm =crypto_kpp_reqtfm (req); +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +struct kpp_request *fb_req; + +if (ctx->fallback) { + fb_req =hpre_dh_prepare_fb_req (req); +return crypto_kpp_generate_public_key (fb_req); + } + +return hpre_dh_compute_value (req); +} + +static int hpre_dh_compute_shared_secret (struct kpp_request *req) +{ +struct crypto_kpp *tfm =crypto_kpp_reqtfm (req); +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +struct kpp_request *fb_req; + +if (ctx->fallback) { + fb_req =hpre_dh_prepare_fb_req (req); +return crypto_kpp_compute_shared_secret (fb_req); + } + +return hpre_dh_compute_value (req); +} +static int hpre_is_dh_params_length_valid (unsigned int key_sz) {#define _HPRE_DH_GRP1 768
@@ -535,13 +582,6 @@ static int hpre_dh_set_params(struct hpre_ctx *ctx, struct dh *params)struct device *dev = ctx->dev;unsigned int sz; -if (params->p_size >HPRE_DH_MAX_P_SZ ) -return -EINVAL ; - -if (hpre_is_dh_params_length_valid (params->p_size << -HPRE_BITS_2_BYTES_SHIFT )) -return -EINVAL ; - sz = ctx->key_sz = params->p_size; ctx->dh.xa_p =dma_alloc_coherent (dev, sz <<1 , &ctx->dh.dma_xa_p,GFP_KERNEL );
@@ -574,6 +614,9 @@ static void hpre_dh_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)struct device *dev = ctx->dev;unsigned int sz = ctx->key_sz; +if (!ctx->qp) +return ; +if (ctx->dh.g) {dma_free_coherent (dev, sz, ctx->dh.g, ctx->dh.dma_g); ctx->dh.g =NULL ;
@@ -599,6 +642,13 @@ static int hpre_dh_set_secret(struct crypto_kpp *tfm, const void *buf,if (crypto_dh_decode_key (buf, len, ¶ms) <0 )return -EINVAL ; +if (!ctx->qp) + goto set_soft_secret; + +if (hpre_is_dh_params_length_valid (params.p_size << +HPRE_BITS_2_BYTES_SHIFT )) + goto set_soft_secret; +/* Free old secret if any */ hpre_dh_clear_ctx (ctx, false);
@@ -609,27 +659,55 @@ static int hpre_dh_set_secret(struct crypto_kpp *tfm, const void *buf,memcpy (ctx->dh.xa_p + (ctx->key_sz - params.key_size), params.key, params.key_size); + ctx->fallback = false;return 0 ; err_clear_ctx:hpre_dh_clear_ctx (ctx, false);return ret; +set_soft_secret: + ctx->fallback = true; +return crypto_kpp_set_secret (ctx->dh.soft_tfm, buf, len); }static unsigned int hpre_dh_max_size (struct crypto_kpp *tfm) {struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +if (ctx->fallback) +return crypto_kpp_maxsize (ctx->dh.soft_tfm); +return ctx->key_sz; }static int hpre_dh_init_tfm (struct crypto_kpp *tfm) {struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +const char *alg =kpp_alg_name (tfm); +unsigned int reqsize; +int ret; + + ctx->dh.soft_tfm =crypto_alloc_kpp (alg,0 ,CRYPTO_ALG_NEED_FALLBACK ); +if (IS_ERR (ctx->dh.soft_tfm)) { +pr_err ("Failed to alloc dh tfm!\n" ); +return PTR_ERR (ctx->dh.soft_tfm); + } + +crypto_kpp_set_flags (ctx->dh.soft_tfm,crypto_kpp_get_flags (tfm)); + + reqsize =max (sizeof (struct hpre_asym_request ) +hpre_align_pd (), +sizeof (struct kpp_request ) +crypto_kpp_reqsize (ctx->dh.soft_tfm)); +kpp_set_reqsize (tfm, reqsize); -kpp_set_reqsize (tfm,sizeof (struct hpre_asym_request ) +hpre_align_pd ()); + ret =hpre_ctx_init (ctx,HPRE_V2_ALG_TYPE ); +if (ret && ret != -ENODEV ) { +crypto_free_kpp (ctx->dh.soft_tfm); +return ret; + }else if (ret == -ENODEV ) { + ctx->fallback = true; + } -return hpre_ctx_init (ctx,HPRE_V2_ALG_TYPE ); +return 0 ; }static void hpre_dh_exit_tfm (struct crypto_kpp *tfm)
@@ -637,6 +715,7 @@ static void hpre_dh_exit_tfm(struct crypto_kpp *tfm)struct hpre_ctx *ctx =kpp_tfm_ctx (tfm);hpre_dh_clear_ctx (ctx, true); +crypto_free_kpp (ctx->dh.soft_tfm); }static void hpre_rsa_drop_leading_zeros (const char **ptr,size_t *len)
@@ -676,9 +755,8 @@ static int hpre_rsa_enc(struct akcipher_request *req)struct hpre_sqe *msg = &hpre_req->req;int ret; -/* For 512 and 1536 bits key size, use soft tfm instead */ -if (ctx->key_sz ==HPRE_RSA_512BITS_KSZ || - ctx->key_sz ==HPRE_RSA_1536BITS_KSZ ) { +/* For unsupported key size and unavailable devices, use soft tfm instead */ +if (ctx->fallback) {akcipher_request_set_tfm (req, ctx->rsa.soft_tfm); ret =crypto_akcipher_encrypt (req);akcipher_request_set_tfm (req, tfm);
@@ -723,9 +801,8 @@ static int hpre_rsa_dec(struct akcipher_request *req)struct hpre_sqe *msg = &hpre_req->req;int ret; -/* For 512 and 1536 bits key size, use soft tfm instead */ -if (ctx->key_sz ==HPRE_RSA_512BITS_KSZ || - ctx->key_sz ==HPRE_RSA_1536BITS_KSZ ) { +/* For unsupported key size and unavailable devices, use soft tfm instead */ +if (ctx->fallback) {akcipher_request_set_tfm (req, ctx->rsa.soft_tfm); ret =crypto_akcipher_decrypt (req);akcipher_request_set_tfm (req, tfm);
@@ -778,8 +855,10 @@ static int hpre_rsa_set_n(struct hpre_ctx *ctx, const char *value, ctx->key_sz = vlen;/* if invalid key size provided, we use software tfm */ -if (!hpre_rsa_key_size_is_support (ctx->key_sz)) +if (!hpre_rsa_key_size_is_support (ctx->key_sz)) { + ctx->fallback = true;return 0 ; + } ctx->rsa.pubkey = dma_alloc_coherent(ctx->dev, vlen << 1, &ctx->rsa.dma_pubkey,
@@ -914,6 +993,9 @@ static void hpre_rsa_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)unsigned int half_key_sz = ctx->key_sz >>1 ;struct device *dev = ctx->dev; +if (!ctx->qp) +return ; +if (ctx->rsa.pubkey) {dma_free_coherent (dev, ctx->key_sz <<1 , ctx->rsa.pubkey, ctx->rsa.dma_pubkey);
@@ -993,6 +1075,7 @@ static int hpre_rsa_setkey(struct hpre_ctx *ctx, const void *key, goto free; } + ctx->fallback = false;return 0 ; free:
@@ -1010,6 +1093,9 @@ static int hpre_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,if (ret)return ret; +if (!ctx->qp) +return 0 ; +return hpre_rsa_setkey (ctx, key, keylen, false); }
@@ -1023,6 +1109,9 @@ static int hpre_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,if (ret)return ret; +if (!ctx->qp) +return 0 ; +return hpre_rsa_setkey (ctx, key, keylen, true); }
@@ -1030,9 +1119,8 @@ static unsigned int hpre_rsa_max_size(struct crypto_akcipher *tfm) {struct hpre_ctx *ctx =akcipher_tfm_ctx (tfm); -/* For 512 and 1536 bits key size, use soft tfm instead */ -if (ctx->key_sz ==HPRE_RSA_512BITS_KSZ || - ctx->key_sz ==HPRE_RSA_1536BITS_KSZ ) +/* For unsupported key size and unavailable devices, use soft tfm instead */ +if (ctx->fallback)return crypto_akcipher_maxsize (ctx->rsa.soft_tfm);return ctx->key_sz;
@@ -1053,10 +1141,14 @@ static int hpre_rsa_init_tfm(struct crypto_akcipher *tfm) hpre_align_pd()); ret =hpre_ctx_init (ctx,HPRE_V2_ALG_TYPE ); -if (ret) +if (ret && ret != -ENODEV ) {crypto_free_akcipher (ctx->rsa.soft_tfm); +return ret; + }else if (ret == -ENODEV ) { + ctx->fallback = true; + } -return ret; +return 0 ; }static void hpre_rsa_exit_tfm (struct crypto_akcipher *tfm)
@@ -1260,6 +1352,9 @@ static int hpre_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,struct ecdh params;int ret; +if (ctx->fallback) +return crypto_kpp_set_secret (ctx->ecdh.soft_tfm, buf, len); +if (crypto_ecdh_decode_key (buf, len, ¶ms) <0 ) {dev_err (dev,"failed to decode ecdh key!\n" );return -EINVAL ;
@@ -1485,23 +1580,82 @@ static int hpre_ecdh_compute_value(struct kpp_request *req)return ret; } +static int hpre_ecdh_generate_public_key (struct kpp_request *req) +{ +struct crypto_kpp *tfm =crypto_kpp_reqtfm (req); +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +int ret; + +if (ctx->fallback) { +kpp_request_set_tfm (req, ctx->ecdh.soft_tfm); + ret =crypto_kpp_generate_public_key (req); +kpp_request_set_tfm (req, tfm); +return ret; + } + +return hpre_ecdh_compute_value (req); +} + +static int hpre_ecdh_compute_shared_secret (struct kpp_request *req) +{ +struct crypto_kpp *tfm =crypto_kpp_reqtfm (req); +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +int ret; + +if (ctx->fallback) { +kpp_request_set_tfm (req, ctx->ecdh.soft_tfm); + ret =crypto_kpp_compute_shared_secret (req); +kpp_request_set_tfm (req, tfm); +return ret; + } + +return hpre_ecdh_compute_value (req); +} +static unsigned int hpre_ecdh_max_size (struct crypto_kpp *tfm) {struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +if (ctx->fallback) +return crypto_kpp_maxsize (ctx->ecdh.soft_tfm); +/* max size is the pub_key_size, include x and y */ return ctx->key_sz <<1 ; } +static int hpre_ecdh_init_tfm (struct crypto_kpp *tfm) +{ +struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +const char *alg =kpp_alg_name (tfm); +int ret; + + ret =hpre_ctx_init (ctx,HPRE_V3_ECC_ALG_TYPE ); +if (!ret) { +kpp_set_reqsize (tfm,sizeof (struct hpre_asym_request ) +hpre_align_pd ()); +return 0 ; + }else if (ret && ret != -ENODEV ) { +return ret; + } + + ctx->ecdh.soft_tfm =crypto_alloc_kpp (alg,0 ,CRYPTO_ALG_NEED_FALLBACK ); +if (IS_ERR (ctx->ecdh.soft_tfm)) { +pr_err ("Failed to alloc %s tfm!\n" , alg); +return PTR_ERR (ctx->ecdh.soft_tfm); + } + +crypto_kpp_set_flags (ctx->ecdh.soft_tfm,crypto_kpp_get_flags (tfm)); + ctx->fallback = true; + +return 0 ; +} +static int hpre_ecdh_nist_p192_init_tfm (struct crypto_kpp *tfm) {struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); ctx->curve_id =ECC_CURVE_NIST_P192 ; -kpp_set_reqsize (tfm,sizeof (struct hpre_asym_request ) +hpre_align_pd ()); - -return hpre_ctx_init (ctx,HPRE_V3_ECC_ALG_TYPE ); +return hpre_ecdh_init_tfm (tfm); }static int hpre_ecdh_nist_p256_init_tfm (struct crypto_kpp *tfm)
@@ -1511,9 +1665,7 @@ static int hpre_ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm) ctx->curve_id =ECC_CURVE_NIST_P256 ; ctx->enable_hpcore =1 ; -kpp_set_reqsize (tfm,sizeof (struct hpre_asym_request ) +hpre_align_pd ()); - -return hpre_ctx_init (ctx,HPRE_V3_ECC_ALG_TYPE ); +return hpre_ecdh_init_tfm (tfm); }static int hpre_ecdh_nist_p384_init_tfm (struct crypto_kpp *tfm)
@@ -1522,15 +1674,18 @@ static int hpre_ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm) ctx->curve_id =ECC_CURVE_NIST_P384 ; -kpp_set_reqsize (tfm,sizeof (struct hpre_asym_request ) +hpre_align_pd ()); - -return hpre_ctx_init (ctx,HPRE_V3_ECC_ALG_TYPE ); +return hpre_ecdh_init_tfm (tfm); }static void hpre_ecdh_exit_tfm (struct crypto_kpp *tfm) {struct hpre_ctx *ctx =kpp_tfm_ctx (tfm); +if (ctx->fallback) { +crypto_free_kpp (ctx->ecdh.soft_tfm); +return ; + } +hpre_ecc_clear_ctx (ctx, true); }
@@ -1548,13 +1703,14 @@ static struct akcipher_alg rsa = { .cra_name = "rsa", .cra_driver_name = "hpre-rsa", .cra_module = THIS_MODULE, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, }, };static struct kpp_alg dh = { .set_secret = hpre_dh_set_secret, - .generate_public_key = hpre_dh_compute_value, - .compute_shared_secret = hpre_dh_compute_value, + .generate_public_key = hpre_dh_generate_public_key, + .compute_shared_secret = hpre_dh_compute_shared_secret, .max_size = hpre_dh_max_size, .init = hpre_dh_init_tfm, .exit = hpre_dh_exit_tfm,
@@ -1564,14 +1720,15 @@ static struct kpp_alg dh = { .cra_name = "dh", .cra_driver_name = "hpre-dh", .cra_module = THIS_MODULE, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, }, };static struct kpp_alg ecdh_curves[] = { { .set_secret = hpre_ecdh_set_secret, - .generate_public_key = hpre_ecdh_compute_value, - .compute_shared_secret = hpre_ecdh_compute_value, + .generate_public_key = hpre_ecdh_generate_public_key, + .compute_shared_secret = hpre_ecdh_compute_shared_secret, .max_size = hpre_ecdh_max_size, .init = hpre_ecdh_nist_p192_init_tfm, .exit = hpre_ecdh_exit_tfm,
@@ -1581,11 +1738,12 @@ static struct kpp_alg ecdh_curves[] = { .cra_name = "ecdh-nist-p192", .cra_driver_name = "hpre-ecdh-nist-p192", .cra_module = THIS_MODULE, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, }, }, { .set_secret = hpre_ecdh_set_secret, - .generate_public_key = hpre_ecdh_compute_value, - .compute_shared_secret = hpre_ecdh_compute_value, + .generate_public_key = hpre_ecdh_generate_public_key, + .compute_shared_secret = hpre_ecdh_compute_shared_secret, .max_size = hpre_ecdh_max_size, .init = hpre_ecdh_nist_p256_init_tfm, .exit = hpre_ecdh_exit_tfm,
@@ -1595,11 +1753,12 @@ static struct kpp_alg ecdh_curves[] = { .cra_name = "ecdh-nist-p256", .cra_driver_name = "hpre-ecdh-nist-p256", .cra_module = THIS_MODULE, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, }, }, { .set_secret = hpre_ecdh_set_secret, - .generate_public_key = hpre_ecdh_compute_value, - .compute_shared_secret = hpre_ecdh_compute_value, + .generate_public_key = hpre_ecdh_generate_public_key, + .compute_shared_secret = hpre_ecdh_compute_shared_secret, .max_size = hpre_ecdh_max_size, .init = hpre_ecdh_nist_p384_init_tfm, .exit = hpre_ecdh_exit_tfm,
@@ -1609,6 +1768,7 @@ static struct kpp_alg ecdh_curves[] = { .cra_name = "ecdh-nist-p384", .cra_driver_name = "hpre-ecdh-nist-p384", .cra_module = THIS_MODULE, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, }, } };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 82/641 crypto: hisilicon/sec2 - support skcipher/aead fallback for hardware queue unavailable
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Tao <[email protected]>
[ Upstream commit e7507439628052363500d717caffb5c2241854dc ]
When all hardware queues are busy and no shareable queue, new processes fail to apply for queues. To avoid affecting tasks, support fallback mechanism when hardware queues are unavailable.
--- drivers/crypto/hisilicon/sec2/sec_crypto.c | 62 ++++++++++++++++------ 1 file changed, 47 insertions(+), 15 deletions(-)
drivers/crypto/hisilicon/sec2/sec_crypto.c +47 -15
@@ -663,10 +663,8 @@ static int sec_ctx_base_init(struct sec_ctx *ctx)int i, ret; ctx->qps =sec_create_qps (); -if (!ctx->qps) { -pr_err ("Can not create sec qps!\n" ); +if (!ctx->qps)return -ENODEV ; - } sec = container_of(ctx->qps[0]->qm, struct sec_dev, qm); ctx->sec = sec;
@@ -702,6 +700,9 @@ static void sec_ctx_base_uninit(struct sec_ctx *ctx) {int i; +if (!ctx->qps) +return ; +for (i =0 ; i < ctx->sec->ctx_q_num; i++)sec_release_qp_ctx (ctx, &ctx->qp_ctx[i]);
@@ -713,6 +714,9 @@ static int sec_cipher_init(struct sec_ctx *ctx) {struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; +if (!ctx->qps) +return 0 ; + c_ctx->c_key =dma_alloc_coherent (ctx->dev,SEC_MAX_KEY_SIZE , &c_ctx->c_key_dma,GFP_KERNEL );if (!c_ctx->c_key)
@@ -725,6 +729,9 @@ static void sec_cipher_uninit(struct sec_ctx *ctx) {struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; +if (!ctx->qps) +return ; +memzero_explicit (c_ctx->c_key,SEC_MAX_KEY_SIZE );dma_free_coherent (ctx->dev,SEC_MAX_KEY_SIZE , c_ctx->c_key, c_ctx->c_key_dma);
@@ -746,6 +753,9 @@ static void sec_auth_uninit(struct sec_ctx *ctx) {struct sec_auth_ctx *a_ctx = &ctx->a_ctx; +if (!ctx->qps) +return ; +memzero_explicit (a_ctx->a_key,SEC_MAX_AKEY_SIZE );dma_free_coherent (ctx->dev,SEC_MAX_AKEY_SIZE , a_ctx->a_key, a_ctx->a_key_dma);
@@ -783,7 +793,7 @@ static int sec_skcipher_init(struct crypto_skcipher *tfm) } ret =sec_ctx_base_init (ctx); -if (ret) +if (ret && ret != -ENODEV )return ret; ret =sec_cipher_init (ctx);
@@ -892,6 +902,9 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,struct device *dev = ctx->dev;int ret; +if (!ctx->qps) + goto set_soft_key; +if (c_mode ==SEC_CMODE_XTS ) { ret =xts_verify_key (tfm, key, keylen);if (ret) {
@@ -922,13 +935,14 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, }memcpy (c_ctx->c_key, key, keylen); -if (c_ctx->fbtfm) { - ret =crypto_sync_skcipher_setkey (c_ctx->fbtfm, key, keylen); -if (ret) { -dev_err (dev,"failed to set fallback skcipher key!\n" ); -return ret; - } + +set_soft_key: + ret =crypto_sync_skcipher_setkey (c_ctx->fbtfm, key, keylen); +if (ret) { +dev_err (dev,"failed to set fallback skcipher key!\n" ); +return ret; } +return 0 ; }
@@ -1392,6 +1406,9 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,struct crypto_authenc_keys keys;int ret; +if (!ctx->qps) +return sec_aead_fallback_setkey (a_ctx, tfm, key, keylen); + ctx->a_ctx.a_alg = a_alg; ctx->c_ctx.c_alg = c_alg; c_ctx->c_mode = c_mode;
@@ -2048,6 +2065,9 @@ static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm)if (ret)return ret; +if (!ctx->qps) +return 0 ; +if (ctx->sec->qm.ver <QM_HW_V3 ) { ctx->type_supported =SEC_BD_TYPE2 ; ctx->req_op = &sec_skcipher_req_ops;
@@ -2056,7 +2076,7 @@ static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm) ctx->req_op = &sec_skcipher_req_ops_v3; } -return ret; +return 0 ; }static void sec_skcipher_ctx_exit (struct crypto_skcipher *tfm)
@@ -2124,7 +2144,7 @@ static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name)int ret; ret =sec_aead_init (tfm); -if (ret) { +if (ret && ret != -ENODEV ) {pr_err ("hisi_sec2: aead init error!\n" );return ret; }
@@ -2166,7 +2186,7 @@ static int sec_aead_xcm_ctx_init(struct crypto_aead *tfm)int ret; ret =sec_aead_init (tfm); -if (ret) { +if (ret && ret != -ENODEV ) {dev_err (ctx->dev,"hisi_sec2: aead xcm init error!\n" );return ret; }
@@ -2311,6 +2331,9 @@ static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt)bool need_fallback = false;int ret; +if (!ctx->qps) + goto soft_crypto; +if (!sk_req->cryptlen) {if (ctx->c_ctx.c_mode ==SEC_CMODE_XTS )return -EINVAL ;
@@ -2328,9 +2351,12 @@ static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt)return -EINVAL ;if (unlikely (ctx->c_ctx.fallback || need_fallback)) -return sec_skcipher_soft_crypto (ctx, sk_req, encrypt); + goto soft_crypto;return ctx->req_op->process (ctx, req); + +soft_crypto: +return sec_skcipher_soft_crypto (ctx, sk_req, encrypt); }static int sec_skcipher_encrypt (struct skcipher_request *sk_req)
@@ -2538,6 +2564,9 @@ static int sec_aead_crypto(struct aead_request *a_req, bool encrypt)bool need_fallback = false;int ret; +if (!ctx->qps) + goto soft_crypto; + req->flag = a_req->base.flags; req->aead_req.aead_req = a_req; req->c_req.encrypt = encrypt;
@@ -2548,11 +2577,14 @@ static int sec_aead_crypto(struct aead_request *a_req, bool encrypt) ret =sec_aead_param_check (ctx, req, &need_fallback);if (unlikely (ret)) {if (need_fallback) -return sec_aead_soft_crypto (ctx, a_req, encrypt); + goto soft_crypto;return -EINVAL ; }return ctx->req_op->process (ctx, req); + +soft_crypto: +return sec_aead_soft_crypto (ctx, a_req, encrypt); }static int sec_aead_encrypt (struct aead_request *a_req)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 83/641 crypto: hisilicon/sgl - fix inconsistent map/unmap direction issue
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
[ Upstream commit 4154f7d3b1c133b909d20c44ecb8277e8482aa6b ]
Ensure that the direction for dma_map_sg and dma_unmap_sg is consistent.
--- drivers/crypto/hisilicon/sgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/hisilicon/sgl.c +1 -1
@@ -265,7 +265,7 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev, struct scatterlist *sgl,return curr_hw_sgl; err_unmap: -dma_unmap_sg (dev, sgl, sg_n,DMA_BIDIRECTIONAL ); +dma_unmap_sg (dev, sgl, sg_n, dir);return ERR_PTR (ret); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 84/641 bpf: Preserve id of register in sync_linked_regs()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Puranjay Mohan <[email protected]>
[ Upstream commit af9e89d8dd39530c8bd14c33ddf6b502df1071b6 ]
sync_linked_regs() copies the id of known_reg to reg when propagating bounds of known_reg to reg using the off of known_reg, but when known_reg was linked to reg like:
known_reg = reg ; both known_reg and reg get same idknown_reg += 4 ; known_reg gets off = 4, and its id gets BPF_ADD_CONST
now when a call to sync_linked_regs() happens, let's say with the following:
if known_reg >= 10 goto pc+2
known_reg's new bounds are propagated to reg but now reg gets BPF_ADD_CONST from the copy.
This means if another link to reg is created like:
another_reg = reg ; another_reg should get the id of reg but
assign_scalar_id_before_mov() sees BPF_ADD_CONST on reg and assigns a new id to it.
As reg has a new id now, known_reg's link to reg is broken. If we find new bounds for known_reg, they will not be propagated to reg.
This can be seen in the selftest added in the next commit:
0: (85) call bpf_get_prandom_u32#7 ; R0=scalar() 1: (57) r0 &= 255 ; R0=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) 2: (bf) r1 = r0 ; R0=scalar(id=1,smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) R1=scalar(id=1,smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) 3: (07) r1 += 4 ; R1=scalar(id=1+4,smin=umin=smin32=umin32=4,smax=umax=smax32=umax32=259,var_off=(0x0; 0x1ff)) 4: (a5) if r1 < 0xa goto pc+4 ; R1=scalar(id=1+4,smin=umin=smin32=umin32=10,smax=umax=smax32=umax32=259,var_off=(0x0; 0x1ff)) 5: (bf) r2 = r0 ; R0=scalar(id=2,smin=umin=smin32=umin32=6,smax=umax=smax32=umax32=255) R2=scalar(id=2,smin=umin=smin32=umin32=6,smax=umax=smax32=umax32=255) 6: (a5) if r1 < 0xe goto pc+2 ; R1=scalar(id=1+4,smin=umin=smin32=umin32=14,smax=umax=smax32=umax32=259,var_off=(0x0; 0x1ff)) 7: (35) if r0 >= 0xa goto pc+1 ; R0=scalar(id=2,smin=umin=smin32=umin32=6,smax=umax=smax32=umax32=9,var_off=(0x0; 0xf))
8: (37) r0 /= 0
div by zero
When 4 is verified, r1's bounds are propagated to r0 but r0 also gets BPF_ADD_CONST (bug).
When 5 is verified, r0 gets a new id (2) and its link with r1 is broken.
After 6 we know r1 has bounds [14, 259] and therefore r0 should have bounds [10, 255], therefore the branch at 7 is always taken. But because r0's id was changed to 2, r1's new bounds are not propagated to r0. The verifier still thinks r0 has bounds [6, 255] before 7 and execution can reach div by zero.
Fix this by preserving id in sync_linked_regs() like off and subreg_def.
--- kernel/bpf/verifier.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +3 -1
@@ -16715,6 +16715,7 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s }else {s32 saved_subreg_def = reg->subreg_def;s32 saved_off = reg->off; +u32 saved_id = reg->id; fake_reg.type =SCALAR_VALUE ;__mark_reg_known (&fake_reg, (s32 )reg->off - (s32 )known_reg->off);
@@ -16722,10 +16723,11 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s/* reg = known_reg; reg += delta */ copy_register_state (reg, known_reg);/* -* Must preserve off, id and add_const flag, +* Must preserve off, id and subreg_def flag, * otherwise another sync_linked_regs() will be incorrect. */ reg->off = saved_off; + reg->id = saved_id; reg->subreg_def = saved_subreg_def;scalar32_min_max_add (reg, &fake_reg);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 85/641 bpf: Fix memory access flags in helper prototypes
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zesen Liu <[email protected]>
[ Upstream commit 802eef5afb1865bc5536a5302c068ba2215a1f72 ]
After commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking"), the verifier started relying on the access type flags in helper function prototypes to perform memory access optimizations.
Currently, several helper functions utilizing ARG_PTR_TO_MEM lack the corresponding MEM_RDONLY or MEM_WRITE flags. This omission causes the verifier to incorrectly assume that the buffer contents are unchanged across the helper call. Consequently, the verifier may optimize away subsequent reads based on this wrong assumption, leading to correctness issues.
For bpf_get_stack_proto_raw_tp, the original MEM_RDONLY was incorrect since the helper writes to the buffer. Change it to ARG_PTR_TO_UNINIT_MEM which correctly indicates write access to potentially uninitialized memory.
Similar issues were recently addressed for specific helpers in commit ac44dcc788b9 ("bpf: Fix verifier assumptions of bpf_d_path's output buffer") and commit 2eb7648558a7 ("bpf: Specify access type of bpf_sysctl_get_name args").
Fix these prototypes by adding the correct memory access flags.
--- kernel/bpf/helpers.c | 2 +- kernel/bpf/syscall.c | 2 +- kernel/trace/bpf_trace.c | 6 +++--- net/core/filter.c | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-)
kernel/bpf/helpers.c +1 -1
@@ -1080,7 +1080,7 @@ const struct bpf_func_proto bpf_snprintf_proto = { .func = bpf_snprintf, .gpl_only = true, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM_OR_NULL, + .arg1_type = ARG_PTR_TO_MEM_OR_NULL | MEM_WRITE, .arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg3_type = ARG_PTR_TO_CONST_STR, .arg4_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY,
kernel/bpf/syscall.c +1 -1
@@ -6396,7 +6396,7 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = { .func = bpf_kallsyms_lookup_name, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM, + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg3_type = ARG_ANYTHING, .arg4_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
kernel/trace/bpf_trace.c +3 -3
@@ -1022,7 +1022,7 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = { .func = bpf_snprintf_btf, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM, + .arg1_type = ARG_PTR_TO_MEM | MEM_WRITE, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg4_type = ARG_CONST_SIZE,
@@ -1526,7 +1526,7 @@ static const struct bpf_func_proto bpf_read_branch_records_proto = { .gpl_only = true, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_MEM_OR_NULL, + .arg2_type = ARG_PTR_TO_MEM_OR_NULL | MEM_WRITE, .arg3_type = ARG_CONST_SIZE_OR_ZERO, .arg4_type = ARG_ANYTHING, };
@@ -1661,7 +1661,7 @@ static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = { .gpl_only = true, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg2_type = ARG_PTR_TO_UNINIT_MEM, .arg3_type = ARG_CONST_SIZE_OR_ZERO, .arg4_type = ARG_ANYTHING, };
net/core/filter.c +10 -10
@@ -6325,7 +6325,7 @@ static const struct bpf_func_proto bpf_xdp_fib_lookup_proto = { .gpl_only = true, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_WRITE, .arg3_type = ARG_CONST_SIZE, .arg4_type = ARG_ANYTHING, };
@@ -6380,7 +6380,7 @@ static const struct bpf_func_proto bpf_skb_fib_lookup_proto = { .gpl_only = true, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_WRITE, .arg3_type = ARG_CONST_SIZE, .arg4_type = ARG_ANYTHING, };
@@ -7934,9 +7934,9 @@ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv4_proto = { .gpl_only = true, /* __cookie_v4_init_sequence() is GPL */ .pkt_access = true, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg1_size = sizeof(struct iphdr), - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_CONST_SIZE_OR_ZERO, };
@@ -7966,9 +7966,9 @@ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv6_proto = { .gpl_only = true, /* __cookie_v6_init_sequence() is GPL */ .pkt_access = true, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg1_size = sizeof(struct ipv6hdr), - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_CONST_SIZE_OR_ZERO, };
@@ -7986,9 +7986,9 @@ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv4_proto = { .gpl_only = true, /* __cookie_v4_check is GPL */ .pkt_access = true, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg1_size = sizeof(struct iphdr), - .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg2_size = sizeof(struct tcphdr), };
@@ -8010,9 +8010,9 @@ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv6_proto = { .gpl_only = true, /* __cookie_v6_check is GPL */ .pkt_access = true, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg1_size = sizeof(struct ipv6hdr), - .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY, .arg2_size = sizeof(struct tcphdr), };#endif /* CONFIG_SYN_COOKIES */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 86/641 selftests/bpf: Fix resource leak in serial_test_wq on attach failure
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kery Qi <[email protected]>
[ Upstream commit a32ae2658471dd87a2f7a438388ed7d9a5767212 ]
When wq__attach() fails, serial_test_wq() returns early without calling wq__destroy(), leaking the skeleton resources allocated by wq__open_and_load(). This causes ASAN leak reports in selftests runs.
Fix this by jumping to a common clean_up label that calls wq__destroy() on all exit paths after successful open_and_load.
Note that the early return after wq__open_and_load() failure is correct and doesn't need fixing, since that function returns NULL on failure (after internally cleaning up any partial allocations).
--- tools/testing/selftests/bpf/prog_tests/wq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/prog_tests/wq.c +3 -2
@@ -16,12 +16,12 @@ void serial_test_wq(void)/* re-run the success test to check if the timer was actually executed */ wq_skel =wq__open_and_load (); -if (!ASSERT_OK_PTR (wq_skel,"wq_skel_load" )) +if (!ASSERT_OK_PTR (wq_skel,"wq__open_and_load" ))return ; err =wq__attach (wq_skel);if (!ASSERT_OK (err,"wq_attach" )) -return ; + goto clean_up; prog_fd =bpf_program__fd (wq_skel->progs.test_syscall_array_sleepable); err =bpf_prog_test_run_opts (prog_fd, &topts);
@@ -31,6 +31,7 @@ void serial_test_wq(void)usleep (50 );/* 10 usecs should be enough, but give it extra */ ASSERT_EQ (wq_skel->bss->ok_sleepable, (1 <<1 ),"ok_sleepable" ); +clean_up:wq__destroy (wq_skel); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 87/641 hrtimer: Fix trace oddity
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 5d6446f409da00e5a389125ddb5ce09f5bc404c9 ]
It turns out that __run_hrtimer() will trace like:
<idle>-0 [032] d.h2. 20705.474563: hrtimer_cancel: hrtimer=0xff2db8f77f8226e8
<idle>-0 [032] d.h1. 20705.474563: hrtimer_expire_entry: hrtimer=0xff2db8f77f8226e8 now=20699452001850 function=tick_nohz_handler/0x0Which is a bit nonsensical, the timer doesn't get canceled on expiration. The cause is the use of the incorrect debug helper.
--- kernel/time/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/hrtimer.c +1 -1
@@ -1742,7 +1742,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,lockdep_assert_held (&cpu_base->lock); -debug_deactivate (timer); +debug_hrtimer_deactivate (timer); base->running = timer;/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 88/641 crypto: inside-secure/eip93 - fix kernel panic in driver detach
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit b6e32ba6d32503440a3e3e16c8d0521cbb7e0c5d ]
During driver detach, the same hash algorithm is unregistered multiple times due to a wrong iterator.
--- drivers/crypto/inside-secure/eip93/eip93-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/inside-secure/eip93/eip93-main.c +1 -1
@@ -90,7 +90,7 @@ static void eip93_unregister_algs(unsigned int i)crypto_unregister_aead (&eip93_algs[j]->alg.aead);break ;case EIP93_ALG_TYPE_HASH : -crypto_unregister_ahash (&eip93_algs[i]->alg.ahash); +crypto_unregister_ahash (&eip93_algs[j]->alg.ahash);break ; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 89/641 crypto: ccp - Fix a case where SNP_SHUTDOWN is missed
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Lendacky <[email protected]>
[ Upstream commit 551120148b67e04527b405c5ec33a31593846ba4 ]
If page reclaim fails in sev_ioctl_do_snp_platform_status() and SNP was moved from UNINIT to INIT for the function, SNP is not moved back to UNINIT state. Additionally, SNP is not required to be initialized in order to execute the SNP_PLATFORM_STATUS command, so don't attempt to move to INIT state and let SNP_PLATFORM_STATUS report the status as is.
--- drivers/crypto/ccp/sev-dev.c | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-)
drivers/crypto/ccp/sev-dev.c +23 -23
@@ -2351,11 +2351,10 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)static int sev_ioctl_do_snp_platform_status (struct sev_issue_cmd *argp) {struct sev_device *sev = psp_master->sev_data; -bool shutdown_required = false;struct sev_data_snp_addr buf;struct page *status_page; -int ret, error;void *data; +int ret;if (!argp->data)return -EINVAL ;
@@ -2366,31 +2365,35 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) data =page_address (status_page); -if (!sev->snp_initialized) { - ret =snp_move_to_init_state (argp, &shutdown_required); -if (ret) - goto cleanup; - } -/* -* Firmware expects status page to be in firmware-owned state, otherwise -* it will report firmware error code INVALID_PAGE_STATE (0x1A). +* SNP_PLATFORM_STATUS can be executed in any SNP state. But if executed +* when SNP has been initialized, the status page must be firmware-owned. */ -if (rmp_mark_pages_firmware (__pa (data),1 , true)) { - ret = -EFAULT ; - goto cleanup; +if (sev->snp_initialized) { +/* +* Firmware expects the status page to be in Firmware state, +* otherwise it will report an error INVALID_PAGE_STATE. +*/ +if (rmp_mark_pages_firmware (__pa (data),1 , true)) { + ret = -EFAULT ; + goto cleanup; + } } buf.address =__psp_pa (data); ret =__sev_do_cmd_locked (SEV_CMD_SNP_PLATFORM_STATUS , &buf, &argp->error); -/* -* Status page will be transitioned to Reclaim state upon success, or -* left in Firmware state in failure. Use snp_reclaim_pages() to -* transition either case back to Hypervisor-owned state. -*/ -if (snp_reclaim_pages (__pa (data),1 , true)) -return -EFAULT ; +if (sev->snp_initialized) { +/* +* The status page will be in Reclaim state on success, or left +* in Firmware state on failure. Use snp_reclaim_pages() to +* transition either case back to Hypervisor-owned state. +*/ +if (snp_reclaim_pages (__pa (data),1 , true)) { +snp_leak_pages (__page_to_pfn (status_page),1 ); +return -EFAULT ; + } + }if (ret) goto cleanup;
@@ -2400,9 +2403,6 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) ret = -EFAULT ; cleanup: -if (shutdown_required) -__sev_snp_shutdown_locked (&error, false); -__free_pages (status_page,0 );return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 90/641 crypto: ccp - narrow scope of snp_range_list
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tycho Andersen (AMD) <[email protected]>
[ Upstream commit dc8ccab15081efc4f2c5a9fc7b209cd641d29177 ]
snp_range_list is only used in __sev_snp_init_locked() in the SNP_INIT_EX case, move the declaration there and add a __free() cleanup helper for it instead of waiting until shutdown.
--- drivers/crypto/ccp/sev-dev.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
drivers/crypto/ccp/sev-dev.c +1 -12
@@ -119,13 +119,6 @@ static size_t sev_es_tmr_size = SEV_TMR_SIZE;#define NV_LENGTH (32 * 1024)static void *sev_init_ex_buffer; -/* -* SEV_DATA_RANGE_LIST: -* Array containing range of pages that firmware transitions to HV-fixed -* page state. -*/ -static struct sev_data_range_list *snp_range_list; -static void __sev_firmware_shutdown (struct sev_device *sev,bool panic); static int snp_shutdown_on_panic(struct notifier_block *nb,
@@ -1365,6 +1358,7 @@ static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)static int __sev_snp_init_locked (int *error,unsigned int max_snp_asid) { + struct sev_data_range_list *snp_range_list __free(kfree) = NULL;struct psp_device *psp = psp_master;struct sev_data_snp_init_ex data;struct sev_device *sev;
@@ -2753,11 +2747,6 @@ static void __sev_firmware_shutdown(struct sev_device *sev, bool panic) sev_init_ex_buffer =NULL ; } -if (snp_range_list) { -kfree (snp_range_list); - snp_range_list =NULL ; - } -__sev_snp_shutdown_locked (&error, panic); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 91/641 hwrng: airoha - set rng quality to 900
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit c0008a29a006091d7f9d288620c2456afa23ff27 ]
Airoha uses RAW mode to collect noise from the TRNG. These appear to be unprocessed oscillations from the tero loop. For this reason, they do not have a perfect distribution and entropy. Simple noise compression reduces its size by 9%, so setting the quality to 900 seems reasonable. The same value is used by the downstream driver.
Compare the size before and after compression:
$ ls -l random_airoha* -rw-r--r-- 1 aleksander aleksander 76546048 Jan 3 23:43 random_airoha -rw-rw-r-- 1 aleksander aleksander 69783562 Jan 5 20:23 random_airoha.zip
FIPS test results:
$ cat random_airoha | rngtest -c 10000 rngtest 2.6 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests...
rngtest: bits received from input: 200000032
rngtest: FIPS 140-2 successes: 0
rngtest: FIPS 140-2 failures: 10000
rngtest: FIPS 140-2(2001-10-10) Monobit: 9957
rngtest: FIPS 140-2(2001-10-10) Poker: 10000
rngtest: FIPS 140-2(2001-10-10) Runs: 10000
rngtest: FIPS 140-2(2001-10-10) Long run: 4249
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=953.674; avg=27698.935; max=19073.486)Mibits/s
rngtest: FIPS tests speed: (min=59.791; avg=298.028; max=328.853)Mibits/s
rngtest: Program run time: 647638 microseconds
In general, these data look like real noise, but with lower entropy than expected.
--- drivers/char/hw_random/airoha-trng.c | 1 + 1 file changed, 1 insertion(+)
drivers/char/hw_random/airoha-trng.c +1 -0
@@ -212,6 +212,7 @@ static int airoha_trng_probe(struct platform_device *pdev) trng->rng.init = airoha_trng_init; trng->rng.cleanup = airoha_trng_cleanup; trng->rng.read = airoha_trng_read; + trng->rng.quality =900 ; ret =devm_hwrng_register (dev, &trng->rng);if (ret) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 92/641 rqspinlock: Fix TAS fallback lock entry creation
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 82f3b142c99cf44c7b1e70b7720169c646b9760f ]
The TAS fallback can be invoked directly when queued spin locks are disabled, and through the slow path when paravirt is enabled for queued spin locks. In the latter case, the res_spin_lock macro will attempt the fast path and already hold the entry when entering the slow path. This will lead to creation of extraneous entries that are not released, which may cause false positives for deadlock detection.
Fix this by always preceding invocation of the TAS fallback in every case with the grabbing of the held lock entry, and add a comment to make note of this.
--- include/asm-generic/rqspinlock.h | 2 +- kernel/bpf/rqspinlock.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-)
include/asm-generic/rqspinlock.h +1 -1
@@ -191,7 +191,7 @@ static __always_inline int res_spin_lock(rqspinlock_t *lock)#else -#define res_spin_lock (lock) resilient_tas_spin_lock(lock) +#define res_spin_lock (lock) ({ grab_held_lock_entry(lock); resilient_tas_spin_lock(lock); })#endif /* CONFIG_QUEUED_SPINLOCKS */
kernel/bpf/rqspinlock.c +4 -3
@@ -276,10 +276,11 @@ int __lockfunc resilient_tas_spin_lock(rqspinlock_t *lock)RES_INIT_TIMEOUT (ts);/* -* The fast path is not invoked for the TAS fallback, so we must grab -* the deadlock detection entry here. +* We are either called directly from res_spin_lock after grabbing the +* deadlock detection entry when queued spinlocks are disabled, or from +* resilient_queued_spin_lock_slowpath after grabbing the deadlock +* detection entry. No need to obtain it here. */ -grab_held_lock_entry (lock);/* * Since the waiting loop's time is dependent on the amount of
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 93/641 bpf, sockmap: Fix incorrect copied_seq calculation
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit b40cc5adaa80e1471095a62d78233b611d7a558c ]
A socket using sockmap has its own independent receive queue: ingress_msg. This queue may contain data from its own protocol stack or from other sockets.
The issue is that when reading from ingress_msg, we update tp->copied_seq by default. However, if the data is not from its own protocol stack, tcp->rcv_nxt is not increased. Later, if we convert this socket to a native socket, reading from this socket may fail because copied_seq might be significantly larger than rcv_nxt.
This fix also addresses the syzkaller-reported bug referenced in the Closes tag.
This patch marks the skmsg objects in ingress_msg. When reading, we update copied_seq only if the data is from its own protocol stack.
FD1:read()
-- FD1->copied_seq++
| [read data]
|
[enqueue data] v
[sockmap] -> ingress to self -> ingress_msg queue
FD1 native stack ------> ^
-- FD1->rcv_nxt++ -> redirect to other | [enqueue data]
| | | ingress to FD1
v ^
... | [sockmap]
FD2 native stack
--- include/linux/skmsg.h | 2 ++ net/core/skmsg.c | 27 ++++++++++++++++++++++++--- net/ipv4/tcp_bpf.c | 5 +++-- 3 files changed, 29 insertions(+), 5 deletions(-)
include/linux/skmsg.h +2 -0
@@ -141,6 +141,8 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct iov_iter *from, struct sk_msg *msg, u32 bytes);int sk_msg_recvmsg (struct sock *sk,struct sk_psock *psock,struct msghdr *msg,int len,int flags); +int __sk_msg_recvmsg (struct sock *sk,struct sk_psock *psock,struct msghdr *msg, +int len,int flags,int *copied_from_self);bool sk_msg_is_readable (struct sock *sk);static inline void sk_msg_check_to_free (struct sk_msg *msg,u32 i,u32 bytes)
net/core/skmsg.c +24 -3
@@ -409,22 +409,26 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct iov_iter *from, }EXPORT_SYMBOL_GPL (sk_msg_memcopy_from_iter); -/* Receive sk_msg from psock->ingress_msg to @msg. */ -int sk_msg_recvmsg (struct sock *sk,struct sk_psock *psock,struct msghdr *msg, -int len,int flags) +int __sk_msg_recvmsg (struct sock *sk,struct sk_psock *psock,struct msghdr *msg, +int len,int flags,int *copied_from_self) {struct iov_iter *iter = &msg->msg_iter;int peek = flags &MSG_PEEK ;struct sk_msg *msg_rx;int i, copied =0 ; +bool from_self; msg_rx =sk_psock_peek_msg (psock); +if (copied_from_self) + *copied_from_self =0 ; +while (copied != len) {struct scatterlist *sge;if (unlikely (!msg_rx))break ; + from_self = msg_rx->sk == sk; i = msg_rx->sg.start; do { struct page *page;
@@ -443,6 +447,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, } copied += copy; +if (from_self && copied_from_self) + *copied_from_self += copy; +if (likely (!peek)) { sge->offset += copy; sge->length -= copy;
@@ -487,6 +494,13 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, out:return copied; } + +/* Receive sk_msg from psock->ingress_msg to @msg. */ +int sk_msg_recvmsg (struct sock *sk,struct sk_psock *psock,struct msghdr *msg, +int len,int flags) +{ +return __sk_msg_recvmsg (sk, psock, msg, len, flags,NULL ); +}EXPORT_SYMBOL_GPL (sk_msg_recvmsg);bool sk_msg_is_readable (struct sock *sk)
@@ -616,6 +630,12 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skbif (unlikely (!msg))return -EAGAIN ;skb_set_owner_r (skb, sk); + +/* This is used in tcp_bpf_recvmsg_parser() to determine whether the +* data originates from the socket's own protocol stack. No need to +* refcount sk because msg's lifetime is bound to sk via the ingress_msg. +*/ + msg->sk = sk; err =sk_psock_skb_ingress_enqueue (skb, off, len, psock, sk, msg, take_ref);if (err <0 )kfree (msg);
@@ -909,6 +929,7 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock,sk_msg_compute_data_pointers (msg); msg->sk = sk; ret =bpf_prog_run_pin_on_cpu (prog, msg); + msg->sk =NULL ; ret =sk_psock_map_verd (ret, msg->sk_redir); psock->apply_bytes = msg->apply_bytes;if (ret == __SK_REDIRECT) {
net/ipv4/tcp_bpf.c +3 -2
@@ -226,6 +226,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,int peek = flags &MSG_PEEK ;struct sk_psock *psock;struct tcp_sock *tcp; +int copied_from_self =0 ;int copied =0 ;u32 seq;
@@ -262,7 +263,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk, } msg_bytes_ready: - copied =sk_msg_recvmsg (sk, psock, msg, len, flags); + copied =__sk_msg_recvmsg (sk, psock, msg, len, flags, &copied_from_self);/* The typical case for EFAULT is the socket was gracefully * shutdown with a FIN pkt. So check here the other case is * some error on copy_page_to_iter which would be unexpected.
@@ -277,7 +278,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk, goto out; } } - seq += copied; + seq += copied_from_self;if (!copied) {long timeo;int data;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 94/641 bpf, sockmap: Fix FIONREAD for sockmap
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 929e30f9312514902133c45e51c79088421ab084 ]
A socket using sockmap has its own independent receive queue: ingress_msg. This queue may contain data from its own protocol stack or from other sockets.
Therefore, for sockmap, relying solely on copied_seq and rcv_nxt to calculate FIONREAD is not enough.
This patch adds a new msg_tot_len field in the psock structure to record the data length in ingress_msg. Additionally, we implement new ioctl interfaces for TCP and UDP to intercept FIONREAD operations.
Note that we intentionally do not include sk_receive_queue data in the FIONREAD result. Data in sk_receive_queue has not yet been processed by the BPF verdict program, and may be redirected to other sockets or dropped. Including it would create semantic ambiguity since this data may never be readable by the user.
Unix and VSOCK sockets have similar issues, but fixing them is outside the scope of this patch as it would require more intrusive changes.
Previous work by John Fastabend made some efforts towards FIONREAD support:
commit e5c6de5fa025 ("bpf, sockmap: Incorrectly handling copied_seq") Although the current patch is based on the previous work by John Fastabend, it is acceptable for our Fixes tag to point to the same commit.
FD1:read()
-- FD1->copied_seq++
| [read data]
|
[enqueue data] v
[sockmap] -> ingress to self -> ingress_msg queue
FD1 native stack ------> ^
-- FD1->rcv_nxt++ -> redirect to other | [enqueue data]
| | | ingress to FD1
v ^
... | [sockmap]
FD2 native stack
--- include/linux/skmsg.h | 68 +++++++++++++++++++++++++++++++++++++++++-- net/core/skmsg.c | 3 ++ net/ipv4/tcp_bpf.c | 20 +++++++++++++ net/ipv4/udp_bpf.c | 23 ++++++++++++--- 4 files changed, 108 insertions(+), 6 deletions(-)
include/linux/skmsg.h +66 -2
@@ -97,6 +97,8 @@ struct sk_psock {struct sk_buff_head ingress_skb;struct list_head ingress_msg;spinlock_t ingress_lock; +/** @msg_tot_len: Total bytes queued in ingress_msg list. */ +u32 msg_tot_len;unsigned long state;struct list_head link;spinlock_t link_lock;
@@ -321,6 +323,27 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb)kfree_skb (skb); } +static inline u32 sk_psock_get_msg_len_nolock (struct sk_psock *psock) +{ +/* Used by ioctl to read msg_tot_len only; lock-free for performance */ +return READ_ONCE (psock->msg_tot_len); +} + +static inline void sk_psock_msg_len_add_locked (struct sk_psock *psock,int diff) +{ +/* Use WRITE_ONCE to ensure correct read in sk_psock_get_msg_len_nolock(). +* ingress_lock should be held to prevent concurrent updates to msg_tot_len +*/ +WRITE_ONCE (psock->msg_tot_len, psock->msg_tot_len + diff); +} + +static inline void sk_psock_msg_len_add (struct sk_psock *psock,int diff) +{ +spin_lock_bh (&psock->ingress_lock); +sk_psock_msg_len_add_locked (psock, diff); +spin_unlock_bh (&psock->ingress_lock); +} +static inline bool sk_psock_queue_msg (struct sk_psock *psock,struct sk_msg *msg) {
@@ -329,6 +352,7 @@ static inline bool sk_psock_queue_msg(struct sk_psock *psock,spin_lock_bh (&psock->ingress_lock);if (sk_psock_test_state (psock,SK_PSOCK_TX_ENABLED )) {list_add_tail (&msg->list, &psock->ingress_msg); +sk_psock_msg_len_add_locked (psock, msg->sg.size); ret = true; }else {sk_msg_free (psock->sk, msg);
@@ -345,18 +369,25 @@ static inline struct sk_msg *sk_psock_dequeue_msg(struct sk_psock *psock)spin_lock_bh (&psock->ingress_lock); msg = list_first_entry_or_null(&psock->ingress_msg, struct sk_msg, list); -if (msg) +if (msg) {list_del (&msg->list); +sk_psock_msg_len_add_locked (psock, -msg->sg.size); + }spin_unlock_bh (&psock->ingress_lock);return msg; } +static inline struct sk_msg *sk_psock_peek_msg_locked (struct sk_psock *psock) +{ + return list_first_entry_or_null(&psock->ingress_msg, struct sk_msg, list); +} +static inline struct sk_msg *sk_psock_peek_msg (struct sk_psock *psock) {struct sk_msg *msg;spin_lock_bh (&psock->ingress_lock); - msg = list_first_entry_or_null(&psock->ingress_msg, struct sk_msg, list); + msg =sk_psock_peek_msg_locked (psock);spin_unlock_bh (&psock->ingress_lock);return msg; }
@@ -523,6 +554,39 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock)return !!psock->saved_data_ready; } +/* for tcp only, sk is locked */ +static inline ssize_t sk_psock_msg_inq (struct sock *sk) +{ +struct sk_psock *psock; +ssize_t inq =0 ; + + psock =sk_psock_get (sk); +if (likely (psock)) { + inq =sk_psock_get_msg_len_nolock (psock); +sk_psock_put (sk, psock); + } +return inq; +} + +/* for udp only, sk is not locked */ +static inline ssize_t sk_msg_first_len (struct sock *sk) +{ +struct sk_psock *psock; +struct sk_msg *msg; +ssize_t inq =0 ; + + psock =sk_psock_get (sk); +if (likely (psock)) { +spin_lock_bh (&psock->ingress_lock); + msg =sk_psock_peek_msg_locked (psock); +if (msg) + inq = msg->sg.size; +spin_unlock_bh (&psock->ingress_lock); +sk_psock_put (sk, psock); + } +return inq; +} +#if IS_ENABLED (CONFIG_NET_SOCK_MSG )#define BPF_F_STRPARSER (1UL << 1)
net/core/skmsg.c +3 -0
@@ -458,6 +458,7 @@ int __sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msgatomic_sub (copy, &sk->sk_rmem_alloc); } msg_rx->sg.size -= copy; +sk_psock_msg_len_add (psock, -copy);if (!sge->length) {sk_msg_iter_var_next (i);
@@ -821,9 +822,11 @@ static void __sk_psock_purge_ingress_msg(struct sk_psock *psock)list_del (&msg->list);if (!msg->skb)atomic_sub (msg->sg.size, &psock->sk->sk_rmem_alloc); +sk_psock_msg_len_add (psock, -msg->sg.size);sk_msg_free (psock->sk, msg);kfree (msg); } +WARN_ON_ONCE (psock->msg_tot_len); }static void __sk_psock_zap_ingress (struct sk_psock *psock)
net/ipv4/tcp_bpf.c +20 -0
@@ -10,6 +10,7 @@#include <net/inet_common.h> #include <net/tls.h> +#include <asm/ioctls.h> void tcp_eat_skb (struct sock *sk,struct sk_buff *skb) {
@@ -332,6 +333,24 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,return copied; } +static int tcp_bpf_ioctl (struct sock *sk,int cmd,int *karg) +{ +bool slow; + +if (cmd !=SIOCINQ ) +return tcp_ioctl (sk, cmd, karg); + +/* works similar as tcp_ioctl */ +if (sk->sk_state ==TCP_LISTEN ) +return -EINVAL ; + + slow =lock_sock_fast (sk); + *karg =sk_psock_msg_inq (sk); +unlock_sock_fast (sk, slow); + +return 0 ; +} +static int tcp_bpf_recvmsg (struct sock *sk,struct msghdr *msg,size_t len,int flags,int *addr_len) {
@@ -610,6 +629,7 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS], prot[TCP_BPF_BASE ].close = sock_map_close; prot[TCP_BPF_BASE ].recvmsg = tcp_bpf_recvmsg; prot[TCP_BPF_BASE ].sock_is_readable = sk_msg_is_readable; + prot[TCP_BPF_BASE ].ioctl = tcp_bpf_ioctl; prot[TCP_BPF_TX ] = prot[TCP_BPF_BASE ]; prot[TCP_BPF_TX ].sendmsg = tcp_bpf_sendmsg;
net/ipv4/udp_bpf.c +19 -4
@@ -5,6 +5,7 @@#include <net/sock.h> #include <net/udp.h> #include <net/inet_common.h> +#include <asm/ioctls.h> #include "udp_impl.h"
@@ -111,12 +112,26 @@ enum {static DEFINE_SPINLOCK (udpv6_prot_lock);static struct proto udp_bpf_prots[UDP_BPF_NUM_PROTS ]; +static int udp_bpf_ioctl (struct sock *sk,int cmd,int *karg) +{ +if (cmd !=SIOCINQ ) +return udp_ioctl (sk, cmd, karg); + +/* Since we don't hold a lock, sk_receive_queue may contain data. +* BPF might only be processing this data at the moment. We only +* care about the data in the ingress_msg here. +*/ + *karg =sk_msg_first_len (sk); +return 0 ; +} +static void udp_bpf_rebuild_protos (struct proto *prot,const struct proto *base) { - *prot = *base; - prot->close = sock_map_close; - prot->recvmsg = udp_bpf_recvmsg; - prot->sock_is_readable = sk_msg_is_readable; + *prot = *base; + prot->close = sock_map_close; + prot->recvmsg = udp_bpf_recvmsg; + prot->sock_is_readable = sk_msg_is_readable; + prot->ioctl = udp_bpf_ioctl; }static void udp_bpf_check_v6_needs_rebuild (struct proto *ops)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 95/641 bpf: Fix tcx/netkit detach permissions when prog fd isnt given
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Gonnet <[email protected]>
[ Upstream commit ae23bc81ddf7c17b663c4ed1b21e35527b0a7131 ]
This commit fixes a security issue where BPF_PROG_DETACH on tcx or netkit devices could be executed by any user when no program fd was provided, bypassing permission checks. The fix adds a capability check for CAP_NET_ADMIN or CAP_SYS_ADMIN in this case.
--- include/linux/bpf.h | 5 +++++ include/linux/bpf_mprog.h | 10 ++++++++++ kernel/bpf/syscall.c | 7 ++----- 3 files changed, 17 insertions(+), 5 deletions(-)
include/linux/bpf.h +5 -0
@@ -3200,6 +3200,11 @@ static inline void bpf_prog_report_arena_violation(bool write, unsigned long add }#endif /* CONFIG_BPF_SYSCALL */ +static inline bool bpf_net_capable (void ) +{ +return capable (CAP_NET_ADMIN ) ||capable (CAP_SYS_ADMIN ); +} + static __always_inline intbpf_probe_read_kernel_common (void *dst,u32 size,const void *unsafe_ptr) {
include/linux/bpf_mprog.h +10 -0
@@ -340,4 +340,14 @@ static inline bool bpf_mprog_supported(enum bpf_prog_type type) return false; } } + +static inline bool bpf_mprog_detach_empty (enum bpf_prog_type type) +{ +switch (type) { +case BPF_PROG_TYPE_SCHED_CLS : +return bpf_net_capable (); +default : +return false; + } +}#endif /* __BPF_MPROG_H */
kernel/bpf/syscall.c +2 -5
@@ -1365,11 +1365,6 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token,return ret; } -static bool bpf_net_capable (void ) -{ -return capable (CAP_NET_ADMIN ) ||capable (CAP_SYS_ADMIN ); -} -#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size/* called via syscall */ static int map_create (union bpf_attr *attr,bpfptr_t uattr)
@@ -4554,6 +4549,8 @@ static int bpf_prog_detach(const union bpf_attr *attr) prog =bpf_prog_get_type (attr->attach_bpf_fd, ptype);if (IS_ERR (prog))return PTR_ERR (prog); + }else if (!bpf_mprog_detach_empty (ptype)) { +return -EPERM ; } }else if (is_cgroup_prog_type (ptype,0 , false)) {if (attr->attach_flags || attr->relative_fd)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 96/641 bpf: Fix verifier_bug_if to account for BPF_CALL
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Gerhorst <[email protected]>
[ Upstream commit cd3b6a3d49f8061d0c4c7e4226783051fe592ae7 ]
The BPF verifier assumes insn_aux->nospec_result is only set for direct memory writes (e.g., *(u32*)(r1+off) = r2). However, the assertion fails to account for helper calls (e.g., bpf_skb_load_bytes_relative) that perform writes to stack memory. Make the check more precise to resolve this.
The problem is that BPF_CALL instructions have BPF_CLASS(insn->code) == BPF_JMP, which triggers the warning check:
- Helpers like bpf_skb_load_bytes_relative write to stack memory
- check_helper_call() loops through meta.access_size, calling check_mem_access(..., BPF_WRITE)
- check_stack_write() sets insn_aux->nospec_result = 1
- Since BPF_CALL is encoded as BPF_JMP | BPF_CALL, the warning fires
Execution flow:
```
1. Drop capabilities → Enable Spectre mitigation
2. Load BPF program
└─> do_check()
├─> check_cond_jmp_op() → Marks dead branch as speculative
│ └─> push_stack(..., speculative=true)
├─> pop_stack() → state->speculative = 1
├─> check_helper_call() → Processes helper in dead branch
│ └─> check_mem_access(..., BPF_WRITE)
│ └─> insn_aux->nospec_result = 1
└─> Checks: state->speculative && insn_aux->nospec_result
└─> BPF_CLASS(insn->code) == BPF_JMP → WARNING
```To fix the assert, it would be nice to be able to reuse bpf_insn_successors() here, but bpf_insn_successors()->cnt is not exactly what we want as it may also be 1 for BPF_JA. Instead, we could check opcode_info.can_jump, but then we would have to share the table between the functions. This would mean moving the table out of the function and adding bpf_opcode_info(). As the verifier_bug_if() only runs for insns with nospec_result set, the impact on verification time would likely still be negligible. However, I assume sharing bpf_opcode_info() between liveness.c and verifier.c will not be worth it. It seems as only adjust_jmp_off() could also be simplified using it, and there imm/off is touched. Thus it is maybe better to rely on exact opcode/class matching there.
Therefore, to avoid this sharing only for a verifier_bug_if(), just check the opcode. This should now cover all opcodes for which can_jump in bpf_insn_successors() is true.
Parts of the description and example are taken from the bug report.
--- kernel/bpf/verifier.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
kernel/bpf/verifier.c +8 -6
@@ -20149,17 +20149,19 @@ static int do_check(struct bpf_verifier_env *env)* may skip a nospec patched-in after the jump. This can * currently never happen because nospec_result is only * used for the write-ops -* `*(size*)(dst_reg+off)=src_reg|imm32` which must -* never skip the following insn. Still, add a warning -* to document this in case nospec_result is used -* elsewhere in the future. +* `*(size*)(dst_reg+off)=src_reg|imm32` and helper +* calls. These must never skip the following insn +* (i.e., bpf_insn_successors()'s opcode_info.can_jump +* is false). Still, add a warning to document this in +* case nospec_result is used elsewhere in the future. * * All non-branch instructions have a single * fall-through edge. For these, nospec_result should * already work. */ -if (verifier_bug_if (BPF_CLASS (insn->code) ==BPF_JMP || -BPF_CLASS (insn->code) ==BPF_JMP32 , env, +if (verifier_bug_if ((BPF_CLASS (insn->code) ==BPF_JMP || +BPF_CLASS (insn->code) ==BPF_JMP32 ) && +BPF_OP (insn->code) !=BPF_CALL , env,"speculation barrier after jump instruction may not have the desired effect" ))return -EFAULT ; process_bpf_exit:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 97/641 crypto: ccp - Fix a crash due to incorrect cleanup usage of kfree
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ella Ma <[email protected]>
[ Upstream commit d5abcc33ee76bc26d58b39dc1a097e43a99dd438 ]
Annotating a local pointer variable, which will be assigned with the kmalloc-family functions, with the __cleanup(kfree) attribute will make the address of the local variable, rather than the address returned by kmalloc, passed to kfree directly and lead to a crash due to invalid deallocation of stack address. According to other places in the repo, the correct usage should be __free(kfree). The code coincidentally compiled because the parameter type void * of kfree is compatible with the desired type struct { ... } **.
--- drivers/crypto/ccp/ccp-ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/ccp/ccp-ops.c +1 -1
@@ -642,7 +642,7 @@ ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)struct ccp_data dst;struct ccp_data aad;struct ccp_op op; - } *wa __cleanup(kfree) = kzalloc(sizeof *wa, GFP_KERNEL); + } *wa __free(kfree) = kzalloc(sizeof(*wa), GFP_KERNEL);unsigned int dm_offset;unsigned int authsize;unsigned int jobid;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 98/641 crypto: inside-secure/eip93 - unregister only available algorithm
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit 0ceeadc7b53a041d89d5843f6bf0ccb7c98b0b4f ]
EIP93 has an options register. This register indicates which crypto algorithms are implemented in silicon. Supported algorithms are registered on this basis. Unregister algorithms on the same basis. Currently, all algorithms are unregistered, even those not supported by HW. This results in panic on platforms that don't have all options implemented in silicon.
--- .../crypto/inside-secure/eip93/eip93-main.c | 92 +++++++++++-------- 1 file changed, 53 insertions(+), 39 deletions(-)
drivers/crypto/inside-secure/eip93/eip93-main.c +53 -39
@@ -77,11 +77,44 @@ inline void eip93_irq_clear(struct eip93_device *eip93, u32 mask)__raw_writel (mask, eip93->base +EIP93_REG_INT_CLR ); } -static void eip93_unregister_algs (unsigned int i) +static int eip93_algo_is_supported (u32 alg_flags,u32 supported_algo_flags) +{ +if ((IS_DES (alg_flags) ||IS_3DES (alg_flags)) && + !(supported_algo_flags &EIP93_PE_OPTION_TDES )) +return 0 ; + +if (IS_AES (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_AES )) +return 0 ; + +if (IS_HASH_MD5 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_MD5 )) +return 0 ; + +if (IS_HASH_SHA1 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_1 )) +return 0 ; + +if (IS_HASH_SHA224 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_224 )) +return 0 ; + +if (IS_HASH_SHA256 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_256 )) +return 0 ; + +return 1 ; +} + +static void eip93_unregister_algs (u32 supported_algo_flags,unsigned int i) {unsigned int j;for (j =0 ; j < i; j++) { +if (!eip93_algo_is_supported (eip93_algs[j]->flags, + supported_algo_flags)) +continue ; +switch (eip93_algs[j]->type) {case EIP93_ALG_TYPE_SKCIPHER :crypto_unregister_skcipher (&eip93_algs[j]->alg.skcipher);
@@ -106,49 +139,27 @@ static int eip93_register_algs(struct eip93_device *eip93, u32 supported_algo_fl eip93_algs[i]->eip93 = eip93; -if ((IS_DES (alg_flags) ||IS_3DES (alg_flags)) && - !(supported_algo_flags &EIP93_PE_OPTION_TDES )) +if (!eip93_algo_is_supported (alg_flags, supported_algo_flags))continue ; -if (IS_AES (alg_flags)) { -if (!(supported_algo_flags &EIP93_PE_OPTION_AES )) -continue ; +if (IS_AES (alg_flags) && !IS_HMAC (alg_flags)) { +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY128 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_128 ; -if (!IS_HMAC (alg_flags)) { -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY128 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_128 ; +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY192 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_192 ; -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY192 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_192 ; +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY256 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_256 ; -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY256 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_256 ; - -if (IS_RFC3686 (alg_flags)) - eip93_algs[i]->alg.skcipher.max_keysize += -CTR_RFC3686_NONCE_SIZE ; - } +if (IS_RFC3686 (alg_flags)) + eip93_algs[i]->alg.skcipher.max_keysize += +CTR_RFC3686_NONCE_SIZE ; } -if (IS_HASH_MD5 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_MD5 )) -continue ; - -if (IS_HASH_SHA1 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_1 )) -continue ; - -if (IS_HASH_SHA224 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_224 )) -continue ; - -if (IS_HASH_SHA256 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_256 )) -continue ; -switch (eip93_algs[i]->type) {case EIP93_ALG_TYPE_SKCIPHER : ret =crypto_register_skcipher (&eip93_algs[i]->alg.skcipher);
@@ -167,7 +178,7 @@ static int eip93_register_algs(struct eip93_device *eip93, u32 supported_algo_flreturn 0 ; fail: -eip93_unregister_algs (i); +eip93_unregister_algs (supported_algo_flags, i);return ret; }
@@ -469,8 +480,11 @@ static int eip93_crypto_probe(struct platform_device *pdev)static void eip93_crypto_remove (struct platform_device *pdev) {struct eip93_device *eip93 =platform_get_drvdata (pdev); +u32 algo_flags; + + algo_flags =readl (eip93->base +EIP93_REG_PE_OPTION_1 ); -eip93_unregister_algs (ARRAY_SIZE (eip93_algs)); +eip93_unregister_algs (algo_flags,ARRAY_SIZE (eip93_algs));eip93_cleanup (eip93); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 99/641 x86/fgraph: Fix return_to_handler regs.rsp value
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit 8bc11700e0d23d4fdb7d8d5a73b2e95de427cabc ]
The previous change (Fixes commit) messed up the rsp register value, which is wrong because it's already adjusted with FRAME_SIZE, we need the original rsp value.
This change does not affect fprobe current kernel unwind, the !perf_hw_regs path perf_callchain_kernel:
if (perf_hw_regs(regs)) {
if (perf_callchain_store(entry, regs->ip))
return;
unwind_start(&state, current, regs, NULL);
} else {
unwind_start(&state, current, NULL, (void *)regs->sp);
}which uses pt_regs.sp as first_frame boundary (FRAME_SIZE shift makes no difference, unwind stil stops at the right frame).
This change fixes the other path when we want to unwind directly from pt_regs sp/fp/ip state, which is coming in following change.
--- arch/x86/kernel/ftrace_64.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/kernel/ftrace_64.S +4 -1
@@ -354,6 +354,9 @@ SYM_CODE_START(return_to_handler) UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR + /* Store original rsp for pt_regs.sp value. */ + movq %rsp, %rdi + /* Restore return_to_handler value that got eaten by previous ret instruction. */ subq $8, %rsp UNWIND_HINT_FUNC
@@ -364,7 +367,7 @@ SYM_CODE_START(return_to_handler) movq %rax, RAX(%rsp) movq %rdx, RDX(%rsp) movq %rbp, RBP(%rsp) - movq %rsp, RSP(%rsp) + movq %rdi, RSP(%rsp) movq %rsp, %rdi call ftrace_return_to_handler
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 100/641 x86/fgraph,bpf: Switch kprobe_multi program stack unwind to hw_regs path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit aea251799998aa1b78eacdfb308f18ea114ea5b3 ]
Mahe reported missing function from stack trace on top of kprobe multi program. The missing function is the very first one in the stacktrace, the one that the bpf program is attached to.
# bpftrace -e 'kprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118 ('*' is used for kprobe_multi attachment)
The reason is that the previous change (the Fixes commit) fixed stack unwind for tracepoint, but removed attached function address from the stack trace on top of kprobe multi programs, which I also overlooked in the related test (check following patch).
The tracepoint and kprobe_multi have different stack setup, but use same unwind path. I think it's better to keep the previous change, which fixed tracepoint unwind and instead change the kprobe multi unwind as explained below.
The bpf program stack unwind calls perf_callchain_kernel for kernel portion and it follows two unwind paths based on X86_EFLAGS_FIXED bit in pt_regs.flags.
When the bit set we unwind from stack represented by pt_regs argument, otherwise we unwind currently executed stack up to 'first_frame' boundary.
The 'first_frame' value is taken from regs.rsp value, but ftrace_caller and ftrace_regs_caller (ftrace trampoline) functions set the regs.rsp to the previous stack frame, so we skip the attached function entry.
If we switch kprobe_multi unwind to use the X86_EFLAGS_FIXED bit, we set the start of the unwind to the attached function address. As another benefit we also cut extra unwind cycles needed to reach the 'first_frame' boundary.
The speedup can be measured with trigger bench for kprobe_multi program and stacktrace support.
- trigger bench with stacktrace on current code:
kprobe-multi : 0.810 ± 0.001M/s
kretprobe-multi: 0.808 ± 0.001M/s- and with the fix:
kprobe-multi : 1.264 ± 0.001M/s
kretprobe-multi: 1.401 ± 0.002M/sWith the fix, the entry probe stacktrace:
# bpftrace -e 'kprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... __x64_sys_newuname+9
do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118The return probe skips the attached function, because it's no longer on the stack at the point of the unwind and this way is the same how standard kretprobe works.
# bpftrace -e 'kretprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118--- arch/x86/include/asm/ftrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/ftrace.h +1 -1
@@ -57,7 +57,7 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs) }#define arch_ftrace_partial_regs (regs) do { \ - regs->flags &= ~X86_EFLAGS_FIXED; \ + regs->flags |= X86_EFLAGS_FIXED; \ regs->cs = __KERNEL_CS; \ } while (0)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 101/641 selftests/bpf: Fix kprobe multi stacktrace_ips test
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit 0207f94971e72a13380e28022c86da147e8e090f ]
We now include the attached function in the stack trace, fixing the test accordingly.
--- .../selftests/bpf/prog_tests/stacktrace_ips.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c +14 -5
@@ -74,11 +74,20 @@ static void test_stacktrace_ips_kprobe_multi(bool retprobe)load_kallsyms (); -check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,4 , -ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), -ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), -ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), -ksym_get_addr ("bpf_testmod_test_read" )); +if (retprobe) { +check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,4 , +ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), +ksym_get_addr ("bpf_testmod_test_read" )); + }else { +check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,5 , +ksym_get_addr ("bpf_testmod_stacktrace_test" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), +ksym_get_addr ("bpf_testmod_test_read" )); + } cleanup:stacktrace_ips__destroy (skel);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 102/641 crypto: hisilicon/trng - support tfms sharing the device
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weili Qian <[email protected]>
[ Upstream commit 3d3135057ff567d5c09fff4c9ef6391a684e8042 ]
Since the number of devices is limited, and the number of tfms may exceed the number of devices, to ensure that tfms can be successfully allocated, support tfms sharing the same device.
--- drivers/crypto/hisilicon/trng/trng.c | 121 +++++++++++++++++++-------- 1 file changed, 86 insertions(+), 35 deletions(-)
drivers/crypto/hisilicon/trng/trng.c +86 -35
@@ -40,6 +40,7 @@#define SEED_SHIFT_24 24#define SEED_SHIFT_16 16#define SEED_SHIFT_8 8 +#define SW_MAX_RANDOM_BYTES 65520struct hisi_trng_list {struct mutex lock;
@@ -53,8 +54,10 @@ struct hisi_trng {struct list_head list;struct hwrng rng;u32 ver; -bool is_used; -struct mutex mutex; +u32 ctx_num; +/* The bytes of the random number generated since the last seeding. */ +u32 random_bytes; +struct mutex lock; };struct hisi_trng_ctx {
@@ -63,10 +66,14 @@ struct hisi_trng_ctx {static atomic_t trng_active_devs;static struct hisi_trng_list trng_devices; +static int hisi_trng_read (struct hwrng *rng,void *buf,size_t max,bool wait); -static void hisi_trng_set_seed (struct hisi_trng *trng,const u8 *seed) +static int hisi_trng_set_seed (struct hisi_trng *trng,const u8 *seed) {u32 val, seed_reg, i; +int ret; + +writel (0x0 , trng->base +SW_DRBG_BLOCKS );for (i =0 ; i <SW_DRBG_SEED_SIZE ; i +=SW_DRBG_SEED_SIZE /SW_DRBG_SEED_REGS_NUM ) {
@@ -78,6 +85,20 @@ static void hisi_trng_set_seed(struct hisi_trng *trng, const u8 *seed) seed_reg = (i >>SW_DRBG_NUM_SHIFT ) %SW_DRBG_SEED_REGS_NUM ;writel (val, trng->base +SW_DRBG_SEED (seed_reg)); } + +writel (SW_DRBG_BLOCKS_NUM | (0x1 <<SW_DRBG_ENABLE_SHIFT ), + trng->base +SW_DRBG_BLOCKS ); +writel (0x1 , trng->base +SW_DRBG_INIT ); + ret =readl_relaxed_poll_timeout (trng->base +SW_DRBG_STATUS , + val, val &BIT (0 ),SLEEP_US ,TIMEOUT_US ); +if (ret) { +pr_err ("failed to init trng(%d)\n" , ret); +return -EIO ; + } + + trng->random_bytes =0 ; + +return 0 ; } static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,
@@ -85,8 +106,7 @@ static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed, {struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm);struct hisi_trng *trng = ctx->trng; -u32 val =0 ; -int ret =0 ; +int ret;if (slen <SW_DRBG_SEED_SIZE ) { pr_err("slen(%u) is not matched with trng(%d)\n", slen,
@@ -94,43 +114,45 @@ static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,return -EINVAL ; } -writel (0x0 , trng->base +SW_DRBG_BLOCKS ); -hisi_trng_set_seed (trng, seed); +mutex_lock (&trng->lock); + ret =hisi_trng_set_seed (trng, seed); +mutex_unlock (&trng->lock); -writel (SW_DRBG_BLOCKS_NUM | (0x1 <<SW_DRBG_ENABLE_SHIFT ), - trng->base +SW_DRBG_BLOCKS ); -writel (0x1 , trng->base +SW_DRBG_INIT ); +return ret; +} - ret =readl_relaxed_poll_timeout (trng->base +SW_DRBG_STATUS , - val, val &BIT (0 ),SLEEP_US ,TIMEOUT_US ); -if (ret) -pr_err ("fail to init trng(%d)\n" , ret); +static int hisi_trng_reseed (struct hisi_trng *trng) +{ +u8 seed[SW_DRBG_SEED_SIZE ]; +int size; -return ret; +if (!trng->random_bytes) +return 0 ; + + size =hisi_trng_read (&trng->rng, seed,SW_DRBG_SEED_SIZE , false); +if (size !=SW_DRBG_SEED_SIZE ) +return -EIO ; + +return hisi_trng_set_seed (trng, seed); } -static int hisi_trng_generate (struct crypto_rng *tfm,const u8 *src, -unsigned int slen,u8 *dstn,unsigned int dlen) +static int hisi_trng_get_bytes (struct hisi_trng *trng,u8 *dstn,unsigned int dlen) { -struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm); -struct hisi_trng *trng = ctx->trng;u32 data[SW_DRBG_DATA_NUM ];u32 currsize =0 ;u32 val =0 ;int ret;u32 i; -if (dlen >SW_DRBG_BLOCKS_NUM *SW_DRBG_BYTES || dlen ==0 ) { -pr_err ("dlen(%u) exceeds limit(%d)!\n" , dlen, -SW_DRBG_BLOCKS_NUM *SW_DRBG_BYTES ); -return -EINVAL ; - } + ret =hisi_trng_reseed (trng); +if (ret) +return ret; do { ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS, - val, val & BIT(1), SLEEP_US, TIMEOUT_US); + val, val & BIT(1), SLEEP_US, TIMEOUT_US); if (ret) { - pr_err("fail to generate random number(%d)!\n", ret); + pr_err("failed to generate random number(%d)!\n", ret); break; }
@@ -145,30 +167,57 @@ static int hisi_trng_generate(struct crypto_rng *tfm, const u8 *src, currsize = dlen; } + trng->random_bytes +=SW_DRBG_BYTES ;writel (0x1 , trng->base +SW_DRBG_GEN ); }while (currsize < dlen);return ret; } +static int hisi_trng_generate (struct crypto_rng *tfm,const u8 *src, +unsigned int slen,u8 *dstn,unsigned int dlen) +{ +struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm); +struct hisi_trng *trng = ctx->trng; +unsigned int currsize =0 ; +unsigned int block_size; +int ret; + +if (!dstn || !dlen) { +pr_err ("output is error, dlen %u!\n" , dlen); +return -EINVAL ; + } + +do { + block_size = min_t(unsigned int, dlen - currsize, SW_MAX_RANDOM_BYTES); +mutex_lock (&trng->lock); + ret =hisi_trng_get_bytes (trng, dstn + currsize, block_size); +mutex_unlock (&trng->lock); +if (ret) +return ret; + currsize += block_size; + }while (currsize < dlen); + +return 0 ; +} +static int hisi_trng_init (struct crypto_tfm *tfm) {struct hisi_trng_ctx *ctx =crypto_tfm_ctx (tfm);struct hisi_trng *trng; -int ret = -EBUSY ; +u32 ctx_num = ~0 ;mutex_lock (&trng_devices.lock);list_for_each_entry (trng, &trng_devices.list, list) { -if (!trng->is_used) { - trng->is_used = true; +if (trng->ctx_num < ctx_num) { + ctx_num = trng->ctx_num; ctx->trng = trng; - ret =0 ; -break ; } } + ctx->trng->ctx_num++;mutex_unlock (&trng_devices.lock); -return ret; +return 0 ; }static void hisi_trng_exit (struct crypto_tfm *tfm)
@@ -176,7 +225,7 @@ static void hisi_trng_exit(struct crypto_tfm *tfm)struct hisi_trng_ctx *ctx =crypto_tfm_ctx (tfm);mutex_lock (&trng_devices.lock); - ctx->trng->is_used = false; + ctx->trng->ctx_num--;mutex_unlock (&trng_devices.lock); }
@@ -238,7 +287,7 @@ static int hisi_trng_del_from_list(struct hisi_trng *trng)int ret = -EBUSY ;mutex_lock (&trng_devices.lock); -if (!trng->is_used) { +if (!trng->ctx_num) {list_del (&trng->list); ret =0 ; }
@@ -262,7 +311,9 @@ static int hisi_trng_probe(struct platform_device *pdev)if (IS_ERR (trng->base))return PTR_ERR (trng->base); - trng->is_used = false; + trng->ctx_num =0 ; + trng->random_bytes =SW_MAX_RANDOM_BYTES ; +mutex_init (&trng->lock); trng->ver =readl (trng->base +HISI_TRNG_VERSION );if (!trng_devices.is_init) {INIT_LIST_HEAD (&trng_devices.list);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 103/641 crypto: caam - fix netdev memory leak in dpaa2_caam_probe
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianpeng Chang <[email protected]>
[ Upstream commit 7d43252b3060b0ba4a192dce5dba85a3f39ffe39 ]
When commit 0e1a4d427f58 ("crypto: caam: Unembed net_dev structure in dpaa2") converted embedded net_device to dynamically allocated pointers, it added cleanup in dpaa2_dpseci_disable() but missed adding cleanup in dpaa2_dpseci_free() for error paths.
This causes memory leaks when dpaa2_dpseci_dpio_setup() fails during probe due to DPIO devices not being ready yet. The kernel's deferred probe mechanism handles the retry successfully, but the netdevs allocated during the failed probe attempt are never freed, resulting in kmemleak reports showing multiple leaked netdev-related allocations all traced back to dpaa2_caam_probe().
Fix this by preserving the CPU mask of allocated netdevs during setup and using it for cleanup in dpaa2_dpseci_free(). This approach ensures that only the CPUs that actually had netdevs allocated will be cleaned up, avoiding potential issues with CPU hotplug scenarios.
--- drivers/crypto/caam/caamalg_qi2.c | 27 +++++++++++++++------------ drivers/crypto/caam/caamalg_qi2.h | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-)
drivers/crypto/caam/caamalg_qi2.c +15 -12
@@ -4814,7 +4814,8 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv) {struct device *dev = priv->dev;struct fsl_mc_device *ls_dev =to_fsl_mc_device (dev); -int err; +struct dpaa2_caam_priv_per_cpu *ppriv; +int i, err;if (DPSECI_VER (priv->major_ver, priv->minor_ver) >DPSECI_VER (5 ,3 )) { err =dpseci_reset (priv->mc_io,0 , ls_dev->mc_handle);
@@ -4822,6 +4823,12 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)dev_err (dev,"dpseci_reset() failed\n" ); } +for_each_cpu (i, priv->clean_mask) { + ppriv =per_cpu_ptr (priv->ppriv, i); +free_netdev (ppriv->net_dev); + } +free_cpumask_var (priv->clean_mask); +dpaa2_dpseci_congestion_free (priv);dpseci_close (priv->mc_io,0 , ls_dev->mc_handle); }
@@ -5007,16 +5014,15 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)struct device *dev = &ls_dev->dev;struct dpaa2_caam_priv *priv;struct dpaa2_caam_priv_per_cpu *ppriv; -cpumask_var_t clean_mask;int err, cpu;u8 i; err = -ENOMEM ; -if (!zalloc_cpumask_var (&clean_mask,GFP_KERNEL )) - goto err_cpumask; - priv =dev_get_drvdata (dev); +if (!zalloc_cpumask_var (&priv->clean_mask,GFP_KERNEL )) + goto err_cpumask; + priv->dev = dev; priv->dpsec_id = ls_dev->obj_desc.id;
@@ -5118,7 +5124,7 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) err = -ENOMEM ; goto err_alloc_netdev; } -cpumask_set_cpu (cpu, clean_mask); +cpumask_set_cpu (cpu, priv->clean_mask); ppriv->net_dev->dev = *dev; netif_napi_add_tx_weight(ppriv->net_dev, &ppriv->napi,
@@ -5126,18 +5132,16 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) DPAA2_CAAM_NAPI_WEIGHT); } - err =0 ; - goto free_cpumask; +return 0 ; err_alloc_netdev: -free_dpaa2_pcpu_netdev (priv, clean_mask); +free_dpaa2_pcpu_netdev (priv, priv->clean_mask); err_get_rx_queue:dpaa2_dpseci_congestion_free (priv); err_get_vers:dpseci_close (priv->mc_io,0 , ls_dev->mc_handle); err_open: -free_cpumask: -free_cpumask_var (clean_mask); +free_cpumask_var (priv->clean_mask); err_cpumask:return err; }
@@ -5182,7 +5186,6 @@ static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv) ppriv =per_cpu_ptr (priv->ppriv, i);napi_disable (&ppriv->napi);netif_napi_del (&ppriv->napi); -free_netdev (ppriv->net_dev); }return 0 ;
drivers/crypto/caam/caamalg_qi2.h +2 -0
@@ -42,6 +42,7 @@* @mc_io: pointer to MC portal's I/O object * @domain: IOMMU domain * @ppriv: per CPU pointers to privata data +* @clean_mask: CPU mask of CPUs that have allocated netdevs */ struct dpaa2_caam_priv {int dpsec_id;
@@ -65,6 +66,7 @@ struct dpaa2_caam_priv {struct dpaa2_caam_priv_per_cpu __percpu *ppriv;struct dentry *dfs_root; +cpumask_var_t clean_mask; };/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 104/641 bpf: Fix bpf_xdp_store_bytes proto for read-only arg
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Chaignon <[email protected]>
[ Upstream commit 6557f1565d779851c4db9c488c49c05a47a6e72f ]
While making some maps in Cilium read-only from the BPF side, we noticed that the bpf_xdp_store_bytes proto is incorrect. In particular, the verifier was throwing the following error:
; ret = ctx_store_bytes(ctx, l3_off + offsetof(struct iphdr, saddr),
&nat->address, 4, 0); 635: (79) r1 = *(u64 *)(r10 -144) ; R1=ctx() R10=fp0 fp-144=ctx() 636: (b4) w2 = 26 ; R2=26 637: (b4) w4 = 4 ; R4=4 638: (b4) w5 = 0 ; R5=0
639: (85) call bpf_xdp_store_bytes#190 write into map forbidden, value_size=6 off=0 size=4
nat comes from a BPF_F_RDONLY_PROG map, so R3 is a PTR_TO_MAP_VALUE. The verifier checks the helper's memory access to R3 in check_mem_size_reg, as it reaches ARG_CONST_SIZE argument. The third argument has expected type ARG_PTR_TO_UNINIT_MEM, which includes the MEM_WRITE flag. The verifier thus checks for a BPF_WRITE access on R3. Given R3 points to a read-only map, the check fails.
Conversely, ARG_PTR_TO_UNINIT_MEM can also lead to the helper reading from uninitialized memory.
This patch simply fixes the expected argument type to match that of bpf_skb_store_bytes.
--- net/core/filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/filter.c +1 -1
@@ -4133,7 +4133,7 @@ static const struct bpf_func_proto bpf_xdp_store_bytes_proto = { .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, - .arg3_type = ARG_PTR_TO_UNINIT_MEM, + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg4_type = ARG_CONST_SIZE, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 105/641 genirq: Set IRQF_COND_ONESHOT in devm_request_irq().
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 943b052ded21feb84f293d40b06af3181cd0d0d7 ]
The flag IRQF_COND_ONESHOT was already force-added to request_irq() because the ACPI SCI interrupt handler is using the IRQF_ONESHOT flag which breaks all shared handlers.
devm_request_irq() needs the same change since some users, such as int0002_vgpio, are using this function instead.
Add IRQF_COND_ONESHOT to the flags passed to devm_request_irq().
--- include/linux/interrupt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/interrupt.h +1 -1
@@ -215,7 +215,7 @@ static inline int __must_check devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) { - return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags, + return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags | IRQF_COND_ONESHOT, devname, dev_id); }
Signature · 1 line
2.51.0