6.1.130-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainercover 6.1.130-rc1 review
This is the start of the stable review cycle for the 6.1.130 release. There are 176 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, 07 Mar 2025 17:44:26 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.130-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.1.130-rc1
Fullway Wang <[email protected]>
media: mtk-vcodec: potential null pointer deference in SCP
Quang Le <[email protected]>
pfifo_tail_enqueue: Drop new packet when sch->limit == 0
Phillip Lougher <[email protected]>
Squashfs: check the inode number is not the invalid value of zero
Jiaxun Yang <[email protected]>
mm/memory: Use exception ip to search exception tables
Jiaxun Yang <[email protected]>
ptrace: Introduce exception_ip arch hook
Thomas Gleixner <[email protected]>
intel_idle: Handle older CPUs, which stop the TSC in deeper C states, correctly
chr[] <[email protected]>
amdgpu/pm/legacy: fix suspend/resume issues
Sohaib Nadeem <[email protected]>
drm/amd/display: fixed integer types and null check locations
Andreas Schwab <[email protected]>
riscv/futex: sign extend compare value in atomic cmpxchg
Thomas Gleixner <[email protected]>
sched/core: Prevent rescheduling when interrupts are disabled
Ard Biesheuvel <[email protected]>
vmlinux.lds: Ensure that const vars with relocations are mapped R/O
Matthieu Baerts (NGI0) <[email protected]>
mptcp: reset when MPTCP opts are dropped after join
Paolo Abeni <[email protected]>
mptcp: always handle address removal under msk socket lock
Kaustabh Chakraborty <[email protected]>
phy: exynos5-usbdrd: fix MPLL_MULTIPLIER and SSC_REFCLKSEL masks in refclk
BH Hsieh <[email protected]>
phy: tegra: xusb: reset VBUS & ID OVERRIDE
Wei Fang <[email protected]>
net: enetc: fix the off-by-one issue in enetc_map_tx_tso_buffs()
Wei Fang <[email protected]>
net: enetc: correct the xdp_tx statistics
Wei Fang <[email protected]>
net: enetc: update UDP checksum when updating originTimestamp field
Wei Fang <[email protected]>
net: enetc: keep track of correct Tx BD count in enetc_map_tx_tso_buffs()
Wei Fang <[email protected]>
net: enetc: fix the off-by-one issue in enetc_map_tx_buffs()
Nikita Zhandarovich <[email protected]>
usbnet: gl620a: fix endpoint checking in genelink_bind()
Tyrone Ting <[email protected]>
i2c: npcm: disable interrupt enable bit before devm_request_irq
Roman Li <[email protected]>
drm/amd/display: Fix HPD after gpu reset
Tom Chung <[email protected]>
drm/amd/display: Disable PSR-SU on eDP panels
Kan Liang <[email protected]>
perf/core: Fix low freq setting via IOC_PERIOD
Kan Liang <[email protected]>
perf/x86: Fix low freqency setting issue
Dmitry Panchenko <[email protected]>
ALSA: usb-audio: Re-add sample rate quirk for Pioneer DJM-900NXS2
Nikolay Kuratov <[email protected]>
ftrace: Avoid potential division by zero in function_stat_show()
Steven Rostedt <[email protected]>
tracing: Fix bad hist from corrupting named_triggers list
Chukun Pan <[email protected]>
phy: rockchip: naneng-combphy: compatible reset with old DT
Russell Senior <[email protected]>
x86/CPU: Fix warm boot hang regression on AMD SC1100 SoC systems
Pavel Begunkov <[email protected]>
io_uring/net: save msg_control for compat
Tong Tiangen <[email protected]>
uprobes: Reject the shared zeropage in uprobe_write_opcode()
David Howells <[email protected]>
mm: Don't pin ZERO_PAGE in pin_user_pages()
Justin Iurman <[email protected]>
net: ipv6: fix dst ref loop on input in rpl lwt
Justin Iurman <[email protected]>
net: ipv6: rpl_iptunnel: mitigate 2-realloc issue
Justin Iurman <[email protected]>
net: ipv6: fix dst ref loop on input in seg6 lwt
Justin Iurman <[email protected]>
net: ipv6: seg6_iptunnel: mitigate 2-realloc issue
Justin Iurman <[email protected]>
include: net: add static inline dst_dev_overhead() to dst.h
Shay Drory <[email protected]>
net/mlx5: IRQ, Fix null string in debug print
Harshal Chaudhari <[email protected]>
net: mvpp2: cls: Fixed Non IP flow, with vlan tag flow defination.
Mohammad Heib <[email protected]>
net: Clear old fragment checksum value in napi_reuse_skb
Wang Hai <[email protected]>
tcp: Defer ts_recent changes until req is owned
Philo Lu <[email protected]>
ipvs: Always clear ipvs_property flag in skb_scrub_packet()
Nicolas Frattaroli <[email protected]>
ASoC: es8328: fix route from DAC to output
Sean Anderson <[email protected]>
net: cadence: macb: Synchronize stats calculations
Eric Dumazet <[email protected]>
ipvlan: ensure network headers are in skb linear part
Guillaume Nault <[email protected]>
ipvlan: Prepare ipvlan_process_v4_outbound() to future .flowi4_tos conversion.
Guillaume Nault <[email protected]>
ipv4: Convert ip_route_input() to dscp_t.
Guillaume Nault <[email protected]>
ipv4: Convert icmp_route_lookup() to dscp_t.
Ido Schimmel <[email protected]>
ipvlan: Unmask upper DSCP bits in ipvlan_process_v4_outbound()
Ido Schimmel <[email protected]>
ipv4: icmp: Unmask upper DSCP bits in icmp_route_lookup()
Ido Schimmel <[email protected]>
ipv4: icmp: Pass full DS field to ip_route_input()
Peilin He <[email protected]>
net/ipv4: add tracepoint for icmp_send
Jiri Slaby (SUSE) <[email protected]>
net: set the minimum for net_hotdata.netdev_budget_usecs
Ido Schimmel <[email protected]>
net: loopback: Avoid sending IP packets without an Ethernet header
David Howells <[email protected]>
afs: Fix the server_list to unuse a displaced server rather than putting it
David Howells <[email protected]>
afs: Make it possible to find the volumes that are using a server
Colin Ian King <[email protected]>
afs: remove variable nr_servers
Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
Takashi Iwai <[email protected]>
ALSA: usb-audio: Avoid dropping MIDI events at closing multiple ports
Arnd Bergmann <[email protected]>
sunrpc: suppress warnings for unused procfs functions
Patrisious Haddad <[email protected]>
RDMA/mlx5: Fix bind QP error cleanup flow
Ye Bin <[email protected]>
scsi: core: Clear driver private data when retrying request
Patrisious Haddad <[email protected]>
RDMA/mlx5: Fix AH static rate parsing
Or Har-Toov <[email protected]>
IB/core: Add support for XDR link speed
Leon Romanovsky <[email protected]>
RDMA/mlx5: Reduce QP table exposure
Mark Zhang <[email protected]>
RDMA/mlx: Calling qp event handler in workqueue context
Trond Myklebust <[email protected]>
SUNRPC: Prevent looping due to rpc_signal_task() races
Stephen Brennan <[email protected]>
SUNRPC: convert RPC_TASK_* constants to enum
Vasiliy Kovalev <[email protected]>
ovl: fix UAF in ovl_dentry_update_reval by moving dput() in ovl_link_up
Mark Zhang <[email protected]>
IB/mlx5: Set and get correct qp_num for a DCT QP
Yishai Hadas <[email protected]>
RDMA/mlx5: Fix the recovery flow of the UMR QP
Shay Drory <[email protected]>
RDMA/mlx5: Implement mkeys management via LIFO queue
Michael Guralnik <[email protected]>
RDMA/mlx5: Add work to remove temporary entries from the cache
Michael Guralnik <[email protected]>
RDMA/mlx5: Cache all user cacheable mkeys on dereg MR flow
Michael Guralnik <[email protected]>
RDMA/mlx5: Introduce mlx5r_cache_rb_key
Michael Guralnik <[email protected]>
RDMA/mlx5: Change the cache structure to an RB-tree
Aharon Landau <[email protected]>
RDMA/mlx5: Remove implicit ODP cache entry
Aharon Landau <[email protected]>
RDMA/mlx5: Don't keep umrable 'page_shift' in cache entries
Xin Long <[email protected]>
netfilter: allow exp not to be removed in nf_ct_find_expectation
Alexander Dahl <[email protected]>
spi: atmel-quadspi: Fix wrong register value written to MR
Alexander Dahl <[email protected]>
spi: atmel-quadspi: Avoid overwriting delay register settings
Yunfei Dong <[email protected]>
media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
Yu Kuai <[email protected]>
block, bfq: fix bfqq uaf in bfq_limit_depth()
Paolo Valente <[email protected]>
block, bfq: split sync bfq_queues on a per-actuator basis
Patrick Bellasi <[email protected]>
x86/cpu/kvm: SRSO: Fix possible missing IBPB on VM-Exit
Steven Rostedt <[email protected]>
ftrace: Do not add duplicate entries in subops manager ops
Sebastian Andrzej Siewior <[email protected]>
ftrace: Correct preemption accounting for function tracing.
Komal Bajaj <[email protected]>
EDAC/qcom: Correct interrupt enable register configuration
Haoxiang Li <[email protected]>
smb: client: Add check for next_buffer in receive_encrypted_standard()
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: fix incorrect device in dma_unmap_single
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: use dma_map_resource for sdma address
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: fix error code in cadence_nand_init()
Ricardo Cañuelo Navarro <[email protected]>
mm,madvise,hugetlb: check for 0-length range after end address adjustment
Christian Brauner <[email protected]>
acct: block access to kernel internal filesystems
Christian Brauner <[email protected]>
acct: perform last write from workqueue
John Veness <[email protected]>
ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED
Wentao Liang <[email protected]>
ALSA: hda: Add error check for snd_ctl_rename_id() in snd_hda_create_dig_out_ctls()
Nikita Zhandarovich <[email protected]>
ASoC: fsl_micfil: Enable default case in micfil_set_quality()
Haoxiang Li <[email protected]>
nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
Gavrilov Ilia <[email protected]>
drop_monitor: fix incorrect initialization order
Sumit Garg <[email protected]>
tee: optee: Fix supplicant wait loop
Ville Syrjälä <[email protected]>
drm/i915: Make sure all planes in use by the joiner have their crtc included
Jessica Zhang <[email protected]>
drm/msm/dpu: Disable dither in phys encoder cleanup
Yan Zhai <[email protected]>
bpf: skip non exist keys in generic_map_lookup_batch
Caleb Sander Mateos <[email protected]>
nvme/ioctl: add missing space in err message
Marijn Suijten <[email protected]>
drm/msm/dpu: Don't leak bits_per_component into random DSC_ENC fields
David Hildenbrand <[email protected]>
nouveau/svm: fix missing folio unlock + put after make_device_exclusive_range()
Andrey Vatoropin <[email protected]>
power: supply: da9150-fg: fix potential overflow
Jiayuan Chen <[email protected]>
bpf: Fix wrong copied_seq calculation
Jiayuan Chen <[email protected]>
strparser: Add read_sock callback
Shigeru Yoshida <[email protected]>
bpf, test_run: Fix use-after-free issue in eth_skb_pkt_type()
Tomi Valkeinen <[email protected]>
drm/rcar-du: dsi: Fix PHY lock bit check
Devarsh Thakkar <[email protected]>
drm/tidss: Fix race condition while handling interrupt registers
Tomi Valkeinen <[email protected]>
drm/tidss: Add simple K2G manual reset
Sabrina Dubroca <[email protected]>
tcp: drop secpath at the same time as we currently drop dst
Nick Hu <[email protected]>
net: axienet: Set mac_managed_pm
Breno Leitao <[email protected]>
arp: switch to dev_getbyhwaddr() in arp_req_set_public()
Breno Leitao <[email protected]>
net: Add non-RCU dev_getbyhwaddr() helper
Cong Wang <[email protected]>
flow_dissector: Fix port range key handling in BPF conversion
Cong Wang <[email protected]>
flow_dissector: Fix handling of mixed port and port-range keys
Kuniyuki Iwashima <[email protected]>
geneve: Suppress list corruption splat in geneve_destroy_tunnels().
Kuniyuki Iwashima <[email protected]>
gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
Nick Child <[email protected]>
ibmvnic: Don't reference skb after sending to VIOS
Nick Child <[email protected]>
ibmvnic: Add stat for tx direct vs tx batched
Nick Child <[email protected]>
ibmvnic: Introduce send sub-crq direct
Nick Child <[email protected]>
ibmvnic: Return error code on TX scrq flush fail
Vitaly Rodionov <[email protected]>
ALSA: hda/cirrus: Correct the full scale volume set logic
Kuniyuki Iwashima <[email protected]>
geneve: Fix use-after-free in geneve_find_dev().
Christophe Leroy <[email protected]>
powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC
Kailang Yang <[email protected]>
ALSA: hda/realtek: Fixup ALC225 depop procedure
Christophe Leroy <[email protected]>
powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline
Michael Ellerman <[email protected]>
powerpc/64s/mm: Move __real_pte stubs into hash-4k.h
John Keeping <[email protected]>
ASoC: rockchip: i2s-tdm: fix shift config for SND_SOC_DAIFMT_DSP_[AB]
Jill Donahue <[email protected]>
USB: gadget: f_midi: f_midi_complete to call queue_work
Roy Luo <[email protected]>
usb: gadget: core: flush gadget workqueue after device removal
Roy Luo <[email protected]>
USB: gadget: core: create sysfs link between udc and gadget
Ricardo Ribalda <[email protected]>
media: uvcvideo: Remove dangling pointers
Ricardo Ribalda <[email protected]>
media: uvcvideo: Only save async fh if success
Ricardo Ribalda <[email protected]>
media: uvcvideo: Refactor iterators
Ricardo Ribalda <[email protected]>
media: uvcvideo: Fix crash during unbind if gpio unit is in use
Yang Yingliang <[email protected]>
media: Switch to use dev_err_probe() helper
Krzysztof Kozlowski <[email protected]>
soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
Uwe Kleine-König <[email protected]>
soc/mediatek: mtk-devapc: Convert to platform remove callback returning void
Krzysztof Kozlowski <[email protected]>
soc: mediatek: mtk-devapc: Fix leaking IO map on error paths
AngeloGioacchino Del Regno <[email protected]>
soc: mediatek: mtk-devapc: Switch to devm_clk_get_enabled()
Jarkko Sakkinen <[email protected]>
tpm: Change to kvalloc() in eventlog/acpi.c
Eddie James <[email protected]>
tpm: Use managed allocation for bios event log
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sm8450: Fix CDSP memory length
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: trim addresses to 8 digits
Chen-Yu Tsai <[email protected]>
arm64: dts: mediatek: mt8183: Disable DSI display output by default
Igor Pylypiv <[email protected]>
scsi: core: Do not retry I/Os during depopulation
Douglas Gilbert <[email protected]>
scsi: core: Handle depopulation and restoration in progress
Dan Carpenter <[email protected]>
ASoC: renesas: rz-ssi: Add a check for negative sample_space
Daniel Golle <[email protected]>
clk: mediatek: mt2701-img: add missing dummy clk
Daniel Golle <[email protected]>
clk: mediatek: mt2701-bdp: add missing dummy clk
Daniel Golle <[email protected]>
clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
AngeloGioacchino Del Regno <[email protected]>
clk: mediatek: clk-mtk: Add dummy clock ops
Zijun Hu <[email protected]>
Bluetooth: qca: Fix poor RF performance for WCN6855
Cheng Jiang <[email protected]>
Bluetooth: qca: Update firmware-name to support board specific nvm
Zijun Hu <[email protected]>
Bluetooth: qca: Support downloading board id specific NVM for WCN7850
Bence Csókás <[email protected]>
spi: atmel-qspi: Memory barriers after memory-mapped I/O
Csókás, Bence <[email protected]>
spi: atmel-quadspi: Create atmel_qspi_ops to support newer SoC families
Yang Yingliang <[email protected]>
spi: atmel-quadspi: switch to use modern name
Tudor Ambarus <[email protected]>
spi: atmel-quadspi: Add support for configuring CS timing
Chen Ridong <[email protected]>
memcg: fix soft lockup in the OOM process
Carlos Galo <[email protected]>
mm: update mark_victim tracepoints fields
Yu Kuai <[email protected]>
md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime
Yu Kuai <[email protected]>
md/md-bitmap: add 'sync_size' into struct md_bitmap_stats
Yu Kuai <[email protected]>
md/md-cluster: fix spares warnings for __le64
Yu Kuai <[email protected]>
md/md-bitmap: replace md_bitmap_status() with a new helper md_bitmap_get_stats()
Yu Kuai <[email protected]>
md: simplify md_seq_ops
Yu Kuai <[email protected]>
md: factor out a helper from mddev_put()
Yu Kuai <[email protected]>
md: use separate work_struct for md_start_sync()
Catalin Marinas <[email protected]>
arm64: mte: Do not allow PROT_MTE on MAP_HUGETLB user mappings
-------------
Diffstat:
Documentation/core-api/pin_user_pages.rst | 6 + Documentation/networking/strparser.rst | 9 +- Makefile | 4 +- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 + arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8450.dtsi | 4 +- arch/arm64/include/asm/mman.h | 9 +- arch/mips/include/asm/ptrace.h | 2 + arch/mips/kernel/ptrace.c | 7 + arch/powerpc/include/asm/book3s/64/hash-4k.h | 28 + arch/powerpc/include/asm/book3s/64/pgtable.h | 26 - arch/powerpc/lib/code-patching.c | 2 +- arch/riscv/include/asm/futex.h | 2 +- arch/x86/Kconfig | 3 +- arch/x86/events/core.c | 2 +- arch/x86/kernel/cpu/bugs.c | 20 +- arch/x86/kernel/cpu/cyrix.c | 4 +- block/bfq-cgroup.c | 97 +-- block/bfq-iosched.c | 195 ++++-- block/bfq-iosched.h | 51 +- drivers/bluetooth/btqca.c | 110 ++- drivers/char/tpm/eventlog/acpi.c | 16 +- drivers/char/tpm/eventlog/efi.c | 13 +- drivers/char/tpm/eventlog/of.c | 3 +- drivers/char/tpm/tpm-chip.c | 1 - drivers/clk/mediatek/clk-mt2701-bdp.c | 1 + drivers/clk/mediatek/clk-mt2701-img.c | 1 + drivers/clk/mediatek/clk-mt2701-vdec.c | 1 + drivers/clk/mediatek/clk-mtk.c | 16 + drivers/clk/mediatek/clk-mtk.h | 19 + drivers/edac/qcom_edac.c | 4 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 14 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 3 +- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 16 +- drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 25 +- drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c | 8 +- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 26 +- drivers/gpu/drm/i915/display/intel_display.c | 18 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 3 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 9 +- drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 2 +- drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 1 - drivers/gpu/drm/tidss/tidss_dispc.c | 22 +- drivers/gpu/drm/tidss/tidss_irq.c | 2 + drivers/i2c/busses/i2c-npcm7xx.c | 7 + drivers/idle/intel_idle.c | 4 + drivers/infiniband/core/sysfs.c | 4 + drivers/infiniband/core/uverbs_std_types_device.c | 3 +- drivers/infiniband/core/verbs.c | 3 + drivers/infiniband/hw/mlx4/main.c | 8 + drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 + drivers/infiniband/hw/mlx4/qp.c | 121 +++- drivers/infiniband/hw/mlx5/ah.c | 3 +- drivers/infiniband/hw/mlx5/counters.c | 8 +- drivers/infiniband/hw/mlx5/main.c | 7 + drivers/infiniband/hw/mlx5/mlx5_ib.h | 60 +- drivers/infiniband/hw/mlx5/mr.c | 742 ++++++++++++++------- drivers/infiniband/hw/mlx5/odp.c | 40 +- drivers/infiniband/hw/mlx5/qp.c | 129 ++-- drivers/infiniband/hw/mlx5/qp.h | 14 +- drivers/infiniband/hw/mlx5/qpc.c | 3 +- drivers/infiniband/hw/mlx5/umr.c | 87 ++- drivers/md/md-bitmap.c | 34 +- drivers/md/md-bitmap.h | 9 +- drivers/md/md-cluster.c | 34 +- drivers/md/md.c | 171 +++-- drivers/md/md.h | 5 +- drivers/media/cec/platform/stm32/stm32-cec.c | 9 +- drivers/media/i2c/ad5820.c | 18 +- drivers/media/i2c/imx274.c | 5 +- drivers/media/i2c/tc358743.c | 9 +- drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c | 5 +- .../platform/mediatek/vcodec/mtk_vcodec_fw_scp.c | 2 + .../mediatek/vcodec/vdec/vdec_h264_req_multi_if.c | 9 +- .../media/platform/samsung/exynos4-is/media-dev.c | 4 +- drivers/media/platform/st/stm32/stm32-dcmi.c | 27 +- drivers/media/platform/ti/omap3isp/isp.c | 3 +- drivers/media/platform/xilinx/xilinx-csi2rxss.c | 8 +- drivers/media/rc/gpio-ir-recv.c | 10 +- drivers/media/rc/gpio-ir-tx.c | 9 +- drivers/media/rc/ir-rx51.c | 9 +- drivers/media/usb/uvc/uvc_ctrl.c | 99 ++- drivers/media/usb/uvc/uvc_driver.c | 35 +- drivers/media/usb/uvc/uvc_v4l2.c | 2 + drivers/media/usb/uvc/uvcvideo.h | 10 +- drivers/mtd/nand/raw/cadence-nand-controller.c | 42 +- drivers/net/ethernet/cadence/macb.h | 2 + drivers/net/ethernet/cadence/macb_main.c | 12 +- drivers/net/ethernet/freescale/enetc/enetc.c | 100 ++- drivers/net/ethernet/ibm/ibmvnic.c | 85 ++- drivers/net/ethernet/ibm/ibmvnic.h | 3 +- drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 2 +- drivers/net/ethernet/mellanox/mlx4/qp.c | 14 +- drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 2 +- drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 2 + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 + drivers/net/geneve.c | 16 +- drivers/net/gtp.c | 5 - drivers/net/ipvlan/ipvlan_core.c | 24 +- drivers/net/loopback.c | 14 + drivers/net/usb/gl620a.c | 4 +- drivers/nvme/host/ioctl.c | 3 +- drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 5 +- drivers/phy/samsung/phy-exynos5-usbdrd.c | 12 +- drivers/phy/tegra/xusb-tegra186.c | 11 + drivers/power/supply/da9150-fg.c | 4 +- drivers/scsi/scsi_lib.c | 22 +- drivers/scsi/sd.c | 4 + drivers/soc/mediatek/mtk-devapc.c | 36 +- drivers/spi/atmel-quadspi.c | 172 +++-- drivers/tee/optee/supp.c | 35 +- drivers/usb/gadget/function/f_midi.c | 2 +- drivers/usb/gadget/udc/core.c | 11 +- fs/afs/cell.c | 1 + fs/afs/internal.h | 23 +- fs/afs/server.c | 1 + fs/afs/server_list.c | 114 +++- fs/afs/vl_alias.c | 2 +- fs/afs/volume.c | 40 +- fs/overlayfs/copy_up.c | 2 +- fs/smb/client/smb2ops.c | 4 + fs/squashfs/inode.c | 5 +- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/mlx4/qp.h | 1 + include/linux/mlx5/driver.h | 10 - include/linux/mm.h | 26 +- include/linux/netdevice.h | 2 + include/linux/ptrace.h | 4 + include/linux/skmsg.h | 2 + include/linux/sunrpc/sched.h | 17 +- include/net/dst.h | 9 + include/net/ip.h | 5 + include/net/netfilter/nf_conntrack_expect.h | 2 +- include/net/route.h | 5 +- include/net/strparser.h | 2 + include/net/tcp.h | 22 + include/rdma/ib_verbs.h | 4 +- include/trace/events/icmp.h | 67 ++ include/trace/events/oom.h | 36 +- include/trace/events/sunrpc.h | 3 +- include/uapi/rdma/ib_user_ioctl_verbs.h | 3 +- io_uring/net.c | 4 +- kernel/acct.c | 134 ++-- kernel/bpf/syscall.c | 18 +- kernel/events/core.c | 17 +- kernel/events/uprobes.c | 5 + kernel/sched/core.c | 2 +- kernel/trace/ftrace.c | 30 +- kernel/trace/trace_events_hist.c | 34 +- kernel/trace/trace_functions.c | 6 +- mm/gup.c | 31 +- mm/madvise.c | 11 +- mm/memcontrol.c | 7 +- mm/memory.c | 4 +- mm/oom_kill.c | 14 +- net/bluetooth/l2cap_core.c | 9 +- net/bpf/test_run.c | 5 +- net/bridge/br_netfilter_hooks.c | 8 +- net/core/dev.c | 37 +- net/core/drop_monitor.c | 39 +- net/core/flow_dissector.c | 49 +- net/core/gro.c | 1 + net/core/skbuff.c | 2 +- net/core/skmsg.c | 7 + net/core/sysctl_net_core.c | 3 +- net/ipv4/arp.c | 2 +- net/ipv4/icmp.c | 24 +- net/ipv4/ip_options.c | 3 +- net/ipv4/tcp.c | 29 +- net/ipv4/tcp_bpf.c | 36 + net/ipv4/tcp_fastopen.c | 4 +- net/ipv4/tcp_input.c | 8 +- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_minisocks.c | 10 +- net/ipv6/ip6_tunnel.c | 4 +- net/ipv6/rpl_iptunnel.c | 58 +- net/ipv6/seg6_iptunnel.c | 97 ++- net/mptcp/pm_netlink.c | 5 - net/mptcp/subflow.c | 15 +- net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_expect.c | 4 +- net/netfilter/nft_ct.c | 2 + net/sched/sch_fifo.c | 3 + net/strparser/strparser.c | 11 +- net/sunrpc/cache.c | 10 +- net/sunrpc/sched.c | 2 - sound/pci/hda/hda_codec.c | 4 +- sound/pci/hda/patch_conexant.c | 1 + sound/pci/hda/patch_cs8409-tables.c | 6 +- sound/pci/hda/patch_cs8409.c | 20 +- sound/pci/hda/patch_cs8409.h | 5 +- sound/pci/hda/patch_realtek.c | 1 + sound/soc/codecs/es8328.c | 15 +- sound/soc/fsl/fsl_micfil.c | 2 + sound/soc/rockchip/rockchip_i2s_tdm.c | 4 +- sound/soc/sh/rz-ssi.c | 2 + sound/usb/midi.c | 2 +- sound/usb/quirks.c | 1 + 199 files changed, 3053 insertions(+), 1460 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/176 arm64: mte: Do not allow PROT_MTE on MAP_HUGETLB user mappings
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
PROT_MTE (memory tagging extensions) is not supported on all user mmap() types for various reasons (memory attributes, backing storage, CoW handling). The arm64 arch_validate_flags() function checks whether the VM_MTE_ALLOWED flag has been set for a vma during mmap(), usually by arch_calc_vm_flag_bits().
Linux prior to 6.13 does not support PROT_MTE hugetlb mappings. This was added by commit 25c17c4b55de ("hugetlb: arm64: add mte support"). However, earlier kernels inadvertently set VM_MTE_ALLOWED on (MAP_ANONYMOUS | MAP_HUGETLB) mappings by only checking for MAP_ANONYMOUS.
Explicitly check MAP_HUGETLB in arch_calc_vm_flag_bits() and avoid setting VM_MTE_ALLOWED for such mappings.
--- arch/arm64/include/asm/mman.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/arm64/include/asm/mman.h +6 -3
@@ -31,9 +31,12 @@ static inline unsigned long arch_calc_vm* backed by tags-capable memory. The vm_flags may be overridden by a * filesystem supporting MTE (RAM-based). */ -if (system_supports_mte () && - ((flags &MAP_ANONYMOUS ) ||shmem_file (file))) -return VM_MTE_ALLOWED ; +if (system_supports_mte ()) { +if ((flags &MAP_ANONYMOUS ) && !(flags &MAP_HUGETLB )) +return VM_MTE_ALLOWED ; +if (shmem_file (file)) +return VM_MTE_ALLOWED ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 2/176 md: use separate work_struct for md_start_sync()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit ac619781967bd5663c29606246b50dbebd8b3473 ]
It's a little weird to borrow 'del_work' for md_start_sync(), declare a new work_struct 'sync_work' for md_start_sync().
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md.c | 10 ++++++---- drivers/md/md.h | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-)
drivers/md/md.c +6 -4
@@ -682,13 +682,13 @@ void mddev_put(struct mddev *mddev)* flush_workqueue() after mddev_find will succeed in waiting * for the work to be done. */ -INIT_WORK (&mddev->del_work, mddev_delayed_delete);queue_work (md_misc_wq, &mddev->del_work); }spin_unlock (&all_mddevs_lock); }static void md_safemode_timeout (struct timer_list *t); +static void md_start_sync (struct work_struct *ws);void mddev_init (struct mddev *mddev) {
@@ -710,6 +710,9 @@ void mddev_init(struct mddev *mddev) mddev->resync_min =0 ; mddev->resync_max = MaxSector; mddev->level =LEVEL_NONE ; + +INIT_WORK (&mddev->sync_work, md_start_sync); +INIT_WORK (&mddev->del_work, mddev_delayed_delete); }EXPORT_SYMBOL_GPL (mddev_init);
@@ -9308,7 +9311,7 @@ static int remove_and_add_spares(struct mddev *mddev,static void md_start_sync (struct work_struct *ws) { - struct mddev *mddev = container_of(ws, struct mddev, del_work); + struct mddev *mddev = container_of(ws, struct mddev, sync_work); mddev->sync_thread = md_register_thread(md_do_sync, mddev,
@@ -9516,8 +9519,7 @@ void md_check_recovery(struct mddev *mddev)*/ md_bitmap_write_all (mddev->bitmap); } -INIT_WORK (&mddev->del_work, md_start_sync); -queue_work (md_misc_wq, &mddev->del_work); +queue_work (md_misc_wq, &mddev->sync_work); goto unlock; } not_running:
drivers/md/md.h +4 -1
@@ -452,7 +452,10 @@ struct mddev {struct kernfs_node *sysfs_degraded;/*handle for 'degraded' */ struct kernfs_node *sysfs_level;/*handle for 'level' */ -struct work_struct del_work;/* used for delayed sysfs removal */ +/* used for delayed sysfs removal */ +struct work_struct del_work; +/* used for register new sync thread */ +struct work_struct sync_work;/* "lock" protects: * flush_bio transition from NULL to !NULL
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 3/176 md: factor out a helper from mddev_put()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 3d8d32873c7b6d9cec5b40c2ddb8c7c55961694f ]
There are no functional changes, prepare to simplify md_seq_ops in next patch.
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
drivers/md/md.c +17 -12
@@ -667,23 +667,28 @@ static inline struct mddev *mddev_get(struct mddev *mddev)static void mddev_delayed_delete (struct work_struct *ws); +static void __mddev_put (struct mddev *mddev) +{ +if (mddev->raid_disks || !list_empty (&mddev->disks) || + mddev->ctime || mddev->hold_active) +return ; + +/* Array is not configured at all, and not held active, so destroy it */ +set_bit (MD_DELETED , &mddev->flags); + +/* +* Call queue_work inside the spinlock so that flush_workqueue() after +* mddev_find will succeed in waiting for the work to be done. +*/ +queue_work (md_misc_wq, &mddev->del_work); +} +void mddev_put (struct mddev *mddev) {if (!atomic_dec_and_lock (&mddev->active, &all_mddevs_lock))return ; -if (!mddev->raid_disks &&list_empty (&mddev->disks) && - mddev->ctime ==0 && !mddev->hold_active) { -/* Array is not configured at all, and not held active, -* so destroy it */ -set_bit (MD_DELETED , &mddev->flags); -/* -* Call queue_work inside the spinlock so that -* flush_workqueue() after mddev_find will succeed in waiting -* for the work to be done. -*/ -queue_work (md_misc_wq, &mddev->del_work); - } +__mddev_put (mddev);spin_unlock (&all_mddevs_lock); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 4/176 md: simplify md_seq_ops
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit cf1b6d4441fffd0ba8ae4ced6a12f578c95ca049 ]
Before this patch, the implementation is hacky and hard to understand:
1) md_seq_start set pos to 1;
2) md_seq_show found pos is 1, then print Personalities;
3) md_seq_next found pos is 1, then it update pos to the first mddev;
4) md_seq_show found pos is not 1 or 2, show mddev;
5) md_seq_next found pos is not 1 or 2, update pos to next mddev;
6) loop 4-5 until the last mddev, then md_seq_next update pos to 2;
7) md_seq_show found pos is 2, then print unused devices;
8) md_seq_next found pos is 2, stop;
This patch remove the magic value and use seq_list_start/next/stop() directly, and move printing "Personalities" to md_seq_start(), "unsed devices" to md_seq_stop():
1) md_seq_start print Personalities, and then set pos to first mddev;
2) md_seq_show show mddev;
3) md_seq_next update pos to next mddev;
4) loop 2-3 until the last mddev;
5) md_seq_stop print unsed devices;
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md.c | 100 +++++++++++------------------------------------- 1 file changed, 22 insertions(+), 78 deletions(-)
drivers/md/md.c +22 -78
@@ -8250,105 +8250,46 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev) }static void *md_seq_start (struct seq_file *seq,loff_t *pos) + __acquires(&all_mddevs_lock) { -struct list_head *tmp; -loff_t l = *pos; -struct mddev *mddev; +struct md_personality *pers; -if (l ==0x10000 ) { - ++*pos; -return (void *)2 ; - } -if (l >0x10000 ) -return NULL ; -if (!l--) -/* header */ -return (void *)1 ; +seq_puts (seq,"Personalities : " ); +spin_lock (&pers_lock); +list_for_each_entry (pers, &pers_list, list) +seq_printf (seq,"[%s] " , pers->name); + +spin_unlock (&pers_lock); +seq_puts (seq,"\n" ); + seq->poll_event =atomic_read (&md_event_count);spin_lock (&all_mddevs_lock); -list_for_each (tmp,&all_mddevs) -if (!l--) { - mddev = list_entry(tmp, struct mddev, all_mddevs); -if (!mddev_get (mddev)) -continue ; -spin_unlock (&all_mddevs_lock); -return mddev; - } -spin_unlock (&all_mddevs_lock); -if (!l--) -return (void *)2 ;/* tail */ -return NULL ; + +return seq_list_start (&all_mddevs, *pos); }static void *md_seq_next (struct seq_file *seq,void *v,loff_t *pos) { -struct list_head *tmp; -struct mddev *next_mddev, *mddev = v; -struct mddev *to_put =NULL ; - - ++*pos; -if (v == (void *)2 ) -return NULL ; - -spin_lock (&all_mddevs_lock); -if (v == (void *)1 ) { - tmp = all_mddevs.next; - }else { - to_put = mddev; - tmp = mddev->all_mddevs.next; - } - -for (;;) { -if (tmp == &all_mddevs) { - next_mddev = (void *)2 ; - *pos =0x10000 ; -break ; - } - next_mddev = list_entry(tmp, struct mddev, all_mddevs); -if (mddev_get (next_mddev)) -break ; - mddev = next_mddev; - tmp = mddev->all_mddevs.next; - } -spin_unlock (&all_mddevs_lock); - -if (to_put) -mddev_put (to_put); -return next_mddev; - +return seq_list_next (v, &all_mddevs, pos); }static void md_seq_stop (struct seq_file *seq,void *v) + __releases(&all_mddevs_lock) { -struct mddev *mddev = v; - -if (mddev && v != (void *)1 && v != (void *)2 ) -mddev_put (mddev); +status_unused (seq); +spin_unlock (&all_mddevs_lock); }static int md_seq_show (struct seq_file *seq,void *v) { -struct mddev *mddev = v; + struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);sector_t sectors;struct md_rdev *rdev; -if (v == (void *)1 ) { -struct md_personality *pers; -seq_printf (seq,"Personalities : " ); -spin_lock (&pers_lock); -list_for_each_entry (pers, &pers_list, list) -seq_printf (seq,"[%s] " , pers->name); - -spin_unlock (&pers_lock); -seq_printf (seq,"\n" ); - seq->poll_event =atomic_read (&md_event_count); +if (!mddev_get (mddev))return 0 ; - } -if (v == (void *)2 ) { -status_unused (seq); -return 0 ; - } +spin_unlock (&all_mddevs_lock);spin_lock (&mddev->lock);if (mddev->pers || mddev->raid_disks || !list_empty (&mddev->disks)) { seq_printf(seq, "%s : %sactive", mdname(mddev),
@@ -8419,6 +8360,9 @@ static int md_seq_show(struct seq_file *seq, void *v)seq_printf (seq,"\n" ); }spin_unlock (&mddev->lock); +spin_lock (&all_mddevs_lock); +if (atomic_dec_and_test (&mddev->active)) +__mddev_put (mddev);return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 5/176 md/md-bitmap: replace md_bitmap_status() with a new helper md_bitmap_get_stats()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 38f287d7e495ae00d4481702f44ff7ca79f5c9bc ]
There are no functional changes, and the new helper will be used in multiple places in following patches to avoid dereferencing bitmap directly.
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md-bitmap.c | 25 ++++++------------------- drivers/md/md-bitmap.h | 8 +++++++- drivers/md/md.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 21 deletions(-)
drivers/md/md-bitmap.c +6 -19
@@ -2022,32 +2022,19 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, }EXPORT_SYMBOL_GPL (md_bitmap_copy_from_slot); - -void md_bitmap_status (struct seq_file *seq,struct bitmap *bitmap) +int md_bitmap_get_stats (struct bitmap *bitmap,struct md_bitmap_stats *stats) { -unsigned long chunk_kb;struct bitmap_counts *counts;if (!bitmap) -return ; +return -ENOENT ; counts = &bitmap->counts; + stats->missing_pages = counts->missing_pages; + stats->pages = counts->pages; + stats->file = bitmap->storage.file; - chunk_kb = bitmap->mddev->bitmap_info.chunksize >>10 ; -seq_printf (seq,"bitmap: %lu/%lu pages [%luKB], " -"%lu%s chunk" , - counts->pages - counts->missing_pages, - counts->pages, - (counts->pages - counts->missing_pages) - << (PAGE_SHIFT -10 ), - chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize, - chunk_kb ?"KB" :"B" ); -if (bitmap->storage.file) { -seq_printf (seq,", file: " ); -seq_file_path (seq, bitmap->storage.file," \t\n" ); - } - -seq_printf (seq,"\n" ); +return 0 ; } int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
drivers/md/md-bitmap.h +7 -1
@@ -233,6 +233,12 @@ struct bitmap {int cluster_slot;/* Slot offset for clustered env */ }; +struct md_bitmap_stats { +unsigned long missing_pages; +unsigned long pages; +struct file *file; +}; +/* the bitmap API */ /* these are used only by md/bitmap */
@@ -243,7 +249,7 @@ void md_bitmap_destroy(struct mddev *mddev);void md_bitmap_print_sb (struct bitmap *bitmap);void md_bitmap_update_sb (struct bitmap *bitmap); -void md_bitmap_status (struct seq_file *seq,struct bitmap *bitmap); +int md_bitmap_get_stats (struct bitmap *bitmap,struct md_bitmap_stats *stats);int md_bitmap_setallbits (struct bitmap *bitmap);void md_bitmap_write_all (struct bitmap *bitmap);
drivers/md/md.c +28 -1
@@ -8280,6 +8280,33 @@ static void md_seq_stop(struct seq_file *seq, void *v)spin_unlock (&all_mddevs_lock); } +static void md_bitmap_status (struct seq_file *seq,struct mddev *mddev) +{ +struct md_bitmap_stats stats; +unsigned long used_pages; +unsigned long chunk_kb; +int err; + + err =md_bitmap_get_stats (mddev->bitmap, &stats); +if (err) +return ; + + chunk_kb = mddev->bitmap_info.chunksize >>10 ; + used_pages = stats.pages - stats.missing_pages; + +seq_printf (seq,"bitmap: %lu/%lu pages [%luKB], %lu%s chunk" , + used_pages, stats.pages, used_pages << (PAGE_SHIFT -10 ), + chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize, + chunk_kb ?"KB" :"B" ); + +if (stats.file) { +seq_puts (seq,", file: " ); +seq_file_path (seq, stats.file," \t\n" ); + } + +seq_putc (seq,'\n' ); +} +static int md_seq_show (struct seq_file *seq,void *v) { struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
@@ -8355,7 +8382,7 @@ static int md_seq_show(struct seq_file *seq, void *v) }else seq_printf (seq,"\n " ); -md_bitmap_status (seq, mddev->bitmap); +md_bitmap_status (seq, mddev);seq_printf (seq,"\n" ); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 6/176 md/md-cluster: fix spares warnings for __le64
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 82697ccf7e495c1ba81e315c2886d6220ff84c2c ]
drivers/md/md-cluster.c:1220:22: warning: incorrect type in assignment (different base types)drivers/md/md-cluster.c:1220:22: expected unsigned long my_sync_sizedrivers/md/md-cluster.c:1220:22: got restricted __le64 [usertype] sync_sizedrivers/md/md-cluster.c:1252:35: warning: incorrect type in assignment (different base types)drivers/md/md-cluster.c:1252:35: expected unsigned long sync_sizedrivers/md/md-cluster.c:1252:35: got restricted __le64 [usertype] sync_sizedrivers/md/md-cluster.c:1253:41: warning: restricted __le64 degrades to integer
Fix the warnings by using le64_to_cpu() to convet __le64 to integer.
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md-cluster.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/md/md-cluster.c +3 -3
@@ -1195,7 +1195,7 @@ static int cluster_check_sync_size(struct mddev *mddev)struct dlm_lock_resource *bm_lockres; sb =kmap_atomic (bitmap->storage.sb_page); - my_sync_size = sb->sync_size; + my_sync_size =le64_to_cpu (sb->sync_size);kunmap_atomic (sb);for (i =0 ; i < node_num; i++) {
@@ -1227,8 +1227,8 @@ static int cluster_check_sync_size(struct mddev *mddev) sb =kmap_atomic (bitmap->storage.sb_page);if (sync_size ==0 ) - sync_size = sb->sync_size; -else if (sync_size != sb->sync_size) { + sync_size =le64_to_cpu (sb->sync_size); +else if (sync_size !=le64_to_cpu (sb->sync_size)) {kunmap_atomic (sb);md_bitmap_free (bitmap);return -1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 7/176 md/md-bitmap: add sync_size into struct md_bitmap_stats
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit ec6bb299c7c3dd4ca1724d13d5f5fae3ee54fc65 ]
To avoid dereferencing bitmap directly in md-cluster to prepare inventing a new bitmap.
BTW, also fix following checkpatch warnings:
WARNING: Deprecated use of 'kmap_atomic', prefer 'kmap_local_page' instead
WARNING: Deprecated use of 'kunmap_atomic', prefer 'kunmap_local' instead
Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
--- drivers/md/md-bitmap.c | 6 ++++++ drivers/md/md-bitmap.h | 1 + drivers/md/md-cluster.c | 34 ++++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 14 deletions(-)
drivers/md/md-bitmap.c +6 -0
@@ -2025,10 +2025,15 @@ EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);int md_bitmap_get_stats (struct bitmap *bitmap,struct md_bitmap_stats *stats) {struct bitmap_counts *counts; +bitmap_super_t *sb;if (!bitmap)return -ENOENT ; + sb =kmap_local_page (bitmap->storage.sb_page); + stats->sync_size =le64_to_cpu (sb->sync_size); +kunmap_local (sb); + counts = &bitmap->counts; stats->missing_pages = counts->missing_pages; stats->pages = counts->pages;
@@ -2036,6 +2041,7 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)return 0 ; } +EXPORT_SYMBOL_GPL (md_bitmap_get_stats);int md_bitmap_resize (struct bitmap *bitmap,sector_t blocks,int chunksize,int init)
drivers/md/md-bitmap.h +1 -0
@@ -235,6 +235,7 @@ struct bitmap {struct md_bitmap_stats {unsigned long missing_pages; +unsigned long sync_size;unsigned long pages;struct file *file; };
drivers/md/md-cluster.c +20 -14
@@ -1185,18 +1185,21 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz*/ static int cluster_check_sync_size (struct mddev *mddev) { -int i, rv; -bitmap_super_t *sb; -unsigned long my_sync_size, sync_size =0 ; -int node_num = mddev->bitmap_info.nodes;int current_slot = md_cluster_ops->slot_number (mddev); +int node_num = mddev->bitmap_info.nodes;struct bitmap *bitmap = mddev->bitmap; -char str[64 ];struct dlm_lock_resource *bm_lockres; +struct md_bitmap_stats stats; +unsigned long sync_size =0 ; +unsigned long my_sync_size; +char str[64 ]; +int i, rv; - sb =kmap_atomic (bitmap->storage.sb_page); - my_sync_size =le64_to_cpu (sb->sync_size); -kunmap_atomic (sb); + rv =md_bitmap_get_stats (bitmap, &stats); +if (rv) +return rv; + + my_sync_size = stats.sync_size;for (i =0 ; i < node_num; i++) {if (i == current_slot)
@@ -1225,15 +1228,18 @@ static int cluster_check_sync_size(struct mddev *mddev)md_bitmap_update_sb (bitmap);lockres_free (bm_lockres); - sb =kmap_atomic (bitmap->storage.sb_page); -if (sync_size ==0 ) - sync_size =le64_to_cpu (sb->sync_size); -else if (sync_size !=le64_to_cpu (sb->sync_size)) { -kunmap_atomic (sb); + rv =md_bitmap_get_stats (bitmap, &stats); +if (rv) { +md_bitmap_free (bitmap); +return rv; + } + +if (sync_size ==0 ) { + sync_size = stats.sync_size; + }else if (sync_size != stats.sync_size) {md_bitmap_free (bitmap);return -1 ; } -kunmap_atomic (sb);md_bitmap_free (bitmap); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 8/176 md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 8d28d0ddb986f56920ac97ae704cc3340a699a30 ]
After commit ec6bb299c7c3 ("md/md-bitmap: add 'sync_size' into struct md_bitmap_stats"), following panic is reported:
Oops: general protection fault, probably for non-canonical address RIP: 0010:bitmap_get_stats+0x2b/0xa0 Call Trace: <TASK> md_seq_show+0x2d2/0x5b0 seq_read_iter+0x2b9/0x470 seq_read+0x12f/0x180 proc_reg_read+0x57/0xb0 vfs_read+0xf6/0x380 ksys_read+0x6c/0xf0 do_syscall_64+0x82/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Root cause is that bitmap_get_stats() can be called at anytime if mddev is still there, even if bitmap is destroyed, or not fully initialized. Deferenceing bitmap in this case can crash the kernel. Meanwhile, the above commit start to deferencing bitmap->storage, make the problem easier to trigger.
Fix the problem by protecting bitmap_get_stats() with bitmap_info.mutex.
--- drivers/md/md-bitmap.c | 5 ++++- drivers/md/md.c | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/md/md-bitmap.c +4 -1
@@ -2029,7 +2029,10 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)if (!bitmap)return -ENOENT ; - +if (bitmap->mddev->bitmap_info.external) +return -ENOENT ; +if (!bitmap->storage.sb_page)/* no superblock */ +return -EINVAL ; sb =kmap_local_page (bitmap->storage.sb_page); stats->sync_size =le64_to_cpu (sb->sync_size);kunmap_local (sb);
drivers/md/md.c +5 -0
@@ -8317,6 +8317,10 @@ static int md_seq_show(struct seq_file *seq, void *v)return 0 ;spin_unlock (&all_mddevs_lock); + +/* prevent bitmap to be freed after checking */ +mutex_lock (&mddev->bitmap_info.mutex); +spin_lock (&mddev->lock);if (mddev->pers || mddev->raid_disks || !list_empty (&mddev->disks)) { seq_printf(seq, "%s : %sactive", mdname(mddev),
@@ -8387,6 +8391,7 @@ static int md_seq_show(struct seq_file *seq, void *v)seq_printf (seq,"\n" ); }spin_unlock (&mddev->lock); +mutex_unlock (&mddev->bitmap_info.mutex);spin_lock (&all_mddevs_lock);if (atomic_dec_and_test (&mddev->active))__mddev_put (mddev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 9/176 mm: update mark_victim tracepoints fields
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Galo <[email protected]>
[ Upstream commit 72ba14deb40a9e9668ec5e66a341ed657e5215c2 ]
The current implementation of the mark_victim tracepoint provides only the process ID (pid) of the victim process. This limitation poses challenges for userspace tools requiring real-time OOM analysis and intervention. Although this information is available from the kernel logs, it’s not the appropriate format to provide OOM notifications. In Android, BPF programs are used with the mark_victim trace events to notify userspace of an OOM kill. For consistency, update the trace event to include the same information about the OOMed victim as the kernel logs.
- UID
In Android each installed application has a unique UID. Including the uid assists in correlating OOM events with specific apps.
- Process Name (comm)
Enables identification of the affected process.
- OOM Score
Will allow userspace to get additional insight of the relative kill priority of the OOM victim. In Android, the oom_score_adj is used to categorize app state (foreground, background, etc.), which aids in analyzing user-perceptible impacts of OOM events [1].
- Total VM, RSS Stats, and pgtables
Amount of memory used by the victim that will, potentially, be freed up by killing it.
Stable-dep-of: ade81479c7dd ("memcg: fix soft lockup in the OOM process")
--- include/trace/events/oom.h | 36 ++++++++++++++++++++++++++++++++---- mm/oom_kill.c | 6 +++++- 2 files changed, 37 insertions(+), 5 deletions(-)
include/trace/events/oom.h +32 -4
@@ -7,6 +7,8 @@#include <linux/tracepoint.h> #include <trace/events/mmflags.h> +#define PG_COUNT_TO_KB (x) ((x) << (PAGE_SHIFT - 10)) + TRACE_EVENT(oom_score_adj_update, TP_PROTO(struct task_struct *task),
@@ -72,19 +74,45 @@ TRACE_EVENT(reclaim_retry_zone, );TRACE_EVENT (mark_victim, - TP_PROTO(int pid), + TP_PROTO(struct task_struct *task, uid_t uid), -TP_ARGS (pid), +TP_ARGS (task, uid),TP_STRUCT__entry ( __field(int, pid) + __string(comm, task->comm) + __field(unsigned long, total_vm) + __field(unsigned long, anon_rss) + __field(unsigned long, file_rss) + __field(unsigned long, shmem_rss) + __field(uid_t, uid) + __field(unsigned long, pgtables) +__field (short, oom_score_adj) ),TP_fast_assign ( - __entry->pid = pid; + __entry->pid = task->pid; + __assign_str(comm, task->comm); + __entry->total_vm = PG_COUNT_TO_KB(task->mm->total_vm); + __entry->anon_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_ANONPAGES)); + __entry->file_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_FILEPAGES)); + __entry->shmem_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_SHMEMPAGES)); + __entry->uid = uid; + __entry->pgtables = mm_pgtables_bytes(task->mm) >> 10; + __entry->oom_score_adj = task->signal->oom_score_adj; ), -TP_printk ("pid=%d" , __entry->pid) +TP_printk ("pid=%d comm=%s total-vm=%lukB anon-rss=%lukB file-rss:%lukB shmem-rss:%lukB uid=%u pgtables=%lukB oom_score_adj=%hd" , + __entry->pid, +__get_str (comm), + __entry->total_vm, + __entry->anon_rss, + __entry->file_rss, + __entry->shmem_rss, + __entry->uid, + __entry->pgtables, + __entry->oom_score_adj + ) ); TRACE_EVENT(wake_reaper,
mm/oom_kill.c +5 -1
@@ -44,6 +44,7 @@#include <linux/kthread.h> #include <linux/init.h> #include <linux/mmu_notifier.h> +#include <linux/cred.h> #include <asm/tlb.h> #include "internal.h"
@@ -757,6 +758,7 @@ static inline void queue_oom_reaper(struct task_struct *tsk)*/ static void mark_oom_victim (struct task_struct *tsk) { +const struct cred *cred;struct mm_struct *mm = tsk->mm;WARN_ON (oom_killer_disabled);
@@ -776,7 +778,9 @@ static void mark_oom_victim(struct task_struct *tsk)*/ __thaw_task (tsk);atomic_inc (&oom_victims); -trace_mark_victim (tsk->pid); + cred =get_task_cred (tsk); +trace_mark_victim (tsk, cred->uid.val); +put_cred (cred); }/**
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 10/176 memcg: fix soft lockup in the OOM process
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ridong <[email protected]>
[ Upstream commit ade81479c7dda1ce3eedb215c78bc615bbd04f06 ]
A soft lockup issue was found in the product with about 56,000 tasks were in the OOM cgroup, it was traversing them when the soft lockup was triggered.
watchdog: BUG: soft lockup - CPU#2 stuck for 23s! [VM Thread:1503066] CPU: 2 PID: 1503066 Comm: VM Thread Kdump: loaded Tainted: G Hardware name: Huawei Cloud OpenStack Nova, BIOS RIP: 0010:console_unlock+0x343/0x540 RSP: 0000:ffffb751447db9a0 EFLAGS: 00000247 ORIG_RAX: ffffffffffffff13 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000ffffffff RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000247 RBP: ffffffffafc71f90 R08: 0000000000000000 R09: 0000000000000040 R10: 0000000000000080 R11: 0000000000000000 R12: ffffffffafc74bd0 R13: ffffffffaf60a220 R14: 0000000000000247 R15: 0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f2fe6ad91f0 CR3: 00000004b2076003 CR4: 0000000000360ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: vprintk_emit+0x193/0x280 printk+0x52/0x6e dump_task+0x114/0x130 mem_cgroup_scan_tasks+0x76/0x100 dump_header+0x1fe/0x210 oom_kill_process+0xd1/0x100 out_of_memory+0x125/0x570 mem_cgroup_out_of_memory+0xb5/0xd0 try_charge+0x720/0x770 mem_cgroup_try_charge+0x86/0x180 mem_cgroup_try_charge_delay+0x1c/0x40 do_anonymous_page+0xb5/0x390 handle_mm_fault+0xc4/0x1f0
This is because thousands of processes are in the OOM cgroup, it takes a long time to traverse all of them. As a result, this lead to soft lockup in the OOM process.
To fix this issue, call 'cond_resched' in the 'mem_cgroup_scan_tasks' function per 1000 iterations. For global OOM, call 'touch_softlockup_watchdog' per 1000 iterations to avoid this issue.
--- mm/memcontrol.c | 7 ++++++- mm/oom_kill.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
mm/memcontrol.c +6 -1
@@ -1242,6 +1242,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, {struct mem_cgroup *iter;int ret =0 ; +int i =0 ;BUG_ON (memcg == root_mem_cgroup);
@@ -1250,8 +1251,12 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,struct task_struct *task;css_task_iter_start (&iter->css,CSS_TASK_ITER_PROCS , &it); -while (!ret && (task =css_task_iter_next (&it))) +while (!ret && (task =css_task_iter_next (&it))) { +/* Avoid potential softlockup warning */ +if ((++i &1023 ) ==0 ) +cond_resched (); ret =fn (task, arg); + }css_task_iter_end (&it);if (ret) {mem_cgroup_iter_break (memcg, iter);
mm/oom_kill.c +7 -1
@@ -45,6 +45,7 @@#include <linux/init.h> #include <linux/mmu_notifier.h> #include <linux/cred.h> +#include <linux/nmi.h> #include <asm/tlb.h> #include "internal.h"
@@ -430,10 +431,15 @@ static void dump_tasks(struct oom_control *oc)mem_cgroup_scan_tasks (oc->memcg, dump_task, oc); else {struct task_struct *p; +int i =0 ;rcu_read_lock (); -for_each_process (p) +for_each_process (p) { +/* Avoid potential softlockup warning */ +if ((++i &1023 ) ==0 ) +touch_softlockup_watchdog ();dump_task (p, oc); + }rcu_read_unlock (); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 11/176 spi: atmel-quadspi: Add support for configuring CS timing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus <[email protected]>
[ Upstream commit f732646d0ccd22f42ed7de5e59c0abb7a848e034 ]
The at91 QSPI IP uses a default value of half of the period of the QSPI clock period for the cs-setup time, which is not always enough, an example being the sst26vf064b SPI NOR flash which requires a minimum cs-setup time of 5 ns. It was observed that none of the at91 SoCs can fulfill the minimum CS setup time for the aforementioned flash, as they operate at high frequencies and half a period does not suffice for the required CS setup time. Add support for configuring the CS timing in the controller.
Stable-dep-of: be92ab2de0ee ("spi: atmel-qspi: Memory barriers after memory-mapped I/O")
--- drivers/spi/atmel-quadspi.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
drivers/spi/atmel-quadspi.c +34 -0
@@ -510,6 +510,39 @@ static int atmel_qspi_setup(struct spi_device *spi)return 0 ; } +static int atmel_qspi_set_cs_timing (struct spi_device *spi) +{ +struct spi_controller *ctrl = spi->master; +struct atmel_qspi *aq =spi_controller_get_devdata (ctrl); +unsigned long clk_rate; +u32 cs_setup; +int delay; +int ret; + + delay =spi_delay_to_ns (&spi->cs_setup,NULL ); +if (delay <=0 ) +return delay; + + clk_rate =clk_get_rate (aq->pclk); +if (!clk_rate) +return -EINVAL ; + + cs_setup =DIV_ROUND_UP ((delay *DIV_ROUND_UP (clk_rate,1000000 )), +1000 ); + + ret =pm_runtime_resume_and_get (ctrl->dev.parent); +if (ret <0 ) +return ret; + + aq->scr |=QSPI_SCR_DLYBS (cs_setup); +atmel_qspi_write (aq->scr, aq,QSPI_SCR ); + +pm_runtime_mark_last_busy (ctrl->dev.parent); +pm_runtime_put_autosuspend (ctrl->dev.parent); + +return 0 ; +} +static void atmel_qspi_init (struct atmel_qspi *aq) {/* Reset the QSPI controller */
@@ -555,6 +588,7 @@ static int atmel_qspi_probe(struct platform_device *pdev) ctrl->mode_bits =SPI_RX_DUAL |SPI_RX_QUAD |SPI_TX_DUAL |SPI_TX_QUAD ; ctrl->setup = atmel_qspi_setup; + ctrl->set_cs_timing = atmel_qspi_set_cs_timing; ctrl->bus_num =-1 ; ctrl->mem_ops = &atmel_qspi_mem_ops; ctrl->num_chipselect =1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 12/176 spi: atmel-quadspi: switch to use modern name
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit ccbc6554ed66dc37778b8ed823bcaaabfb1731cf ]
Change legacy name master to modern name host or controller.
No functional changed.
Stable-dep-of: be92ab2de0ee ("spi: atmel-qspi: Memory barriers after memory-mapped I/O")
--- drivers/spi/atmel-quadspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/spi/atmel-quadspi.c +4 -4
@@ -406,7 +406,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,static int atmel_qspi_exec_op (struct spi_mem *mem,const struct spi_mem_op *op) { -struct atmel_qspi *aq =spi_controller_get_devdata (mem->spi->master); +struct atmel_qspi *aq =spi_controller_get_devdata (mem->spi->controller);u32 sr, offset;int err;
@@ -476,7 +476,7 @@ static const struct spi_controller_mem_ops atmel_qspi_mem_ops = {static int atmel_qspi_setup (struct spi_device *spi) { -struct spi_controller *ctrl = spi->master; +struct spi_controller *ctrl = spi->controller;struct atmel_qspi *aq =spi_controller_get_devdata (ctrl);unsigned long src_rate;u32 scbr;
@@ -512,7 +512,7 @@ static int atmel_qspi_setup(struct spi_device *spi)static int atmel_qspi_set_cs_timing (struct spi_device *spi) { -struct spi_controller *ctrl = spi->master; +struct spi_controller *ctrl = spi->controller;struct atmel_qspi *aq =spi_controller_get_devdata (ctrl);unsigned long clk_rate;u32 cs_setup;
@@ -582,7 +582,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)struct resource *res;int irq, err =0 ; - ctrl =devm_spi_alloc_master (&pdev->dev,sizeof (*aq)); + ctrl =devm_spi_alloc_host (&pdev->dev,sizeof (*aq));if (!ctrl)return -ENOMEM ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 13/176 spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC families
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Csókás, Bence <[email protected]>
[ Upstream commit c0a0203cf57963792d59b3e4317a1d07b73df42a ]
Refactor the code to introduce an ops struct, to prepare for merging support for later SoCs, such as SAMA7G5. This code was based on the vendor's kernel (linux4microchip). Cc'ing original contributors.
Stable-dep-of: be92ab2de0ee ("spi: atmel-qspi: Memory barriers after memory-mapped I/O")
--- drivers/spi/atmel-quadspi.c | 111 +++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 34 deletions(-)
drivers/spi/atmel-quadspi.c +77 -34
@@ -138,11 +138,15 @@#define QSPI_WPSR_WPVSRC_MASK GENMASK(15, 8)#define QSPI_WPSR_WPVSRC (src) (((src) << 8) & QSPI_WPSR_WPVSRC) +#define ATMEL_QSPI_TIMEOUT 1000/* ms */ +struct atmel_qspi_caps {bool has_qspick;bool has_ricr; }; +struct atmel_qspi_ops ; +struct atmel_qspi {void __iomem *regs;void __iomem *mem;
@@ -150,13 +154,22 @@ struct atmel_qspi {struct clk *qspick;struct platform_device *pdev;const struct atmel_qspi_caps *caps; +const struct atmel_qspi_ops *ops;resource_size_t mmap_size;u32 pending; +u32 irq_mask;u32 mr;u32 scr;struct completion cmd_completion; }; +struct atmel_qspi_ops { +int (*set_cfg)(struct atmel_qspi *aq,const struct spi_mem_op *op, +u32 *offset); +int (*transfer)(struct spi_mem *mem,const struct spi_mem_op *op, +u32 offset); +}; +struct atmel_qspi_mode {u8 cmd_buswidth;u8 addr_buswidth;
@@ -404,10 +417,60 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,return 0 ; } +static int atmel_qspi_wait_for_completion (struct atmel_qspi *aq,u32 irq_mask) +{ +int err =0 ; +u32 sr; + +/* Poll INSTRuction End status */ + sr =atmel_qspi_read (aq,QSPI_SR ); +if ((sr & irq_mask) == irq_mask) +return 0 ; + +/* Wait for INSTRuction End interrupt */ +reinit_completion (&aq->cmd_completion); + aq->pending = sr & irq_mask; + aq->irq_mask = irq_mask; +atmel_qspi_write (irq_mask, aq,QSPI_IER ); +if (!wait_for_completion_timeout (&aq->cmd_completion, +msecs_to_jiffies (ATMEL_QSPI_TIMEOUT ))) + err = -ETIMEDOUT ; +atmel_qspi_write (irq_mask, aq,QSPI_IDR ); + +return err; +} + +static int atmel_qspi_transfer (struct spi_mem *mem, +const struct spi_mem_op *op,u32 offset) +{ +struct atmel_qspi *aq =spi_controller_get_devdata (mem->spi->controller); + +/* Skip to the final steps if there is no data */ +if (!op->data.nbytes) +return atmel_qspi_wait_for_completion (aq, +QSPI_SR_CMD_COMPLETED ); + +/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ + (void )atmel_qspi_read (aq,QSPI_IFR ); + +/* Send/Receive data */ +if (op->data.dir ==SPI_MEM_DATA_IN ) +memcpy_fromio (op->data.buf.in, aq->mem + offset, + op->data.nbytes); +else +memcpy_toio (aq->mem + offset, op->data.buf.out, + op->data.nbytes); + +/* Release the chip-select */ +atmel_qspi_write (QSPI_CR_LASTXFER , aq,QSPI_CR ); + +return atmel_qspi_wait_for_completion (aq,QSPI_SR_CMD_COMPLETED ); +} +static int atmel_qspi_exec_op (struct spi_mem *mem,const struct spi_mem_op *op) {struct atmel_qspi *aq =spi_controller_get_devdata (mem->spi->controller); -u32 sr, offset; +u32 offset;int err;/*
@@ -416,46 +479,20 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)* when the flash memories overrun the controller's memory space. */ if (op->addr.val + op->data.nbytes > aq->mmap_size) -return -ENOTSUPP ; +return -EOPNOTSUPP ; + +if (op->addr.nbytes >4 ) +return -EOPNOTSUPP ; err =pm_runtime_resume_and_get (&aq->pdev->dev);if (err <0 )return err; - err =atmel_qspi_set_cfg (aq, op, &offset); + err = aq->ops->set_cfg (aq, op, &offset);if (err) goto pm_runtime_put; -/* Skip to the final steps if there is no data */ -if (op->data.nbytes) { -/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ - (void )atmel_qspi_read (aq,QSPI_IFR ); - -/* Send/Receive data */ -if (op->data.dir ==SPI_MEM_DATA_IN ) -memcpy_fromio (op->data.buf.in, aq->mem + offset, - op->data.nbytes); -else -memcpy_toio (aq->mem + offset, op->data.buf.out, - op->data.nbytes); - -/* Release the chip-select */ -atmel_qspi_write (QSPI_CR_LASTXFER , aq,QSPI_CR ); - } - -/* Poll INSTRuction End status */ - sr =atmel_qspi_read (aq,QSPI_SR ); -if ((sr &QSPI_SR_CMD_COMPLETED ) ==QSPI_SR_CMD_COMPLETED ) - goto pm_runtime_put; - -/* Wait for INSTRuction End interrupt */ -reinit_completion (&aq->cmd_completion); - aq->pending = sr &QSPI_SR_CMD_COMPLETED ; -atmel_qspi_write (QSPI_SR_CMD_COMPLETED , aq,QSPI_IER ); -if (!wait_for_completion_timeout (&aq->cmd_completion, -msecs_to_jiffies (1000 ))) - err = -ETIMEDOUT ; -atmel_qspi_write (QSPI_SR_CMD_COMPLETED , aq,QSPI_IDR ); + err = aq->ops->transfer (mem, op, offset); pm_runtime_put:pm_runtime_mark_last_busy (&aq->pdev->dev);
@@ -569,12 +606,17 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)return IRQ_NONE ; aq->pending |= pending; -if ((aq->pending &QSPI_SR_CMD_COMPLETED ) ==QSPI_SR_CMD_COMPLETED ) +if ((aq->pending & aq->irq_mask) == aq->irq_mask)complete (&aq->cmd_completion);return IRQ_HANDLED ; } +static const struct atmel_qspi_ops atmel_qspi_ops = { + .set_cfg = atmel_qspi_set_cfg, + .transfer = atmel_qspi_transfer, +}; +static int atmel_qspi_probe (struct platform_device *pdev) {struct spi_controller *ctrl;
@@ -599,6 +641,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)init_completion (&aq->cmd_completion); aq->pdev = pdev; + aq->ops = &atmel_qspi_ops;/* Map the registers */ res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"qspi_base" );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 14/176 spi: atmel-qspi: Memory barriers after memory-mapped I/O
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bence Csókás <[email protected]>
[ Upstream commit be92ab2de0ee1a13291c3b47b2d7eb24d80c0a2c ]
The QSPI peripheral control and status registers are accessible via the SoC's APB bus, whereas MMIO transactions' data travels on the AHB bus.
Microchip documentation and even sample code from Atmel emphasises the need for a memory barrier before the first MMIO transaction to the AHB-connected QSPI, and before the last write to its registers via APB. This is achieved by the following lines in atmel_qspi_transfer():
/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ (void)atmel_qspi_read(aq, QSPI_IFR);
However, the current documentation makes no mention to synchronization requirements in the other direction, i.e. after the last data written via AHB, and before the first register access on APB.
In our case, we were facing an issue where the QSPI peripheral would cease to send any new CSR (nCS Rise) interrupts, leading to a timeout in atmel_qspi_wait_for_completion() and ultimately this panic in higher levels:
ubi0 error: ubi_io_write: error -110 while writing 63108 bytes
to PEB 491:128, written 63104 bytes
After months of extensive research of the codebase, fiddling around the debugger with kgdb, and back-and-forth with Microchip, we came to the conclusion that the issue is probably that the peripheral is still busy receiving on AHB when the LASTXFER bit is written to its Control Register on APB, therefore this write gets lost, and the peripheral still thinks there is more data to come in the MMIO transfer. This was first formulated when we noticed that doubling the write() of QSPI_CR_LASTXFER seemed to solve the problem.
Ultimately, the solution is to introduce memory barriers after the AHB-mapped MMIO transfers, to ensure ordering.
--- drivers/spi/atmel-quadspi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/spi/atmel-quadspi.c +9 -2
@@ -454,13 +454,20 @@ static int atmel_qspi_transfer(struct spi_mem *mem, (void )atmel_qspi_read (aq,QSPI_IFR );/* Send/Receive data */ -if (op->data.dir ==SPI_MEM_DATA_IN ) +if (op->data.dir ==SPI_MEM_DATA_IN ) {memcpy_fromio (op->data.buf.in, aq->mem + offset, op->data.nbytes); -else + +/* Synchronize AHB and APB accesses again */ +rmb (); + }else {memcpy_toio (aq->mem + offset, op->data.buf.out, op->data.nbytes); +/* Synchronize AHB and APB accesses again */ +wmb (); + } +/* Release the chip-select */ atmel_qspi_write (QSPI_CR_LASTXFER , aq,QSPI_CR );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 15/176 Bluetooth: qca: Support downloading board id specific NVM for WCN7850
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit e41137d8bd1a8e8bab8dcbfe3ec056418db3df18 ]
Download board id specific NVM instead of default for WCN7850 if board id is available.
Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855")
--- drivers/bluetooth/btqca.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/bluetooth/btqca.c +15 -3
@@ -739,6 +739,19 @@ static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,snprintf (fwname, max_size,"qca/hpnv%02x%s.%x" , rom_ver, variant, bid); } +static inline void qca_get_nvm_name_generic (struct qca_fw_config *cfg, +const char *stem,u8 rom_ver,u16 bid) +{ +if (bid ==0x0 ) +snprintf (cfg->fwname,sizeof (cfg->fwname),"qca/%snv%02x.bin" , stem, rom_ver); +else if (bid &0xff00 ) +snprintf (cfg->fwname,sizeof (cfg->fwname), +"qca/%snv%02x.b%x" , stem, rom_ver, bid); +else +snprintf (cfg->fwname,sizeof (cfg->fwname), +"qca/%snv%02x.b%02x" , stem, rom_ver, bid); +} +int qca_uart_setup (struct hci_dev *hdev,uint8_t baudrate,enum qca_btsoc_type soc_type,struct qca_btsoc_version ver,const char *firmware_name)
@@ -819,7 +832,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,/* Give the controller some time to get ready to receive the NVM */ msleep (10 ); -if (soc_type ==QCA_QCA2066 ) +if (soc_type ==QCA_QCA2066 || soc_type ==QCA_WCN7850 )qca_read_fw_board_id (hdev, &boardid);/* Download NVM configuration */
@@ -861,8 +874,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/hpnv%02x.bin", rom_ver);break ;case QCA_WCN7850 : -snprintf (config.fwname,sizeof (config.fwname), -"qca/hmtnv%02x.bin" , rom_ver); +qca_get_nvm_name_generic (&config,"hmt" , rom_ver, boardid);break ;default :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 16/176 Bluetooth: qca: Update firmware-name to support board specific nvm
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Jiang <[email protected]>
[ Upstream commit a4c5a468c6329bde7dfd46bacff2cbf5f8a8152e ]
Different connectivity boards may be attached to the same platform. For example, QCA6698-based boards can support either a two-antenna or three-antenna solution, both of which work on the sa8775p-ride platform. Due to differences in connectivity boards and variations in RF performance from different foundries, different NVM configurations are used based on the board ID.
Therefore, in the firmware-name property, if the NVM file has an extension, the NVM file will be used. Otherwise, the system will first try the .bNN (board ID) file, and if that fails, it will fall back to the .bin file.
Possible configurations:
firmware-name = "QCA6698/hpnv21";
firmware-name = "QCA6698/hpnv21.bin";
Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855")
--- drivers/bluetooth/btqca.c | 113 ++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 28 deletions(-)
drivers/bluetooth/btqca.c +85 -28
@@ -289,6 +289,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) }EXPORT_SYMBOL_GPL (qca_send_pre_shutdown_cmd); +static bool qca_filename_has_extension (const char *filename) +{ +const char *suffix =strrchr (filename,'.' ); + +/* File extensions require a dot, but not as the first or last character */ +if (!suffix || suffix == filename || *(suffix +1 ) =='\0' ) +return 0 ; + +/* Avoid matching directories with names that look like files with extensions */ +return !strchr (suffix,'/' ); +} + +static bool qca_get_alt_nvm_file (char *filename,size_t max_size) +{ +char fwname[64 ]; +const char *suffix; + +/* nvm file name has an extension, replace with .bin */ +if (qca_filename_has_extension (filename)) { + suffix =strrchr (filename,'.' ); +strscpy (fwname, filename, suffix - filename +1 ); +snprintf (fwname + (suffix - filename), +sizeof (fwname) - (suffix - filename),".bin" ); +/* If nvm file is already the default one, return false to skip the retry. */ +if (strcmp (fwname, filename) ==0 ) +return false; + +snprintf (filename, max_size,"%s" , fwname); +return true; + } +return false; +} + static int qca_tlv_check_data(struct hci_dev *hdev, struct qca_fw_config *config, u8 *fw_data, size_t fw_size,
@@ -586,6 +619,19 @@ static int qca_download_firmware(struct hci_dev *hdev, config->fwname, ret);return ret; } + } +/* If the board-specific file is missing, try loading the default +* one, unless that was attempted already. +*/ +else if (config->type ==TLV_TYPE_NVM && +qca_get_alt_nvm_file (config->fwname,sizeof (config->fwname))) { +bt_dev_info (hdev,"QCA Downloading %s" , config->fwname); + ret =request_firmware (&fw, config->fwname, &hdev->dev); +if (ret) { +bt_dev_err (hdev,"QCA Failed to request file: %s (%d)" , + config->fwname, ret); +return ret; + } }else {bt_dev_err (hdev,"QCA Failed to request file: %s (%d)" , config->fwname, ret);
@@ -722,34 +768,38 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *coreturn 0 ; } -static void qca_generate_hsp_nvm_name (char *fwname,size_t max_size, +static void qca_get_nvm_name_by_board (char *fwname,size_t max_size, +const char *stem,enum qca_btsoc_type soc_type,struct qca_btsoc_version ver,u8 rom_ver,u16 bid) {const char *variant; +const char *prefix; -/* hsp gf chip */ -if ((le32_to_cpu (ver.soc_id) &QCA_HSP_GF_SOC_MASK ) ==QCA_HSP_GF_SOC_ID ) - variant ="g" ; -else - variant ="" ; +/* Set the default value to variant and prefix */ + variant ="" ; + prefix ="b" ; -if (bid ==0x0 ) -snprintf (fwname, max_size,"qca/hpnv%02x%s.bin" , rom_ver, variant); -else -snprintf (fwname, max_size,"qca/hpnv%02x%s.%x" , rom_ver, variant, bid); -} +if (soc_type ==QCA_QCA2066 ) + prefix ="" ; -static inline void qca_get_nvm_name_generic (struct qca_fw_config *cfg, -const char *stem,u8 rom_ver,u16 bid) -{ -if (bid ==0x0 ) -snprintf (cfg->fwname,sizeof (cfg->fwname),"qca/%snv%02x.bin" , stem, rom_ver); -else if (bid &0xff00 ) -snprintf (cfg->fwname,sizeof (cfg->fwname), -"qca/%snv%02x.b%x" , stem, rom_ver, bid); -else -snprintf (cfg->fwname,sizeof (cfg->fwname), -"qca/%snv%02x.b%02x" , stem, rom_ver, bid); +if (soc_type ==QCA_WCN6855 || soc_type ==QCA_QCA2066 ) { +/* If the chip is manufactured by GlobalFoundries */ +if ((le32_to_cpu (ver.soc_id) &QCA_HSP_GF_SOC_MASK ) ==QCA_HSP_GF_SOC_ID ) + variant ="g" ; + } + +if (rom_ver !=0 ) { +if (bid ==0x0 || bid ==0xffff ) +snprintf (fwname, max_size,"qca/%s%02x%s.bin" , stem, rom_ver, variant); +else +snprintf (fwname, max_size,"qca/%s%02x%s.%s%02x" , stem, rom_ver, + variant, prefix, bid); + }else { +if (bid ==0x0 || bid ==0xffff ) +snprintf (fwname, max_size,"qca/%s%s.bin" , stem, variant); +else +snprintf (fwname, max_size,"qca/%s%s.%s%02x" , stem, variant, prefix, bid); + } } int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
@@ -838,8 +888,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,/* Download NVM configuration */ config.type =TLV_TYPE_NVM ;if (firmware_name) { -snprintf (config.fwname,sizeof (config.fwname), -"qca/%s" , firmware_name); +/* The firmware name has an extension, use it directly */ +if (qca_filename_has_extension (firmware_name)) { +snprintf (config.fwname,sizeof (config.fwname),"qca/%s" , firmware_name); + }else { +qca_read_fw_board_id (hdev, &boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), + firmware_name, soc_type, ver,0 , boardid); + } }else {switch (soc_type) {case QCA_WCN3990 :
@@ -858,8 +914,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/apnv%02x.bin", rom_ver);break ;case QCA_QCA2066 : -qca_generate_hsp_nvm_name (config.fwname, -sizeof (config.fwname), ver, rom_ver, boardid); +qca_get_nvm_name_by_board (config.fwname, +sizeof (config.fwname),"hpnv" , soc_type, ver, + rom_ver, boardid);break ;case QCA_QCA6390 : snprintf(config.fwname, sizeof(config.fwname),
@@ -874,9 +931,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/hpnv%02x.bin", rom_ver);break ;case QCA_WCN7850 : -qca_get_nvm_name_generic (&config,"hmt" , rom_ver, boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), +"hmtnv" , soc_type, ver, rom_ver, boardid);break ; -default :snprintf (config.fwname,sizeof (config.fwname),"qca/nvm_%08x.bin" , soc_ver);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 17/176 Bluetooth: qca: Fix poor RF performance for WCN6855
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit a2fad248947d702ed3dcb52b8377c1a3ae201e44 ]
For WCN6855, board ID specific NVM needs to be downloaded once board ID is available, but the default NVM is always downloaded currently.
The wrong NVM causes poor RF performance, and effects user experience for several types of laptop with WCN6855 on the market.
Fix by downloading board ID specific NVM if board ID is available.
--- drivers/bluetooth/btqca.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/bluetooth/btqca.c +3 -2
@@ -927,8 +927,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/msnv%02x.bin", rom_ver);break ;case QCA_WCN6855 : -snprintf (config.fwname,sizeof (config.fwname), -"qca/hpnv%02x.bin" , rom_ver); +qca_read_fw_board_id (hdev, &boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), +"hpnv" , soc_type, ver, rom_ver, boardid);break ;case QCA_WCN7850 : qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 18/176 clk: mediatek: clk-mtk: Add dummy clock ops
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit b8eb1081d267708ba976525a1fe2162901b34f3a ]
In order to migrate some (few) old clock drivers to the common mtk_clk_simple_probe() function, add dummy clock ops to be able to insert a dummy clock with ID 0 at the beginning of the list.
Stable-dep-of: 7c8746126a4e ("clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe")
--- drivers/clk/mediatek/clk-mtk.c | 16 ++++++++++++++++ drivers/clk/mediatek/clk-mtk.h | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+)
drivers/clk/mediatek/clk-mtk.c +16 -0
@@ -21,6 +21,22 @@#include "clk-gate.h" #include "clk-mux.h" +const struct mtk_gate_regs cg_regs_dummy = {0 ,0 ,0 }; +EXPORT_SYMBOL_GPL (cg_regs_dummy); + +static int mtk_clk_dummy_enable (struct clk_hw *hw) +{ +return 0 ; +} + +static void mtk_clk_dummy_disable (struct clk_hw *hw) { } + +const struct clk_ops mtk_clk_dummy_ops = { + .enable = mtk_clk_dummy_enable, + .disable = mtk_clk_dummy_disable, +}; +EXPORT_SYMBOL_GPL (mtk_clk_dummy_ops); +static void mtk_init_clk_data (struct clk_hw_onecell_data *clk_data,unsigned int clk_num) {
drivers/clk/mediatek/clk-mtk.h +19 -0
@@ -22,6 +22,25 @@struct platform_device ; +/* +* We need the clock IDs to start from zero but to maintain devicetree +* backwards compatibility we can't change bindings to start from zero. +* Only a few platforms are affected, so we solve issues given by the +* commonized MTK clocks probe function(s) by adding a dummy clock at +* the beginning where needed. +*/ +#define CLK_DUMMY 0 + +extern const struct clk_ops mtk_clk_dummy_ops; +extern const struct mtk_gate_regs cg_regs_dummy; + +#define GATE_DUMMY (_id, _name) { \ + .id = _id, \ + .name = _name, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } +struct mtk_fixed_clk {int id;const char *name;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 19/176 clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle <[email protected]>
[ Upstream commit 7c8746126a4e256fcf1af9174ee7d92cc3f3bc31 ]
Commit 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver") broke DT bindings as the highest index was reduced by 1 because the id count starts from 1 and not from 0.
Fix this, like for other drivers which had the same issue, by adding a dummy clk at index 0.
--- drivers/clk/mediatek/clk-mt2701-vdec.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/mediatek/clk-mt2701-vdec.c +1 -0
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = { GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)static const struct mtk_gate vdec_clks[] = { +GATE_DUMMY (CLK_DUMMY ,"vdec_dummy" ),GATE_VDEC0 (CLK_VDEC_CKGEN ,"vdec_cken" ,"vdec_sel" ,0 ),GATE_VDEC1 (CLK_VDEC_LARB ,"vdec_larb_cken" ,"mm_sel" ,0 ), };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 20/176 clk: mediatek: mt2701-bdp: add missing dummy clk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle <[email protected]>
[ Upstream commit fd291adc5e9a4ee6cd91e57f148f3b427f80647b ]
Add dummy clk for index 0 which was missed during the conversion to mtk_clk_simple_probe().
--- drivers/clk/mediatek/clk-mt2701-bdp.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/mediatek/clk-mt2701-bdp.c +1 -0
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = { GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)static const struct mtk_gate bdp_clks[] = { +GATE_DUMMY (CLK_DUMMY ,"bdp_dummy" ),GATE_BDP0 (CLK_BDP_BRG_BA ,"brg_baclk" ,"mm_sel" ,0 ),GATE_BDP0 (CLK_BDP_BRG_DRAM ,"brg_dram" ,"mm_sel" ,1 ),GATE_BDP0 (CLK_BDP_LARB_DRAM ,"larb_dram" ,"mm_sel" ,2 ),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 21/176 clk: mediatek: mt2701-img: add missing dummy clk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle <[email protected]>
[ Upstream commit 366640868ccb4a7991aebe8442b01340fab218e2 ]
Add dummy clk for index 0 which was missed during the conversion to mtk_clk_simple_probe().
--- drivers/clk/mediatek/clk-mt2701-img.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/mediatek/clk-mt2701-img.c +1 -0
@@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = { GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)static const struct mtk_gate img_clks[] = { +GATE_DUMMY (CLK_DUMMY ,"img_dummy" ),GATE_IMG (CLK_IMG_SMI_COMM ,"img_smi_comm" ,"mm_sel" ,0 ),GATE_IMG (CLK_IMG_RESZ ,"img_resz" ,"mm_sel" ,1 ),GATE_IMG (CLK_IMG_JPGDEC_SMI ,"img_jpgdec_smi" ,"mm_sel" ,5 ),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 22/176 ASoC: renesas: rz-ssi: Add a check for negative sample_space
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 82a0a3e6f8c02b3236b55e784a083fa4ee07c321 ]
My static checker rule complains about this code. The concern is that if "sample_space" is negative then the "sample_space >= runtime->channels" condition will not work as intended because it will be type promoted to a high unsigned int value.
strm->fifo_sample_size is SSI_FIFO_DEPTH (32). The SSIFSR_TDC_MASK is 0x3f. Without any further context it does seem like a reasonable warning and it can't hurt to add a check for negatives.
--- sound/soc/sh/rz-ssi.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/sh/rz-ssi.c +2 -0
@@ -483,6 +483,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) sample_space = strm->fifo_sample_size; ssifsr =rz_ssi_reg_readl (ssi,SSIFSR ); sample_space -= (ssifsr >>SSIFSR_TDC_SHIFT ) &SSIFSR_TDC_MASK ; +if (sample_space <0 ) +return -EINVAL ;/* Only add full frames at a time */ while (frames_left && (sample_space >= runtime->channels)) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 23/176 scsi: core: Handle depopulation and restoration in progress
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Gilbert <[email protected]>
[ Upstream commit 2bbeb8d12404cf0603f513fc33269ef9abfbb396 ]
The default handling of the NOT READY sense key is to wait for the device to become ready. The "wait" is assumed to be relatively short. However there is a sub-class of NOT READY that have the "... in progress" phrase in their additional sense code and these can take much longer. Following on from commit 505aa4b6a883 ("scsi: sd: Defer spinning up drive while SANITIZE is in progress") we now have element depopulation and restoration that can take a long time. For example, over 24 hours for a 20 TB, 7200 rpm hard disk to depopulate 1 of its 20 elements.
Add handling of ASC/ASCQ: 0x4,0x24 (depopulation in progress) and ASC/ASCQ: 0x4,0x25 (depopulation restoration in progress) to sd.c . The scsi_lib.c has incomplete handling of these two messages, so complete it.
Stable-dep-of: 9ff7c383b8ac ("scsi: core: Do not retry I/Os during depopulation")
--- drivers/scsi/scsi_lib.c | 1 + drivers/scsi/sd.c | 4 ++++ 2 files changed, 5 insertions(+)
drivers/scsi/scsi_lib.c +1 -0
@@ -783,6 +783,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)case 0x1b :/* sanitize in progress */ case 0x1d :/* configuration in progress */ case 0x24 :/* depopulation in progress */ +case 0x25 :/* depopulation restore in progress */ action =ACTION_DELAYED_RETRY ;break ;case 0x0a :/* ALUA state transition */
drivers/scsi/sd.c +4 -0
@@ -2191,6 +2191,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)break ;/* unavailable */ if (sshdr.asc ==4 && sshdr.ascq ==0x1b )break ;/* sanitize in progress */ +if (sshdr.asc ==4 && sshdr.ascq ==0x24 ) +break ;/* depopulation in progress */ +if (sshdr.asc ==4 && sshdr.ascq ==0x25 ) +break ;/* depopulation restoration in progress */ /* * Issue command to spin up drive when not ready */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 24/176 scsi: core: Do not retry I/Os during depopulation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Pylypiv <[email protected]>
[ Upstream commit 9ff7c383b8ac0c482a1da7989f703406d78445c6 ]
Fail I/Os instead of retry to prevent user space processes from being blocked on the I/O completion for several minutes.
Retrying I/Os during "depopulation in progress" or "depopulation restore in progress" results in a continuous retry loop until the depopulation completes or until the I/O retry loop is aborted due to a timeout by the scsi_cmd_runtime_exceeced().
Depopulation is slow and can take 24+ hours to complete on 20+ TB HDDs. Most I/Os in the depopulation retry loop end up taking several minutes before returning the failure to user space.
--- drivers/scsi/scsi_lib.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/scsi/scsi_lib.c +7 -2
@@ -782,13 +782,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)case 0x1a :/* start stop unit in progress */ case 0x1b :/* sanitize in progress */ case 0x1d :/* configuration in progress */ -case 0x24 :/* depopulation in progress */ -case 0x25 :/* depopulation restore in progress */ action =ACTION_DELAYED_RETRY ;break ;case 0x0a :/* ALUA state transition */ action =ACTION_DELAYED_REPREP ;break ; +/* +* Depopulation might take many hours, +* thus it is not worthwhile to retry. +*/ +case 0x24 :/* depopulation in progress */ +case 0x25 :/* depopulation restore in progress */ + fallthrough;default : action =ACTION_FAIL ;break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 25/176 arm64: dts: mediatek: mt8183: Disable DSI display output by default
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 26f6e91fa29a58fdc76b47f94f8f6027944a490c ]
Most SoC dtsi files have the display output interfaces disabled by default, and only enabled on boards that utilize them. The MT8183 has it backwards: the display outputs are left enabled by default, and only disabled at the board level.
Reverse the situation for the DSI output so that it follows the normal scheme. For ease of backporting the DPI output is handled in a separate patch.
--- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/mediatek/mt8183.dtsi +1 -0
@@ -1753,6 +1753,7 @@ resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>; phys = <&mipi_tx0>; phy-names = "dphy"; + status = "disabled"; }; mutex: mutex@14016000 {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 26/176 arm64: dts: qcom: trim addresses to 8 digits
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 22dbcfd6f4a9f7d4391f0aa66d3f46addea4bee9 ]
Hex numbers in addresses and sizes should be rather eight digits, not nine. Drop leading zeros. No functional change (same DTB).
Stable-dep-of: 3751fe2cba2a ("arm64: dts: qcom: sm8450: Fix CDSP memory length")
--- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8450.dtsi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/qcom/sm8350.dtsi +1 -1
@@ -2226,7 +2226,7 @@ cdsp: remoteproc@98900000 { compatible = "qcom,sm8350-cdsp-pas"; - reg = <0 0x098900000 0 0x1400000>; + reg = <0 0x98900000 0 0x1400000>; interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
arch/arm64/boot/dts/qcom/sm8450.dtsi +2 -2
@@ -2093,7 +2093,7 @@ remoteproc_adsp: remoteproc@30000000 { compatible = "qcom,sm8450-adsp-pas"; - reg = <0 0x030000000 0 0x100>; + reg = <0 0x30000000 0 0x100>; interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2159,7 +2159,7 @@ remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,sm8450-cdsp-pas"; - reg = <0 0x032300000 0 0x1400000>; + reg = <0 0x32300000 0 0x1400000>; interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 27/176 arm64: dts: qcom: sm8450: Fix CDSP memory length
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 3751fe2cba2a9fba2204ef62102bc4bb027cec7b ]
The address space in CDSP PAS (Peripheral Authentication Service) remoteproc node should point to the QDSP PUB address space (QDSP6...SS_PUB) which has a length of 0x10000. Value of 0x1400000 was copied from older DTS, but it does not look accurate at all.
This should have no functional impact on Linux users, because PAS loader does not use this address space at all.
--- arch/arm64/boot/dts/qcom/sm8450.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8450.dtsi +1 -1
@@ -2159,7 +2159,7 @@ remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,sm8450-cdsp-pas"; - reg = <0 0x32300000 0 0x1400000>; + reg = <0 0x32300000 0 0x10000>; interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 28/176 tpm: Use managed allocation for bios event log
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eddie James <[email protected]>
[ Upstream commit 441b7152729f4a2bdb100135a58625fa0aeb69e4 ]
Since the bios event log is freed in the device release function, let devres handle the deallocation. This will allow other memory allocation/mapping functions to be used for the bios event log.
Stable-dep-of: a3a860bc0fd6 ("tpm: Change to kvalloc() in eventlog/acpi.c")
--- drivers/char/tpm/eventlog/acpi.c | 5 +++-- drivers/char/tpm/eventlog/efi.c | 13 +++++++------ drivers/char/tpm/eventlog/of.c | 3 ++- drivers/char/tpm/tpm-chip.c | 1 - 4 files changed, 12 insertions(+), 10 deletions(-)
drivers/char/tpm/eventlog/acpi.c +3 -2
@@ -14,6 +14,7 @@* Access to the event log extended by the TCG BIOS of PC platform */ +#include <linux/device.h> #include <linux/seq_file.h> #include <linux/fs.h> #include <linux/security.h>
@@ -135,7 +136,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) }/* malloc EventLog space */ - log->bios_event_log =kmalloc (len,GFP_KERNEL ); + log->bios_event_log =devm_kmalloc (&chip->dev, len,GFP_KERNEL );if (!log->bios_event_log)return -ENOMEM ;
@@ -164,7 +165,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)return format; err: -kfree (log->bios_event_log); +devm_kfree (&chip->dev, log->bios_event_log); log->bios_event_log =NULL ;return ret; }
drivers/char/tpm/eventlog/efi.c +7 -6
@@ -6,6 +6,7 @@* Thiebaud Weksteen <[email protected]> */ +#include <linux/device.h> #include <linux/efi.h> #include <linux/tpm_eventlog.h>
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip) }/* malloc EventLog space */ - log->bios_event_log =kmemdup (log_tbl->log, log_size,GFP_KERNEL ); + log->bios_event_log =devm_kmemdup (&chip->dev, log_tbl->log, log_size,GFP_KERNEL );if (!log->bios_event_log) { ret = -ENOMEM ; goto out;
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip) MEMREMAP_WB);if (!final_tbl) {pr_err ("Could not map UEFI TPM final log\n" ); -kfree (log->bios_event_log); +devm_kfree (&chip->dev, log->bios_event_log); ret = -ENOMEM ; goto out; }
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)* Allocate memory for the 'combined log' where we will append the * 'final events log' to. */ - tmp =krealloc (log->bios_event_log, - log_size + final_events_log_size, -GFP_KERNEL ); + tmp =devm_krealloc (&chip->dev, log->bios_event_log, + log_size + final_events_log_size, +GFP_KERNEL );if (!tmp) { -kfree (log->bios_event_log); +devm_kfree (&chip->dev, log->bios_event_log); ret = -ENOMEM ; goto out; }
drivers/char/tpm/eventlog/of.c +2 -1
@@ -10,6 +10,7 @@* Read the event log created by the firmware on PPC64 */ +#include <linux/device.h> #include <linux/slab.h> #include <linux/of.h> #include <linux/tpm_eventlog.h>
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)return -EIO ; } - log->bios_event_log =kmemdup (__va (base), size,GFP_KERNEL ); + log->bios_event_log =devm_kmemdup (&chip->dev,__va (base), size,GFP_KERNEL );if (!log->bios_event_log)return -ENOMEM ;
drivers/char/tpm/tpm-chip.c +0 -1
@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)idr_remove (&dev_nums_idr, chip->dev_num);mutex_unlock (&idr_lock); -kfree (chip->log.bios_event_log);kfree (chip->work_space.context_buf);kfree (chip->work_space.session_buf);kfree (chip->allocated_banks);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 29/176 tpm: Change to kvalloc() in eventlog/acpi.c
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
[ Upstream commit a3a860bc0fd6c07332e4911cf9a238d20de90173 ]
The following failure was reported on HPE ProLiant D320:
[ 10.693310][ T1] tpm_tis STM0925:00: 2.0 TPM (device-id 0x3, rev-id 0) [ 10.848132][ T1] ------------[ cut here ]------------ [ 10.853559][ T1] WARNING: CPU: 59 PID: 1 at mm/page_alloc.c:4727 __alloc_pages_noprof+0x2ca/0x330 [ 10.862827][ T1] Modules linked in: [ 10.866671][ T1] CPU: 59 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.0-lp155.2.g52785e2-default #1 openSUSE Tumbleweed (unreleased) 588cd98293a7c9eba9013378d807364c088c9375 [ 10.882741][ T1] Hardware name: HPE ProLiant DL320 Gen12/ProLiant DL320 Gen12, BIOS 1.20 10/28/2024 [ 10.892170][ T1] RIP: 0010:__alloc_pages_noprof+0x2ca/0x330 [ 10.898103][ T1] Code: 24 08 e9 4a fe ff ff e8 34 36 fa ff e9 88 fe ff ff 83 fe 0a 0f 86 b3 fd ff ff 80 3d 01 e7 ce 01 00 75 09 c6 05 f8 e6 ce 01 01 <0f> 0b 45 31 ff e9 e5 fe ff ff f7 c2 00 00 08 00 75 42 89 d9 80 e1 [ 10.917750][ T1] RSP: 0000:ffffb7cf40077980 EFLAGS: 00010246 [ 10.923777][ T1] RAX: 0000000000000000 RBX: 0000000000040cc0 RCX: 0000000000000000 [ 10.931727][ T1] RDX: 0000000000000000 RSI: 000000000000000c RDI: 0000000000040cc0
The above transcript shows that ACPI pointed a 16 MiB buffer for the log events because RSI maps to the 'order' parameter of __alloc_pages_noprof(). Address the bug by moving from devm_kmalloc() to devm_add_action() and kvmalloc() and devm_add_action().
--- drivers/char/tpm/eventlog/acpi.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/char/tpm/eventlog/acpi.c +13 -2
@@ -63,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len)return n ==0 ; } +static void tpm_bios_log_free (void *data) +{ +kvfree (data); +} +/* read binary bios log */ int tpm_read_log_acpi (struct tpm_chip *chip) {
@@ -136,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) }/* malloc EventLog space */ - log->bios_event_log =devm_kmalloc (&chip->dev, len,GFP_KERNEL ); + log->bios_event_log =kvmalloc (len,GFP_KERNEL );if (!log->bios_event_log)return -ENOMEM ;
@@ -162,10 +167,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip) goto err; } + ret =devm_add_action (&chip->dev, tpm_bios_log_free, log->bios_event_log); +if (ret) { + log->bios_event_log =NULL ; + goto err; + } +return format; err: -devm_kfree (&chip->dev, log->bios_event_log); +tpm_bios_log_free (log->bios_event_log); log->bios_event_log =NULL ;return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 30/176 soc: mediatek: mtk-devapc: Switch to devm_clk_get_enabled()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit 916120df5aa926d65f4666c075ed8d4955ef7bab ]
This driver does exactly devm_clk_get() and clk_prepare_enable() right after, which is exactly what devm_clk_get_enabled() does: clean that up by switching to the latter.
This commit brings no functional changes.
Stable-dep-of: c0eb059a4575 ("soc: mediatek: mtk-devapc: Fix leaking IO map on error paths")
--- drivers/soc/mediatek/mtk-devapc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/soc/mediatek/mtk-devapc.c +2 -9
@@ -276,19 +276,14 @@ static int mtk_devapc_probe(struct platform_device *pdev)if (!devapc_irq)return -EINVAL ; - ctx->infra_clk =devm_clk_get (&pdev->dev,"devapc-infra-clock" ); + ctx->infra_clk =devm_clk_get_enabled (&pdev->dev,"devapc-infra-clock" );if (IS_ERR (ctx->infra_clk))return -EINVAL ; -if (clk_prepare_enable (ctx->infra_clk)) -return -EINVAL ; - ret =devm_request_irq (&pdev->dev, devapc_irq, devapc_violation_irq,IRQF_TRIGGER_NONE ,"devapc" , ctx); -if (ret) { -clk_disable_unprepare (ctx->infra_clk); +if (ret)return ret; - }platform_set_drvdata (pdev, ctx);
@@ -303,8 +298,6 @@ static int mtk_devapc_remove(struct platform_device *pdev)stop_devapc (ctx); -clk_disable_unprepare (ctx->infra_clk); -return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 31/176 soc: mediatek: mtk-devapc: Fix leaking IO map on error paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit c0eb059a4575ed57f265d9883a5203799c19982c ]
Error paths of mtk_devapc_probe() should unmap the memory. Reported by Smatch:
drivers/soc/mediatek/mtk-devapc.c:292 mtk_devapc_probe() warn: 'ctx->infra_base' from of_iomap() not released on lines: 277,281,286.
--- drivers/soc/mediatek/mtk-devapc.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/soc/mediatek/mtk-devapc.c +13 -5
@@ -273,23 +273,31 @@ static int mtk_devapc_probe(struct platform_device *pdev)return -EINVAL ; devapc_irq =irq_of_parse_and_map (node,0 ); -if (!devapc_irq) -return -EINVAL ; +if (!devapc_irq) { + ret = -EINVAL ; + goto err; + } ctx->infra_clk =devm_clk_get_enabled (&pdev->dev,"devapc-infra-clock" ); -if (IS_ERR (ctx->infra_clk)) -return -EINVAL ; +if (IS_ERR (ctx->infra_clk)) { + ret = -EINVAL ; + goto err; + } ret =devm_request_irq (&pdev->dev, devapc_irq, devapc_violation_irq,IRQF_TRIGGER_NONE ,"devapc" , ctx);if (ret) -return ret; + goto err;platform_set_drvdata (pdev, ctx);start_devapc (ctx);return 0 ; + +err: +iounmap (ctx->infra_base); +return ret; }static int mtk_devapc_remove (struct platform_device *pdev)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 32/176 soc/mediatek: mtk-devapc: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit a129ac3555c0dca6f04ae404dc0f0790656587fb ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: c9c0036c1990 ("soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove")
--- drivers/soc/mediatek/mtk-devapc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/soc/mediatek/mtk-devapc.c +2 -4
@@ -300,18 +300,16 @@ static int mtk_devapc_probe(struct platform_device *pdev)return ret; } -static int mtk_devapc_remove (struct platform_device *pdev) +static void mtk_devapc_remove (struct platform_device *pdev) {struct mtk_devapc_context *ctx =platform_get_drvdata (pdev);stop_devapc (ctx); - -return 0 ; }static struct platform_driver mtk_devapc_driver = { .probe = mtk_devapc_probe, - .remove = mtk_devapc_remove, + .remove_new = mtk_devapc_remove, .driver = { .name ="mtk-devapc" , .of_match_table = mtk_devapc_dt_match,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 33/176 soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit c9c0036c1990da8d2dd33563e327e05a775fcf10 ]
Driver removal should fully clean up - unmap the memory.
--- drivers/soc/mediatek/mtk-devapc.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/mediatek/mtk-devapc.c +1 -0
@@ -305,6 +305,7 @@ static void mtk_devapc_remove(struct platform_device *pdev)struct mtk_devapc_context *ctx =platform_get_drvdata (pdev);stop_devapc (ctx); +iounmap (ctx->infra_base); }static struct platform_driver mtk_devapc_driver = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 34/176 media: Switch to use dev_err_probe() helper
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 6cb7d1b3ff83e98e852db9739892c4643a31804b ]
In the probe path, dev_err() can be replaced with dev_err_probe() which will check if error code is -EPROBE_DEFER.
Stable-dep-of: a9ea1a3d88b7 ("media: uvcvideo: Fix crash during unbind if gpio unit is in use")
--- drivers/media/cec/platform/stm32/stm32-cec.c | 9 +++---- drivers/media/i2c/ad5820.c | 18 +++++-------- drivers/media/i2c/imx274.c | 5 ++-- drivers/media/i2c/tc358743.c | 9 +++---- .../platform/mediatek/mdp/mtk_mdp_comp.c | 5 ++-- .../platform/samsung/exynos4-is/media-dev.c | 4 +-- drivers/media/platform/st/stm32/stm32-dcmi.c | 27 +++++++------------ drivers/media/platform/ti/omap3isp/isp.c | 3 +-- .../media/platform/xilinx/xilinx-csi2rxss.c | 8 +++--- drivers/media/rc/gpio-ir-recv.c | 10 +++---- drivers/media/rc/gpio-ir-tx.c | 9 +++---- drivers/media/rc/ir-rx51.c | 9 ++----- drivers/media/usb/uvc/uvc_driver.c | 9 +++---- 13 files changed, 41 insertions(+), 84 deletions(-)
drivers/media/cec/platform/stm32/stm32-cec.c +3 -6
@@ -288,12 +288,9 @@ static int stm32_cec_probe(struct platform_device *pdev)return ret; cec->clk_cec =devm_clk_get (&pdev->dev,"cec" ); -if (IS_ERR (cec->clk_cec)) { -if (PTR_ERR (cec->clk_cec) != -EPROBE_DEFER ) -dev_err (&pdev->dev,"Cannot get cec clock\n" ); - -return PTR_ERR (cec->clk_cec); - } +if (IS_ERR (cec->clk_cec)) +return dev_err_probe (&pdev->dev,PTR_ERR (cec->clk_cec), +"Cannot get cec clock\n" ); ret =clk_prepare (cec->clk_cec);if (ret) {
drivers/media/i2c/ad5820.c +6 -12
@@ -301,21 +301,15 @@ static int ad5820_probe(struct i2c_client *client,return -ENOMEM ; coil->vana =devm_regulator_get (&client->dev,"VANA" ); -if (IS_ERR (coil->vana)) { - ret =PTR_ERR (coil->vana); -if (ret != -EPROBE_DEFER ) -dev_err (&client->dev,"could not get regulator for vana\n" ); -return ret; - } +if (IS_ERR (coil->vana)) +return dev_err_probe (&client->dev,PTR_ERR (coil->vana), +"could not get regulator for vana\n" ); coil->enable_gpio =devm_gpiod_get_optional (&client->dev,"enable" ,GPIOD_OUT_LOW ); -if (IS_ERR (coil->enable_gpio)) { - ret =PTR_ERR (coil->enable_gpio); -if (ret != -EPROBE_DEFER ) -dev_err (&client->dev,"could not get enable gpio\n" ); -return ret; - } +if (IS_ERR (coil->enable_gpio)) +return dev_err_probe (&client->dev,PTR_ERR (coil->enable_gpio), +"could not get enable gpio\n" );mutex_init (&coil->power_lock);
drivers/media/i2c/imx274.c +2 -3
@@ -2060,9 +2060,8 @@ static int imx274_probe(struct i2c_client *client) imx274->reset_gpio =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH );if (IS_ERR (imx274->reset_gpio)) { -if (PTR_ERR (imx274->reset_gpio) != -EPROBE_DEFER ) -dev_err (dev,"Reset GPIO not setup in DT" ); - ret =PTR_ERR (imx274->reset_gpio); + ret =dev_err_probe (dev,PTR_ERR (imx274->reset_gpio), +"Reset GPIO not setup in DT\n" ); goto err_me; }
drivers/media/i2c/tc358743.c +3 -6
@@ -1891,12 +1891,9 @@ static int tc358743_probe_of(struct tc358743_state *state)int ret; refclk =devm_clk_get (dev,"refclk" ); -if (IS_ERR (refclk)) { -if (PTR_ERR (refclk) != -EPROBE_DEFER ) -dev_err (dev,"failed to get refclk: %ld\n" , -PTR_ERR (refclk)); -return PTR_ERR (refclk); - } +if (IS_ERR (refclk)) +return dev_err_probe (dev,PTR_ERR (refclk), +"failed to get refclk\n" ); ep =of_graph_get_next_endpoint (dev->of_node,NULL );if (!ep) {
drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c +2 -3
@@ -52,9 +52,8 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,for (i =0 ; i <ARRAY_SIZE (comp->clk); i++) { comp->clk[i] =of_clk_get (node, i);if (IS_ERR (comp->clk[i])) { -if (PTR_ERR (comp->clk[i]) != -EPROBE_DEFER ) -dev_err (dev,"Failed to get clock\n" ); - ret =PTR_ERR (comp->clk[i]); + ret =dev_err_probe (dev,PTR_ERR (comp->clk[i]), +"Failed to get clock\n" ); goto put_dev; }
drivers/media/platform/samsung/exynos4-is/media-dev.c +1 -3
@@ -1471,9 +1471,7 @@ static int fimc_md_probe(struct platform_device *pdev) pinctrl =devm_pinctrl_get (dev);if (IS_ERR (pinctrl)) { - ret =PTR_ERR (pinctrl); -if (ret != -EPROBE_DEFER ) -dev_err (dev,"Failed to get pinctrl: %d\n" , ret); + ret =dev_err_probe (dev,PTR_ERR (pinctrl),"Failed to get pinctrl\n" ); goto err_clk; }
drivers/media/platform/st/stm32/stm32-dcmi.c +9 -18
@@ -1946,12 +1946,9 @@ static int dcmi_probe(struct platform_device *pdev)return -ENOMEM ; dcmi->rstc =devm_reset_control_get_exclusive (&pdev->dev,NULL ); -if (IS_ERR (dcmi->rstc)) { -if (PTR_ERR (dcmi->rstc) != -EPROBE_DEFER ) -dev_err (&pdev->dev,"Could not get reset control\n" ); - -return PTR_ERR (dcmi->rstc); - } +if (IS_ERR (dcmi->rstc)) +return dev_err_probe (&pdev->dev,PTR_ERR (dcmi->rstc), +"Could not get reset control\n" );/* Get bus characteristics from devicetree */ np =of_graph_get_next_endpoint (np,NULL );
@@ -2003,20 +2000,14 @@ static int dcmi_probe(struct platform_device *pdev) } mclk =devm_clk_get (&pdev->dev,"mclk" ); -if (IS_ERR (mclk)) { -if (PTR_ERR (mclk) != -EPROBE_DEFER ) -dev_err (&pdev->dev,"Unable to get mclk\n" ); -return PTR_ERR (mclk); - } +if (IS_ERR (mclk)) +return dev_err_probe (&pdev->dev,PTR_ERR (mclk), +"Unable to get mclk\n" ); chan =dma_request_chan (&pdev->dev,"tx" ); -if (IS_ERR (chan)) { - ret =PTR_ERR (chan); -if (ret != -EPROBE_DEFER ) -dev_err (&pdev->dev, -"Failed to request DMA channel: %d\n" , ret); -return ret; - } +if (IS_ERR (chan)) +return dev_err_probe (&pdev->dev,PTR_ERR (chan), +"Failed to request DMA channel\n" ); dcmi->dma_max_burst =UINT_MAX ; ret =dma_get_slave_caps (chan, &caps);
drivers/media/platform/ti/omap3isp/isp.c +1 -2
@@ -1884,8 +1884,7 @@ static int isp_initialize_modules(struct isp_device *isp) ret =omap3isp_ccp2_init (isp);if (ret <0 ) { -if (ret != -EPROBE_DEFER ) -dev_err (isp->dev,"CCP2 initialization failed\n" ); +dev_err_probe (isp->dev, ret,"CCP2 initialization failed\n" ); goto error_ccp2; }
drivers/media/platform/xilinx/xilinx-csi2rxss.c +3 -5
@@ -976,11 +976,9 @@ static int xcsi2rxss_probe(struct platform_device *pdev)/* Reset GPIO */ xcsi2rxss->rst_gpio =devm_gpiod_get_optional (dev,"video-reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (xcsi2rxss->rst_gpio)) { -if (PTR_ERR (xcsi2rxss->rst_gpio) != -EPROBE_DEFER ) -dev_err (dev,"Video Reset GPIO not setup in DT" ); -return PTR_ERR (xcsi2rxss->rst_gpio); - } +if (IS_ERR (xcsi2rxss->rst_gpio)) +return dev_err_probe (dev,PTR_ERR (xcsi2rxss->rst_gpio), +"Video Reset GPIO not setup in DT\n" ); ret =xcsi2rxss_parse_of (xcsi2rxss);if (ret <0 )
drivers/media/rc/gpio-ir-recv.c +3 -7
@@ -74,13 +74,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)return -ENOMEM ; gpio_dev->gpiod =devm_gpiod_get (dev,NULL ,GPIOD_IN ); -if (IS_ERR (gpio_dev->gpiod)) { - rc =PTR_ERR (gpio_dev->gpiod); -/* Just try again if this happens */ -if (rc != -EPROBE_DEFER ) -dev_err (dev,"error getting gpio (%d)\n" , rc); -return rc; - } +if (IS_ERR (gpio_dev->gpiod)) +return dev_err_probe (dev,PTR_ERR (gpio_dev->gpiod), +"error getting gpio\n" ); gpio_dev->irq =gpiod_to_irq (gpio_dev->gpiod);if (gpio_dev->irq <0 )return gpio_dev->irq;
drivers/media/rc/gpio-ir-tx.c +3 -6
@@ -174,12 +174,9 @@ static int gpio_ir_tx_probe(struct platform_device *pdev)return -ENOMEM ; gpio_ir->gpio =devm_gpiod_get (&pdev->dev,NULL ,GPIOD_OUT_LOW ); -if (IS_ERR (gpio_ir->gpio)) { -if (PTR_ERR (gpio_ir->gpio) != -EPROBE_DEFER ) -dev_err (&pdev->dev,"Failed to get gpio (%ld)\n" , -PTR_ERR (gpio_ir->gpio)); -return PTR_ERR (gpio_ir->gpio); - } +if (IS_ERR (gpio_ir->gpio)) +return dev_err_probe (&pdev->dev,PTR_ERR (gpio_ir->gpio), +"Failed to get gpio\n" ); rcdev->priv = gpio_ir; rcdev->driver_name =DRIVER_NAME ;
drivers/media/rc/ir-rx51.c +2 -7
@@ -231,13 +231,8 @@ static int ir_rx51_probe(struct platform_device *dev)struct rc_dev *rcdev; pwm =pwm_get (&dev->dev,NULL ); -if (IS_ERR (pwm)) { -int err =PTR_ERR (pwm); - -if (err != -EPROBE_DEFER ) -dev_err (&dev->dev,"pwm_get failed: %d\n" , err); -return err; - } +if (IS_ERR (pwm)) +return dev_err_probe (&dev->dev,PTR_ERR (pwm),"pwm_get failed\n" );/* Use default, in case userspace does not set the carrier */ ir_rx51.freq =DIV_ROUND_CLOSEST_ULL (pwm_get_period (pwm),NSEC_PER_SEC );
drivers/media/usb/uvc/uvc_driver.c +3 -6
@@ -1253,12 +1253,9 @@ static int uvc_gpio_parse(struct uvc_device *dev)return PTR_ERR_OR_ZERO (gpio_privacy); irq =gpiod_to_irq (gpio_privacy); -if (irq <0 ) { -if (irq !=EPROBE_DEFER ) -dev_err (&dev->udev->dev, -"No IRQ for privacy GPIO (%d)\n" , irq); -return irq; - } +if (irq <0 ) +return dev_err_probe (&dev->udev->dev, irq, +"No IRQ for privacy GPIO\n" ); unit =uvc_alloc_entity (UVC_EXT_GPIO_UNIT ,UVC_EXT_GPIO_UNIT_ID ,0 ,1 );if (!unit)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 35/176 media: uvcvideo: Fix crash during unbind if gpio unit is in use
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit a9ea1a3d88b7947ce8cadb2afceee7a54872bbc5 ]
We used the wrong device for the device managed functions. We used the usb device, when we should be using the interface device.
If we unbind the driver from the usb interface, the cleanup functions are never called. In our case, the IRQ is never disabled.
If an IRQ is triggered, it will try to access memory sections that are already free, causing an OOPS.
We cannot use the function devm_request_threaded_irq here. The devm_* clean functions may be called after the main structure is released by uvc_delete.
Luckily this bug has small impact, as it is only affected by devices with gpio units and the user has to unbind the device, a disconnect will not trigger this error.
--- drivers/media/usb/uvc/uvc_driver.c | 28 +++++++++++++++++++++------- drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 22 insertions(+), 7 deletions(-)
drivers/media/usb/uvc/uvc_driver.c +21 -7
@@ -1247,14 +1247,14 @@ static int uvc_gpio_parse(struct uvc_device *dev)struct gpio_desc *gpio_privacy;int irq; - gpio_privacy =devm_gpiod_get_optional (&dev->udev->dev,"privacy" , + gpio_privacy =devm_gpiod_get_optional (&dev->intf->dev,"privacy" ,GPIOD_IN );if (IS_ERR_OR_NULL (gpio_privacy))return PTR_ERR_OR_ZERO (gpio_privacy); irq =gpiod_to_irq (gpio_privacy);if (irq <0 ) -return dev_err_probe (&dev->udev->dev, irq, +return dev_err_probe (&dev->intf->dev, irq,"No IRQ for privacy GPIO\n" ); unit =uvc_alloc_entity (UVC_EXT_GPIO_UNIT ,UVC_EXT_GPIO_UNIT_ID ,0 ,1 );
@@ -1280,15 +1280,27 @@ static int uvc_gpio_parse(struct uvc_device *dev)static int uvc_gpio_init_irq (struct uvc_device *dev) {struct uvc_entity *unit = dev->gpio_unit; +int ret;if (!unit || unit->gpio.irq <0 )return 0 ; -return devm_request_threaded_irq (&dev->udev->dev, unit->gpio.irq,NULL , - uvc_gpio_irq, -IRQF_ONESHOT |IRQF_TRIGGER_FALLING | -IRQF_TRIGGER_RISING , -"uvc_privacy_gpio" , dev); + ret =request_threaded_irq (unit->gpio.irq,NULL , uvc_gpio_irq, +IRQF_ONESHOT |IRQF_TRIGGER_FALLING | +IRQF_TRIGGER_RISING , +"uvc_privacy_gpio" , dev); + + unit->gpio.initialized = !ret; + +return ret; +} + +static void uvc_gpio_deinit (struct uvc_device *dev) +{ +if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) +return ; + +free_irq (dev->gpio_unit->gpio.irq, dev); }/* ------------------------------------------------------------------------
@@ -1882,6 +1894,8 @@ static void uvc_unregister_video(struct uvc_device *dev) {struct uvc_streaming *stream; +uvc_gpio_deinit (dev); +list_for_each_entry (stream, &dev->streams, list) {/* Nothing to do here, continue. */ if (!video_is_registered (&stream->vdev))
drivers/media/usb/uvc/uvcvideo.h +1 -0
@@ -227,6 +227,7 @@ struct uvc_entity {u8 *bmControls;struct gpio_desc *gpio_privacy;int irq; +bool initialized; } gpio; };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 36/176 media: uvcvideo: Refactor iterators
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit 64627daf0c5f7838111f52bbbd1a597cb5d6871a ]
Avoid using the iterators after the list_for_each() constructs. This patch should be a NOP, but makes cocci, happier:
drivers/media/usb/uvc/uvc_ctrl.c:1861:44-50: ERROR: invalid reference to the index variable of the iterator on line 1850 drivers/media/usb/uvc/uvc_ctrl.c:2195:17-23: ERROR: invalid reference to the index variable of the iterator on line 2179
Stable-dep-of: d9fecd096f67 ("media: uvcvideo: Only save async fh if success")
--- drivers/media/usb/uvc/uvc_ctrl.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +13 -11
@@ -1786,16 +1786,18 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,list_for_each_entry (entity, &chain->entities, chain) { ret =uvc_ctrl_commit_entity (chain->dev, entity, rollback, &err_ctrl); -if (ret <0 ) +if (ret <0 ) { +if (ctrls) + ctrls->error_idx = +uvc_ctrl_find_ctrl_idx (entity, ctrls, + err_ctrl); goto done; + } }if (!rollback)uvc_ctrl_send_events (handle, ctrls->controls, ctrls->count); done: -if (ret <0 && ctrls) - ctrls->error_idx =uvc_ctrl_find_ctrl_idx (entity, ctrls, - err_ctrl);mutex_unlock (&chain->ctrl_mutex);return ret; }
@@ -2100,7 +2102,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,int uvc_xu_ctrl_query (struct uvc_video_chain *chain,struct uvc_xu_control_query *xqry) { -struct uvc_entity *entity; +struct uvc_entity *entity, *iter;struct uvc_control *ctrl;unsigned int i;bool found;
@@ -2110,16 +2112,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,int ret;/* Find the extension unit. */ - found = false; -list_for_each_entry (entity, &chain->entities, chain) { -if (UVC_ENTITY_TYPE (entity) ==UVC_VC_EXTENSION_UNIT && - entity->id == xqry->unit) { - found = true; + entity =NULL ; +list_for_each_entry (iter, &chain->entities, chain) { +if (UVC_ENTITY_TYPE (iter) ==UVC_VC_EXTENSION_UNIT && + iter->id == xqry->unit) { + entity = iter;break ; } } -if (!found) { +if (!entity) {uvc_dbg (chain->dev,CONTROL ,"Extension unit %u not found\n" , xqry->unit);return -ENOENT ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 37/176 media: uvcvideo: Only save async fh if success
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit d9fecd096f67a4469536e040a8a10bbfb665918b ]
Now we keep a reference to the active fh for any call to uvc_ctrl_set, regardless if it is an actual set or if it is a just a try or if the device refused the operation.
We should only keep the file handle if the device actually accepted applying the operation.
--- drivers/media/usb/uvc/uvc_ctrl.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +11 -7
@@ -1700,7 +1700,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) }static int uvc_ctrl_commit_entity (struct uvc_device *dev, -struct uvc_entity *entity,int rollback,struct uvc_control **err_ctrl) +struct uvc_fh *handle, +struct uvc_entity *entity, +int rollback, +struct uvc_control **err_ctrl) {struct uvc_control *ctrl;unsigned int i;
@@ -1748,6 +1751,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, *err_ctrl = ctrl;return ret; } + +if (!rollback && handle && + ctrl->info.flags &UVC_CTRL_FLAG_ASYNCHRONOUS ) + ctrl->handle = handle; }return 0 ;
@@ -1784,8 +1791,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,/* Find the control. */ list_for_each_entry (entity, &chain->entities, chain) { - ret =uvc_ctrl_commit_entity (chain->dev, entity, rollback, - &err_ctrl); + ret =uvc_ctrl_commit_entity (chain->dev, handle, entity, + rollback, &err_ctrl);if (ret <0 ) {if (ctrls) ctrls->error_idx =
@@ -1927,9 +1934,6 @@ int uvc_ctrl_set(struct uvc_fh *handle, mapping->set (mapping, value,uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT )); -if (ctrl->info.flags &UVC_CTRL_FLAG_ASYNCHRONOUS ) - ctrl->handle = handle; - ctrl->dirty =1 ; ctrl->modified =1 ;return 0 ;
@@ -2258,7 +2262,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev) ctrl->dirty =1 ; } - ret =uvc_ctrl_commit_entity (dev, entity,0 ,NULL ); + ret =uvc_ctrl_commit_entity (dev,NULL , entity,0 ,NULL );if (ret <0 )return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 38/176 media: uvcvideo: Remove dangling pointers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit 221cd51efe4565501a3dbf04cc011b537dcce7fb ]
When an async control is written, we copy a pointer to the file handle that started the operation. That pointer will be used when the device is done. Which could be anytime in the future.
If the user closes that file descriptor, its structure will be freed, and there will be one dangling pointer per pending async control, that the driver will try to use.
Clean all the dangling pointers during release().
To avoid adding a performance penalty in the most common case (no async operation), a counter has been introduced with some logic to make sure that it is properly handled.
--- drivers/media/usb/uvc/uvc_ctrl.c | 59 ++++++++++++++++++++++++++++++-- drivers/media/usb/uvc/uvc_v4l2.c | 2 ++ drivers/media/usb/uvc/uvcvideo.h | 9 ++++- 3 files changed, 67 insertions(+), 3 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +57 -2
@@ -1470,6 +1470,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,uvc_ctrl_send_event (chain, handle, ctrl, mapping, val, changes); } +static void uvc_ctrl_set_handle (struct uvc_fh *handle,struct uvc_control *ctrl, +struct uvc_fh *new_handle) +{ +lockdep_assert_held (&handle->chain->ctrl_mutex); + +if (new_handle) { +if (ctrl->handle) +dev_warn_ratelimited (&handle->stream->dev->udev->dev, +"UVC non compliance: Setting an async control with a pending operation." ); + +if (new_handle == ctrl->handle) +return ; + +if (ctrl->handle) { +WARN_ON (!ctrl->handle->pending_async_ctrls); +if (ctrl->handle->pending_async_ctrls) + ctrl->handle->pending_async_ctrls--; + } + + ctrl->handle = new_handle; + handle->pending_async_ctrls++; +return ; + } + +/* Cannot clear the handle for a control not owned by us.*/ +if (WARN_ON (ctrl->handle != handle)) +return ; + + ctrl->handle =NULL ; +if (WARN_ON (!handle->pending_async_ctrls)) +return ; + handle->pending_async_ctrls--; +} +void uvc_ctrl_status_event (struct uvc_video_chain *chain,struct uvc_control *ctrl,const u8 *data) {
@@ -1480,7 +1514,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,mutex_lock (&chain->ctrl_mutex); handle = ctrl->handle; - ctrl->handle =NULL ; +if (handle) +uvc_ctrl_set_handle (handle, ctrl,NULL );list_for_each_entry (mapping, &ctrl->info.mappings, list) {s32 value =__uvc_ctrl_get_value (mapping, data);
@@ -1754,7 +1789,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,if (!rollback && handle && ctrl->info.flags &UVC_CTRL_FLAG_ASYNCHRONOUS ) - ctrl->handle = handle; +uvc_ctrl_set_handle (handle, ctrl, handle); }return 0 ;
@@ -2666,6 +2701,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev)return 0 ; } +void uvc_ctrl_cleanup_fh (struct uvc_fh *handle) +{ +struct uvc_entity *entity; + +guard (mutex)(&handle->chain->ctrl_mutex); + +if (!handle->pending_async_ctrls) +return ; + +list_for_each_entry (entity, &handle->chain->dev->entities, list) { +for (unsigned int i =0 ; i < entity->ncontrols; ++i) { +if (entity->controls[i].handle != handle) +continue ; +uvc_ctrl_set_handle (handle, &entity->controls[i],NULL ); + } + } + +WARN_ON (handle->pending_async_ctrls); +} +/* * Cleanup device controls. */
drivers/media/usb/uvc/uvc_v4l2.c +2 -0
@@ -607,6 +607,8 @@ static int uvc_v4l2_release(struct file *file)uvc_dbg (stream->dev,CALLS ,"%s\n" , __func__); +uvc_ctrl_cleanup_fh (handle); +/* Only free resources if this is a privileged handle. */ if (uvc_has_privileges (handle))uvc_queue_release (&stream->queue);
drivers/media/usb/uvc/uvcvideo.h +8 -1
@@ -331,7 +331,11 @@ struct uvc_video_chain {struct uvc_entity *processing;/* Processing unit */ struct uvc_entity *selector;/* Selector unit */ -struct mutex ctrl_mutex;/* Protects ctrl.info */ +struct mutex ctrl_mutex;/* +* Protects ctrl.info, +* ctrl.handle and +* uvc_fh.pending_async_ctrls +*/ struct v4l2_prio_state prio;/* V4L2 priority state */ u32 caps;/* V4L2 chain-wide caps */
@@ -585,6 +589,7 @@ struct uvc_fh {struct uvc_video_chain *chain;struct uvc_streaming *stream;enum uvc_handle_state state; +unsigned int pending_async_ctrls; };struct uvc_driver {
@@ -769,6 +774,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,int uvc_xu_ctrl_query (struct uvc_video_chain *chain,struct uvc_xu_control_query *xqry); +void uvc_ctrl_cleanup_fh (struct uvc_fh *handle); +/* Utility functions */ struct usb_host_endpoint *uvc_find_endpoint (struct usb_host_interface *alts,u8 epaddr);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 39/176 USB: gadget: core: create sysfs link between udc and gadget
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roy Luo <[email protected]>
[ Upstream commit 0ef40f399aa2be8c04aee9b7430705612c104ce5 ]
udc device and gadget device are tightly coupled, yet there's no good way to corelate the two. Add a sysfs link in udc that points to the corresponding gadget device.
An example use case: userspace configures a f_midi configfs driver and bind the udc device, then it tries to locate the corresponding midi device, which is a child device of the gadget device. The gadget device that's associated to the udc device has to be identified in order to index the midi device. Having a sysfs link would make things much easier.
Stable-dep-of: 399a45e5237c ("usb: gadget: core: flush gadget workqueue after device removal")
--- drivers/usb/gadget/udc/core.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/gadget/udc/core.c +9 -0
@@ -1419,8 +1419,16 @@ int usb_add_gadget(struct usb_gadget *gadget)if (ret) goto err_free_id; + ret =sysfs_create_link (&udc->dev.kobj, + &gadget->dev.kobj,"gadget" ); +if (ret) + goto err_del_gadget; +return 0 ; + err_del_gadget: +device_del (&gadget->dev); + err_free_id:ida_free (&gadget_id_numbers, gadget->id_number);
@@ -1529,6 +1537,7 @@ void usb_del_gadget(struct usb_gadget *gadget)mutex_unlock (&udc_lock);kobject_uevent (&udc->dev.kobj,KOBJ_REMOVE ); +sysfs_remove_link (&udc->dev.kobj,"gadget" );flush_work (&gadget->work);device_del (&gadget->dev);ida_free (&gadget_id_numbers, gadget->id_number);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 40/176 usb: gadget: core: flush gadget workqueue after device removal
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roy Luo <[email protected]>
[ Upstream commit 399a45e5237ca14037120b1b895bd38a3b4492ea ]
device_del() can lead to new work being scheduled in gadget->work workqueue. This is observed, for example, with the dwc3 driver with the following call stack:
device_del()
gadget_unbind_driver()
usb_gadget_disconnect_locked()
dwc3_gadget_pullup()
dwc3_gadget_soft_disconnect()
usb_gadget_set_state()
schedule_work(&gadget->work)Move flush_work() after device_del() to ensure the workqueue is cleaned up.
--- drivers/usb/gadget/udc/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/core.c +1 -1
@@ -1538,8 +1538,8 @@ void usb_del_gadget(struct usb_gadget *gadget)kobject_uevent (&udc->dev.kobj,KOBJ_REMOVE );sysfs_remove_link (&udc->dev.kobj,"gadget" ); -flush_work (&gadget->work);device_del (&gadget->dev); +flush_work (&gadget->work);ida_free (&gadget_id_numbers, gadget->id_number);cancel_work_sync (&udc->vbus_work);device_unregister (&udc->dev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 41/176 USB: gadget: f_midi: f_midi_complete to call queue_work
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jill Donahue <[email protected]>
[ Upstream commit 4ab37fcb42832cdd3e9d5e50653285ca84d6686f ]
When using USB MIDI, a lock is attempted to be acquired twice through a re-entrant call to f_midi_transmit, causing a deadlock.
Fix it by using queue_work() to schedule the inner f_midi_transmit() via a high priority work queue from the completion handler.
--- drivers/usb/gadget/function/f_midi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/function/f_midi.c +1 -1
@@ -282,7 +282,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)/* Our transmit completed. See if there's more to go. * f_midi_transmit eats req, don't queue it again. */ req->length =0 ; -f_midi_transmit (midi); +queue_work (system_highpri_wq, &midi->work);return ; }break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 42/176 ASoC: rockchip: i2s-tdm: fix shift config for SND_SOC_DAIFMT_DSP_[AB]
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
[ Upstream commit 6b24e67b4056ba83b1e95e005b7e50fdb1cc6cf4 ]
Commit 2f45a4e289779 ("ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B") applied a partial change to fix the configuration for DSP A and DSP B formats.
The shift control also needs updating to set the correct offset for frame data compared to LRCK. Set the correct values.
--- sound/soc/rockchip/rockchip_i2s_tdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/rockchip/rockchip_i2s_tdm.c +2 -2
@@ -453,11 +453,11 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,break ;case SND_SOC_DAIFMT_DSP_A : val =I2S_TXCR_TFS_TDM_PCM ; - tdm_val =TDM_SHIFT_CTRL (0 ); + tdm_val =TDM_SHIFT_CTRL (2 );break ;case SND_SOC_DAIFMT_DSP_B : val =I2S_TXCR_TFS_TDM_PCM ; - tdm_val =TDM_SHIFT_CTRL (2 ); + tdm_val =TDM_SHIFT_CTRL (4 );break ;default : ret = -EINVAL ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 43/176 powerpc/64s/mm: Move __real_pte stubs into hash-4k.h
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit 8ae4f16f7d7b59cca55aeca6db7c9636ffe7fbaa ]
The stub versions of __real_pte() etc are only used with HPT & 4K pages, so move them into the hash-4k.h header.
Stable-dep-of: 61bcc752d1b8 ("powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline")
--- arch/powerpc/include/asm/book3s/64/hash-4k.h | 20 +++++++++++++++ arch/powerpc/include/asm/book3s/64/pgtable.h | 26 -------------------- 2 files changed, 20 insertions(+), 26 deletions(-)
arch/powerpc/include/asm/book3s/64/hash-4k.h +20 -0
@@ -89,6 +89,26 @@ static inline int hash__hugepd_ok(hugepd_t hpd) }#endif +/* +* With 4K page size the real_pte machinery is all nops. +*/ +#define __real_pte (e, p, o) ((real_pte_t){(e)}) +#define __rpte_to_pte (r) ((r).pte) +#define __rpte_to_hidx (r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) + +#define pte_iterate_hashed_subpages (rpte, psize, va, index, shift) \ + do { \ + index = 0; \ + shift = mmu_psize_defs[psize].shift; \ + +#define pte_iterate_hashed_end () } while(0) + +/* +* We expect this to be called only for user addresses or kernel virtual +* addresses other than the linear mapping. +*/ +#define pte_pagesize_index (mm, addr, pte) MMU_PAGE_4K +/* * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just * a matter of returning the PTE bits that need to be modified. On 64K PTE,
arch/powerpc/include/asm/book3s/64/pgtable.h +0 -26
@@ -318,32 +318,6 @@ extern unsigned long pci_io_base;#ifndef __ASSEMBLY__ -/* -* This is the default implementation of various PTE accessors, it's -* used in all cases except Book3S with 64K pages where we have a -* concept of sub-pages -*/ -#ifndef __real_pte - -#define __real_pte (e, p, o) ((real_pte_t){(e)}) -#define __rpte_to_pte (r) ((r).pte) -#define __rpte_to_hidx (r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) - -#define pte_iterate_hashed_subpages (rpte, psize, va, index, shift) \ - do { \ - index = 0; \ - shift = mmu_psize_defs[psize].shift; \ - -#define pte_iterate_hashed_end () } while(0) - -/* -* We expect this to be called only for user addresses or kernel virtual -* addresses other than the linear mapping. -*/ -#define pte_pagesize_index (mm, addr, pte) MMU_PAGE_4K - -#endif /* __real_pte */ -static inline unsigned long pte_update (struct mm_struct *mm,unsigned long addr,pte_t *ptep,unsigned long clr,unsigned long set,int huge)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 44/176 powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit 61bcc752d1b81fde3cae454ff20c1d3c359df500 ]
Rewrite __real_pte() and __rpte_to_hidx() as static inline in order to avoid following warnings/errors when building with 4k page size:
CC arch/powerpc/mm/book3s64/hash_tlb.o
arch/powerpc/mm/book3s64/hash_tlb.c: In function 'hpte_need_flush':
arch/powerpc/mm/book3s64/hash_tlb.c:49:16: error: variable 'offset' set but not used [-Werror=unused-but-set-variable]
49 | int i, offset;
| ^~~~~~
CC arch/powerpc/mm/book3s64/hash_native.o
arch/powerpc/mm/book3s64/hash_native.c: In function 'native_flush_hash_range':
arch/powerpc/mm/book3s64/hash_native.c:782:29: error: variable 'index' set but not used [-Werror=unused-but-set-variable]
782 | unsigned long hash, index, hidx, shift, slot;
| ^~~~~
--- arch/powerpc/include/asm/book3s/64/hash-4k.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/book3s/64/hash-4k.h +10 -2
@@ -92,9 +92,17 @@ static inline int hash__hugepd_ok(hugepd_t hpd)/* * With 4K page size the real_pte machinery is all nops. */ -#define __real_pte (e, p, o) ((real_pte_t){(e)}) +static inline real_pte_t __real_pte (pte_t pte,pte_t *ptep,int offset) +{ +return (real_pte_t ){pte}; +} +#define __rpte_to_pte (r) ((r).pte) -#define __rpte_to_hidx (r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) + +static inline unsigned long __rpte_to_hidx (real_pte_t rpte,unsigned long index) +{ +return pte_val (__rpte_to_pte (rpte)) >>H_PAGE_F_GIX_SHIFT ; +}#define pte_iterate_hashed_subpages (rpte, psize, va, index, shift) \ do { \
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 45/176 ALSA: hda/realtek: Fixup ALC225 depop procedure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
[ Upstream commit 174448badb4409491bfba2e6b46f7aa078741c5e ]
Headset MIC will no function when power_save=0.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -3776,6 +3776,7 @@ static void alc225_init(struct hda_codec *codec) AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);msleep (75 ); +alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 );alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 46/176 powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit d262a192d38e527faa5984629aabda2e0d1c4f54 ]
Erhard reported the following KASAN hit while booting his PowerMac G4 with a KASAN-enabled kernel 6.13-rc6:
BUG: KASAN: vmalloc-out-of-bounds in copy_to_kernel_nofault+0xd8/0x1c8 Write of size 8 at addr f1000000 by task chronyd/1293 CPU: 0 UID: 123 PID: 1293 Comm: chronyd Tainted: G W 6.13.0-rc6-PMacG4 #2 Tainted: [W]=WARN Hardware name: PowerMac3,6 7455 0x80010303 PowerMac Call Trace: [c2437590] [c1631a84] dump_stack_lvl+0x70/0x8c (unreliable) [c24375b0] [c0504998] print_report+0xdc/0x504 [c2437610] [c050475c] kasan_report+0xf8/0x108 [c2437690] [c0505a3c] kasan_check_range+0x24/0x18c [c24376a0] [c03fb5e4] copy_to_kernel_nofault+0xd8/0x1c8 [c24376c0] [c004c014] patch_instructions+0x15c/0x16c [c2437710] [c00731a8] bpf_arch_text_copy+0x60/0x7c [c2437730] [c0281168] bpf_jit_binary_pack_finalize+0x50/0xac [c2437750] [c0073cf4] bpf_int_jit_compile+0xb30/0xdec [c2437880] [c0280394] bpf_prog_select_runtime+0x15c/0x478 [c24378d0] [c1263428] bpf_prepare_filter+0xbf8/0xc14 [c2437990] [c12677ec] bpf_prog_create_from_user+0x258/0x2b4 [c24379d0] [c027111c] do_seccomp+0x3dc/0x1890 [c2437ac0] [c001d8e0] system_call_exception+0x2dc/0x420 [c2437f30] [c00281ac] ret_from_syscall+0x0/0x2c --- interrupt: c00 at 0x5a1274 NIP: 005a1274 LR: 006a3b3c CTR: 005296c8 REGS: c2437f40 TRAP: 0c00 Tainted: G W (6.13.0-rc6-PMacG4) MSR: 0200f932 <VEC,EE,PR,FP,ME,IR,DR,RI> CR: 24004422 XER: 00000000
GPR00: 00000166 af8f3fa0 a7ee3540 00000001 00000000 013b6500 005a5858 0200f932
GPR08: 00000000 00001fe9 013d5fc8 005296c8 2822244c 00b2fcd8 00000000 af8f4b57
GPR16: 00000000 00000001 00000000 00000000 00000000 00000001 00000000 00000002
GPR24: 00afdbb0 00000000 00000000 00000000 006e0004 013ce060 006e7c1c 00000001 NIP [005a1274] 0x5a1274
LR [006a3b3c] 0x6a3b3c
--- interrupt: c00
The buggy address belongs to the virtual mapping at
[f1000000, f1002000) created by:
text_area_cpu_up+0x20/0x190
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:00000000 index:0x0 pfn:0x76e30
flags: 0x80000000(zone=2)
raw: 80000000 00000000 00000122 00000000 00000000 00000000 ffffffff 00000001
raw: 00000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
f0ffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0ffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>f1000000: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
^
f1000080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
f1000100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
==================================================================f8 corresponds to KASAN_VMALLOC_INVALID which means the area is not initialised hence not supposed to be used yet.
Powerpc text patching infrastructure allocates a virtual memory area using get_vm_area() and flags it as VM_ALLOC. But that flag is meant to be used for vmalloc() and vmalloc() allocated memory is not supposed to be used before a call to __vmalloc_node_range() which is never called for that area.
That went undetected until commit e4137f08816b ("mm, kasan, kmsan:
instrument copy_from/to_kernel_nofault")
The area allocated by text_area_cpu_up() is not vmalloc memory, it is mapped directly on demand when needed by map_kernel_page(). There is no VM flag corresponding to such usage, so just pass no flag. That way the area will be unpoisonned and usable immediately.
--- arch/powerpc/lib/code-patching.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/lib/code-patching.c +1 -1
@@ -53,7 +53,7 @@ static int text_area_cpu_up(unsigned int cpu)unsigned long addr;int err; - area =get_vm_area (PAGE_SIZE ,VM_ALLOC ); + area =get_vm_area (PAGE_SIZE ,0 );if (!area) {WARN_ONCE (1 ,"Failed to create text area for cpu %d\n" , cpu);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 47/176 geneve: Fix use-after-free in geneve_find_dev().
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 9593172d93b9f91c362baec4643003dc29802929 ]
syzkaller reported a use-after-free in geneve_find_dev() [0] without repro.
geneve_configure() links struct geneve_dev.next to net_generic(net, geneve_net_id)->geneve_list.
The net here could differ from dev_net(dev) if IFLA_NET_NS_PID, IFLA_NET_NS_FD, or IFLA_TARGET_NETNSID is set.
When dev_net(dev) is dismantled, geneve_exit_batch_rtnl() finally calls unregister_netdevice_queue() for each dev in the netns, and later the dev is freed.
However, its geneve_dev.next is still linked to the backend UDP socket netns.
Then, use-after-free will occur when another geneve dev is created in the netns.
Let's call geneve_dellink() instead in geneve_destroy_tunnels().
[0]:
BUG: KASAN: slab-use-after-free in geneve_find_dev drivers/net/geneve.c:1295 [inline] BUG: KASAN: slab-use-after-free in geneve_configure+0x234/0x858 drivers/net/geneve.c:1343 Read of size 2 at addr ffff000054d6ee24 by task syz.1.4029/13441 CPU: 1 UID: 0 PID: 13441 Comm: syz.1.4029 Not tainted 6.13.0-g0ad9617c78ac #24 dc35ca22c79fb82e8e7bc5c9c9adafea898b1e3d Hardware name: linux,dummy-virt (DT) Call trace: show_stack+0x38/0x50 arch/arm64/kernel/stacktrace.c:466 (C) __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0xbc/0x108 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x16c/0x6f0 mm/kasan/report.c:489 kasan_report+0xc0/0x120 mm/kasan/report.c:602 __asan_report_load2_noabort+0x20/0x30 mm/kasan/report_generic.c:379 geneve_find_dev drivers/net/geneve.c:1295 [inline] geneve_configure+0x234/0x858 drivers/net/geneve.c:1343 geneve_newlink+0xb8/0x128 drivers/net/geneve.c:1634 rtnl_newlink_create+0x23c/0x868 net/core/rtnetlink.c:3795 __rtnl_newlink net/core/rtnetlink.c:3906 [inline] rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021 rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911 netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543 rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:713 [inline] __sock_sendmsg net/socket.c:728 [inline] ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568 ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622 __sys_sendmsg net/socket.c:2654 [inline] __do_sys_sendmsg net/socket.c:2659 [inline] __se_sys_sendmsg net/socket.c:2657 [inline] __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132 do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151 el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600 Allocated by task 13247: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x30/0x68 mm/kasan/common.c:68 kasan_save_alloc_info+0x44/0x58 mm/kasan/generic.c:568 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x84/0xa0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4298 [inline] __kmalloc_node_noprof+0x2a0/0x560 mm/slub.c:4304 __kvmalloc_node_noprof+0x9c/0x230 mm/util.c:645 alloc_netdev_mqs+0xb8/0x11a0 net/core/dev.c:11470 rtnl_create_link+0x2b8/0xb50 net/core/rtnetlink.c:3604 rtnl_newlink_create+0x19c/0x868 net/core/rtnetlink.c:3780 __rtnl_newlink net/core/rtnetlink.c:3906 [inline] rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021 rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911 netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543 rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:713 [inline] __sock_sendmsg net/socket.c:728 [inline] ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568 ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622 __sys_sendmsg net/socket.c:2654 [inline] __do_sys_sendmsg net/socket.c:2659 [inline] __se_sys_sendmsg net/socket.c:2657 [inline] __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132 do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151 el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600 Freed by task 45: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x30/0x68 mm/kasan/common.c:68 kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:582 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x48/0x68 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2353 [inline] slab_free mm/slub.c:4613 [inline] kfree+0x140/0x420 mm/slub.c:4761 kvfree+0x4c/0x68 mm/util.c:688 netdev_release+0x94/0xc8 net/core/net-sysfs.c:2065 device_release+0x98/0x1c0 kobject_cleanup lib/kobject.c:689 [inline] kobject_release lib/kobject.c:720 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x2b0/0x438 lib/kobject.c:737 netdev_run_todo+0xe5c/0xfc8 net/core/dev.c:11185 rtnl_unlock+0x20/0x38 net/core/rtnetlink.c:151 cleanup_net+0x4fc/0x8c0 net/core/net_namespace.c:648 process_one_work+0x700/0x1398 kernel/workqueue.c:3236 process_scheduled_works kernel/workqueue.c:3317 [inline] worker_thread+0x8c4/0xe10 kernel/workqueue.c:3398 kthread+0x4bc/0x608 kernel/kthread.c:464 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:862 The buggy address belongs to the object at ffff000054d6e000 which belongs to the cache kmalloc-cg-4k of size 4096
The buggy address is located 3620 bytes inside of
freed 4096-byte region [ffff000054d6e000, ffff000054d6f000)
The buggy address belongs to the physical page: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x94d68
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 memcg:ffff000016276181
flags: 0x3fffe0000000040(head|node=0|zone=0|lastcpupid=0x1ffff)page_type: f5(slab)
raw: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
head: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000
head: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
head: 03fffe0000000003 fffffdffc1535a01 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff000054d6ed00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff000054d6ed80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff000054d6ee00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff000054d6ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff000054d6ef00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb--- drivers/net/geneve.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/net/geneve.c +3 -8
@@ -1970,16 +1970,11 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head)/* gather any geneve devices that were moved into this ns */ for_each_netdev_safe (net, dev, aux)if (dev->rtnl_link_ops == &geneve_link_ops) -unregister_netdevice_queue (dev, head); +geneve_dellink (dev, head);/* now gather any other geneve devices that were created in this ns */ -list_for_each_entry_safe (geneve, next, &gn->geneve_list, next) { -/* If geneve->dev is in the same netns, it was already added -* to the list by the previous loop. -*/ -if (!net_eq (dev_net (geneve->dev), net)) -unregister_netdevice_queue (geneve->dev, head); - } +list_for_each_entry_safe (geneve, next, &gn->geneve_list, next) +geneve_dellink (geneve->dev, head); } static void __net_exit geneve_exit_batch_net(struct list_head *net_list)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 48/176 ALSA: hda/cirrus: Correct the full scale volume set logic
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaly Rodionov <[email protected]>
[ Upstream commit 08b613b9e2ba431db3bd15cb68ca72472a50ef5c ]
This patch corrects the full-scale volume setting logic. On certain platforms, the full-scale volume bit is required. The current logic mistakenly sets this bit and incorrectly clears reserved bit 0, causing the headphone output to be muted.
--- sound/pci/hda/patch_cs8409-tables.c | 6 +++--- sound/pci/hda/patch_cs8409.c | 20 +++++++++++--------- sound/pci/hda/patch_cs8409.h | 5 +++-- 3 files changed, 17 insertions(+), 14 deletions(-)
sound/pci/hda/patch_cs8409-tables.c +3 -3
@@ -121,7 +121,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f }, - { CS42L42_HP_CTL, 0x03 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIC_DET_CTL1, 0xB6 }, { CS42L42_TIPSENSE_CTL, 0xC2 }, { CS42L42_HS_CLAMP_DISABLE, 0x01 },
@@ -315,7 +315,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { CS42L42_ASP_TX_SZ_EN, 0x01 }, { CS42L42_PWR_CTL1, 0x0A }, { CS42L42_PWR_CTL2, 0x84 }, - { CS42L42_HP_CTL, 0x03 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f },
@@ -371,7 +371,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { CS42L42_ASP_TX_SZ_EN, 0x00 }, { CS42L42_PWR_CTL1, 0x0E }, { CS42L42_PWR_CTL2, 0x84 }, - { CS42L42_HP_CTL, 0x01 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f },
sound/pci/hda/patch_cs8409.c +11 -9
@@ -876,7 +876,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) { CS42L42_DET_INT_STATUS2, 0x00 }, { CS42L42_TSRS_PLUG_STATUS, 0x00 }, }; -int fsv_old, fsv_new; +unsigned int fsv;/* Bring CS42L42 out of Reset */ spec->gpio_data =snd_hda_codec_read (codec,CS8409_PIN_AFG ,0 ,AC_VERB_GET_GPIO_DATA ,0 );
@@ -893,13 +893,15 @@ static void cs42l42_resume(struct sub_codec *cs42l42)/* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read (cs42l42, irq_regs,ARRAY_SIZE (irq_regs)); - fsv_old =cs8409_i2c_read (cs42l42,CS42L42_HP_CTL ); -if (cs42l42->full_scale_vol ==CS42L42_FULL_SCALE_VOL_0DB ) - fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK ; -else - fsv_new = fsv_old &CS42L42_FULL_SCALE_VOL_MASK ; -if (fsv_new != fsv_old) -cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv_new); + fsv =cs8409_i2c_read (cs42l42,CS42L42_HP_CTL ); +if (cs42l42->full_scale_vol) { +// Set the full scale volume bit + fsv |=CS42L42_FULL_SCALE_VOL_MASK ; +cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv); + } +// Unmute analog channels A and B + fsv = (fsv & ~CS42L42_ANA_MUTE_AB ); +cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv);/* we have to explicitly allow unsol event handling even during the * resume phase so that the jack event is processed properly
@@ -921,7 +923,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, - { CS42L42_HP_CTL, 0x0F }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_ASP_RX_DAI0_EN, 0x00 }, { CS42L42_ASP_CLK_CFG, 0x00 }, { CS42L42_PWR_CTL1, 0xFE },
sound/pci/hda/patch_cs8409.h +3 -2
@@ -230,9 +230,10 @@ enum cs8409_coefficient_index_registers {#define CS42L42_PDN_TIMEOUT_US (250000)#define CS42L42_PDN_SLEEP_US (2000)#define CS42L42_INIT_TIMEOUT_MS (45) +#define CS42L42_ANA_MUTE_AB (0x0C)#define CS42L42_FULL_SCALE_VOL_MASK (2) -#define CS42L42_FULL_SCALE_VOL_0DB (1) -#define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) +#define CS42L42_FULL_SCALE_VOL_0DB (0) +#define CS42L42_FULL_SCALE_VOL_MINUS6DB (1)/* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 49/176 ibmvnic: Return error code on TX scrq flush fail
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <[email protected]>
[ Upstream commit 5cb431dcf8048572e9ffc6c30cdbd8832cbe502d ]
In ibmvnic_xmit() if ibmvnic_tx_scrq_flush() returns H_CLOSED then it will inform upper level networking functions to disable tx queues. H_CLOSED signals that the connection with the vnic server is down and a transport event is expected to recover the device.
Previously, ibmvnic_tx_scrq_flush() was hard-coded to return success. Therefore, the queues would remain active until ibmvnic_cleanup() is called within do_reset().
The problem is that do_reset() depends on the RTNL lock. If several ibmvnic devices are resetting then there can be a long wait time until the last device can grab the lock. During this time the tx/rx queues still appear active to upper level functions.
FYI, we do make a call to netif_carrier_off() outside the RTNL lock but its calls to dev_deactivate() are also dependent on the RTNL lock.
As a result, large amounts of retransmissions were observed in a short period of time, eventually leading to ETIMEOUT. This was specifically seen with HNV devices, likely because of even more RTNL dependencies.
Therefore, ensure the return code of ibmvnic_tx_scrq_flush() is propagated to the xmit function to allow for an earlier (and lock-less) response to a transport event.
Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
--- drivers/net/ethernet/ibm/ibmvnic.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +7 -3
@@ -2181,7 +2181,7 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,ibmvnic_tx_scrq_clean_buffer (adapter, tx_scrq); else ind_bufp->index = 0; -return 0 ; +return rc; }static netdev_tx_t ibmvnic_xmit (struct sk_buff *skb,struct net_device *netdev)
@@ -2234,7 +2234,9 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_dropped++; tx_send_failed++; ret =NETDEV_TX_OK ; -ibmvnic_tx_scrq_flush (adapter, tx_scrq); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); +if (lpar_rc !=H_SUCCESS ) + goto tx_err; goto out; }
@@ -2249,8 +2251,10 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)dev_kfree_skb_any (skb); tx_send_failed++; tx_dropped++; -ibmvnic_tx_scrq_flush (adapter, tx_scrq); ret =NETDEV_TX_OK ; + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); +if (lpar_rc !=H_SUCCESS ) + goto tx_err; goto out; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 50/176 ibmvnic: Introduce send sub-crq direct
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <[email protected]>
[ Upstream commit 74839f7a82689bf5a21a5447cae8e3a7b7a606d2 ]
Firmware supports two hcalls to send a sub-crq request:H_SEND_SUB_CRQ_INDIRECT and H_SEND_SUB_CRQ. The indirect hcall allows for submission of batched messages while the other hcall is limited to only one message. This protocol is defined in PAPR section 17.2.3.3.
Previously, the ibmvnic xmit function only used the indirect hcall. This allowed the driver to batch it's skbs. A single skb can occupy a few entries per hcall depending on if FW requires skb header information or not. The FW only needs header information if the packet is segmented.
By this logic, if an skb is not GSO then it can fit in one sub-crq message and therefore is a candidate for H_SEND_SUB_CRQ. Batching skb transmission is only useful when there are more packets coming down the line (ie netdev_xmit_more is true).
As it turns out, H_SEND_SUB_CRQ induces less latency than H_SEND_SUB_CRQ_INDIRECT. Therefore, use H_SEND_SUB_CRQ where appropriate.
Small latency gains seen when doing TCP_RR_150 (request/response workload). Ftrace results (graph-time=1):
Previous:
ibmvnic_xmit = 29618270.83 us / 8860058.0 hits = AVG 3.34
ibmvnic_tx_scrq_flush = 21972231.02 us / 6553972.0 hits = AVG 3.35
Now:
ibmvnic_xmit = 22153350.96 us / 8438942.0 hits = AVG 2.63
ibmvnic_tx_scrq_flush = 15858922.4 us / 6244076.0 hits = AVG 2.54Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
--- drivers/net/ethernet/ibm/ibmvnic.c | 52 ++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +46 -6
@@ -116,6 +116,7 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter, struct ibmvnic_long_term_buff *ltb);static void ibmvnic_disable_irqs (struct ibmvnic_adapter *adapter);static void flush_reset_queue (struct ibmvnic_adapter *adapter); +static void print_subcrq_error (struct device *dev,int rc,const char *func);struct ibmvnic_stat {char name[ETH_GSTRING_LEN ];
@@ -2160,8 +2161,29 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, } } +static int send_subcrq_direct (struct ibmvnic_adapter *adapter, +u64 remote_handle,u64 *entry) +{ +unsigned int ua = adapter->vdev->unit_address; +struct device *dev = &adapter->vdev->dev; +int rc; + +/* Make sure the hypervisor sees the complete request */ +dma_wmb (); + rc =plpar_hcall_norets (H_SEND_SUB_CRQ , ua, +cpu_to_be64 (remote_handle), +cpu_to_be64 (entry[0 ]),cpu_to_be64 (entry[1 ]), +cpu_to_be64 (entry[2 ]),cpu_to_be64 (entry[3 ])); + +if (rc) +print_subcrq_error (dev, rc, __func__); + +return rc; +} +static int ibmvnic_tx_scrq_flush (struct ibmvnic_adapter *adapter, -struct ibmvnic_sub_crq_queue *tx_scrq) +struct ibmvnic_sub_crq_queue *tx_scrq, +bool indirect) {struct ibmvnic_ind_xmit_queue *ind_bufp;u64 dma_addr;
@@ -2176,7 +2198,13 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,if (!entries)return 0 ; - rc =send_subcrq_indirect (adapter, handle, dma_addr, entries); + +if (indirect) + rc =send_subcrq_indirect (adapter, handle, dma_addr, entries); +else + rc =send_subcrq_direct (adapter, handle, + (u64 *)ind_bufp->indir_arr); +if (rc)ibmvnic_tx_scrq_clean_buffer (adapter, tx_scrq);else
@@ -2234,7 +2262,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_dropped++; tx_send_failed++; ret =NETDEV_TX_OK ; - lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq, true);if (lpar_rc !=H_SUCCESS ) goto tx_err; goto out;
@@ -2252,7 +2280,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_send_failed++; tx_dropped++; ret =NETDEV_TX_OK ; - lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq, true);if (lpar_rc !=H_SUCCESS ) goto tx_err; goto out;
@@ -2350,6 +2378,16 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_crq.v1.flags1 |=IBMVNIC_TX_LSO ; tx_crq.v1.mss =cpu_to_be16 (skb_shinfo (skb)->gso_size); hdrs +=2 ; + }else if (!ind_bufp->index && !netdev_xmit_more ()) { + ind_bufp->indir_arr[0 ] = tx_crq; + ind_bufp->index =1 ; + tx_buff->num_entries =1 ; +netdev_tx_sent_queue (txq, skb->len); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq, false); +if (lpar_rc !=H_SUCCESS ) + goto tx_err; + + goto early_exit; }if ((*hdrs >>7 ) &1 )
@@ -2359,7 +2397,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_buff->num_entries = num_entries;/* flush buffer if current entry can not fit */ if (num_entries + ind_bufp->index >IBMVNIC_MAX_IND_DESCS ) { - lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq, true);if (lpar_rc !=H_SUCCESS ) goto tx_flush_err; }
@@ -2367,15 +2405,17 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) indir_arr[0 ] = tx_crq;memcpy (&ind_bufp->indir_arr[ind_bufp->index], &indir_arr[0 ], num_entries *sizeof (struct ibmvnic_generic_scrq )); + ind_bufp->index += num_entries;if (__netdev_tx_sent_queue (txq, skb->len,netdev_xmit_more () && ind_bufp->index <IBMVNIC_MAX_IND_DESCS )) { - lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq); + lpar_rc =ibmvnic_tx_scrq_flush (adapter, tx_scrq, true);if (lpar_rc !=H_SUCCESS ) goto tx_err; } +early_exit:if (atomic_add_return (num_entries, &tx_scrq->used) >= adapter->req_tx_entries_per_subcrq) {netdev_dbg (netdev,"Stopping queue %d\n" , queue_num);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 51/176 ibmvnic: Add stat for tx direct vs tx batched
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <[email protected]>
[ Upstream commit 2ee73c54a615b74d2e7ee6f20844fd3ba63fc485 ]
Allow tracking of packets sent with send_subcrq direct vs indirect. ethtool -S <dev> will now provide a counter of the number of uses of each xmit method. This metric will be useful in performance debugging.
Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
--- drivers/net/ethernet/ibm/ibmvnic.c | 23 ++++++++++++++++------- drivers/net/ethernet/ibm/ibmvnic.h | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +16 -7
@@ -2136,7 +2136,7 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, tx_buff = &tx_pool->tx_buff[index]; adapter->netdev->stats.tx_packets--; adapter->netdev->stats.tx_bytes -= tx_buff->skb->len; - adapter->tx_stats_buffers[queue_num].packets--; + adapter->tx_stats_buffers[queue_num].batched_packets--; adapter->tx_stats_buffers[queue_num].bytes -= tx_buff->skb->len;dev_kfree_skb_any (tx_buff->skb);
@@ -2228,7 +2228,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)unsigned int tx_map_failed =0 ;union sub_crq indir_arr[16 ];unsigned int tx_dropped =0 ; -unsigned int tx_packets =0 ; +unsigned int tx_dpackets =0 ; +unsigned int tx_bpackets =0 ;unsigned int tx_bytes =0 ;dma_addr_t data_dma_addr;struct netdev_queue *txq;
@@ -2387,6 +2388,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)if (lpar_rc !=H_SUCCESS ) goto tx_err; + tx_dpackets++; goto early_exit; }
@@ -2415,6 +2417,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) goto tx_err; } + tx_bpackets++; + early_exit:if (atomic_add_return (num_entries, &tx_scrq->used) >= adapter->req_tx_entries_per_subcrq) {
@@ -2422,7 +2426,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)netif_stop_subqueue (netdev, queue_num); } - tx_packets++; tx_bytes += skb->len;txq_trans_cond_update (txq); ret =NETDEV_TX_OK ;
@@ -2452,10 +2455,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)rcu_read_unlock (); netdev->stats.tx_dropped += tx_dropped; netdev->stats.tx_bytes += tx_bytes; - netdev->stats.tx_packets += tx_packets; + netdev->stats.tx_packets += tx_bpackets + tx_dpackets; adapter->tx_send_failed += tx_send_failed; adapter->tx_map_failed += tx_map_failed; - adapter->tx_stats_buffers[queue_num].packets += tx_packets; + adapter->tx_stats_buffers[queue_num].batched_packets += tx_bpackets; + adapter->tx_stats_buffers[queue_num].direct_packets += tx_dpackets; adapter->tx_stats_buffers[queue_num].bytes += tx_bytes; adapter->tx_stats_buffers[queue_num].dropped_packets += tx_dropped;
@@ -3621,7 +3625,10 @@ static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)memcpy (data, ibmvnic_stats[i].name,ETH_GSTRING_LEN );for (i =0 ; i < adapter->req_tx_queues; i++) { -snprintf (data,ETH_GSTRING_LEN ,"tx%d_packets" , i); +snprintf (data,ETH_GSTRING_LEN ,"tx%d_batched_packets" , i); + data +=ETH_GSTRING_LEN ; + +snprintf (data,ETH_GSTRING_LEN ,"tx%d_direct_packets" , i); data +=ETH_GSTRING_LEN ;snprintf (data,ETH_GSTRING_LEN ,"tx%d_bytes" , i);
@@ -3686,7 +3693,9 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev, (adapter, ibmvnic_stats[i].offset));for (j =0 ; j < adapter->req_tx_queues; j++) { - data[i] = adapter->tx_stats_buffers[j].packets; + data[i] = adapter->tx_stats_buffers[j].batched_packets; + i++; + data[i] = adapter->tx_stats_buffers[j].direct_packets; i++; data[i] = adapter->tx_stats_buffers[j].bytes; i++;
drivers/net/ethernet/ibm/ibmvnic.h +2 -1
@@ -213,7 +213,8 @@ struct ibmvnic_statistics {#define NUM_TX_STATS 3struct ibmvnic_tx_queue_stats { -u64 packets; +u64 batched_packets; +u64 direct_packets;u64 bytes;u64 dropped_packets; };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 52/176 ibmvnic: Dont reference skb after sending to VIOS
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <[email protected]>
[ Upstream commit bdf5d13aa05ec314d4385b31ac974d6c7e0997c9 ]
Previously, after successfully flushing the xmit buffer to VIOS, the tx_bytes stat was incremented by the length of the skb.
It is invalid to access the skb memory after sending the buffer to the VIOS because, at any point after sending, the VIOS can trigger an interrupt to free this memory. A race between reading skb->len and freeing the skb is possible (especially during LPM) and will result in use-after-free:
==================================================================
BUG: KASAN: slab-use-after-free in ibmvnic_xmit+0x75c/0x1808 [ibmvnic] Read of size 4 at addr c00000024eb48a70 by task hxecom/14495 <...> Call Trace: [c000000118f66cf0] [c0000000018cba6c] dump_stack_lvl+0x84/0xe8 (unreliable) [c000000118f66d20] [c0000000006f0080] print_report+0x1a8/0x7f0 [c000000118f66df0] [c0000000006f08f0] kasan_report+0x128/0x1f8 [c000000118f66f00] [c0000000006f2868] __asan_load4+0xac/0xe0 [c000000118f66f20] [c0080000046eac84] ibmvnic_xmit+0x75c/0x1808 [ibmvnic] [c000000118f67340] [c0000000014be168] dev_hard_start_xmit+0x150/0x358 <...> Freed by task 0: kasan_save_stack+0x34/0x68 kasan_save_track+0x2c/0x50 kasan_save_free_info+0x64/0x108 __kasan_mempool_poison_object+0x148/0x2d4 napi_skb_cache_put+0x5c/0x194 net_tx_action+0x154/0x5b8 handle_softirqs+0x20c/0x60c do_softirq_own_stack+0x6c/0x88 <...> The buggy address belongs to the object at c00000024eb48a00 which belongs to the cache skbuff_head_cache of size 224 ==================================================================
--- drivers/net/ethernet/ibm/ibmvnic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/ibm/ibmvnic.c +3 -1
@@ -2234,6 +2234,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)dma_addr_t data_dma_addr;struct netdev_queue *txq;unsigned long lpar_rc; +unsigned int skblen;union sub_crq tx_crq;unsigned int offset;int num_entries =1 ;
@@ -2336,6 +2337,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_buff->skb = skb; tx_buff->index = bufidx; tx_buff->pool_index = queue_num; + skblen = skb->len;memset (&tx_crq,0 ,sizeof (tx_crq)); tx_crq.v1.first =IBMVNIC_CRQ_CMD ;
@@ -2426,7 +2428,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)netif_stop_subqueue (netdev, queue_num); } - tx_bytes += skb->len; + tx_bytes += skblen;txq_trans_cond_update (txq); ret =NETDEV_TX_OK ; goto out;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 53/176 gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 4ccacf86491d33d2486b62d4d44864d7101b299d ]
Brad Spengler reported the list_del() corruption splat in gtp_net_exit_batch_rtnl(). [0]
Commit eb28fd76c0a0 ("gtp: Destroy device along with udp socket's netns dismantle.") added the for_each_netdev() loop in gtp_net_exit_batch_rtnl() to destroy devices in each netns as done in geneve and ip tunnels.
However, this could trigger ->dellink() twice for the same device during ->exit_batch_rtnl().
Say we have two netns A & B and gtp device B that resides in netns B but whose UDP socket is in netns A.
1. cleanup_net() processes netns A and then B.
2. gtp_net_exit_batch_rtnl() finds the device B while iterating
netns A's gn->gtp_dev_list and calls ->dellink().
[ device B is not yet unlinked from netns B
as unregister_netdevice_many() has not been called. ]
3. gtp_net_exit_batch_rtnl() finds the device B while iterating
netns B's for_each_netdev() and calls ->dellink().
gtp_dellink() cleans up the device's hash table, unlinks the dev from gn->gtp_dev_list, and calls unregister_netdevice_queue().
Basically, calling gtp_dellink() multiple times is fine unless CONFIG_DEBUG_LIST is enabled.
Let's remove for_each_netdev() in gtp_net_exit_batch_rtnl() and delegate the destruction to default_device_exit_batch() as done in bareudp.
[0]:list_del corruption, ffff8880aaa62c00->next (autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object]) is LIST_POISON1 (ffffffffffffff02) (prev is 0xffffffffffffff04) kernel BUG at lib/list_debug.c:58!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 UID: 0 PID: 1804 Comm: kworker/u8:7 Tainted: G T 6.12.13-grsec-full-20250211091339 #1 Tainted: [T]=RANDSTRUCT Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Workqueue: netns cleanup_net RIP: 0010:[<ffffffff84947381>] __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58 Code: c2 76 91 31 c0 e8 9f b1 f7 fc 0f 0b 4d 89 f0 48 c7 c1 02 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 e0 c2 76 91 31 c0 e8 7f b1 f7 fc <0f> 0b 4d 89 e8 48 c7 c1 04 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 60 RSP: 0018:fffffe8040b4fbd0 EFLAGS: 00010283 RAX: 00000000000000cc RBX: dffffc0000000000 RCX: ffffffff818c4054 RDX: ffffffff84947381 RSI: ffffffff818d1512 RDI: 0000000000000000 RBP: ffff8880aaa62c00 R08: 0000000000000001 R09: fffffbd008169f32 R10: fffffe8040b4f997 R11: 0000000000000001 R12: a1988d84f24943e4 R13: ffffffffffffff02 R14: ffffffffffffff04 R15: ffff8880aaa62c08 RBX: kasan shadow of 0x0 RCX: __wake_up_klogd.part.0+0x74/0xe0 kernel/printk/printk.c:4554 RDX: __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58 RSI: vprintk+0x72/0x100 kernel/printk/printk_safe.c:71 RBP: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object] RSP: process kstack fffffe8040b4fbd0+0x7bd0/0x8000 [kworker/u8:7+netns 1804 ] R09: kasan shadow of process kstack fffffe8040b4f990+0x7990/0x8000 [kworker/u8:7+netns 1804 ] R10: process kstack fffffe8040b4f997+0x7997/0x8000 [kworker/u8:7+netns 1804 ] R15: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc08/0x1000 [slab object] FS: 0000000000000000(0000) GS:ffff888116000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000748f5372c000 CR3: 0000000015408000 CR4: 00000000003406f0 shadow CR4: 00000000003406f0 Stack: 0000000000000000 ffffffff8a0c35e7 ffffffff8a0c3603 ffff8880aaa62c00 ffff8880aaa62c00 0000000000000004 ffff88811145311c 0000000000000005 0000000000000001 ffff8880aaa62000 fffffe8040b4fd40 ffffffff8a0c360d Call Trace: <TASK> [<ffffffff8a0c360d>] __list_del_entry_valid include/linux/list.h:131 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] __list_del_entry include/linux/list.h:248 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] list_del include/linux/list.h:262 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] gtp_dellink+0x16d/0x360 drivers/net/gtp.c:1557 fffffe8040b4fc28 [<ffffffff8a0d0404>] gtp_net_exit_batch_rtnl+0x124/0x2c0 drivers/net/gtp.c:2495 fffffe8040b4fc88 [<ffffffff8e705b24>] cleanup_net+0x5a4/0xbe0 net/core/net_namespace.c:635 fffffe8040b4fcd0 [<ffffffff81754c97>] process_one_work+0xbd7/0x2160 kernel/workqueue.c:3326 fffffe8040b4fd88 [<ffffffff81757195>] process_scheduled_works kernel/workqueue.c:3407 [inline] fffffe8040b4fec0 [<ffffffff81757195>] worker_thread+0x6b5/0xfa0 kernel/workqueue.c:3488 fffffe8040b4fec0 [<ffffffff817782a0>] kthread+0x360/0x4c0 kernel/kthread.c:397 fffffe8040b4ff78 [<ffffffff814d8594>] ret_from_fork+0x74/0xe0 arch/x86/kernel/process.c:172 fffffe8040b4ffb8 [<ffffffff8110f509>] ret_from_fork_asm+0x29/0xc0 arch/x86/entry/entry_64.S:399 fffffe8040b4ffe8 </TASK> Modules linked in:
--- drivers/net/gtp.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/net/gtp.c +0 -5
@@ -1894,11 +1894,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,list_for_each_entry (net, net_list, exit_list) {struct gtp_net *gn =net_generic (net, gtp_net_id);struct gtp_dev *gtp, *gtp_next; -struct net_device *dev; - -for_each_netdev (net, dev) -if (dev->rtnl_link_ops == >p_link_ops) -gtp_dellink (dev, dev_to_kill);list_for_each_entry_safe (gtp, gtp_next, &gn->gtp_dev_list, list)gtp_dellink (gtp->dev, dev_to_kill);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 54/176 geneve: Suppress list corruption splat in geneve_destroy_tunnels().
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 62fab6eef61f245dc8797e3a6a5b890ef40e8628 ]
As explained in the previous patch, iterating for_each_netdev() and gn->geneve_list during ->exit_batch_rtnl() could trigger ->dellink() twice for the same device.
If CONFIG_DEBUG_LIST is enabled, we will see a list_del() corruption splat in the 2nd call of geneve_dellink().
Let's remove for_each_netdev() in geneve_destroy_tunnels() and delegate that part to default_device_exit_batch().
--- drivers/net/geneve.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/net/geneve.c +0 -7
@@ -1965,14 +1965,7 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) {struct geneve_net *gn =net_generic (net, geneve_net_id);struct geneve_dev *geneve, *next; -struct net_device *dev, *aux; -/* gather any geneve devices that were moved into this ns */ -for_each_netdev_safe (net, dev, aux) -if (dev->rtnl_link_ops == &geneve_link_ops) -geneve_dellink (dev, head); - -/* now gather any other geneve devices that were created in this ns */ list_for_each_entry_safe (geneve, next, &gn->geneve_list, next)geneve_dellink (geneve->dev, head); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 55/176 flow_dissector: Fix handling of mixed port and port-range keys
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 3e5796862c692ea608d96f0a1437f9290f44953a ]
This patch fixes a bug in TC flower filter where rules combining a specific destination port with a source port range weren't working correctly.
The specific case was when users tried to configure rules like:
tc filter add dev ens38 ingress protocol ip flower ip_proto udp \dst_port 5000 src_port 2000-3000 action drop
The root cause was in the flow dissector code. While both FLOW_DISSECTOR_KEY_PORTS and FLOW_DISSECTOR_KEY_PORTS_RANGE flags were being set correctly in the classifier, the __skb_flow_dissect_ports() function was only populating one of them: whichever came first in the enum check. This meant that when the code needed both a specific port and a port range, one of them would be left as 0, causing the filter to not match packets as expected.
Fix it by removing the either/or logic and instead checking and populating both key types independently when they're in use.
--- net/core/flow_dissector.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
net/core/flow_dissector.c +19 -12
@@ -751,23 +751,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb, void *target_container, const void *data, int nhoff, u8 ip_proto, int hlen) { - enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX; -struct flow_dissector_key_ports *key_ports; + struct flow_dissector_key_ports_range *key_ports_range = NULL; +struct flow_dissector_key_ports *key_ports =NULL ; +__be32 ports;if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) - dissector_ports =FLOW_DISSECTOR_KEY_PORTS ; -else if (dissector_uses_key (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE )) - dissector_ports =FLOW_DISSECTOR_KEY_PORTS_RANGE ; + key_ports =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS , + target_container); -if (dissector_ports ==FLOW_DISSECTOR_KEY_MAX ) +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS_RANGE )) + key_ports_range =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE , + target_container); + +if (!key_ports && !key_ports_range)return ; - key_ports =skb_flow_dissector_target (flow_dissector, - dissector_ports, - target_container); - key_ports->ports =__skb_flow_get_ports (skb, nhoff, ip_proto, - data, hlen); + ports =__skb_flow_get_ports (skb, nhoff, ip_proto, data, hlen); + +if (key_ports) + key_ports->ports = ports; + +if (key_ports_range) + key_ports_range->tp.ports = ports; } static void
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 56/176 flow_dissector: Fix port range key handling in BPF conversion
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 69ab34f705fbfabcace64b5d53bb7a4450fac875 ]
Fix how port range keys are handled in __skb_flow_bpf_to_target() by:
- Separating PORTS and PORTS_RANGE key handling
- Using correct key_ports_range structure for range keys
- Properly initializing both key types independently
This ensures port range information is correctly stored in its dedicated structure rather than incorrectly using the regular ports key structure.
--- net/core/flow_dissector.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
net/core/flow_dissector.c +10 -8
@@ -829,6 +829,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,struct flow_dissector *flow_dissector, void *target_container) { + struct flow_dissector_key_ports_range *key_ports_range = NULL;struct flow_dissector_key_ports *key_ports =NULL ;struct flow_dissector_key_control *key_control;struct flow_dissector_key_basic *key_basic;
@@ -873,20 +874,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, key_control->addr_type =FLOW_DISSECTOR_KEY_IPV6_ADDRS ; } -if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) { key_ports =skb_flow_dissector_target (flow_dissector,FLOW_DISSECTOR_KEY_PORTS , target_container); -else if (dissector_uses_key (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE )) - key_ports =skb_flow_dissector_target (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE , - target_container); - -if (key_ports) { key_ports->src = flow_keys->sport; key_ports->dst = flow_keys->dport; } +if (dissector_uses_key (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE )) { + key_ports_range =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE , + target_container); + key_ports_range->tp.src = flow_keys->sport; + key_ports_range->tp.dst = flow_keys->dport; + }if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_FLOW_LABEL )) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 57/176 net: Add non-RCU dev_getbyhwaddr() helper
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 4b5a28b38c4a0106c64416a1b2042405166b26ce ]
Add dedicated helper for finding devices by hardware address when holding rtnl_lock, similar to existing dev_getbyhwaddr_rcu(). This prevents PROVE_LOCKING warnings when rtnl_lock is held but RCU read lock is not.
Extract common address comparison logic into dev_addr_cmp().
The context about this change could be found in the following discussion:
Stable-dep-of: 4eae0ee0f1e6 ("arp: switch to dev_getbyhwaddr() in arp_req_set_public()")
--- include/linux/netdevice.h | 2 ++ net/core/dev.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-)
include/linux/netdevice.h +2 -0
@@ -3011,6 +3011,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net) }int netdev_boot_setup_check (struct net_device *dev); +struct net_device *dev_getbyhwaddr (struct net *net,unsigned short type, +const char *hwaddr);struct net_device *dev_getbyhwaddr_rcu (struct net *net,unsigned short type,const char *hwaddr);struct net_device *dev_getfirstbyhwtype (struct net *net,unsigned short type);
net/core/dev.c +34 -3
@@ -921,6 +921,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex)return ret; } +static bool dev_addr_cmp (struct net_device *dev,unsigned short type, +const char *ha) +{ +return dev->type == type && !memcmp (dev->dev_addr, ha, dev->addr_len); +} +/** * dev_getbyhwaddr_rcu - find a device by its hardware address * @net: the applicable net namespace
@@ -929,7 +935,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex)* * Search for an interface by MAC address. Returns NULL if the device * is not found or a pointer to the device. -* The caller must hold RCU or RTNL. +* The caller must hold RCU. * The returned device has not had its ref count increased * and the caller must therefore be careful about locking *
@@ -941,14 +947,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,struct net_device *dev;for_each_netdev_rcu (net, dev) -if (dev->type == type && - !memcmp (dev->dev_addr, ha, dev->addr_len)) +if (dev_addr_cmp (dev, type, ha))return dev;return NULL ; }EXPORT_SYMBOL (dev_getbyhwaddr_rcu); +/** +* dev_getbyhwaddr() - find a device by its hardware address +* @net: the applicable net namespace +* @type: media type of device +* @ha: hardware address +* +* Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold +* rtnl_lock. +* +* Context: rtnl_lock() must be held. +* Return: pointer to the net_device, or NULL if not found +*/ +struct net_device *dev_getbyhwaddr (struct net *net,unsigned short type, +const char *ha) +{ +struct net_device *dev; + +ASSERT_RTNL (); +for_each_netdev (net, dev) +if (dev_addr_cmp (dev, type, ha)) +return dev; + +return NULL ; +} +EXPORT_SYMBOL (dev_getbyhwaddr); +struct net_device *dev_getfirstbyhwtype (struct net *net,unsigned short type) {struct net_device *dev, *ret =NULL ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 58/176 arp: switch to dev_getbyhwaddr() in arp_req_set_public()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 4eae0ee0f1e6256d0b0b9dd6e72f1d9cf8f72e08 ]
The arp_req_set_public() function is called with the rtnl lock held, which provides enough synchronization protection. This makes the RCU variant of dev_getbyhwaddr() unnecessary. Switch to using the simpler dev_getbyhwaddr() function since we already have the required rtnl locking.
This change helps maintain consistency in the networking code by using the appropriate helper function for the existing locking context. Since we're not holding the RCU read lock in arp_req_set_public() existing code could trigger false positive locking warnings.
--- net/ipv4/arp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/arp.c +1 -1
@@ -1030,7 +1030,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,if (mask && mask !=htonl (0xFFFFFFFF ))return -EINVAL ;if (!dev && (r->arp_flags &ATF_COM )) { - dev =dev_getbyhwaddr_rcu (net, r->arp_ha.sa_family, + dev =dev_getbyhwaddr (net, r->arp_ha.sa_family, r->arp_ha.sa_data);if (!dev)return -ENODEV ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 59/176 net: axienet: Set mac_managed_pm
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Hu <[email protected]>
[ Upstream commit a370295367b55662a32a4be92565fe72a5aa79bb ]
The external PHY will undergo a soft reset twice during the resume process when it wake up from suspend. The first reset occurs when the axienet driver calls phylink_of_phy_connect(), and the second occurs when mdio_bus_phy_resume() invokes phy_init_hw(). The second soft reset of the external PHY does not reinitialize the internal PHY, which causes issues with the internal PHY, resulting in the PHY link being down. To prevent this, setting the mac_managed_pm flag skips the mdio_bus_phy_resume() function.
--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +1 -0
@@ -2159,6 +2159,7 @@ static int axienet_probe(struct platform_device *pdev) lp->phylink_config.dev = &ndev->dev; lp->phylink_config.type =PHYLINK_NETDEV ; + lp->phylink_config.mac_managed_pm = true; lp->phylink_config.mac_capabilities =MAC_SYM_PAUSE |MAC_ASYM_PAUSE |MAC_10FD |MAC_100FD |MAC_1000FD ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 60/176 tcp: drop secpath at the same time as we currently drop dst
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <[email protected]>
[ Upstream commit 9b6412e6979f6f9e0632075f8f008937b5cd4efd ]
Xiumei reported hitting the WARN in xfrm6_tunnel_net_exit while running tests that boil down to:
- create a pair of netns
- run a basic TCP test over ipcomp6
- delete the pair of netns
The xfrm_state found on spi_byaddr was not deleted at the time we delete the netns, because we still have a reference on it. This lingering reference comes from a secpath (which holds a ref on the xfrm_state), which is still attached to an skb. This skb is not leaked, it ends up on sk_receive_queue and then gets defer-free'd by skb_attempt_defer_free.
The problem happens when we defer freeing an skb (push it on one CPU's defer_list), and don't flush that list before the netns is deleted. In that case, we still have a reference on the xfrm_state that we don't expect at this point.
We already drop the skb's dst in the TCP receive path when it's no longer needed, so let's also drop the secpath. At this point, tcp_filter has already called into the LSM hooks that may require the secpath, so it should not be needed anymore. However, in some of those places, the MPTCP extension has just been attached to the skb, so we cannot simply drop all extensions.
--- include/net/tcp.h | 14 ++++++++++++++ net/ipv4/tcp_fastopen.c | 4 ++-- net/ipv4/tcp_input.c | 8 ++++---- net/ipv4/tcp_ipv4.c | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-)
include/net/tcp.h +14 -0
@@ -40,6 +40,7 @@#include <net/inet_ecn.h> #include <net/dst.h> #include <net/mptcp.h> +#include <net/xfrm.h> #include <linux/seq_file.h> #include <linux/memcontrol.h>
@@ -640,6 +641,19 @@ void tcp_fin(struct sock *sk);void tcp_check_space (struct sock *sk);void tcp_sack_compress_send_ack (struct sock *sk); +static inline void tcp_cleanup_skb (struct sk_buff *skb) +{ +skb_dst_drop (skb); +secpath_reset (skb); +} + +static inline void tcp_add_receive_queue (struct sock *sk,struct sk_buff *skb) +{ +DEBUG_NET_WARN_ON_ONCE (skb_dst (skb)); +DEBUG_NET_WARN_ON_ONCE (secpath_exists (skb)); +__skb_queue_tail (&sk->sk_receive_queue, skb); +} +/* tcp_timer.c */ void tcp_init_xmit_timers (struct sock *);static inline void tcp_clear_xmit_timers (struct sock *sk)
net/ipv4/tcp_fastopen.c +2 -2
@@ -178,7 +178,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)if (!skb)return ; -skb_dst_drop (skb); +tcp_cleanup_skb (skb);/* segs_in has been initialized to 1 in tcp_create_openreq_child(). * Hence, reset segs_in to 0 before calling tcp_segs_in() * to avoid double counting. Also, tcp_segs_in() expects
@@ -195,7 +195,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)TCP_SKB_CB (skb)->tcp_flags &= ~TCPHDR_SYN ; tp->rcv_nxt =TCP_SKB_CB (skb)->end_seq; -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb); tp->syn_data_acked =1 ;/* u64_stats_update_begin(&tp->syncp) not needed here,
net/ipv4/tcp_input.c +4 -4
@@ -4836,7 +4836,7 @@ static void tcp_ofo_queue(struct sock *sk)tcp_rcv_nxt_update (tp,TCP_SKB_CB (skb)->end_seq); fin =TCP_SKB_CB (skb)->tcp_flags &TCPHDR_FIN ;if (!eaten) -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb);else kfree_skb_partial (skb, fragstolen);
@@ -5027,7 +5027,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, skb, fragstolen)) ? 1 : 0;tcp_rcv_nxt_update (tcp_sk (sk),TCP_SKB_CB (skb)->end_seq);if (!eaten) { -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb);skb_set_owner_r (skb, sk); }return eaten;
@@ -5110,7 +5110,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)__kfree_skb (skb);return ; } -skb_dst_drop (skb); +tcp_cleanup_skb (skb);__skb_pull (skb,tcp_hdr (skb)->doff *4 ); reason =SKB_DROP_REASON_NOT_SPECIFIED ;
@@ -6041,7 +6041,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPHPHITS );/* Bulk data transfer: receiver */ -skb_dst_drop (skb); +tcp_cleanup_skb (skb);__skb_pull (skb, tcp_header_len); eaten =tcp_queue_rcv (sk, skb, &fragstolen);
net/ipv4/tcp_ipv4.c +1 -1
@@ -1791,7 +1791,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,*/ skb_condense (skb); -skb_dst_drop (skb); +tcp_cleanup_skb (skb);if (unlikely (tcp_checksum_complete (skb))) {bh_unlock_sock (sk);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 61/176 drm/tidss: Add simple K2G manual reset
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 576d96c5c896221b5bc8feae473739469a92e144 ]
K2G display controller does not support soft reset, but we can do the most important steps manually: mask the IRQs and disable the VPs.
Stable-dep-of: a9a73f2661e6 ("drm/tidss: Fix race condition while handling interrupt registers")
--- drivers/gpu/drm/tidss/tidss_dispc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/gpu/drm/tidss/tidss_dispc.c +16 -2
@@ -2655,14 +2655,28 @@ static void dispc_init_errata(struct dispc_device *dispc) } } +/* +* K2G display controller does not support soft reset, so we do a basic manual +* reset here: make sure the IRQs are masked and VPs are disabled. +*/ +static void dispc_softreset_k2g (struct dispc_device *dispc) +{ +dispc_set_irqenable (dispc,0 ); +dispc_read_and_clear_irqstatus (dispc); + +for (unsigned int vp_idx =0 ; vp_idx < dispc->feat->num_vps; ++vp_idx) +VP_REG_FLD_MOD (dispc, vp_idx,DISPC_VP_CONTROL ,0 ,0 ,0 ); +} +static int dispc_softreset (struct dispc_device *dispc) {u32 val;int ret =0 ; -/* K2G display controller does not support soft reset */ -if (dispc->feat->subrev ==DISPC_K2G ) +if (dispc->feat->subrev ==DISPC_K2G ) { +dispc_softreset_k2g (dispc);return 0 ; + }/* Soft reset */ REG_FLD_MOD (dispc,DSS_SYSCONFIG ,1 ,1 ,1 );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 62/176 drm/tidss: Fix race condition while handling interrupt registers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devarsh Thakkar <[email protected]>
[ Upstream commit a9a73f2661e6f625d306c9b0ef082e4593f45a21 ]
The driver has a spinlock for protecting the irq_masks field and irq enable registers. However, the driver misses protecting the irq status registers which can lead to races.
Take the spinlock when accessing irqstatus too.
--- drivers/gpu/drm/tidss/tidss_dispc.c | 4 ++++ drivers/gpu/drm/tidss/tidss_irq.c | 2 ++ 2 files changed, 6 insertions(+)
drivers/gpu/drm/tidss/tidss_dispc.c +4 -0
@@ -2661,8 +2661,12 @@ static void dispc_init_errata(struct dispc_device *dispc)*/ static void dispc_softreset_k2g (struct dispc_device *dispc) { +unsigned long flags; + +spin_lock_irqsave (&dispc->tidss->wait_lock, flags);dispc_set_irqenable (dispc,0 );dispc_read_and_clear_irqstatus (dispc); +spin_unlock_irqrestore (&dispc->tidss->wait_lock, flags);for (unsigned int vp_idx =0 ; vp_idx < dispc->feat->num_vps; ++vp_idx)VP_REG_FLD_MOD (dispc, vp_idx,DISPC_VP_CONTROL ,0 ,0 ,0 );
drivers/gpu/drm/tidss/tidss_irq.c +2 -0
@@ -60,7 +60,9 @@ static irqreturn_t tidss_irq_handler(int irq, void *arg)unsigned int id;dispc_irq_t irqstatus; +spin_lock (&tidss->wait_lock); irqstatus =dispc_read_and_clear_irqstatus (tidss->dispc); +spin_unlock (&tidss->wait_lock);for (id =0 ; id < tidss->num_crtcs; id++) {struct drm_crtc *crtc = tidss->crtcs[id];
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 63/176 drm/rcar-du: dsi: Fix PHY lock bit check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 6389e616fae8a101ce00068f7690461ab57b29d8 ]
The driver checks for bit 16 (using CLOCKSET1_LOCK define) in CLOCKSET1 register when waiting for the PPI clock. However, the right bit to check is bit 17 (CLOCKSET1_LOCK_PHY define). Not only that, but there's nothing in the documents for bit 16 for V3U nor V4H.
So, fix the check to use bit 17, and drop the define for bit 16.
--- drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 2 +- drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c +1 -1
@@ -396,7 +396,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,for (timeout =10 ; timeout >0 ; --timeout) {if ((rcar_mipi_dsi_read (dsi,PPICLSR ) &PPICLSR_STPST ) && (rcar_mipi_dsi_read (dsi,PPIDLSR ) &PPIDLSR_STPST ) && - (rcar_mipi_dsi_read (dsi,CLOCKSET1 ) &CLOCKSET1_LOCK )) + (rcar_mipi_dsi_read (dsi,CLOCKSET1 ) &CLOCKSET1_LOCK_PHY ))break ;usleep_range (1000 ,2000 );
drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h +0 -1
@@ -141,7 +141,6 @@#define CLOCKSET1 0x101c#define CLOCKSET1_LOCK_PHY (1 << 17) -#define CLOCKSET1_LOCK (1 << 16)#define CLOCKSET1_CLKSEL (1 << 8)#define CLOCKSET1_CLKINSEL_EXTAL (0 << 2)#define CLOCKSET1_CLKINSEL_DIG (1 << 2)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 64/176 bpf, test_run: Fix use-after-free issue in eth_skb_pkt_type()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shigeru Yoshida <[email protected]>
[ Upstream commit 6b3d638ca897e099fa99bd6d02189d3176f80a47 ]
KMSAN reported a use-after-free issue in eth_skb_pkt_type()[1]. The cause of the issue was that eth_skb_pkt_type() accessed skb's data that didn't contain an Ethernet header. This occurs when bpf_prog_test_run_xdp() passes an invalid value as the user_data argument to bpf_test_init().
Fix this by returning an error when user_data is less than ETH_HLEN in bpf_test_init(). Additionally, remove the check for "if (user_size > size)" as it is unnecessary.
[1]
BUG: KMSAN: use-after-free in eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] BUG: KMSAN: use-after-free in eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 __xdp_build_skb_from_frame+0x5a8/0xa50 net/core/xdp.c:635 xdp_recv_frames net/bpf/test_run.c:272 [inline] xdp_test_run_batch net/bpf/test_run.c:361 [inline] bpf_test_run_xdp_live+0x2954/0x3330 net/bpf/test_run.c:390 bpf_prog_test_run_xdp+0x148e/0x1b10 net/bpf/test_run.c:1318 bpf_prog_test_run+0x5b7/0xa30 kernel/bpf/syscall.c:4371 __sys_bpf+0x6a6/0xe20 kernel/bpf/syscall.c:5777 __do_sys_bpf kernel/bpf/syscall.c:5866 [inline] __se_sys_bpf kernel/bpf/syscall.c:5864 [inline] __x64_sys_bpf+0xa4/0xf0 kernel/bpf/syscall.c:5864 x64_sys_call+0x2ea0/0x3d90 arch/x86/include/generated/asm/syscalls_64.h:322 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xd9/0x1d0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
free_pages_prepare mm/page_alloc.c:1056 [inline] free_unref_page+0x156/0x1320 mm/page_alloc.c:2657 __free_pages+0xa3/0x1b0 mm/page_alloc.c:4838 bpf_ringbuf_free kernel/bpf/ringbuf.c:226 [inline] ringbuf_map_free+0xff/0x1e0 kernel/bpf/ringbuf.c:235 bpf_map_free kernel/bpf/syscall.c:838 [inline] bpf_map_free_deferred+0x17c/0x310 kernel/bpf/syscall.c:862 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa2b/0x1b60 kernel/workqueue.c:3310 worker_thread+0xedf/0x1550 kernel/workqueue.c:3391 kthread+0x535/0x6b0 kernel/kthread.c:389 ret_from_fork+0x6e/0x90 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 CPU: 1 UID: 0 PID: 17276 Comm: syz.1.16450 Not tainted 6.12.0-05490-g9bb88c659673 #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
--- net/bpf/test_run.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
net/bpf/test_run.c +1 -4
@@ -768,12 +768,9 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,void __user *data_in =u64_to_user_ptr (kattr->test.data_in);void *data; -if (size <ETH_HLEN || size >PAGE_SIZE - headroom - tailroom) +if (user_size <ETH_HLEN || user_size >PAGE_SIZE - headroom - tailroom)return ERR_PTR (-EINVAL ); -if (user_size > size) -return ERR_PTR (-EMSGSIZE ); - size =SKB_DATA_ALIGN (size); data =kzalloc (size + headroom + tailroom,GFP_USER );if (!data)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 65/176 strparser: Add read_sock callback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 0532a79efd68a4d9686b0385e4993af4b130ff82 ]
Added a new read_sock handler, allowing users to customize read operations instead of relying on the native socket's read_sock.
Stable-dep-of: 36b62df5683c ("bpf: Fix wrong copied_seq calculation")
--- Documentation/networking/strparser.rst | 9 ++++++++- include/net/strparser.h | 2 ++ net/strparser/strparser.c | 11 +++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-)
Documentation/networking/strparser.rst +8 -1
@@ -112,7 +112,7 @@ Functions Callbacks ========= -There are six callbacks: +There are seven callbacks: ::
@@ -182,6 +182,13 @@ There are six callbacks: the length of the message. skb->len - offset may be greater then full_len since strparser does not trim the skb. + :: + + int (*read_sock)(struct strparser *strp, read_descriptor_t *desc, + sk_read_actor_t recv_actor); + + The read_sock callback is used by strparser instead of + sock->ops->read_sock, if provided. :: int (*read_sock_done)(struct strparser *strp, int err);
include/net/strparser.h +2 -0
@@ -43,6 +43,8 @@ struct strparser;struct strp_callbacks {int (*parse_msg)(struct strparser *strp,struct sk_buff *skb);void (*rcv_msg)(struct strparser *strp,struct sk_buff *skb); +int (*read_sock)(struct strparser *strp,read_descriptor_t *desc, +sk_read_actor_t recv_actor);int (*read_sock_done)(struct strparser *strp,int err);void (*abort_parser)(struct strparser *strp,int err);void (*lock)(struct strparser *strp);
net/strparser/strparser.c +9 -2
@@ -347,7 +347,10 @@ static int strp_read_sock(struct strparser *strp)struct socket *sock = strp->sk->sk_socket;read_descriptor_t desc; -if (unlikely (!sock || !sock->ops || !sock->ops->read_sock)) +if (unlikely (!sock || !sock->ops)) +return -EBUSY ; + +if (unlikely (!strp->cb.read_sock && !sock->ops->read_sock))return -EBUSY ; desc.arg.data = strp;
@@ -355,7 +358,10 @@ static int strp_read_sock(struct strparser *strp) desc.count =1 ;/* give more than one skb per call */ /* sk should be locked here, so okay to do read_sock */ - sock->ops->read_sock (strp->sk, &desc, strp_recv); +if (strp->cb.read_sock) + strp->cb.read_sock (strp, &desc, strp_recv); +else + sock->ops->read_sock (strp->sk, &desc, strp_recv); desc.error = strp->cb.read_sock_done (strp, desc.error);
@@ -468,6 +474,7 @@ int strp_init(struct strparser *strp, struct sock *sk, strp->cb.unlock = cb->unlock ? : strp_sock_unlock; strp->cb.rcv_msg = cb->rcv_msg; strp->cb.parse_msg = cb->parse_msg; + strp->cb.read_sock = cb->read_sock; strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done; strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 66/176 bpf: Fix wrong copied_seq calculation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 36b62df5683c315ba58c950f1a9c771c796c30ec ]
'sk->copied_seq' was updated in the tcp_eat_skb() function when the action of a BPF program was SK_REDIRECT. For other actions, like SK_PASS, the update logic for 'sk->copied_seq' was moved to tcp_bpf_recvmsg_parser() to ensure the accuracy of the 'fionread' feature.
It works for a single stream_verdict scenario, as it also modified sk_data_ready->sk_psock_verdict_data_ready->tcp_read_skb to remove updating 'sk->copied_seq'.
However, for programs where both stream_parser and stream_verdict are active (strparser purpose), tcp_read_sock() was used instead of tcp_read_skb() (sk_data_ready->strp_data_ready->tcp_read_sock). tcp_read_sock() now still updates 'sk->copied_seq', leading to duplicate updates.
In summary, for strparser + SK_PASS, copied_seq is redundantly calculated in both tcp_read_sock() and tcp_bpf_recvmsg_parser().
The issue causes incorrect copied_seq calculations, which prevent correct data reads from the recv() interface in user-land.
We do not want to add new proto_ops to implement a new version of tcp_read_sock, as this would introduce code complexity [1].
We could have added noack and copied_seq to desc, and then called ops->read_sock. However, unfortunately, other modules didn’t fully initialize desc to zero. So, for now, we are directly calling tcp_read_sock_noack() in tcp_bpf.c.
[1]: https://lore.kernel.org/bpf/[email protected]
--- include/linux/skmsg.h | 2 ++ include/net/tcp.h | 8 ++++++++ net/core/skmsg.c | 7 +++++++ net/ipv4/tcp.c | 29 ++++++++++++++++++++++++----- net/ipv4/tcp_bpf.c | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 5 deletions(-)
include/linux/skmsg.h +2 -0
@@ -87,6 +87,8 @@ struct sk_psock {struct sk_psock_progs progs;#if IS_ENABLED (CONFIG_BPF_STREAM_PARSER )struct strparser strp; +u32 copied_seq; +u32 ingress_bytes;#endif struct sk_buff_head ingress_skb;struct list_head ingress_msg;
include/net/tcp.h +8 -0
@@ -700,6 +700,9 @@ void tcp_get_info(struct sock *, struct tcp_info *);/* Read 'sendfile()'-style from a TCP socket */ int tcp_read_sock (struct sock *sk,read_descriptor_t *desc,sk_read_actor_t recv_actor); +int tcp_read_sock_noack (struct sock *sk,read_descriptor_t *desc, +sk_read_actor_t recv_actor,bool noack, +u32 *copied_seq);int tcp_read_skb (struct sock *sk,skb_read_actor_t recv_actor);struct sk_buff *tcp_recv_skb (struct sock *sk,u32 seq,u32 *off);void tcp_read_done (struct sock *sk,size_t len);
@@ -2351,6 +2354,11 @@ struct sk_psock;struct proto *tcp_bpf_get_proto (struct sock *sk,struct sk_psock *psock);int tcp_bpf_update_proto (struct sock *sk,struct sk_psock *psock,bool restore);void tcp_bpf_clone (const struct sock *sk,struct sock *newsk); +#ifdef CONFIG_BPF_STREAM_PARSER +struct strparser ; +int tcp_bpf_strp_read_sock (struct strparser *strp,read_descriptor_t *desc, +sk_read_actor_t recv_actor); +#endif /* CONFIG_BPF_STREAM_PARSER */ #endif /* CONFIG_BPF_SYSCALL */ #ifdef CONFIG_INET
net/core/skmsg.c +7 -0
@@ -547,6 +547,9 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,return num_sge; } +#if IS_ENABLED (CONFIG_BPF_STREAM_PARSER ) + psock->ingress_bytes += len; +#endif copied = len; msg->sg.start =0 ; msg->sg.size = copied;
@@ -1140,6 +1143,10 @@ int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock)if (!ret)sk_psock_set_state (psock,SK_PSOCK_RX_STRP_ENABLED ); +if (sk_is_tcp (sk)) { + psock->strp.cb.read_sock = tcp_bpf_strp_read_sock; + psock->copied_seq =tcp_sk (sk)->copied_seq; + }return ret; }
net/ipv4/tcp.c +24 -5
@@ -1699,12 +1699,13 @@ EXPORT_SYMBOL(tcp_recv_skb);* or for 'peeking' the socket using this routine * (although both would be easy to implement). */ -int tcp_read_sock (struct sock *sk,read_descriptor_t *desc, -sk_read_actor_t recv_actor) +static int __tcp_read_sock (struct sock *sk,read_descriptor_t *desc, +sk_read_actor_t recv_actor,bool noack, +u32 *copied_seq) {struct sk_buff *skb;struct tcp_sock *tp =tcp_sk (sk); -u32 seq = tp->copied_seq; +u32 seq = *copied_seq;u32 offset;int copied =0 ;
@@ -1758,9 +1759,12 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,tcp_eat_recv_skb (sk, skb);if (!desc->count)break ; -WRITE_ONCE (tp->copied_seq, seq); +WRITE_ONCE (*copied_seq, seq); } -WRITE_ONCE (tp->copied_seq, seq); +WRITE_ONCE (*copied_seq, seq); + +if (noack) + goto out;tcp_rcv_space_adjust (sk);
@@ -1769,10 +1773,25 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,tcp_recv_skb (sk, seq, &offset);tcp_cleanup_rbuf (sk, copied); } +out:return copied; } + +int tcp_read_sock (struct sock *sk,read_descriptor_t *desc, +sk_read_actor_t recv_actor) +{ +return __tcp_read_sock (sk, desc, recv_actor, false, + &tcp_sk (sk)->copied_seq); +}EXPORT_SYMBOL (tcp_read_sock); +int tcp_read_sock_noack (struct sock *sk,read_descriptor_t *desc, +sk_read_actor_t recv_actor,bool noack, +u32 *copied_seq) +{ +return __tcp_read_sock (sk, desc, recv_actor, noack, copied_seq); +} +int tcp_read_skb (struct sock *sk,skb_read_actor_t recv_actor) {struct sk_buff *skb;
net/ipv4/tcp_bpf.c +36 -0
@@ -691,6 +691,42 @@ static int tcp_bpf_assert_proto_ops(struct proto *ops) ops->sendpage == tcp_sendpage ?0 : -ENOTSUPP ; } +#if IS_ENABLED (CONFIG_BPF_STREAM_PARSER ) +int tcp_bpf_strp_read_sock (struct strparser *strp,read_descriptor_t *desc, +sk_read_actor_t recv_actor) +{ +struct sock *sk = strp->sk; +struct sk_psock *psock; +struct tcp_sock *tp; +int copied =0 ; + + tp =tcp_sk (sk); +rcu_read_lock (); + psock =sk_psock (sk); +if (WARN_ON_ONCE (!psock)) { + desc->error = -EINVAL ; + goto out; + } + + psock->ingress_bytes =0 ; + copied =tcp_read_sock_noack (sk, desc, recv_actor, true, + &psock->copied_seq); +if (copied <0 ) + goto out; +/* recv_actor may redirect skb to another socket (SK_REDIRECT) or +* just put skb into ingress queue of current socket (SK_PASS). +* For SK_REDIRECT, we need to ack the frame immediately but for +* SK_PASS, we want to delay the ack until tcp_bpf_recvmsg_parser(). +*/ + tp->copied_seq = psock->copied_seq - psock->ingress_bytes; +tcp_rcv_space_adjust (sk); +__tcp_cleanup_rbuf (sk, copied - psock->ingress_bytes); +out: +rcu_read_unlock (); +return copied; +} +#endif /* CONFIG_BPF_STREAM_PARSER */ +int tcp_bpf_update_proto (struct sock *sk,struct sk_psock *psock,bool restore) {int family = sk->sk_family ==AF_INET6 ?TCP_BPF_IPV6 :TCP_BPF_IPV4 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 67/176 power: supply: da9150-fg: fix potential overflow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Vatoropin <[email protected]>
[ Upstream commit 3fb3cb4350befc4f901c54e0cb4a2a47b1302e08 ]
Size of variable sd_gain equals four bytes - DA9150_QIF_SD_GAIN_SIZE. Size of variable shunt_val equals two bytes - DA9150_QIF_SHUNT_VAL_SIZE.
The expression sd_gain * shunt_val is currently being evaluated using 32-bit arithmetic. So during the multiplication an overflow may occur.
As the value of type 'u64' is used as storage for the eventual result, put ULL variable at the first position of each expression in order to give the compiler complete information about the proper arithmetic to use. According to C99 the guaranteed width for a variable of type 'unsigned long long' >= 64 bits.
Remove the explicit cast to u64 as it is meaningless.
Just for the sake of consistency, perform the similar trick with another expression concerning 'iavg'.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/power/supply/da9150-fg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/power/supply/da9150-fg.c +2 -2
@@ -248,9 +248,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg, DA9150_QIF_SD_GAIN_SIZE);da9150_fg_read_sync_end (fg); - div = (u64) (sd_gain * shunt_val *65536ULL ); + div =65536ULL * sd_gain * shunt_val;do_div (div,1000000 ); - res = (u64) (iavg *1000000ULL ); + res =1000000ULL * iavg;do_div (res, div); val->intval = (int ) res;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 68/176 nouveau/svm: fix missing folio unlock + put after make_device_exclusive_range()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit b3fefbb30a1691533cb905006b69b2a474660744 ]
In case we have to retry the loop, we are missing to unlock+put the folio. In that case, we will keep failing make_device_exclusive_range() because we cannot grab the folio lock, and even return from the function with the folio locked and referenced, effectively never succeeding the make_device_exclusive_range().
While at it, convert the other unlock+put to use a folio as well.
This was found by code inspection.
--- drivers/gpu/drm/nouveau/nouveau_svm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nouveau_svm.c +7 -2
@@ -592,6 +592,7 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm,unsigned long timeout = jiffies +msecs_to_jiffies (HMM_RANGE_DEFAULT_TIMEOUT );struct mm_struct *mm = svmm->notifier.mm; +struct folio *folio;struct page *page;unsigned long start = args->p.addr;unsigned long notifier_seq;
@@ -618,12 +619,16 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, ret = -EINVAL ; goto out; } + folio =page_folio (page);mutex_lock (&svmm->mutex);if (!mmu_interval_read_retry (¬ifier->notifier, notifier_seq))break ;mutex_unlock (&svmm->mutex); + +folio_unlock (folio); +folio_put (folio); }/* Map the page on the GPU. */
@@ -639,8 +644,8 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, ret =nvif_object_ioctl (&svmm->vmm->vmm.object, args, size,NULL );mutex_unlock (&svmm->mutex); -unlock_page (page); -put_page (page); +folio_unlock (folio); +folio_put (folio); out:mmu_interval_notifier_remove (¬ifier->notifier);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 69/176 drm/msm/dpu: Dont leak bits_per_component into random DSC_ENC fields
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marijn Suijten <[email protected]>
[ Upstream commit 144429831f447223253a0e4376489f84ff37d1a7 ]
What used to be the input_10_bits boolean - feeding into the lowest bit of DSC_ENC - on MSM downstream turned into an accidental OR with the full bits_per_component number when it was ported to the upstream kernel.
On typical bpc=8 setups we don't notice this because line_buf_depth is always an odd value (it contains bpc+1) and will also set the 4th bit after left-shifting by 3 (hence this |= bits_per_component is a no-op).
Now that guards are being removed to allow more bits_per_component values besides 8 (possible since commit 49fd30a7153b ("drm/msm/dsi: use DRM DSC helpers for DSC setup")), a bpc of 10 will instead clash with the 5th bit which is convert_rgb. This is "fortunately" also always set to true by MSM's dsi_populate_dsc_params() already, but once a bpc of 12 starts being used it'll write into simple_422 which is normally false.
To solve all these overlaps, simply replicate downstream code and only set this lowest bit if bits_per_component is equal to 10. It is unclear why DSC requires this only for bpc=10 but not bpc=12, and also notice that this lowest bit wasn't set previously despite having a panel and patch on the list using it without any mentioned issues.
Patchwork: https://patchwork.freedesktop.org/patch/636311/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +2 -1
@@ -46,6 +46,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,u32 slice_last_group_size;u32 det_thresh_flatness;bool is_cmd_mode = !(mode &DSC_MODE_VIDEO ); +bool input_10_bits = dsc->bits_per_component ==10 ;DPU_REG_WRITE (c,DSC_COMMON_MODE , mode);
@@ -62,7 +63,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, data |= (dsc->line_buf_depth <<3 ); data |= (dsc->simple_422 <<2 ); data |= (dsc->convert_rgb <<1 ); - data |= dsc->bits_per_component; + data |= input_10_bits;DPU_REG_WRITE (c,DSC_ENC , data);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 70/176 nvme/ioctl: add missing space in err message
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos <[email protected]>
[ Upstream commit 487a3ea7b1b8ba2ca7d2c2bb3c3594dc360d6261 ]
nvme_validate_passthru_nsid() logs an err message whose format string is split over 2 lines. There is a missing space between the two pieces, resulting in log lines like "... does not match nsid (1)of namespace". Add the missing space between ")" and "of". Also combine the format string pieces onto a single line to make the err message easier to grep.
--- drivers/nvme/host/ioctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/nvme/host/ioctl.c +1 -2
@@ -262,8 +262,7 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, {if (ns && nsid != ns->head->ns_id) {dev_err (ctrl->device, -"%s: nsid (%u) in cmd does not match nsid (%u)" -"of namespace\n" , +"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n" , current->comm, nsid, ns->head->ns_id);return false; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 71/176 bpf: skip non exist keys in generic_map_lookup_batch
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhai <[email protected]>
[ Upstream commit 5644c6b50ffee0a56c1e01430a8c88e34decb120 ]
The generic_map_lookup_batch currently returns EINTR if it fails with ENOENT and retries several times on bpf_map_copy_value. The next batch would start from the same location, presuming it's a transient issue. This is incorrect if a map can actually have "holes", i.e. "get_next_key" can return a key that does not point to a valid value. At least the array of maps type may contain such holes legitly. Right now these holes show up, generic batch lookup cannot proceed any more. It will always fail with EINTR errors.
Rather, do not retry in generic_map_lookup_batch. If it finds a non existing element, skip to the next key. This simple solution comes with a price that transient errors may not be recovered, and the iteration might cycle back to the first key under parallel deletion. For example, Hou Tao <[email protected]> pointed out a following scenario:
For LPM trie map:
(1) ->map_get_next_key(map, prev_key, key) returns a valid key
(2) bpf_map_copy_value() return -ENOMENT
It means the key must be deleted concurrently.
(3) goto next_key
It swaps the prev_key and key
(4) ->map_get_next_key(map, prev_key, key) againprev_key points to a non-existing key, for LPM trie it will treat just like prev_key=NULL case, the returned key will be duplicated.
With the retry logic, the iteration can continue to the key next to the deleted one. But if we directly skip to the next key, the iteration loop would restart from the first key for the lpm_trie type.
However, not all races may be recovered. For example, if current key is deleted after instead of before bpf_map_copy_value, or if the prev_key also gets deleted, then the loop will still restart from the first key for lpm_tire anyway. For generic lookup it might be better to stay simple, i.e. just skip to the next key. To guarantee that the output keys are not duplicated, it is better to implement map type specific batch operations, which can properly lock the trie and synchronize with concurrent mutators.
--- kernel/bpf/syscall.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-)
kernel/bpf/syscall.c +5 -13
@@ -1713,8 +1713,6 @@ int generic_map_update_batch(struct bpf_map *map,return err; } -#define MAP_LOOKUP_RETRIES 3 -int generic_map_lookup_batch (struct bpf_map *map,const union bpf_attr *attr,union bpf_attr __user *uattr)
@@ -1724,8 +1722,8 @@ int generic_map_lookup_batch(struct bpf_map *map,void __user *values =u64_to_user_ptr (attr->batch.values);void __user *keys =u64_to_user_ptr (attr->batch.keys);void *buf, *buf_prevkey, *prev_key, *key, *value; -int err, retry =MAP_LOOKUP_RETRIES ;u32 value_size, cp, max_count; +int err;if (attr->batch.elem_flags & ~BPF_F_LOCK )return -EINVAL ;
@@ -1771,14 +1769,8 @@ int generic_map_lookup_batch(struct bpf_map *map, err =bpf_map_copy_value (map, key, value, attr->batch.elem_flags); -if (err == -ENOENT ) { -if (retry) { - retry--; -continue ; - } - err = -EINTR ; -break ; - } +if (err == -ENOENT ) + goto next_key;if (err) goto free_buf;
@@ -1793,12 +1785,12 @@ int generic_map_lookup_batch(struct bpf_map *map, goto free_buf; } + cp++; +next_key:if (!prev_key) prev_key = buf_prevkey;swap (prev_key, key); - retry =MAP_LOOKUP_RETRIES ; - cp++;cond_resched (); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 72/176 drm/msm/dpu: Disable dither in phys encoder cleanup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jessica Zhang <[email protected]>
commit f063ac6b55df03ed25996bdc84d9e1c50147cfa1 upstream.
Disable pingpong dither in dpu_encoder_helper_phys_cleanup().
This avoids the issue where an encoder unknowingly uses dither after reserving a pingpong block that was previously bound to an encoder that had enabled dither.
Patchwork: https://patchwork.freedesktop.org/patch/636517/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +3 -0
@@ -2059,6 +2059,9 @@ void dpu_encoder_helper_phys_cleanup(str } } +if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither) + phys_enc->hw_pp->ops.setup_dither (phys_enc->hw_pp,NULL ); +/* reset the merge 3D HW block */ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
Greg Kroah-Hartman
maintainerPATCH 73/176 drm/i915: Make sure all planes in use by the joiner have their crtc included
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit 07fb70d82e0df085980246bf17bc12537588795f upstream.
Any active plane needs to have its crtc included in the atomic state. For planes enabled via uapi that is all handler in the core. But when we use a plane for joiner the uapi code things the plane is disabled and therefore doesn't have a crtc. So we need to pull those in by hand. We do it first thing in intel_joiner_add_affected_crtcs() so that any newly added crtc will subsequently pull in all of its joined crtcs as well.
The symptoms from failing to do this are:
- duct tape in the form of commit 1d5b09f8daf8 ("drm/i915: Fix NULL ptr deref by checking new_crtc_state")
- the plane's hw state will get overwritten by the disabled uapi state if it can't find the uapi counterpart plane in the atomic state from where it should copy the correct state
--- drivers/gpu/drm/i915/display/intel_display.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/gpu/drm/i915/display/intel_display.c +18 -0
@@ -6691,12 +6691,30 @@ static int intel_async_flip_check_hw(strstatic int intel_bigjoiner_add_affected_crtcs (struct intel_atomic_state *state) {struct drm_i915_private *i915 =to_i915 (state->base.dev); +const struct intel_plane_state *plane_state;struct intel_crtc_state *crtc_state; +struct intel_plane *plane;struct intel_crtc *crtc;u8 affected_pipes =0 ;u8 modeset_pipes =0 ;int i; +/* +* Any plane which is in use by the joiner needs its crtc. +* Pull those in first as this will not have happened yet +* if the plane remains disabled according to uapi. +*/ +for_each_new_intel_plane_in_state (state, plane, plane_state, i) { + crtc =to_intel_crtc (plane_state->hw.crtc); +if (!crtc) +continue ; + + crtc_state =intel_atomic_get_crtc_state (&state->base, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + } + +/* Now pull in all joined crtcs */ for_each_new_intel_crtc_in_state (state, crtc, crtc_state, i) { affected_pipes |= crtc_state->bigjoiner_pipes;if (intel_crtc_needs_modeset (crtc_state))
Greg Kroah-Hartman
maintainerPATCH 74/176 tee: optee: Fix supplicant wait loop
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Garg <[email protected]>
commit 70b0d6b0a199c5a3ee6c72f5e61681ed6f759612 upstream.
OP-TEE supplicant is a user-space daemon and it's possible for it be hung or crashed or killed in the middle of processing an OP-TEE RPC call. It becomes more complicated when there is incorrect shutdown ordering of the supplicant process vs the OP-TEE client application which can eventually lead to system hang-up waiting for the closure of the client application.
Allow the client process waiting in kernel for supplicant response to be killed rather than indefinitely waiting in an unkillable state. Also, a normal uninterruptible wait should not have resulted in the hung-task watchdog getting triggered, but the endless loop would.
This fixes issues observed during system reboot/shutdown when supplicant got hung for some reason or gets crashed/killed which lead to client getting hung in an unkillable state. It in turn lead to system being in hung up state requiring hard power off/on to recover.
--- drivers/tee/optee/supp.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-)
drivers/tee/optee/supp.c +8 -27
@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_contestruct optee *optee =tee_get_drvdata (ctx->teedev);struct optee_supp *supp = &optee->supp;struct optee_supp_req *req; -bool interruptable;u32 ret;/*
@@ -111,36 +110,18 @@ u32 optee_supp_thrd_req(struct tee_conte/* * Wait for supplicant to process and return result, once we've * returned from wait_for_completion(&req->c) successfully we have -* exclusive access again. +* exclusive access again. Allow the wait to be killable such that +* the wait doesn't turn into an indefinite state if the supplicant +* gets hung for some reason. */ -while (wait_for_completion_interruptible (&req->c)) { +if (wait_for_completion_killable (&req->c)) {mutex_lock (&supp->mutex); - interruptable = !supp->ctx; -if (interruptable) { -/* -* There's no supplicant available and since the -* supp->mutex currently is held none can -* become available until the mutex released -* again. -* -* Interrupting an RPC to supplicant is only -* allowed as a way of slightly improving the user -* experience in case the supplicant hasn't been -* started yet. During normal operation the supplicant -* will serve all requests in a timely manner and -* interrupting then wouldn't make sense. -*/ -if (req->in_queue) { -list_del (&req->link); - req->in_queue = false; - } +if (req->in_queue) { +list_del (&req->link); + req->in_queue = false; }mutex_unlock (&supp->mutex); - -if (interruptable) { - req->ret =TEEC_ERROR_COMMUNICATION ; -break ; - } + req->ret =TEEC_ERROR_COMMUNICATION ; } ret = req->ret;
Greg Kroah-Hartman
maintainerPATCH 75/176 drop_monitor: fix incorrect initialization order
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gavrilov Ilia <[email protected]>
commit 07b598c0e6f06a0f254c88dafb4ad50f8a8c6eea upstream.
Syzkaller reports the following bug:
BUG: spinlock bad magic on CPU#1, syz-executor.0/7995 lock: 0xffff88805303f3e0, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 CPU: 1 PID: 7995 Comm: syz-executor.0 Tainted: G E 5.10.209+ #1 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x119/0x179 lib/dump_stack.c:118 debug_spin_lock_before kernel/locking/spinlock_debug.c:83 [inline] do_raw_spin_lock+0x1f6/0x270 kernel/locking/spinlock_debug.c:112 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:117 [inline] _raw_spin_lock_irqsave+0x50/0x70 kernel/locking/spinlock.c:159 reset_per_cpu_data+0xe6/0x240 [drop_monitor] net_dm_cmd_trace+0x43d/0x17a0 [drop_monitor] genl_family_rcv_msg_doit+0x22f/0x330 net/netlink/genetlink.c:739 genl_family_rcv_msg net/netlink/genetlink.c:783 [inline] genl_rcv_msg+0x341/0x5a0 net/netlink/genetlink.c:800 netlink_rcv_skb+0x14d/0x440 net/netlink/af_netlink.c:2497 genl_rcv+0x29/0x40 net/netlink/genetlink.c:811 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x54b/0x800 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x914/0xe00 net/netlink/af_netlink.c:1916 sock_sendmsg_nosec net/socket.c:651 [inline] __sock_sendmsg+0x157/0x190 net/socket.c:663 ____sys_sendmsg+0x712/0x870 net/socket.c:2378 ___sys_sendmsg+0xf8/0x170 net/socket.c:2432 __sys_sendmsg+0xea/0x1b0 net/socket.c:2461 do_syscall_64+0x30/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x62/0xc7 RIP: 0033:0x7f3f9815aee9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f3f972bf0c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f3f9826d050 RCX: 00007f3f9815aee9 RDX: 0000000020000000 RSI: 0000000020001300 RDI: 0000000000000007 RBP: 00007f3f981b63bd R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000006e R14: 00007f3f9826d050 R15: 00007ffe01ee6768
If drop_monitor is built as a kernel module, syzkaller may have time to send a netlink NET_DM_CMD_START message during the module loading. This will call the net_dm_monitor_start() function that uses a spinlock that has not yet been initialized.
To fix this, let's place resource initialization above the registration of a generic netlink family.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/core/drop_monitor.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
net/core/drop_monitor.c +14 -15
@@ -1716,30 +1716,30 @@ static int __init init_net_drop_monitor(return -ENOSPC ; } - rc =genl_register_family (&net_drop_monitor_family); -if (rc) { -pr_err ("Could not create drop monitor netlink family\n" ); -return rc; +for_each_possible_cpu (cpu) { +net_dm_cpu_data_init (cpu); +net_dm_hw_cpu_data_init (cpu); } -WARN_ON (net_drop_monitor_family.mcgrp_offset !=NET_DM_GRP_ALERT ); rc =register_netdevice_notifier (&dropmon_net_notifier);if (rc <0 ) {pr_crit ("Failed to register netdevice notifier\n" ); +return rc; + } + + rc =genl_register_family (&net_drop_monitor_family); +if (rc) { +pr_err ("Could not create drop monitor netlink family\n" ); goto out_unreg; } +WARN_ON (net_drop_monitor_family.mcgrp_offset !=NET_DM_GRP_ALERT ); rc =0 ; -for_each_possible_cpu (cpu) { -net_dm_cpu_data_init (cpu); -net_dm_hw_cpu_data_init (cpu); - } - goto out; out_unreg: -genl_unregister_family (&net_drop_monitor_family); +WARN_ON (unregister_netdevice_notifier (&dropmon_net_notifier)); out:return rc; }
@@ -1748,19 +1748,18 @@ static void exit_net_drop_monitor(void) {int cpu; -BUG_ON (unregister_netdevice_notifier (&dropmon_net_notifier)); -/* * Because of the module_get/put we do in the trace state change path * we are guaranteed not to have any current users when we get here */ +BUG_ON (genl_unregister_family (&net_drop_monitor_family)); + +BUG_ON (unregister_netdevice_notifier (&dropmon_net_notifier));for_each_possible_cpu (cpu) {net_dm_hw_cpu_data_fini (cpu);net_dm_cpu_data_fini (cpu); } - -BUG_ON (genl_unregister_family (&net_drop_monitor_family)); }module_init (init_net_drop_monitor);
Greg Kroah-Hartman
maintainerPATCH 76/176 nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 878e7b11736e062514e58f3b445ff343e6705537 upstream.
Add check for the return value of nfp_app_ctrl_msg_alloc() in nfp_bpf_cmsg_alloc() to prevent null pointer dereference.
--- drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +2 -0
@@ -20,6 +20,8 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bstruct sk_buff *skb; skb =nfp_app_ctrl_msg_alloc (bpf->app, size,GFP_KERNEL ); +if (!skb) +return NULL ;skb_put (skb, size);return skb;
Greg Kroah-Hartman
maintainerPATCH 77/176 ASoC: fsl_micfil: Enable default case in micfil_set_quality()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit a8c9a453387640dbe45761970f41301a6985e7fa upstream.
If 'micfil->quality' received from micfil_quality_set() somehow ends up with an unpredictable value, switch() operator will fail to initialize local variable qsel before regmap_update_bits() tries to utilize it.
While it is unlikely, play it safe and enable a default case that returns -EINVAL error.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- sound/soc/fsl/fsl_micfil.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/fsl/fsl_micfil.c +2 -0
@@ -123,6 +123,8 @@ static int micfil_set_quality(struct fslcase QUALITY_VLOW2 : qsel =MICFIL_QSEL_VLOW2_QUALITY ;break ; +default : +return -EINVAL ; } return regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
Greg Kroah-Hartman
maintainerPATCH 78/176 ALSA: hda: Add error check for snd_ctl_rename_id() in snd_hda_create_dig_out_ctls()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit 822b7ec657e99b44b874e052d8540d8b54fe8569 upstream.
Check the return value of snd_ctl_rename_id() in snd_hda_create_dig_out_ctls(). Ensure that failures are properly handled.
[ Note: the error cannot happen practically because the only error
condition in snd_ctl_rename_id() is the missing ID, but this is a rename, hence it must be present. But for the code consistency, it's safer to have always the proper return check -- tiwai ]
--- sound/pci/hda/hda_codec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/pci/hda/hda_codec.c +3 -1
@@ -2465,7 +2465,9 @@ int snd_hda_create_dig_out_ctls(struct hbreak ; id = kctl->id; id.index = spdif_index; -snd_ctl_rename_id (codec->card, &kctl->id, &id); + err =snd_ctl_rename_id (codec->card, &kctl->id, &id); +if (err <0 ) +return err; } bus->primary_dig_out_type =HDA_PCM_TYPE_HDMI ; }
Greg Kroah-Hartman
maintainerPATCH 79/176 ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Veness <[email protected]>
commit 6d1f86610f23b0bc334d6506a186f21a98f51392 upstream.
Allows the LED on the dedicated mute button on the HP ProBook 450 G4 laptop to change colour correctly.
--- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_conexant.c +1 -0
@@ -1098,6 +1098,7 @@ static const struct snd_pci_quirk cxt506SND_PCI_QUIRK (0x103c ,0x814f ,"HP ZBook 15u G3" ,CXT_FIXUP_MUTE_LED_GPIO ),SND_PCI_QUIRK (0x103c ,0x8174 ,"HP Spectre x360" ,CXT_FIXUP_HP_SPECTRE ),SND_PCI_QUIRK (0x103c ,0x822e ,"HP ProBook 440 G4" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x8231 ,"HP ProBook 450 G4" ,CXT_FIXUP_MUTE_LED_GPIO ),SND_PCI_QUIRK (0x103c ,0x828c ,"HP EliteBook 840 G4" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x8299 ,"HP 800 G3 SFF" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 80/176 acct: perform last write from workqueue
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit 56d5f3eba3f5de0efdd556de4ef381e109b973a9 upstream.
In [1] it was reported that the acct(2) system call can be used to trigger NULL deref in cases where it is set to write to a file that triggers an internal lookup. This can e.g., happen when pointing acc(2) to /sys/power/resume. At the point the where the write to this file happens the calling task has already exited and called exit_fs(). A lookup will thus trigger a NULL-deref when accessing current->fs.
Reorganize the code so that the the final write happens from the workqueue but with the caller's credentials. This preserves the (strange) permission model and has almost no regression risk.
This api should stop to exist though.
--- kernel/acct.c | 120 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 50 deletions(-)
kernel/acct.c +70 -50
@@ -104,48 +104,50 @@ struct bsd_acct_struct {atomic_long_t count;struct rcu_head rcu;struct mutex lock; -int active; +bool active; +bool check_space;unsigned long needcheck;struct file *file;struct pid_namespace *ns;struct work_struct work;struct completion done; +acct_t ac; }; -static void do_acct_process (struct bsd_acct_struct *acct); +static void fill_ac (struct bsd_acct_struct *acct); +static void acct_write_process (struct bsd_acct_struct *acct);/* * Check the amount of free space and suspend/resume accordingly. */ -static int check_free_space (struct bsd_acct_struct *acct) +static bool check_free_space (struct bsd_acct_struct *acct) {struct kstatfs sbuf; -if (time_is_after_jiffies (acct->needcheck)) - goto out; +if (!acct->check_space) +return acct->active;/* May block */ if (vfs_statfs (&acct->file->f_path, &sbuf)) - goto out; +return acct->active;if (acct->active) {u64 suspend = sbuf.f_blocks *SUSPEND ;do_div (suspend,100 );if (sbuf.f_bavail <= suspend) { - acct->active =0 ; + acct->active = false;pr_info ("Process accounting paused\n" ); } }else {u64 resume = sbuf.f_blocks *RESUME ;do_div (resume,100 );if (sbuf.f_bavail >= resume) { - acct->active =1 ; + acct->active = true;pr_info ("Process accounting resumed\n" ); } } acct->needcheck = jiffies +ACCT_TIMEOUT *HZ ; -out:return acct->active; }
@@ -190,7 +192,11 @@ static void acct_pin_kill(struct fs_pin {struct bsd_acct_struct *acct =to_acct (pin);mutex_lock (&acct->lock); -do_acct_process (acct); +/* +* Fill the accounting struct with the exiting task's info +* before punting to the workqueue. +*/ +fill_ac (acct);schedule_work (&acct->work);wait_for_completion (&acct->done);cmpxchg (&acct->ns->bacct, pin,NULL );
@@ -203,6 +209,9 @@ static void close_work(struct work_struc { struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work);struct file *file = acct->file; + +/* We were fired by acct_pin_kill() which holds acct->lock. */ +acct_write_process (acct);if (file->f_op->flush) file->f_op->flush (file,NULL );__fput_sync (file);
@@ -431,13 +440,27 @@ static u32 encode_float(u64 value)* do_exit() or when switching to a different output file. */ -static void fill_ac (acct_t *ac) +static void fill_ac (struct bsd_acct_struct *acct) {struct pacct_struct *pacct = ¤t->signal->pacct; +struct file *file = acct->file; +acct_t *ac = &acct->ac;u64 elapsed, run_time;time64_t btime;struct tty_struct *tty; +lockdep_assert_held (&acct->lock); + +if (time_is_after_jiffies (acct->needcheck)) { + acct->check_space = false; + +/* Don't fill in @ac if nothing will be written. */ +if (!acct->active) +return ; + }else { + acct->check_space = true; + } +/* * Fill the accounting struct with the needed info as recorded * by the different kernel functions.
@@ -485,64 +508,61 @@ static void fill_ac(acct_t *ac) ac->ac_majflt =encode_comp_t (pacct->ac_majflt); ac->ac_exitcode = pacct->ac_exitcode;spin_unlock_irq (¤t->sighand->siglock); -} -/* -* do_acct_process does all actual work. Caller holds the reference to file. -*/ -static void do_acct_process (struct bsd_acct_struct *acct) -{ -acct_t ac; -unsigned long flim; -const struct cred *orig_cred; -struct file *file = acct->file; - -/* -* Accounting records are not subject to resource limits. -*/ - flim =rlimit (RLIMIT_FSIZE ); - current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ; -/* Perform file operations on behalf of whoever enabled accounting */ - orig_cred =override_creds (file->f_cred); -/* -* First check to see if there is enough free_space to continue -* the process accounting system. -*/ -if (!check_free_space (acct)) - goto out; - -fill_ac (&ac);/* we really need to bite the bullet and change layout */ - ac.ac_uid =from_kuid_munged (file->f_cred->user_ns, orig_cred->uid); - ac.ac_gid =from_kgid_munged (file->f_cred->user_ns, orig_cred->gid); + ac->ac_uid =from_kuid_munged (file->f_cred->user_ns,current_uid ()); + ac->ac_gid =from_kgid_munged (file->f_cred->user_ns,current_gid ());#if ACCT_VERSION ==1 ||ACCT_VERSION ==2 /* backward-compatible 16 bit fields */ - ac.ac_uid16 = ac.ac_uid; - ac.ac_gid16 = ac.ac_gid; + ac->ac_uid16 = ac->ac_uid; + ac->ac_gid16 = ac->ac_gid;#elif ACCT_VERSION ==3 {struct pid_namespace *ns = acct->ns; - ac.ac_pid =task_tgid_nr_ns (current, ns); + ac->ac_pid =task_tgid_nr_ns (current, ns);rcu_read_lock (); - ac.ac_ppid =task_tgid_nr_ns (rcu_dereference (current->real_parent), - ns); + ac->ac_ppid =task_tgid_nr_ns (rcu_dereference (current->real_parent), ns);rcu_read_unlock (); }#endif +} + +static void acct_write_process (struct bsd_acct_struct *acct) +{ +struct file *file = acct->file; +const struct cred *cred; +acct_t *ac = &acct->ac; + +/* Perform file operations on behalf of whoever enabled accounting */ + cred =override_creds (file->f_cred); +/* -* Get freeze protection. If the fs is frozen, just skip the write -* as we could deadlock the system otherwise. +* First check to see if there is enough free_space to continue +* the process accounting system. Then get freeze protection. If +* the fs is frozen, just skip the write as we could deadlock +* the system otherwise. */ -if (file_start_write_trylock (file)) { +if (check_free_space (acct) &&file_start_write_trylock (file)) {/* it's been opened O_APPEND, so position is irrelevant */ loff_t pos =0 ; -__kernel_write (file, &ac,sizeof (acct_t), &pos); +__kernel_write (file, ac,sizeof (acct_t), &pos);file_end_write (file); } -out: + +revert_creds (cred); +} + +static void do_acct_process (struct bsd_acct_struct *acct) +{ +unsigned long flim; + +/* Accounting records are not subject to resource limits. */ + flim =rlimit (RLIMIT_FSIZE ); + current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ; +fill_ac (acct); +acct_write_process (acct); current->signal->rlim[RLIMIT_FSIZE ].rlim_cur = flim; -revert_creds (orig_cred); }/**
Greg Kroah-Hartman
maintainerPATCH 81/176 acct: block access to kernel internal filesystems
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit 890ed45bde808c422c3c27d3285fc45affa0f930 upstream.
There's no point in allowing anything kernel internal nor procfs or sysfs.
--- kernel/acct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
kernel/acct.c +14 -0
@@ -244,6 +244,20 @@ static int acct_on(struct filename *pathreturn -EACCES ; } +/* Exclude kernel kernel internal filesystems. */ +if (file_inode (file)->i_sb->s_flags & (SB_NOUSER |SB_KERNMOUNT )) { +kfree (acct); +filp_close (file,NULL ); +return -EINVAL ; + } + +/* Exclude procfs and sysfs. */ +if (file_inode (file)->i_sb->s_iflags &SB_I_USERNS_VISIBLE ) { +kfree (acct); +filp_close (file,NULL ); +return -EINVAL ; + } +if (!(file->f_mode &FMODE_CAN_WRITE )) {kfree (acct);filp_close (file,NULL );
Greg Kroah-Hartman
maintainerPATCH 82/176 mm,madvise,hugetlb: check for 0-length range after end address adjustment
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Cañuelo Navarro <[email protected]>
commit 2ede647a6fde3e54a6bfda7cf01c716649655900 upstream.
Add a sanity check to madvise_dontneed_free() to address a corner case in madvise where a race condition causes the current vma being processed to be backed by a different page size.
During a madvise(MADV_DONTNEED) call on a memory region registered with a userfaultfd, there's a period of time where the process mm lock is temporarily released in order to send a UFFD_EVENT_REMOVE and let userspace handle the event. During this time, the vma covering the current address range may change due to an explicit mmap done concurrently by another thread.
If, after that change, the memory region, which was originally backed by 4KB pages, is now backed by hugepages, the end address is rounded down to a hugepage boundary to avoid data loss (see "Fixes" below). This rounding may cause the end address to be truncated to the same address as the start.
Make this corner case follow the same semantics as in other similar cases where the requested region has zero length (ie. return 0).
This will make madvise_walk_vmas() continue to the next vma in the range (this time holding the process mm lock) which, due to the prev pointer becoming stale because of the vma change, will be the same hugepage-backed vma that was just checked before. The next time madvise_dontneed_free() runs for this vma, if the start address isn't aligned to a hugepage boundary, it'll return -EINVAL, which is also in line with the madvise api.
Quoted 1 line
From userspace perspective,
madvise()will return EINVAL because the start
address isn't aligned according to the new vma alignment requirements (hugepage), even though it was correctly page-aligned when the call was issued.
--- mm/madvise.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
mm/madvise.c +10 -1
@@ -879,7 +879,16 @@ static long madvise_dontneed_free(struct*/ end = vma->vm_end; } -VM_WARN_ON (start >= end); +/* +* If the memory region between start and end was +* originally backed by 4kB pages and then remapped to +* be backed by hugepages while mmap_lock was dropped, +* the adjustment for hugetlb vma above may have rounded +* end down to the start address. +*/ +if (start == end) +return 0 ; +VM_WARN_ON (start > end); }if (behavior ==MADV_DONTNEED || behavior ==MADV_DONTNEED_LOCKED )
Greg Kroah-Hartman
maintainerPATCH 83/176 mtd: rawnand: cadence: fix error code in cadence_nand_init()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit 2b9df00cded911e2ca2cfae5c45082166b24f8aa upstream.
Replace dma_request_channel() with dma_request_chan_by_mask() and use helper functions to return proper error code instead of fixed -EBUSY.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +4 -5
@@ -2863,11 +2863,10 @@ static int cadence_nand_init(struct cdnsdma_cap_set (DMA_MEMCPY , mask);if (cdns_ctrl->caps1->has_dma) { - cdns_ctrl->dmac =dma_request_channel (mask,NULL ,NULL ); -if (!cdns_ctrl->dmac) { -dev_err (cdns_ctrl->dev, -"Unable to get a DMA channel\n" ); - ret = -EBUSY ; + cdns_ctrl->dmac =dma_request_chan_by_mask (&mask); +if (IS_ERR (cdns_ctrl->dmac)) { + ret =dev_err_probe (cdns_ctrl->dev,PTR_ERR (cdns_ctrl->dmac), +"%d: Failed to get a DMA channel\n" , ret); goto disable_irq; } }
Greg Kroah-Hartman
maintainerPATCH 84/176 mtd: rawnand: cadence: use dma_map_resource for sdma address
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit d76d22b5096c5b05208fd982b153b3f182350b19 upstream.
Remap the slave DMA I/O resources to enhance driver portability. Using a physical address causes DMA translation failure when the ARM SMMU is enabled.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +25 -4
@@ -469,6 +469,8 @@ struct cdns_nand_ctrl {struct {void __iomem *virt;dma_addr_t dma; +dma_addr_t iova_dma; +u32 size; } io;int irq;
@@ -1830,11 +1832,11 @@ static int cadence_nand_slave_dma_transf }if (dir ==DMA_FROM_DEVICE ) { - src_dma = cdns_ctrl->io.dma; + src_dma = cdns_ctrl->io.iova_dma; dst_dma = buf_dma; }else { src_dma = buf_dma; - dst_dma = cdns_ctrl->io.dma; + dst_dma = cdns_ctrl->io.iova_dma; } tx = dmaengine_prep_dma_memcpy(cdns_ctrl->dmac, dst_dma, src_dma, len,
@@ -2828,6 +2830,7 @@ cadence_nand_irq_cleanup(int irqnum, strstatic int cadence_nand_init (struct cdns_nand_ctrl *cdns_ctrl) {dma_cap_mask_t mask; +struct dma_device *dma_dev = cdns_ctrl->dmac->device;int ret; cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2871,6 +2874,16 @@ static int cadence_nand_init(struct cdns } } + cdns_ctrl->io.iova_dma =dma_map_resource (dma_dev->dev, cdns_ctrl->io.dma, + cdns_ctrl->io.size, +DMA_BIDIRECTIONAL ,0 ); + + ret =dma_mapping_error (dma_dev->dev, cdns_ctrl->io.iova_dma); +if (ret) { +dev_err (cdns_ctrl->dev,"Failed to map I/O resource to DMA\n" ); + goto dma_release_chnl; + } +nand_controller_init (&cdns_ctrl->controller);INIT_LIST_HEAD (&cdns_ctrl->chips);
@@ -2881,18 +2894,22 @@ static int cadence_nand_init(struct cdnsif (ret) {dev_err (cdns_ctrl->dev,"Failed to register MTD: %d\n" , ret); - goto dma_release_chnl; + goto unmap_dma_resource; }kfree (cdns_ctrl->buf); cdns_ctrl->buf =kzalloc (cdns_ctrl->buf_size,GFP_KERNEL );if (!cdns_ctrl->buf) { ret = -ENOMEM ; - goto dma_release_chnl; + goto unmap_dma_resource; }return 0 ; +unmap_dma_resource: +dma_unmap_resource (dma_dev->dev, cdns_ctrl->io.iova_dma, + cdns_ctrl->io.size,DMA_BIDIRECTIONAL ,0 ); + dma_release_chnl:if (cdns_ctrl->dmac)dma_release_channel (cdns_ctrl->dmac);
@@ -2914,6 +2931,8 @@ free_buf_desc:static void cadence_nand_remove (struct cdns_nand_ctrl *cdns_ctrl) {cadence_nand_chips_cleanup (cdns_ctrl); +dma_unmap_resource (cdns_ctrl->dmac->device->dev, cdns_ctrl->io.iova_dma, + cdns_ctrl->io.size,DMA_BIDIRECTIONAL ,0 );cadence_nand_irq_cleanup (cdns_ctrl->irq, cdns_ctrl);kfree (cdns_ctrl->buf); dma_free_coherent(cdns_ctrl->dev, sizeof(struct cadence_nand_cdma_desc),
@@ -2982,7 +3001,9 @@ static int cadence_nand_dt_probe(struct cdns_ctrl->io.virt =devm_platform_get_and_ioremap_resource (ofdev,1 , &res);if (IS_ERR (cdns_ctrl->io.virt))return PTR_ERR (cdns_ctrl->io.virt); + cdns_ctrl->io.dma = res->start; + cdns_ctrl->io.size =resource_size (res); dt->clk =devm_clk_get (cdns_ctrl->dev,"nf_clk" );if (IS_ERR (dt->clk))
Greg Kroah-Hartman
maintainerPATCH 85/176 mtd: rawnand: cadence: fix incorrect device in dma_unmap_single
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit f37d135b42cb484bdecee93f56b9f483214ede78 upstream.
dma_map_single is using physical/bus device (DMA) but dma_unmap_single is using framework device(NAND controller), which is incorrect. Fixed dma_unmap_single to use correct physical/bus device.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +2 -2
@@ -1858,12 +1858,12 @@ static int cadence_nand_slave_dma_transfdma_async_issue_pending (cdns_ctrl->dmac);wait_for_completion (&finished); -dma_unmap_single (cdns_ctrl->dev, buf_dma, len, dir); +dma_unmap_single (dma_dev->dev, buf_dma, len, dir);return 0 ; err_unmap: -dma_unmap_single (cdns_ctrl->dev, buf_dma, len, dir); +dma_unmap_single (dma_dev->dev, buf_dma, len, dir); err:dev_dbg (cdns_ctrl->dev,"Fall back to CPU I/O\n" );
Greg Kroah-Hartman
maintainerPATCH 86/176 smb: client: Add check for next_buffer in receive_encrypted_standard()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 860ca5e50f73c2a1cef7eefc9d39d04e275417f7 upstream.
Add check for the return value of cifs_buf_get() and cifs_small_buf_get() in receive_encrypted_standard() to prevent null pointer dereference.
--- fs/smb/client/smb2ops.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/smb/client/smb2ops.c +4 -0
@@ -5158,6 +5158,10 @@ one_more: next_buffer = (char *)cifs_buf_get (); else next_buffer = (char *)cifs_small_buf_get (); +if (!next_buffer) { +cifs_server_dbg (VFS ,"No memory for (large) SMB response\n" ); +return -1 ; + }memcpy (next_buffer, buf + next_cmd, pdu_length - next_cmd); }
Greg Kroah-Hartman
maintainerPATCH 87/176 EDAC/qcom: Correct interrupt enable register configuration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Komal Bajaj <[email protected]>
commit c158647c107358bf1be579f98e4bb705c1953292 upstream.
The previous implementation incorrectly configured the cmn_interrupt_2_enable register for interrupt handling. Using cmn_interrupt_2_enable to configure Tag, Data RAM ECC interrupts would lead to issues like double handling of the interrupts (EL1 and EL3) as cmn_interrupt_2_enable is meant to be configured for interrupts which needs to be handled by EL3.
EL1 LLCC EDAC driver needs to use cmn_interrupt_0_enable register to configure Tag, Data RAM ECC interrupts instead of cmn_interrupt_2_enable.
--- drivers/edac/qcom_edac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/edac/qcom_edac.c +2 -2
@@ -95,7 +95,7 @@ static int qcom_llcc_core_setup(struct l* Configure interrupt enable registers such that Tag, Data RAM related * interrupts are propagated to interrupt controller for servicing */ - ret =regmap_update_bits (llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, + ret =regmap_update_bits (llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,TRP0_INTERRUPT_ENABLE ,TRP0_INTERRUPT_ENABLE );if (ret)
@@ -113,7 +113,7 @@ static int qcom_llcc_core_setup(struct lif (ret)return ret; - ret =regmap_update_bits (llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, + ret =regmap_update_bits (llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,DRP0_INTERRUPT_ENABLE ,DRP0_INTERRUPT_ENABLE );if (ret)
Greg Kroah-Hartman
maintainerPATCH 88/176 ftrace: Correct preemption accounting for function tracing.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 57b76bedc5c52c66968183b5ef57234894c25ce7 upstream.
The function tracer should record the preemption level at the point when the function is invoked. If the tracing subsystem decrement the preemption counter it needs to correct this before feeding the data into the trace buffer. This was broken in the commit cited below while shifting the preempt-disabled section.
Use tracing_gen_ctx_dec() which properly subtracts one from the preemption counter on a preemptible kernel.
--- kernel/trace/trace_functions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
kernel/trace/trace_functions.c +2 -4
@@ -185,7 +185,7 @@ function_trace_call(unsigned long ip, unif (bit <0 )return ; - trace_ctx =tracing_gen_ctx (); + trace_ctx =tracing_gen_ctx_dec (); cpu =smp_processor_id (); data =per_cpu_ptr (tr->array_buffer.data, cpu);
@@ -285,7 +285,6 @@ function_no_repeats_trace_call(unsignedstruct trace_array *tr = op->private;struct trace_array_cpu *data;unsigned int trace_ctx; -unsigned long flags;int bit;int cpu;
@@ -312,8 +311,7 @@ function_no_repeats_trace_call(unsignedif (is_repeat_check (tr, last_info, ip, parent_ip)) goto out; -local_save_flags (flags); - trace_ctx =tracing_gen_ctx_flags (flags); + trace_ctx =tracing_gen_ctx_dec ();process_repeats (tr, ip, parent_ip, last_info, trace_ctx);trace_function (tr, ip, parent_ip, trace_ctx);
Greg Kroah-Hartman
maintainerPATCH 89/176 ftrace: Do not add duplicate entries in subops manager ops
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit 8eb4b09e0bbd30981305643229fe7640ad41b667 upstream.
Check if a function is already in the manager ops of a subops. A manager ops contains multiple subops, and if two or more subops are tracing the same function, the manager ops only needs a single entry in its hash.
--- kernel/trace/ftrace.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/ftrace.c +3 -0
@@ -5108,6 +5108,9 @@ __ftrace_match_addr(struct ftrace_hash *return -ENOENT ;free_hash_entry (hash, entry);return 0 ; + }else if (__ftrace_lookup_ip (hash, ip) !=NULL ) { +/* Already exists */ +return 0 ; }return add_hash_entry (hash, ip);
Greg Kroah-Hartman
maintainerPATCH 90/176 x86/cpu/kvm: SRSO: Fix possible missing IBPB on VM-Exit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Bellasi <[email protected]>
commit 318e8c339c9a0891c389298bb328ed0762a9935e upstream.
In [1] the meaning of the synthetic IBPB flags has been redefined for a better separation of concerns:
- ENTRY_IBPB -- issue IBPB on entry only
- IBPB_ON_VMEXIT -- issue IBPB on VM-Exit only
and the Retbleed mitigations have been updated to match this new semantics.
Commit [2] was merged shortly before [1], and their interaction was not handled properly. This resulted in IBPB not being triggered on VM-Exit in all SRSO mitigation configs requesting an IBPB there.
Specifically, an IBPB on VM-Exit is triggered only when X86_FEATURE_IBPB_ON_VMEXIT is set. However:
- X86_FEATURE_IBPB_ON_VMEXIT is not set for "spec_rstack_overflow=ibpb", because before [1] having X86_FEATURE_ENTRY_IBPB was enough. Hence, an IBPB is triggered on entry but the expected IBPB on VM-exit is not.
- X86_FEATURE_IBPB_ON_VMEXIT is not set also when "spec_rstack_overflow=ibpb-vmexit" if X86_FEATURE_ENTRY_IBPB is already set.
That's because before [1] this was effectively redundant. Hence, e.g. a "retbleed=ibpb spec_rstack_overflow=bpb-vmexit" config mistakenly reports the machine still vulnerable to SRSO, despite an IBPB being triggered both on entry and VM-Exit, because of the Retbleed selected mitigation config.
- UNTRAIN_RET_VM won't still actually do anything unless CONFIG_MITIGATION_IBPB_ENTRY is set.
For "spec_rstack_overflow=ibpb", enable IBPB on both entry and VM-Exit and clear X86_FEATURE_RSB_VMEXIT which is made superfluous by X86_FEATURE_IBPB_ON_VMEXIT. This effectively makes this mitigation option similar to the one for 'retbleed=ibpb', thus re-order the code for the RETBLEED_MITIGATION_IBPB option to be less confusing by having all features enabling before the disabling of the not needed ones.
For "spec_rstack_overflow=ibpb-vmexit", guard this mitigation setting with CONFIG_MITIGATION_IBPB_ENTRY to ensure UNTRAIN_RET_VM sequence is effectively compiled in. Drop instead the CONFIG_MITIGATION_SRSO guard, since none of the SRSO compile cruft is required in this configuration. Also, check only that the required microcode is present to effectively enabled the IBPB on VM-Exit.
Finally, update the KConfig description for CONFIG_MITIGATION_IBPB_ENTRY to list also all SRSO config settings enabled by this guard.
--- arch/x86/Kconfig | 3 ++- arch/x86/kernel/cpu/bugs.c | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-)
arch/x86/Kconfig +2 -1
@@ -2506,7 +2506,8 @@ config CPU_IBPB_ENTRY depends on CPU_SUP_AMD && X86_64 default y help - Compile the kernel with support for the retbleed=ibpb mitigation. + Compile the kernel with support for the retbleed=ibpb and + spec_rstack_overflow={ibpb,ibpb-vmexit} mitigations. config CPU_IBRS_ENTRY bool "Enable IBRS on kernel entry"
arch/x86/kernel/cpu/bugs.c +14 -6
@@ -1092,6 +1092,8 @@ do_cmd_auto:case RETBLEED_MITIGATION_IBPB :setup_force_cpu_cap (X86_FEATURE_ENTRY_IBPB ); +setup_force_cpu_cap (X86_FEATURE_IBPB_ON_VMEXIT ); + mitigate_smt = true;/* * IBPB on entry already obviates the need for
@@ -1101,8 +1103,6 @@ do_cmd_auto:setup_clear_cpu_cap (X86_FEATURE_UNRET );setup_clear_cpu_cap (X86_FEATURE_RETHUNK ); - mitigate_smt = true; -/* * There is no need for RSB filling: entry_ibpb() ensures * all predictions, including the RSB, are invalidated,
@@ -2607,6 +2607,7 @@ static void __init srso_select_mitigatioif (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY )) {if (has_microcode) {setup_force_cpu_cap (X86_FEATURE_ENTRY_IBPB ); +setup_force_cpu_cap (X86_FEATURE_IBPB_ON_VMEXIT ); srso_mitigation =SRSO_MITIGATION_IBPB ;/*
@@ -2616,6 +2617,13 @@ static void __init srso_select_mitigatio*/ setup_clear_cpu_cap (X86_FEATURE_UNRET );setup_clear_cpu_cap (X86_FEATURE_RETHUNK ); + +/* +* There is no need for RSB filling: entry_ibpb() ensures +* all predictions, including the RSB, are invalidated, +* regardless of IBPB implementation. +*/ +setup_clear_cpu_cap (X86_FEATURE_RSB_VMEXIT ); } }else {pr_err ("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n" );
@@ -2624,8 +2632,8 @@ static void __init srso_select_mitigatiobreak ;case SRSO_CMD_IBPB_ON_VMEXIT : -if (IS_ENABLED (CONFIG_CPU_SRSO )) { -if (!boot_cpu_has (X86_FEATURE_ENTRY_IBPB ) && has_microcode) { +if (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY )) { +if (has_microcode) {setup_force_cpu_cap (X86_FEATURE_IBPB_ON_VMEXIT ); srso_mitigation =SRSO_MITIGATION_IBPB_ON_VMEXIT ;
@@ -2637,9 +2645,9 @@ static void __init srso_select_mitigatiosetup_clear_cpu_cap (X86_FEATURE_RSB_VMEXIT ); } }else { -pr_err ("WARNING: kernel not compiled with CPU_SRSO.\n" ); +pr_err ("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n" ); goto pred_cmd; - } + }break ;default :
Greg Kroah-Hartman
maintainerPATCH 91/176 block, bfq: split sync bfq_queues on a per-actuator basis
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Valente <[email protected]>
commit 9778369a2d6c5ed2b81a04164c4aa9da1bdb193d upstream.
Single-LUN multi-actuator SCSI drives, as well as all multi-actuator SATA drives appear as a single device to the I/O subsystem [1]. Yet they address commands to different actuators internally, as a function of Logical Block Addressing (LBAs). A given sector is reachable by only one of the actuators. For example, Seagate’s Serial Advanced Technology Attachment (SATA) version contains two actuators and maps the lower half of the SATA LBA space to the lower actuator and the upper half to the upper actuator.
Evidently, to fully utilize actuators, no actuator must be left idle or underutilized while there is pending I/O for it. The block layer must somehow control the load of each actuator individually. This commit lays the ground for allowing BFQ to provide such a per-actuator control.
BFQ associates an I/O-request sync bfq_queue with each process doing synchronous I/O, or with a group of processes, in case of queue merging. Then BFQ serves one bfq_queue at a time. While in service, a bfq_queue is emptied in request-position order. Yet the same process, or group of processes, may generate I/O for different actuators. In this case, different streams of I/O (each for a different actuator) get all inserted into the same sync bfq_queue. So there is basically no individual control on when each stream is served, i.e., on when the I/O requests of the stream are picked from the bfq_queue and dispatched to the drive.
This commit enables BFQ to control the service of each actuator individually for synchronous I/O, by simply splitting each sync bfq_queue into N queues, one for each actuator. In other words, a sync bfq_queue is now associated to a pair (process, actuator). As a consequence of this split, the per-queue proportional-share policy implemented by BFQ will guarantee that the sync I/O generated for each actuator, by each process, receives its fair share of service.
This is just a preparatory patch. If the I/O of the same process happens to be sent to different queues, then each of these queues may undergo queue merging. To handle this event, the bfq_io_cq data structure must be properly extended. In addition, stable merging must be disabled to avoid loss of control on individual actuators. Finally, also async queues must be split. These issues are described in detail and addressed in next commits. As for this commit, although multiple per-process bfq_queues are provided, the I/O of each process or group of processes is still sent to only one queue, regardless of the actuator the I/O is for. The forwarding to distinct bfq_queues will be enabled after addressing the above issues.
Stable-dep-of: e8b8344de398 ("block, bfq: fix bfqq uaf in bfq_limit_depth()")
--- block/bfq-cgroup.c | 97 ++++++++++++++++--------------- block/bfq-iosched.c | 160 ++++++++++++++++++++++++++++++++++------------------ block/bfq-iosched.h | 51 +++++++++++++--- 3 files changed, 197 insertions(+), 111 deletions(-)
block/bfq-cgroup.c +51 -46
@@ -704,6 +704,46 @@ void bfq_bfqq_move(struct bfq_data *bfqdbfq_put_queue (bfqq); } +static void bfq_sync_bfqq_move (struct bfq_data *bfqd, +struct bfq_queue *sync_bfqq, +struct bfq_io_cq *bic, +struct bfq_group *bfqg, +unsigned int act_idx) +{ +struct bfq_queue *bfqq; + +if (!sync_bfqq->new_bfqq && !bfq_bfqq_coop (sync_bfqq)) { +/* We are the only user of this bfqq, just move it */ +if (sync_bfqq->entity.sched_data != &bfqg->sched_data) +bfq_bfqq_move (bfqd, sync_bfqq, bfqg); +return ; + } + +/* +* The queue was merged to a different queue. Check +* that the merge chain still belongs to the same +* cgroup. +*/ +for (bfqq = sync_bfqq; bfqq; bfqq = bfqq->new_bfqq) +if (bfqq->entity.sched_data != &bfqg->sched_data) +break ; +if (bfqq) { +/* +* Some queue changed cgroup so the merge is not valid +* anymore. We cannot easily just cancel the merge (by +* clearing new_bfqq) as there may be other processes +* using this queue and holding refs to all queues +* below sync_bfqq->new_bfqq. Similarly if the merge +* already happened, we need to detach from bfqq now +* so that we cannot merge bio to a request from the +* old cgroup. +*/ +bfq_put_cooperator (sync_bfqq); +bfq_release_process_ref (bfqd, sync_bfqq); +bic_set_bfqq (bic,NULL , true, act_idx); + } +} +/** * __bfq_bic_change_cgroup - move @bic to @bfqg. * @bfqd: the queue descriptor.
@@ -714,60 +754,25 @@ void bfq_bfqq_move(struct bfq_data *bfqd* sure that the reference to cgroup is valid across the call (see * comments in bfq_bic_update_cgroup on this issue) */ -static void *__bfq_bic_change_cgroup (struct bfq_data *bfqd, +static void __bfq_bic_change_cgroup (struct bfq_data *bfqd,struct bfq_io_cq *bic,struct bfq_group *bfqg) { -struct bfq_queue *async_bfqq =bic_to_bfqq (bic, false); -struct bfq_queue *sync_bfqq =bic_to_bfqq (bic, true); -struct bfq_entity *entity; - -if (async_bfqq) { - entity = &async_bfqq->entity; +unsigned int act_idx; -if (entity->sched_data != &bfqg->sched_data) { -bic_set_bfqq (bic,NULL , false); +for (act_idx =0 ; act_idx < bfqd->num_actuators; act_idx++) { +struct bfq_queue *async_bfqq =bic_to_bfqq (bic, false, act_idx); +struct bfq_queue *sync_bfqq =bic_to_bfqq (bic, true, act_idx); + +if (async_bfqq && + async_bfqq->entity.sched_data != &bfqg->sched_data) { +bic_set_bfqq (bic,NULL , false, act_idx);bfq_release_process_ref (bfqd, async_bfqq); } - } -if (sync_bfqq) { -if (!sync_bfqq->new_bfqq && !bfq_bfqq_coop (sync_bfqq)) { -/* We are the only user of this bfqq, just move it */ -if (sync_bfqq->entity.sched_data != &bfqg->sched_data) -bfq_bfqq_move (bfqd, sync_bfqq, bfqg); - }else { -struct bfq_queue *bfqq; - -/* -* The queue was merged to a different queue. Check -* that the merge chain still belongs to the same -* cgroup. -*/ -for (bfqq = sync_bfqq; bfqq; bfqq = bfqq->new_bfqq) -if (bfqq->entity.sched_data != - &bfqg->sched_data) -break ; -if (bfqq) { -/* -* Some queue changed cgroup so the merge is -* not valid anymore. We cannot easily just -* cancel the merge (by clearing new_bfqq) as -* there may be other processes using this -* queue and holding refs to all queues below -* sync_bfqq->new_bfqq. Similarly if the merge -* already happened, we need to detach from -* bfqq now so that we cannot merge bio to a -* request from the old cgroup. -*/ -bfq_put_cooperator (sync_bfqq); -bic_set_bfqq (bic,NULL , true); -bfq_release_process_ref (bfqd, sync_bfqq); - } - } +if (sync_bfqq) +bfq_sync_bfqq_move (bfqd, sync_bfqq, bic, bfqg, act_idx); } - -return bfqg; }void bfq_bic_update_cgroup (struct bfq_io_cq *bic,struct bio *bio)
block/bfq-iosched.c +105 -55
324 lines not on this page · raw message
block/bfq-iosched.h +41 -10
87 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 92/176 block, bfq: fix bfqq uaf in bfq_limit_depth()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
commit e8b8344de3980709080d86c157d24e7de07d70ad upstream.
Set new allocated bfqq to bic or remove freed bfqq from bic are both protected by bfqd->lock, however bfq_limit_depth() is deferencing bfqq from bic without the lock, this can lead to UAF if the io_context is shared by multiple tasks.
For example, test bfq with io_uring can trigger following UAF in v6.6:
==================================================================
BUG: KASAN: slab-use-after-free in bfqq_group+0x15/0x50 Call Trace: <TASK> dump_stack_lvl+0x47/0x80 print_address_description.constprop.0+0x66/0x300 print_report+0x3e/0x70 kasan_report+0xb4/0xf0 bfqq_group+0x15/0x50 bfqq_request_over_limit+0x130/0x9a0 bfq_limit_depth+0x1b5/0x480 __blk_mq_alloc_requests+0x2b5/0xa00 blk_mq_get_new_requests+0x11d/0x1d0 blk_mq_submit_bio+0x286/0xb00 submit_bio_noacct_nocheck+0x331/0x400 __block_write_full_folio+0x3d0/0x640 writepage_cb+0x3b/0xc0 write_cache_pages+0x254/0x6c0 write_cache_pages+0x254/0x6c0 do_writepages+0x192/0x310 filemap_fdatawrite_wbc+0x95/0xc0 __filemap_fdatawrite_range+0x99/0xd0 filemap_write_and_wait_range.part.0+0x4d/0xa0 blkdev_read_iter+0xef/0x1e0 io_read+0x1b6/0x8a0 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork_asm+0x1b/0x30 </TASK> Allocated by task 808602: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_slab_alloc+0x83/0x90 kmem_cache_alloc_node+0x1b1/0x6d0 bfq_get_queue+0x138/0xfa0 bfq_get_bfqq_handle_split+0xe3/0x2c0 bfq_init_rq+0x196/0xbb0 bfq_insert_request.isra.0+0xb5/0x480 bfq_insert_requests+0x156/0x180 blk_mq_insert_request+0x15d/0x440 blk_mq_submit_bio+0x8a4/0xb00 submit_bio_noacct_nocheck+0x331/0x400 __blkdev_direct_IO_async+0x2dd/0x330 blkdev_write_iter+0x39a/0x450 io_write+0x22a/0x840 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork+0x2d/0x50 ret_from_fork_asm+0x1b/0x30 Freed by task 808589: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x27/0x40 __kasan_slab_free+0x126/0x1b0 kmem_cache_free+0x10c/0x750 bfq_put_queue+0x2dd/0x770 __bfq_insert_request.isra.0+0x155/0x7a0 bfq_insert_request.isra.0+0x122/0x480 bfq_insert_requests+0x156/0x180 blk_mq_dispatch_plug_list+0x528/0x7e0 blk_mq_flush_plug_list.part.0+0xe5/0x590 __blk_flush_plug+0x3b/0x90 blk_finish_plug+0x40/0x60 do_writepages+0x19d/0x310 filemap_fdatawrite_wbc+0x95/0xc0 __filemap_fdatawrite_range+0x99/0xd0 filemap_write_and_wait_range.part.0+0x4d/0xa0 blkdev_read_iter+0xef/0x1e0 io_read+0x1b6/0x8a0 io_issue_sqe+0x87/0x300 io_wq_submit_work+0xeb/0x390 io_worker_handle_work+0x24d/0x550 io_wq_worker+0x27f/0x6c0 ret_from_fork+0x2d/0x50 ret_from_fork_asm+0x1b/0x30
Fix the problem by protecting bic_to_bfqq() with bfqd->lock.
--- block/bfq-iosched.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
block/bfq-iosched.c +24 -13
@@ -581,23 +581,31 @@ static struct request *bfq_choose_req(st#define BFQ_LIMIT_INLINE_DEPTH 16#ifdef CONFIG_BFQ_GROUP_IOSCHED -static bool bfqq_request_over_limit (struct bfq_queue *bfqq,int limit) +static bool bfqq_request_over_limit (struct bfq_data *bfqd, +struct bfq_io_cq *bic,blk_opf_t opf, +unsigned int act_idx,int limit) { -struct bfq_data *bfqd = bfqq->bfqd; -struct bfq_entity *entity = &bfqq->entity;struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH ];struct bfq_entity **entities = inline_entities; -int depth, level, alloc_depth =BFQ_LIMIT_INLINE_DEPTH ; -int class_idx = bfqq->ioprio_class -1 ; +int alloc_depth =BFQ_LIMIT_INLINE_DEPTH ;struct bfq_sched_data *sched_data; +struct bfq_entity *entity; +struct bfq_queue *bfqq;unsigned long wsum;bool ret = false; - -if (!entity->on_st_or_in_serv) -return false; +int depth; +int level; retry:spin_lock_irq (&bfqd->lock); + bfqq =bic_to_bfqq (bic,op_is_sync (opf), act_idx); +if (!bfqq) + goto out; + + entity = &bfqq->entity; +if (!entity->on_st_or_in_serv) + goto out; +/* +1 for bfqq entity, root cgroup not included */ depth =bfqg_to_blkg (bfqq_group (bfqq))->blkcg->css.cgroup->level +1 ;if (depth > alloc_depth) {
@@ -642,7 +650,7 @@ retry:* class. */ wsum =0 ; -for (i =0 ; i <= class_idx; i++) { +for (i =0 ; i <= bfqq->ioprio_class -1 ; i++) { wsum = wsum *IOPRIO_BE_NR + sched_data->service_tree[i].wsum; }
@@ -665,7 +673,9 @@ out: return ret; }#else -static bool bfqq_request_over_limit (struct bfq_queue *bfqq,int limit) +static bool bfqq_request_over_limit (struct bfq_data *bfqd, +struct bfq_io_cq *bic,blk_opf_t opf, +unsigned int act_idx,int limit) {return false; }
@@ -703,8 +713,9 @@ static void bfq_limit_depth(blk_opf_t op }for (act_idx =0 ; bic && act_idx < bfqd->num_actuators; act_idx++) { -struct bfq_queue *bfqq = -bic_to_bfqq (bic,op_is_sync (opf), act_idx); +/* Fast path to check if bfqq is already allocated. */ +if (!bic_to_bfqq (bic,op_is_sync (opf), act_idx)) +continue ;/* * Does queue (or any parent entity) exceed number of
@@ -712,7 +723,7 @@ static void bfq_limit_depth(blk_opf_t op* limit depth so that it cannot consume more * available requests and thus starve other entities. */ -if (bfqq &&bfqq_request_over_limit (bfqq, limit)) { +if (bfqq_request_over_limit (bfqd, bic, opf, act_idx, limit)) { depth =1 ;break ; }
Greg Kroah-Hartman
maintainerPATCH 93/176 media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunfei Dong <[email protected]>
commit 9be85491619f1953b8a29590ca630be571941ffa upstream.
Fix a smatch static checker warning on vdec_h264_req_multi_if.c. Which leads to a kernel crash when fb is NULL.
[ drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
is renamed from drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c since 0934d3759615 ("media: mediatek: vcodec: separate decoder and encoder"). The path is changed accordingly to apply the patch on 6.1.y. ]
--- drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c +7 -2
@@ -729,11 +729,16 @@ static int vdec_h264_slice_single_decodereturn vpu_dec_reset (vpu); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer (inst->ctx); +if (!fb) { +mtk_vcodec_err (inst,"fb buffer is NULL" ); +return -ENOMEM ; + } + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); - y_fb_dma = fb ? (u64 )fb->base_y.dma_addr :0 ; - c_fb_dma = fb ? (u64 )fb->base_c.dma_addr :0 ; + y_fb_dma = fb->base_y.dma_addr; + c_fb_dma = fb->base_c.dma_addr;mtk_vcodec_debug (inst,"[h264-dec] [%d] y_dma=%llx c_dma=%llx" , inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
Greg Kroah-Hartman
maintainerPATCH 94/176 spi: atmel-quadspi: Avoid overwriting delay register settings
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Dahl <[email protected]>
commit 329ca3eed4a9a161515a8714be6ba182321385c7 upstream.
Previously the MR and SCR registers were just set with the supposedly required values, from cached register values (cached reg content initialized to zero).
All parts fixed here did not consider the current register (cache) content, which would make future support of cs_setup, cs_hold, and cs_inactive impossible.
Setting SCBR in atmel_qspi_setup() erases a possible DLYBS setting from atmel_qspi_set_cs_timing(). The DLYBS setting is applied by ORing over the current setting, without resetting the bits first. All writes to MR did not consider possible settings of DLYCS and DLYBCT.
--- drivers/spi/atmel-quadspi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/spi/atmel-quadspi.c +8 -6
@@ -388,9 +388,9 @@ static int atmel_qspi_set_cfg(struct atm* If the QSPI controller is set in regular SPI mode, set it in * Serial Memory Mode (SMM). */ -if (aq->mr !=QSPI_MR_SMM ) { -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; +if (!(aq->mr &QSPI_MR_SMM )) { + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->scr, aq,QSPI_MR ); }/* Clear pending interrupts */
@@ -545,7 +545,8 @@ static int atmel_qspi_setup(struct spi_dif (ret <0 )return ret; - aq->scr =QSPI_SCR_SCBR (scbr); + aq->scr &= ~QSPI_SCR_SCBR_MASK ; + aq->scr |=QSPI_SCR_SCBR (scbr);atmel_qspi_write (aq->scr, aq,QSPI_SCR );pm_runtime_mark_last_busy (ctrl->dev.parent);
@@ -578,6 +579,7 @@ static int atmel_qspi_set_cs_timing(struif (ret <0 )return ret; + aq->scr &= ~QSPI_SCR_DLYBS_MASK ; aq->scr |=QSPI_SCR_DLYBS (cs_setup);atmel_qspi_write (aq->scr, aq,QSPI_SCR );
@@ -593,8 +595,8 @@ static void atmel_qspi_init(struct atmelatmel_qspi_write (QSPI_CR_SWRST , aq,QSPI_CR );/* Set the QSPI controller by default in Serial Memory Mode */ -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->mr, aq,QSPI_MR );/* Enable the QSPI controller */ atmel_qspi_write (QSPI_CR_QSPIEN , aq,QSPI_CR );
Greg Kroah-Hartman
maintainerPATCH 95/176 spi: atmel-quadspi: Fix wrong register value written to MR
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Dahl <[email protected]>
commit 162d9b5d2308c7e48efbc97d36babbf4d73b2c61 upstream.
aq->mr should go to MR, nothing else.
--- drivers/spi/atmel-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/atmel-quadspi.c +1 -1
@@ -390,7 +390,7 @@ static int atmel_qspi_set_cfg(struct atm*/ if (!(aq->mr &QSPI_MR_SMM )) { aq->mr |=QSPI_MR_SMM ; -atmel_qspi_write (aq->scr, aq,QSPI_MR ); +atmel_qspi_write (aq->mr, aq,QSPI_MR ); }/* Clear pending interrupts */
Greg Kroah-Hartman
maintainerPATCH 96/176 netfilter: allow exp not to be removed in nf_ct_find_expectation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
commit 4914109a8e1e494c6aa9852f9e84ec77a5fc643f upstream.
Currently nf_conntrack_in() calling nf_ct_find_expectation() will remove the exp from the hash table. However, in some scenario, we expect the exp not to be removed when the created ct will not be confirmed, like in OVS and TC conntrack in the following patches.
This patch allows exp not to be removed by setting IPS_CONFIRMED in the status of the tmpl.
--- include/net/netfilter/nf_conntrack_expect.h | 2 +- net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_expect.c | 4 ++-- net/netfilter/nft_ct.c | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-)
include/net/netfilter/nf_conntrack_expect.h +1 -1
@@ -100,7 +100,7 @@ nf_ct_expect_find_get(struct net *net,struct nf_conntrack_expect *nf_ct_find_expectation (struct net *net,const struct nf_conntrack_zone *zone, -const struct nf_conntrack_tuple *tuple); +const struct nf_conntrack_tuple *tuple,bool unlink);void nf_ct_unlink_expect_report (struct nf_conntrack_expect *exp,u32 portid,int report);
net/netfilter/nf_conntrack_core.c +1 -1
@@ -1770,7 +1770,7 @@ init_conntrack(struct net *net, struct n cnet =nf_ct_pernet (net);if (cnet->expect_count) {spin_lock_bh (&nf_conntrack_expect_lock); - exp =nf_ct_find_expectation (net, zone, tuple); + exp =nf_ct_find_expectation (net, zone, tuple, !tmpl ||nf_ct_is_confirmed (tmpl));if (exp) {pr_debug ("expectation arrives ct=%p exp=%p\n" , ct, exp);
net/netfilter/nf_conntrack_expect.c +2 -2
@@ -171,7 +171,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get)struct nf_conntrack_expect *nf_ct_find_expectation (struct net *net,const struct nf_conntrack_zone *zone, -const struct nf_conntrack_tuple *tuple) +const struct nf_conntrack_tuple *tuple,bool unlink) {struct nf_conntrack_net *cnet =nf_ct_pernet (net);struct nf_conntrack_expect *i, *exp =NULL ;
@@ -211,7 +211,7 @@ nf_ct_find_expectation(struct net *net, !refcount_inc_not_zero(&exp->master->ct_general.use)))return NULL ; -if (exp->flags &NF_CT_EXPECT_PERMANENT ) { +if (exp->flags &NF_CT_EXPECT_PERMANENT || !unlink) {refcount_inc (&exp->use);return exp; }else if (del_timer (&exp->timeout)) {
net/netfilter/nft_ct.c +2 -0
@@ -272,6 +272,7 @@ static void nft_ct_set_zone_eval(const s regs->verdict.code =NF_DROP ;return ; } +__set_bit (IPS_CONFIRMED_BIT , &ct->status); }nf_ct_set (skb, ct,IP_CT_NEW );
@@ -378,6 +379,7 @@ static bool nft_ct_tmpl_alloc_pcpu(void)return false; } +__set_bit (IPS_CONFIRMED_BIT , &tmp->status);per_cpu (nft_ct_pcpu_template, cpu) = tmp; }
Greg Kroah-Hartman
maintainerPATCH 97/176 RDMA/mlx5: Dont keep umrable page_shift in cache entries
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aharon Landau <[email protected]>
[ Upstream commit a2a88b8e22d1b202225d0e40b02ad068afab2ccb ]
mkc.log_page_size can be changed using UMR. Therefore, don't treat it as a cache entry property.
Removing it from struct mlx5_cache_ent.
All cache mkeys will be created with default PAGE_SHIFT, and updated with the needed page_shift using UMR when passing them to a user.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 - drivers/infiniband/hw/mlx5/mr.c | 3 +-- drivers/infiniband/hw/mlx5/odp.c | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +0 -1
@@ -759,7 +759,6 @@ struct mlx5_cache_ent {char name[4 ];u32 order;u32 access_mode; -u32 page;unsigned int ndescs; u8 disabled:1;
drivers/infiniband/hw/mlx5/mr.c +1 -2
@@ -297,7 +297,7 @@ static void set_cache_mkc(struct mlx5_cache_ent *ent, void *mkc)MLX5_SET (mkc, mkc, translations_octword_size,get_mkc_octo_size (ent->access_mode, ent->ndescs)); -MLX5_SET (mkc, mkc, log_page_size, ent->page); +MLX5_SET (mkc, mkc, log_page_size,PAGE_SHIFT ); }/* Asynchronously schedule new MRs to be populated in the cache. */
@@ -765,7 +765,6 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)if (ent->order >mkey_cache_max_order (dev))continue ; - ent->page =PAGE_SHIFT ; ent->ndescs =1 << ent->order; ent->access_mode =MLX5_MKC_ACCESS_MODE_MTT ; if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) &&
drivers/infiniband/hw/mlx5/odp.c +0 -2
@@ -1598,14 +1598,12 @@ void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent)switch (ent->order -2 ) {case MLX5_IMR_MTT_CACHE_ENTRY : - ent->page =PAGE_SHIFT ; ent->ndescs =MLX5_IMR_MTT_ENTRIES ; ent->access_mode =MLX5_MKC_ACCESS_MODE_MTT ; ent->limit =0 ;break ;case MLX5_IMR_KSM_CACHE_ENTRY : - ent->page =MLX5_KSM_PAGE_SHIFT ; ent->ndescs = mlx5_imr_ksm_entries; ent->access_mode =MLX5_MKC_ACCESS_MODE_KSM ; ent->limit =0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 98/176 RDMA/mlx5: Remove implicit ODP cache entry
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aharon Landau <[email protected]>
[ Upstream commit 18b1746bddf5e7f6b2618966596d9517172a5cd7 ]
Implicit ODP mkey doesn't have unique properties. It shares the same properties as the order 18 cache entry. There is no need to devote a special entry for that.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/odp.c | 20 +++++--------------- include/linux/mlx5/driver.h | 1 - 2 files changed, 5 insertions(+), 16 deletions(-)
drivers/infiniband/hw/mlx5/odp.c +5 -15
@@ -406,6 +406,7 @@ static void mlx5_ib_page_fault_resume(struct mlx5_ib_dev *dev,static struct mlx5_ib_mr *implicit_get_child_mr (struct mlx5_ib_mr *imr,unsigned long idx) { +int order =order_base_2 (MLX5_IMR_MTT_ENTRIES );struct mlx5_ib_dev *dev =mr_to_mdev (imr);struct ib_umem_odp *odp;struct mlx5_ib_mr *mr;
@@ -418,7 +419,8 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,if (IS_ERR (odp))return ERR_CAST (odp); - mr =mlx5_mr_cache_alloc (dev, &dev->cache.ent[MLX5_IMR_MTT_CACHE_ENTRY ], +BUILD_BUG_ON (order >MKEY_CACHE_LAST_STD_ENTRY ); + mr =mlx5_mr_cache_alloc (dev, &dev->cache.ent[order], imr->access_flags);if (IS_ERR (mr)) {ib_umem_odp_release (odp);
@@ -1595,20 +1597,8 @@ void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent) {if (!(ent->dev->odp_caps.general_caps &IB_ODP_SUPPORT_IMPLICIT ))return ; - -switch (ent->order -2 ) { -case MLX5_IMR_MTT_CACHE_ENTRY : - ent->ndescs =MLX5_IMR_MTT_ENTRIES ; - ent->access_mode =MLX5_MKC_ACCESS_MODE_MTT ; - ent->limit =0 ; -break ; - -case MLX5_IMR_KSM_CACHE_ENTRY : - ent->ndescs = mlx5_imr_ksm_entries; - ent->access_mode =MLX5_MKC_ACCESS_MODE_KSM ; - ent->limit =0 ; -break ; - } + ent->ndescs = mlx5_imr_ksm_entries; + ent->access_mode =MLX5_MKC_ACCESS_MODE_KSM ; }static const struct ib_device_ops mlx5_ib_dev_odp_ops = {
include/linux/mlx5/driver.h +0 -1
@@ -744,7 +744,6 @@ enum {enum {MKEY_CACHE_LAST_STD_ENTRY =20 , -MLX5_IMR_MTT_CACHE_ENTRY ,MLX5_IMR_KSM_CACHE_ENTRY ,MAX_MKEY_CACHE_ENTRIES };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 99/176 RDMA/mlx5: Change the cache structure to an RB-tree
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit b9584517832858a0f78d6851d09b697a829514cd ]
Currently, the cache structure is a static linear array. Therefore, his size is limited to the number of entries in it and is not expandable. The entries are dedicated to mkeys of size 2^x and no access_flags. Mkeys with different properties are not cacheable.
In this patch, we change the cache structure to an RB-tree. This will allow to extend the cache to support more entries with different mkey properties.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 11 +- drivers/infiniband/hw/mlx5/mr.c | 160 ++++++++++++++++++++------- drivers/infiniband/hw/mlx5/odp.c | 8 +- 3 files changed, 132 insertions(+), 47 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +9 -2
@@ -761,6 +761,8 @@ struct mlx5_cache_ent {u32 access_mode;unsigned int ndescs; +struct rb_node node; + u8 disabled:1; u8 fill_to_high_water:1;
@@ -790,8 +792,9 @@ struct mlx5r_async_create_mkey {struct mlx5_mkey_cache {struct workqueue_struct *wq; -struct mlx5_cache_ent ent[MAX_MKEY_CACHE_ENTRIES ]; -struct dentry *root; +struct rb_root rb_root; +struct mutex rb_lock; +struct dentry *fs_root;unsigned long last_add; };
@@ -1336,11 +1339,15 @@ void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num);int mlx5_ib_get_cqe_size (struct ib_cq *ibcq);int mlx5_mkey_cache_init (struct mlx5_ib_dev *dev);int mlx5_mkey_cache_cleanup (struct mlx5_ib_dev *dev); +struct mlx5_cache_ent *mlx5r_cache_create_ent (struct mlx5_ib_dev *dev, +int order);struct mlx5_ib_mr *mlx5_mr_cache_alloc (struct mlx5_ib_dev *dev,struct mlx5_cache_ent *ent,int access_flags); +struct mlx5_ib_mr *mlx5_mr_cache_alloc_order (struct mlx5_ib_dev *dev,u32 order, +int access_flags);int mlx5_ib_check_mr_status (struct ib_mr *ibmr,u32 check_mask,struct ib_mr_status *mr_status); struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
drivers/infiniband/hw/mlx5/mr.c +120 -40
240 lines not on this page · raw message
drivers/infiniband/hw/mlx5/odp.c +3 -5
@@ -420,8 +420,7 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,return ERR_CAST (odp);BUILD_BUG_ON (order >MKEY_CACHE_LAST_STD_ENTRY ); - mr =mlx5_mr_cache_alloc (dev, &dev->cache.ent[order], - imr->access_flags); + mr =mlx5_mr_cache_alloc_order (dev, order, imr->access_flags);if (IS_ERR (mr)) {ib_umem_odp_release (odp);return mr;
@@ -495,9 +494,8 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,if (IS_ERR (umem_odp))return ERR_CAST (umem_odp); - imr =mlx5_mr_cache_alloc (dev, - &dev->cache.ent[MLX5_IMR_KSM_CACHE_ENTRY ], - access_flags); + imr =mlx5_mr_cache_alloc_order (dev,MLX5_IMR_KSM_CACHE_ENTRY , + access_flags);if (IS_ERR (imr)) {ib_umem_odp_release (umem_odp);return imr;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 100/176 RDMA/mlx5: Introduce mlx5r_cache_rb_key
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit 73d09b2fe8336f5f37935e46418666ddbcd3c343 ]
Switch from using the mkey order to using the new struct as the key to the RB tree of cache entries.
The key is all the mkey properties that UMR operations can't modify. Using this key to define the cache entries and to search and create cache mkeys.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 27 ++-- drivers/infiniband/hw/mlx5/mr.c | 228 +++++++++++++++++++-------- drivers/infiniband/hw/mlx5/odp.c | 30 ++-- 3 files changed, 201 insertions(+), 84 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +17 -10
@@ -637,6 +637,13 @@ enum mlx5_mkey_type { MLX5_MKEY_INDIRECT_DEVX, }; +struct mlx5r_cache_rb_key { +u8 ats:1 ; +unsigned int access_mode; +unsigned int access_flags; +unsigned int ndescs; +}; +struct mlx5_ib_mkey {u32 key;enum mlx5_mkey_type type;
@@ -757,11 +764,9 @@ struct mlx5_cache_ent {unsigned long reserved;char name[4 ]; -u32 order; -u32 access_mode; -unsigned int ndescs;struct rb_node node; +struct mlx5r_cache_rb_key rb_key; u8 disabled:1; u8 fill_to_high_water:1;
@@ -1340,14 +1345,13 @@ int mlx5_ib_get_cqe_size(struct ib_cq *ibcq);int mlx5_mkey_cache_init (struct mlx5_ib_dev *dev);int mlx5_mkey_cache_cleanup (struct mlx5_ib_dev *dev);struct mlx5_cache_ent *mlx5r_cache_create_ent (struct mlx5_ib_dev *dev, -int order); +struct mlx5r_cache_rb_key rb_key, +bool persistent_entry);struct mlx5_ib_mr *mlx5_mr_cache_alloc (struct mlx5_ib_dev *dev, -struct mlx5_cache_ent *ent, -int access_flags); +int access_flags,int access_mode, +int ndescs); -struct mlx5_ib_mr *mlx5_mr_cache_alloc_order (struct mlx5_ib_dev *dev,u32 order, -int access_flags);int mlx5_ib_check_mr_status (struct ib_mr *ibmr,u32 check_mask,struct ib_mr_status *mr_status); struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
@@ -1370,7 +1374,7 @@ int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq);void mlx5_ib_odp_cleanup_one (struct mlx5_ib_dev *ibdev);int __init mlx5_ib_odp_init (void );void mlx5_ib_odp_cleanup (void ); -void mlx5_odp_init_mkey_cache_entry (struct mlx5_cache_ent *ent); +int mlx5_odp_init_mkey_cache (struct mlx5_ib_dev *dev);void mlx5_odp_populate_xlt (void *xlt,size_t idx,size_t nentries,struct mlx5_ib_mr *mr,int flags);
@@ -1389,7 +1393,10 @@ static inline int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev,static inline void mlx5_ib_odp_cleanup_one (struct mlx5_ib_dev *ibdev) {}static inline int mlx5_ib_odp_init (void ) {return 0 ; }static inline void mlx5_ib_odp_cleanup (void ) {} -static inline void mlx5_odp_init_mkey_cache_entry (struct mlx5_cache_ent *ent) {} +static inline int mlx5_odp_init_mkey_cache (struct mlx5_ib_dev *dev) +{ +return 0 ; +}static inline void mlx5_odp_populate_xlt (void *xlt,size_t idx,size_t nentries,struct mlx5_ib_mr *mr,int flags) {}
drivers/infiniband/hw/mlx5/mr.c +164 -64
382 lines not on this page · raw message
drivers/infiniband/hw/mlx5/odp.c +20 -10
@@ -406,7 +406,6 @@ static void mlx5_ib_page_fault_resume(struct mlx5_ib_dev *dev,static struct mlx5_ib_mr *implicit_get_child_mr (struct mlx5_ib_mr *imr,unsigned long idx) { -int order =order_base_2 (MLX5_IMR_MTT_ENTRIES );struct mlx5_ib_dev *dev =mr_to_mdev (imr);struct ib_umem_odp *odp;struct mlx5_ib_mr *mr;
@@ -419,8 +418,9 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,if (IS_ERR (odp))return ERR_CAST (odp); -BUILD_BUG_ON (order >MKEY_CACHE_LAST_STD_ENTRY ); - mr =mlx5_mr_cache_alloc_order (dev, order, imr->access_flags); + mr =mlx5_mr_cache_alloc (dev, imr->access_flags, +MLX5_MKC_ACCESS_MODE_MTT , +MLX5_IMR_MTT_ENTRIES );if (IS_ERR (mr)) {ib_umem_odp_release (odp);return mr;
@@ -494,8 +494,8 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,if (IS_ERR (umem_odp))return ERR_CAST (umem_odp); - imr =mlx5_mr_cache_alloc_order (dev,MLX5_IMR_KSM_CACHE_ENTRY , - access_flags); + imr =mlx5_mr_cache_alloc (dev, access_flags,MLX5_MKC_ACCESS_MODE_KSM , + mlx5_imr_ksm_entries);if (IS_ERR (imr)) {ib_umem_odp_release (umem_odp);return imr;
@@ -1591,12 +1591,22 @@ mlx5_ib_odp_destroy_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq)return err; } -void mlx5_odp_init_mkey_cache_entry (struct mlx5_cache_ent *ent) +int mlx5_odp_init_mkey_cache (struct mlx5_ib_dev *dev) { -if (!(ent->dev->odp_caps.general_caps &IB_ODP_SUPPORT_IMPLICIT )) -return ; - ent->ndescs = mlx5_imr_ksm_entries; - ent->access_mode =MLX5_MKC_ACCESS_MODE_KSM ; +struct mlx5r_cache_rb_key rb_key = { + .access_mode =MLX5_MKC_ACCESS_MODE_KSM , + .ndescs = mlx5_imr_ksm_entries, + }; +struct mlx5_cache_ent *ent; + +if (!(dev->odp_caps.general_caps &IB_ODP_SUPPORT_IMPLICIT )) +return 0 ; + + ent =mlx5r_cache_create_ent (dev, rb_key, true); +if (IS_ERR (ent)) +return PTR_ERR (ent); + +return 0 ; }static const struct ib_device_ops mlx5_ib_dev_odp_ops = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 101/176 RDMA/mlx5: Cache all user cacheable mkeys on dereg MR flow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit dd1b913fb0d0e3e6d55e92d2319d954474dd66ac ]
Currently, when dereging an MR, if the mkey doesn't belong to a cache entry, it will be destroyed. As a result, the restart of applications with many non-cached mkeys is not efficient since all the mkeys are destroyed and then recreated. This process takes a long time (for 100,000 MRs, it is ~20 seconds for dereg and ~28 seconds for re-reg).
To shorten the restart runtime, insert all cacheable mkeys to the cache. If there is no fitting entry to the mkey properties, create a temporary entry that fits it.
After a predetermined timeout, the cache entries will shrink to the initial high limit.
The mkeys will still be in the cache when consuming them again after an application restart. Therefore, the registration will be much faster (for 100,000 MRs, it is ~4 seconds for dereg and ~5 seconds for re-reg).
The temporary cache entries created to store the non-cache mkeys are not exposed through sysfs like the default cache entries.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 + drivers/infiniband/hw/mlx5/mr.c | 55 +++++++++++++++++++++------- 2 files changed, 44 insertions(+), 13 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +2 -0
@@ -650,6 +650,8 @@ struct mlx5_ib_mkey {unsigned int ndescs;struct wait_queue_head wait;refcount_t usecount; +/* User Mkey must hold either a rb_key or a cache_ent. */ +struct mlx5r_cache_rb_key rb_key;struct mlx5_cache_ent *cache_ent; };
drivers/infiniband/hw/mlx5/mr.c +42 -13
85 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 102/176 RDMA/mlx5: Add work to remove temporary entries from the cache
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit 627122280c878cf5d3cda2d2c5a0a8f6a7e35cb7 ]
The non-cache mkeys are stored in the cache only to shorten restarting application time. Don't store them longer than needed.
Configure cache entries that store non-cache MRs as temporary entries. If 30 seconds have passed and no user reclaimed the temporarily cached mkeys, an asynchronous work will destroy the mkeys entries.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 9 ++- drivers/infiniband/hw/mlx5/mr.c | 94 ++++++++++++++++++++++------ drivers/infiniband/hw/mlx5/odp.c | 2 +- 3 files changed, 82 insertions(+), 23 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +6 -3
@@ -770,6 +770,7 @@ struct mlx5_cache_ent {struct rb_node node;struct mlx5r_cache_rb_key rb_key; + u8 is_tmp:1; u8 disabled:1; u8 fill_to_high_water:1;
@@ -803,6 +804,7 @@ struct mlx5_mkey_cache {struct mutex rb_lock;struct dentry *fs_root;unsigned long last_add; +struct delayed_work remove_ent_dwork; };struct mlx5_ib_port_resources {
@@ -1346,9 +1348,10 @@ void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num);int mlx5_ib_get_cqe_size (struct ib_cq *ibcq);int mlx5_mkey_cache_init (struct mlx5_ib_dev *dev);int mlx5_mkey_cache_cleanup (struct mlx5_ib_dev *dev); -struct mlx5_cache_ent *mlx5r_cache_create_ent (struct mlx5_ib_dev *dev, -struct mlx5r_cache_rb_key rb_key, -bool persistent_entry); +struct mlx5_cache_ent * +mlx5r_cache_create_ent_locked (struct mlx5_ib_dev *dev, +struct mlx5r_cache_rb_key rb_key, +bool persistent_entry); struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev, int access_flags, int access_mode,
drivers/infiniband/hw/mlx5/mr.c +75 -19
219 lines not on this page · raw message
drivers/infiniband/hw/mlx5/odp.c +1 -1
@@ -1602,7 +1602,7 @@ int mlx5_odp_init_mkey_cache(struct mlx5_ib_dev *dev)if (!(dev->odp_caps.general_caps &IB_ODP_SUPPORT_IMPLICIT ))return 0 ; - ent =mlx5r_cache_create_ent (dev, rb_key, true); + ent =mlx5r_cache_create_ent_locked (dev, rb_key, true);if (IS_ERR (ent))return PTR_ERR (ent);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 103/176 RDMA/mlx5: Implement mkeys management via LIFO queue
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit 57e7071683ef6148c9f5ea0ba84598d2ba681375 ]
Currently, mkeys are managed via xarray. This implementation leads to a degradation in cases many MRs are unregistered in parallel, due to xarray internal implementation, for example: deregistration 1M MRs via 64 threads is taking ~15% more time[1].
Hence, implement mkeys management via LIFO queue, which solved the degradation.
[1]
2.8us in kernel v5.19 compare to 3.2us in kernel v6.4
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 21 +- drivers/infiniband/hw/mlx5/mr.c | 324 ++++++++++++--------------- drivers/infiniband/hw/mlx5/umr.c | 4 +- 3 files changed, 169 insertions(+), 180 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +18 -3
@@ -760,10 +760,25 @@ struct umr_common {unsigned int state; }; +#define NUM_MKEYS_PER_PAGE \ + ((PAGE_SIZE - sizeof(struct list_head)) / sizeof(u32)) + +struct mlx5_mkeys_page { +u32 mkeys[NUM_MKEYS_PER_PAGE ]; +struct list_head list; +}; +static_assert (sizeof (struct mlx5_mkeys_page ) ==PAGE_SIZE ); + +struct mlx5_mkeys_queue { +struct list_head pages_list; +u32 num_pages; +unsigned long ci; +spinlock_t lock;/* sync list ops */ +}; +struct mlx5_cache_ent { -struct xarray mkeys; -unsigned long stored; -unsigned long reserved; +struct mlx5_mkeys_queue mkeys_queue; +u32 pending;char name[4 ];
drivers/infiniband/hw/mlx5/mr.c +149 -175
589 lines not on this page · raw message
drivers/infiniband/hw/mlx5/umr.c +2 -2
@@ -332,8 +332,8 @@ static int mlx5r_umr_post_send_wait(struct mlx5_ib_dev *dev, u32 mkey,WARN_ON_ONCE (1 );mlx5_ib_warn (dev, -"reg umr failed (%u). Trying to recover and resubmit the flushed WQEs\n" , - umr_context.status); +"reg umr failed (%u). Trying to recover and resubmit the flushed WQEs, mkey = %u\n" , + umr_context.status, mkey);mutex_lock (&umrc->lock); err =mlx5r_umr_recover (dev);mutex_unlock (&umrc->lock);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 104/176 RDMA/mlx5: Fix the recovery flow of the UMR QP
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <[email protected]>
[ Upstream commit d97505baea64d93538b16baf14ce7b8c1fbad746 ]
This patch addresses an issue in the recovery flow of the UMR QP, ensuring tasks do not get stuck, as highlighted by the call trace [1].
During recovery, before transitioning the QP to the RESET state, the software must wait for all outstanding WRs to complete.
Failing to do so can cause the firmware to skip sending some flushed CQEs with errors and simply discard them upon the RESET, as per the IB specification.
This race condition can result in lost CQEs and tasks becoming stuck.
To resolve this, the patch sends a final WR which serves only as a barrier before moving the QP state to RESET.
Once a CQE is received for that final WR, it guarantees that no outstanding WRs remain, making it safe to transition the QP to RESET and subsequently back to RTS, restoring proper functionality.
Note:
For the barrier WR, we simply reuse the failed and ready WR. Since the QP is in an error state, it will only receive IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier we don't care about its status.
[1]
INFO: task rdma_resource_l:1922 blocked for more than 120 seconds.
Tainted: G W 6.12.0-rc7+ #1626
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:rdma_resource_l state:D stack:0 pid:1922 tgid:1922 ppid:1369
flags:0x00004004
Call Trace:
<TASK>
__schedule+0x420/0xd30
schedule+0x47/0x130
schedule_timeout+0x280/0x300
? mark_held_locks+0x48/0x80
? lockdep_hardirqs_on_prepare+0xe5/0x1a0
wait_for_completion+0x75/0x130
mlx5r_umr_post_send_wait+0x3c2/0x5b0 [mlx5_ib]
? __pfx_mlx5r_umr_done+0x10/0x10 [mlx5_ib]
mlx5r_umr_revoke_mr+0x93/0xc0 [mlx5_ib]
__mlx5_ib_dereg_mr+0x299/0x520 [mlx5_ib]
? _raw_spin_unlock_irq+0x24/0x40
? wait_for_completion+0xfe/0x130
? rdma_restrack_put+0x63/0xe0 [ib_core]
ib_dereg_mr_user+0x5f/0x120 [ib_core]
? lock_release+0xc6/0x280
destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
uobj_destroy+0x3f/0x70 [ib_uverbs]
ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
? __lock_acquire+0x64e/0x2080
? mark_held_locks+0x48/0x80
? find_held_lock+0x2d/0xa0
? lock_acquire+0xc1/0x2f0
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
? __fget_files+0xc3/0x1b0
ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
__x64_sys_ioctl+0x1b0/0xa70
do_syscall_64+0x6b/0x140
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f99c918b17b
RSP: 002b:00007ffc766d0468 EFLAGS: 00000246 ORIG_RAX:
0000000000000010
RAX: ffffffffffffffda RBX: 00007ffc766d0578 RCX:
00007f99c918b17b
RDX: 00007ffc766d0560 RSI: 00000000c0181b01 RDI:
0000000000000003
RBP: 00007ffc766d0540 R08: 00007f99c8f99010 R09:
000000000000bd7e
R10: 00007f99c94c1c70 R11: 0000000000000246 R12:
00007ffc766d0530
R13: 000000000000001c R14: 0000000040246a80 R15:
0000000000000000
</TASK>--- drivers/infiniband/hw/mlx5/umr.c | 83 +++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 27 deletions(-)
drivers/infiniband/hw/mlx5/umr.c +56 -27
@@ -199,30 +199,6 @@ void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev)ib_dealloc_pd (dev->umrc.pd); } -static int mlx5r_umr_recover (struct mlx5_ib_dev *dev) -{ -struct umr_common *umrc = &dev->umrc; -struct ib_qp_attr attr; -int err; - - attr.qp_state =IB_QPS_RESET ; - err =ib_modify_qp (umrc->qp, &attr,IB_QP_STATE ); -if (err) { -mlx5_ib_dbg (dev,"Couldn't modify UMR QP\n" ); - goto err; - } - - err =mlx5r_umr_qp_rst2rts (dev, umrc->qp); -if (err) - goto err; - - umrc->state =MLX5_UMR_STATE_ACTIVE ; -return 0 ; - -err: - umrc->state =MLX5_UMR_STATE_ERR ; -return err; -}static int mlx5r_umr_post_send (struct ib_qp *ibqp,u32 mkey,struct ib_cqe *cqe,struct mlx5r_umr_wqe *wqe,bool with_data)
@@ -270,6 +246,61 @@ static int mlx5r_umr_post_send(struct ib_qp *ibqp, u32 mkey, struct ib_cqe *cqe,return err; } +static int mlx5r_umr_recover (struct mlx5_ib_dev *dev,u32 mkey, +struct mlx5r_umr_context *umr_context, +struct mlx5r_umr_wqe *wqe,bool with_data) +{ +struct umr_common *umrc = &dev->umrc; +struct ib_qp_attr attr; +int err; + +mutex_lock (&umrc->lock); +/* Preventing any further WRs to be sent now */ +if (umrc->state !=MLX5_UMR_STATE_RECOVER ) { +mlx5_ib_warn (dev,"UMR recovery encountered an unexpected state=%d\n" , + umrc->state); + umrc->state =MLX5_UMR_STATE_RECOVER ; + } +mutex_unlock (&umrc->lock); + +/* Sending a final/barrier WR (the failed one) and wait for its completion. +* This will ensure that all the previous WRs got a completion before +* we set the QP state to RESET. +*/ + err =mlx5r_umr_post_send (umrc->qp, mkey, &umr_context->cqe, wqe, + with_data); +if (err) { +mlx5_ib_warn (dev,"UMR recovery post send failed, err %d\n" , err); + goto err; + } + +/* Since the QP is in an error state, it will only receive +* IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier +* we don't care about its status. +*/ +wait_for_completion (&umr_context->done); + + attr.qp_state =IB_QPS_RESET ; + err =ib_modify_qp (umrc->qp, &attr,IB_QP_STATE ); +if (err) { +mlx5_ib_warn (dev,"Couldn't modify UMR QP to RESET, err=%d\n" , err); + goto err; + } + + err =mlx5r_umr_qp_rst2rts (dev, umrc->qp); +if (err) { +mlx5_ib_warn (dev,"Couldn't modify UMR QP to RTS, err=%d\n" , err); + goto err; + } + + umrc->state =MLX5_UMR_STATE_ACTIVE ; +return 0 ; + +err: + umrc->state =MLX5_UMR_STATE_ERR ; +return err; +} +static void mlx5r_umr_done (struct ib_cq *cq,struct ib_wc *wc) { struct mlx5_ib_umr_context *context =
@@ -334,9 +365,7 @@ static int mlx5r_umr_post_send_wait(struct mlx5_ib_dev *dev, u32 mkey,mlx5_ib_warn (dev,"reg umr failed (%u). Trying to recover and resubmit the flushed WQEs, mkey = %u\n" , umr_context.status, mkey); -mutex_lock (&umrc->lock); - err =mlx5r_umr_recover (dev); -mutex_unlock (&umrc->lock); + err =mlx5r_umr_recover (dev, mkey, &umr_context, wqe, with_data);if (err)mlx5_ib_warn (dev,"couldn't recover UMR, err %d\n" , err);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 105/176 IB/mlx5: Set and get correct qp_num for a DCT QP
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Zhang <[email protected]>
[ Upstream commit 12d044770e12c4205fa69535b4fa8a9981fea98f ]
When a DCT QP is created on an active lag, it's dctc.port is assigned in a round-robin way, which is from 1 to dev->lag_port. In this case when querying this QP, we may get qp_attr.port_num > 2.
Fix this by setting qp->port when modifying a DCT QP, and read port_num from qp->port instead of dctc.port when querying it.
--- drivers/infiniband/hw/mlx5/qp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/qp.c +3 -1
@@ -4466,6 +4466,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, set_id =mlx5_ib_get_counters_id (dev, attr->port_num -1 );MLX5_SET (dctc, dctc, counter_set_id, set_id); + + qp->port = attr->port_num; }else if (cur_state ==IB_QPS_INIT && new_state ==IB_QPS_RTR ) {struct mlx5_ib_modify_qp_resp resp = {};u32 out[MLX5_ST_SZ_DW (create_dct_out)] = {};
@@ -4955,7 +4957,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp, }if (qp_attr_mask &IB_QP_PORT ) - qp_attr->port_num =MLX5_GET (dctc, dctc, port); + qp_attr->port_num = mqp->port;if (qp_attr_mask &IB_QP_MIN_RNR_TIMER ) qp_attr->min_rnr_timer =MLX5_GET (dctc, dctc, min_rnr_nak);if (qp_attr_mask &IB_QP_AV ) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 106/176 ovl: fix UAF in ovl_dentry_update_reval by moving dput() in ovl_link_up
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasiliy Kovalev <[email protected]>
[ Upstream commit c84e125fff2615b4d9c259e762596134eddd2f27 ]
The issue was caused by dput(upper) being called before ovl_dentry_update_reval(), while upper->d_flags was still accessed in ovl_dentry_remote().
Move dput(upper) after its last use to prevent use-after-free.
BUG: KASAN: slab-use-after-free in ovl_dentry_remote fs/overlayfs/util.c:162 [inline] BUG: KASAN: slab-use-after-free in ovl_dentry_update_reval+0xd2/0xf0 fs/overlayfs/util.c:167 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:114 print_address_description mm/kasan/report.c:377 [inline] print_report+0xc3/0x620 mm/kasan/report.c:488 kasan_report+0xd9/0x110 mm/kasan/report.c:601 ovl_dentry_remote fs/overlayfs/util.c:162 [inline] ovl_dentry_update_reval+0xd2/0xf0 fs/overlayfs/util.c:167 ovl_link_up fs/overlayfs/copy_up.c:610 [inline] ovl_copy_up_one+0x2105/0x3490 fs/overlayfs/copy_up.c:1170 ovl_copy_up_flags+0x18d/0x200 fs/overlayfs/copy_up.c:1223 ovl_rename+0x39e/0x18c0 fs/overlayfs/dir.c:1136 vfs_rename+0xf84/0x20a0 fs/namei.c:4893 ... </TASK>
--- fs/overlayfs/copy_up.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/overlayfs/copy_up.c +1 -1
@@ -532,7 +532,6 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) err =PTR_ERR (upper);if (!IS_ERR (upper)) { err =ovl_do_link (ofs,ovl_dentry_upper (c->dentry), udir, upper); -dput (upper);if (!err) {/* Restore timestamps on parent (best effort) */
@@ -540,6 +539,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)ovl_dentry_set_upper_alias (c->dentry);ovl_dentry_update_reval (c->dentry, upper); } +dput (upper); }inode_unlock (udir);if (err)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 107/176 SUNRPC: convert RPC_TASK_* constants to enum
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Brennan <[email protected]>
[ Upstream commit 0b108e83795c9c23101f584ef7e3ab4f1f120ef0 ]
The RPC_TASK_* constants are defined as macros, which means that most kernel builds will not contain their definitions in the debuginfo. However, it's quite useful for debuggers to be able to view the task state constant and interpret it correctly. Conversion to an enum will ensure the constants are present in debuginfo and can be interpreted by debuggers without needing to hard-code them and track their changes.
Stable-dep-of: 5bbd6e863b15 ("SUNRPC: Prevent looping due to rpc_signal_task() races")
--- include/linux/sunrpc/sched.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
include/linux/sunrpc/sched.h +9 -7
@@ -140,13 +140,15 @@ struct rpc_task_setup {#define RPC_WAS_SENT (t) ((t)->tk_flags & RPC_TASK_SENT)#define RPC_IS_MOVEABLE (t) ((t)->tk_flags & RPC_TASK_MOVEABLE) -#define RPC_TASK_RUNNING 0 -#define RPC_TASK_QUEUED 1 -#define RPC_TASK_ACTIVE 2 -#define RPC_TASK_NEED_XMIT 3 -#define RPC_TASK_NEED_RECV 4 -#define RPC_TASK_MSG_PIN_WAIT 5 -#define RPC_TASK_SIGNALLED 6 +enum { +RPC_TASK_RUNNING , +RPC_TASK_QUEUED , +RPC_TASK_ACTIVE , +RPC_TASK_NEED_XMIT , +RPC_TASK_NEED_RECV , +RPC_TASK_MSG_PIN_WAIT , +RPC_TASK_SIGNALLED , +};#define rpc_test_and_set_running (t) \ test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 108/176 SUNRPC: Prevent looping due to rpc_signal_task() races
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 5bbd6e863b15a85221e49b9bdb2d5d8f0bb91f3d ]
If rpc_signal_task() is called while a task is in an rpc_call_done() callback function, and the latter calls rpc_restart_call(), the task can end up looping due to the RPC_TASK_SIGNALLED flag being set without the tk_rpc_status being set.
Removing the redundant mechanism for signalling the task fixes the looping behaviour.
--- include/linux/sunrpc/sched.h | 3 +-- include/trace/events/sunrpc.h | 3 +-- net/sunrpc/sched.c | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-)
include/linux/sunrpc/sched.h +1 -2
@@ -147,7 +147,6 @@ enum {RPC_TASK_NEED_XMIT ,RPC_TASK_NEED_RECV , RPC_TASK_MSG_PIN_WAIT, - RPC_TASK_SIGNALLED, };#define rpc_test_and_set_running (t) \
@@ -160,7 +159,7 @@ enum {#define RPC_IS_ACTIVATED (t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate) -#define RPC_SIGNALLED (t) test_bit(RPC_TASK_SIGNALLED, &(t)->tk_runstate) +#define RPC_SIGNALLED (t) (READ_ONCE(task->tk_rpc_status) == -ERESTARTSYS)/* * Task priorities.
include/trace/events/sunrpc.h +1 -2
@@ -328,8 +328,7 @@ TRACE_EVENT(rpc_request, { (1UL << RPC_TASK_ACTIVE), "ACTIVE" }, \ { (1UL << RPC_TASK_NEED_XMIT), "NEED_XMIT" }, \ { (1UL << RPC_TASK_NEED_RECV), "NEED_RECV" }, \ - { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }, \ - { (1UL << RPC_TASK_SIGNALLED), "SIGNALLED" }) + { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }) DECLARE_EVENT_CLASS(rpc_task_running,
net/sunrpc/sched.c +0 -2
@@ -864,8 +864,6 @@ void rpc_signal_task(struct rpc_task *task)if (!rpc_task_set_rpc_status (task, -ERESTARTSYS ))return ;trace_rpc_task_signalled (task, task->tk_action); -set_bit (RPC_TASK_SIGNALLED , &task->tk_runstate); -smp_mb__after_atomic (); queue =READ_ONCE (task->tk_waitqueue);if (queue)rpc_wake_up_queued_task (queue, task);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 109/176 RDMA/mlx: Calling qp event handler in workqueue context
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Zhang <[email protected]>
[ Upstream commit 312b8f79eb05479628ee71357749815b2eeeeea8 ]
Move the call of qp event handler from atomic to workqueue context, so that the handler is able to block. This is needed by following patches.
Stable-dep-of: c534ffda781f ("RDMA/mlx5: Fix AH static rate parsing")
--- drivers/infiniband/hw/mlx4/main.c | 8 ++ drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 + drivers/infiniband/hw/mlx4/qp.c | 121 +++++++++++++++++------- drivers/infiniband/hw/mlx5/main.c | 7 ++ drivers/infiniband/hw/mlx5/qp.c | 119 ++++++++++++++++------- drivers/infiniband/hw/mlx5/qp.h | 2 + drivers/infiniband/hw/mlx5/qpc.c | 3 +- drivers/net/ethernet/mellanox/mlx4/qp.c | 14 ++- include/linux/mlx4/qp.h | 1 + include/rdma/ib_verbs.h | 2 +- 10 files changed, 202 insertions(+), 78 deletions(-)
drivers/infiniband/hw/mlx4/main.c +8 -0
@@ -3307,6 +3307,10 @@ static int __init mlx4_ib_init(void)if (!wq)return -ENOMEM ; + err =mlx4_ib_qp_event_init (); +if (err) + goto clean_qp_event; + err =mlx4_ib_cm_init ();if (err) goto clean_wq;
@@ -3328,6 +3332,9 @@ static int __init mlx4_ib_init(void)mlx4_ib_cm_destroy (); clean_wq: +mlx4_ib_qp_event_cleanup (); + +clean_qp_event:destroy_workqueue (wq);return err; }
@@ -3337,6 +3344,7 @@ static void __exit mlx4_ib_cleanup(void)mlx4_unregister_interface (&mlx4_ib_interface);mlx4_ib_mcg_destroy ();mlx4_ib_cm_destroy (); +mlx4_ib_qp_event_cleanup ();destroy_workqueue (wq); }
drivers/infiniband/hw/mlx4/mlx4_ib.h +3 -0
@@ -940,4 +940,7 @@ int mlx4_ib_umem_calc_optimal_mtt_size(struct ib_umem *umem, u64 start_va,int mlx4_ib_cm_init (void );void mlx4_ib_cm_destroy (void ); +int mlx4_ib_qp_event_init (void ); +void mlx4_ib_qp_event_cleanup (void ); +#endif /* MLX4_IB_H */
drivers/infiniband/hw/mlx4/qp.c +85 -36
144 lines not on this page · raw message
drivers/infiniband/hw/mlx5/main.c +7 -0
@@ -4410,6 +4410,10 @@ static int __init mlx5_ib_init(void)return -ENOMEM ; } + ret =mlx5_ib_qp_event_init (); +if (ret) + goto qp_event_err; +mlx5_ib_odp_init (); ret =mlx5r_rep_init ();if (ret)
@@ -4427,6 +4431,8 @@ static int __init mlx5_ib_init(void) mp_err:mlx5r_rep_cleanup (); rep_err: +mlx5_ib_qp_event_cleanup (); +qp_event_err:destroy_workqueue (mlx5_ib_event_wq);free_page ((unsigned long )xlt_emergency_page);return ret;
@@ -4438,6 +4444,7 @@ static void __exit mlx5_ib_cleanup(void)auxiliary_driver_unregister (&mlx5r_mp_driver);mlx5r_rep_cleanup (); +mlx5_ib_qp_event_cleanup ();destroy_workqueue (mlx5_ib_event_wq);free_page ((unsigned long )xlt_emergency_page); }
drivers/infiniband/hw/mlx5/qp.c +84 -35
144 lines not on this page · raw message
drivers/infiniband/hw/mlx5/qp.h +2 -0
@@ -44,4 +44,6 @@ void mlx5_core_res_put(struct mlx5_core_rsc_common *res);int mlx5_core_xrcd_alloc (struct mlx5_ib_dev *dev,u32 *xrcdn);int mlx5_core_xrcd_dealloc (struct mlx5_ib_dev *dev,u32 xrcdn);int mlx5_ib_qp_set_counter (struct ib_qp *qp,struct rdma_counter *counter); +int mlx5_ib_qp_event_init (void ); +void mlx5_ib_qp_event_cleanup (void );#endif /* _MLX5_IB_QP_H */
drivers/infiniband/hw/mlx5/qpc.c +2 -1
@@ -135,7 +135,8 @@ static int rsc_event_notifier(struct notifier_block *nb,case MLX5_RES_SQ : qp = (struct mlx5_core_qp *)common; qp->event (qp, event_type); -break ; +/* Need to put resource in event handler */ +return NOTIFY_OK ;case MLX5_RES_DCT : dct = (struct mlx5_core_dct *)common;if (event_type ==MLX5_EVENT_TYPE_DCT_DRAINED )
drivers/net/ethernet/mellanox/mlx4/qp.c +9 -5
@@ -46,6 +46,13 @@#define MLX4_BF_QP_SKIP_MASK 0xc0#define MLX4_MAX_BF_QP_RANGE 0x40 +void mlx4_put_qp (struct mlx4_qp *qp) +{ +if (refcount_dec_and_test (&qp->refcount)) +complete (&qp->free); +} +EXPORT_SYMBOL_GPL (mlx4_put_qp); +void mlx4_qp_event (struct mlx4_dev *dev,u32 qpn,int event_type) {struct mlx4_qp_table *qp_table = &mlx4_priv (dev)->qp_table;
@@ -64,10 +71,8 @@ void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type)return ; } +/* Need to call mlx4_put_qp() in event handler */ qp->event (qp, event_type); - -if (refcount_dec_and_test (&qp->refcount)) -complete (&qp->free); }/* used for INIT/CLOSE port logic */
@@ -523,8 +528,7 @@ EXPORT_SYMBOL_GPL(mlx4_qp_remove);void mlx4_qp_free (struct mlx4_dev *dev,struct mlx4_qp *qp) { -if (refcount_dec_and_test (&qp->refcount)) -complete (&qp->free); +mlx4_put_qp (qp);wait_for_completion (&qp->free);mlx4_qp_free_icm (dev, qp->qpn);
include/linux/mlx4/qp.h +1 -0
@@ -504,4 +504,5 @@ static inline u16 folded_qp(u32 q)u16 mlx4_qp_roce_entropy (struct mlx4_dev *dev,u32 qpn); +void mlx4_put_qp (struct mlx4_qp *qp);#endif /* MLX4_QP_H */
include/rdma/ib_verbs.h +1 -1
@@ -1162,7 +1162,7 @@ enum ib_qp_create_flags {*/ struct ib_qp_init_attr { -/* Consumer's event_handler callback must not block */ +/* This callback occurs in workqueue context */ void (*event_handler)(struct ib_event *,void *);void *qp_context;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 110/176 RDMA/mlx5: Reduce QP table exposure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit 2ecfd946169e7f56534db2a5f6935858be3005ba ]
driver.h is common header to whole mlx5 code base, but struct mlx5_qp_table is used in mlx5_ib driver only. So move that struct to be under sole responsibility of mlx5_ib.
Stable-dep-of: c534ffda781f ("RDMA/mlx5: Fix AH static rate parsing")
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + drivers/infiniband/hw/mlx5/qp.h | 11 ++++++++++- include/linux/mlx5/driver.h | 9 --------- 3 files changed, 11 insertions(+), 10 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -0
@@ -25,6 +25,7 @@#include <rdma/mlx5_user_ioctl_verbs.h> #include "srq.h" +#include "qp.h" #define mlx5_ib_dbg(_dev, format, arg...) \ dev_dbg(&(_dev)->ib_dev.dev, "%s:%d:(pid %d): " format, __func__, \
drivers/infiniband/hw/mlx5/qp.h +10 -1
@@ -6,7 +6,16 @@#ifndef _MLX5_IB_QP_H#define _MLX5_IB_QP_H -#include "mlx5_ib.h" +struct mlx5_ib_dev ; + +struct mlx5_qp_table { +struct notifier_block nb; + +/* protect radix tree +*/ +spinlock_t lock; +struct radix_tree_root tree; +};int mlx5_init_qp_table (struct mlx5_ib_dev *dev);void mlx5_cleanup_qp_table (struct mlx5_ib_dev *dev);
include/linux/mlx5/driver.h +0 -9
@@ -440,15 +440,6 @@ struct mlx5_core_health {struct delayed_work update_fw_log_ts_work; }; -struct mlx5_qp_table { -struct notifier_block nb; - -/* protect radix tree -*/ -spinlock_t lock; -struct radix_tree_root tree; -}; -enum {MLX5_PF_NOTIFY_DISABLE_VF ,MLX5_PF_NOTIFY_ENABLE_VF ,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 111/176 IB/core: Add support for XDR link speed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Or Har-Toov <[email protected]>
[ Upstream commit 703289ce43f740b0096724300107df82d008552f ]
Add new IBTA speed XDR, the new rate that was added to Infiniband spec as part of XDR and supporting signaling rate of 200Gb.
In order to report that value to rdma-core, add new u32 field to query_port response.
Stable-dep-of: c534ffda781f ("RDMA/mlx5: Fix AH static rate parsing")
--- drivers/infiniband/core/sysfs.c | 4 ++++ drivers/infiniband/core/uverbs_std_types_device.c | 3 ++- drivers/infiniband/core/verbs.c | 3 +++ include/rdma/ib_verbs.h | 2 ++ include/uapi/rdma/ib_user_ioctl_verbs.h | 3 ++- 5 files changed, 13 insertions(+), 2 deletions(-)
drivers/infiniband/core/sysfs.c +4 -0
@@ -342,6 +342,10 @@ static ssize_t rate_show(struct ib_device *ibdev, u32 port_num, speed =" NDR" ; rate =1000 ;break ; +case IB_SPEED_XDR : + speed =" XDR" ; + rate =2000 ; +break ;case IB_SPEED_SDR :default :/* default to SDR for invalid rates */ speed =" SDR" ;
drivers/infiniband/core/uverbs_std_types_device.c +2 -1
@@ -203,6 +203,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)(copy_port_attr_to_resp (&attr, &resp.legacy_resp, ib_dev, port_num); resp.port_cap_flags2 = attr.port_cap_flags2; + resp.active_speed_ex = attr.active_speed;return uverbs_copy_to_struct_or_zero (attrs,UVERBS_ATTR_QUERY_PORT_RESP , &resp,sizeof (resp));
@@ -461,7 +462,7 @@ DECLARE_UVERBS_NAMED_METHOD(UVERBS_ATTR_PTR_OUT (UVERBS_ATTR_QUERY_PORT_RESP , UVERBS_ATTR_STRUCT(struct ib_uverbs_query_port_resp_ex, - reserved), + active_speed_ex), UA_MANDATORY)); DECLARE_UVERBS_NAMED_METHOD(
drivers/infiniband/core/verbs.c +3 -0
@@ -147,6 +147,7 @@ __attribute_const__ int ib_rate_to_mult(enum ib_rate rate)case IB_RATE_50_GBPS :return 20 ;case IB_RATE_400_GBPS :return 160 ;case IB_RATE_600_GBPS :return 240 ; +case IB_RATE_800_GBPS :return 320 ;default :return -1 ; } }
@@ -176,6 +177,7 @@ __attribute_const__ enum ib_rate mult_to_ib_rate(int mult)case 20 :return IB_RATE_50_GBPS ;case 160 :return IB_RATE_400_GBPS ;case 240 :return IB_RATE_600_GBPS ; +case 320 :return IB_RATE_800_GBPS ;default :return IB_RATE_PORT_CURRENT ; } }
@@ -205,6 +207,7 @@ __attribute_const__ int ib_rate_to_mbps(enum ib_rate rate)case IB_RATE_50_GBPS :return 53125 ;case IB_RATE_400_GBPS :return 425000 ;case IB_RATE_600_GBPS :return 637500 ; +case IB_RATE_800_GBPS :return 850000 ;default :return -1 ; } }
include/rdma/ib_verbs.h +2 -0
@@ -557,6 +557,7 @@ enum ib_port_speed {IB_SPEED_EDR =32 ,IB_SPEED_HDR =64 ,IB_SPEED_NDR =128 , + IB_SPEED_XDR = 256, }; enum ib_stat_flag {
@@ -836,6 +837,7 @@ enum ib_rate {IB_RATE_50_GBPS =20 ,IB_RATE_400_GBPS =21 ,IB_RATE_600_GBPS =22 , + IB_RATE_800_GBPS = 23, };/**
include/uapi/rdma/ib_user_ioctl_verbs.h +2 -1
@@ -218,7 +218,8 @@ enum ib_uverbs_advise_mr_flag {struct ib_uverbs_query_port_resp_ex {struct ib_uverbs_query_port_resp legacy_resp;__u16 port_cap_flags2; -__u8 reserved[6 ]; +__u8 reserved[2 ]; +__u32 active_speed_ex; };struct ib_uverbs_qp_cap {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 112/176 RDMA/mlx5: Fix AH static rate parsing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <[email protected]>
[ Upstream commit c534ffda781f44a1c6ac25ef6e0e444da38ca8af ]
Previously static rate wasn't translated according to our PRM but simply used the 4 lower bytes.
Correctly translate static rate value passed in AH creation attribute according to our PRM expected values.
In addition change 800GB mapping to zero, which is the PRM specified value.
--- drivers/infiniband/hw/mlx5/ah.c | 3 ++- drivers/infiniband/hw/mlx5/qp.c | 6 +++--- drivers/infiniband/hw/mlx5/qp.h | 1 + 3 files changed, 6 insertions(+), 4 deletions(-)
drivers/infiniband/hw/mlx5/ah.c +2 -1
@@ -67,7 +67,8 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah, ah->av.tclass = grh->traffic_class; } - ah->av.stat_rate_sl = (rdma_ah_get_static_rate (ah_attr) <<4 ); + ah->av.stat_rate_sl = + (mlx5r_ib_rate (dev,rdma_ah_get_static_rate (ah_attr)) <<4 );if (ah_attr->type ==RDMA_AH_ATTR_TYPE_ROCE ) {if (init_attr->xmit_slave)
drivers/infiniband/hw/mlx5/qp.c +3 -3
@@ -3379,11 +3379,11 @@ static int ib_to_mlx5_rate_map(u8 rate)return 0 ; } -static int ib_rate_to_mlx5 (struct mlx5_ib_dev *dev,u8 rate) +int mlx5r_ib_rate (struct mlx5_ib_dev *dev,u8 rate) {u32 stat_rate_support; -if (rate ==IB_RATE_PORT_CURRENT ) +if (rate ==IB_RATE_PORT_CURRENT || rate ==IB_RATE_800_GBPS )return 0 ;if (rate <IB_RATE_2_5_GBPS || rate >IB_RATE_600_GBPS )
@@ -3528,7 +3528,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, sizeof(grh->dgid.raw)); } - err =ib_rate_to_mlx5 (dev,rdma_ah_get_static_rate (ah)); + err =mlx5r_ib_rate (dev,rdma_ah_get_static_rate (ah));if (err <0 )return err;MLX5_SET (ads, path, stat_rate, err);
drivers/infiniband/hw/mlx5/qp.h +1 -0
@@ -55,4 +55,5 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);int mlx5_ib_qp_set_counter (struct ib_qp *qp,struct rdma_counter *counter);int mlx5_ib_qp_event_init (void );void mlx5_ib_qp_event_cleanup (void ); +int mlx5r_ib_rate (struct mlx5_ib_dev *dev,u8 rate);#endif /* _MLX5_IB_QP_H */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 113/176 scsi: core: Clear driver private data when retrying request
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit dce5c4afd035e8090a26e5d776b1682c0e649683 ]
After commit 1bad6c4a57ef ("scsi: zero per-cmd private driver data for each MQ I/O"), the xen-scsifront/virtio_scsi/snic drivers all removed code that explicitly zeroed driver-private command data.
In combination with commit 464a00c9e0ad ("scsi: core: Kill DRIVER_SENSE"), after virtio_scsi performs a capacity expansion, the first request will return a unit attention to indicate that the capacity has changed. And then the original command is retried. As driver-private command data was not cleared, the request would return UA again and eventually time out and fail.
Zero driver-private command data when a request is retried.
--- drivers/scsi/scsi_lib.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/scsi/scsi_lib.c +7 -7
@@ -1579,13 +1579,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req)if (in_flight)__set_bit (SCMD_STATE_INFLIGHT , &cmd->state); -/* -* Only clear the driver-private command data if the LLD does not supply -* a function to initialize that data. -*/ -if (!shost->hostt->init_cmd_priv) -memset (cmd +1 ,0 , shost->hostt->cmd_size); - cmd->prot_op =SCSI_PROT_NORMAL ;if (blk_rq_bytes (req)) cmd->sc_data_direction =rq_dma_dir (req);
@@ -1747,6 +1740,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,if (!scsi_host_queue_ready (q, shost, sdev, cmd)) goto out_dec_target_busy; +/* +* Only clear the driver-private command data if the LLD does not supply +* a function to initialize that data. +*/ +if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv) +memset (cmd +1 ,0 , shost->hostt->cmd_size); +if (!(req->rq_flags &RQF_DONTPREP )) { ret =scsi_prepare_cmd (req);if (ret !=BLK_STS_OK )
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 114/176 RDMA/mlx5: Fix bind QP error cleanup flow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <[email protected]>
[ Upstream commit e1a0bdbdfdf08428f0ede5ae49c7f4139ac73ef5 ]
When there is a failure during bind QP, the cleanup flow destroys the counter regardless if it is the one that created it or not, which is problematic since if it isn't the one that created it, that counter could still be in use.
Fix that by destroying the counter only if it was created during this call.
--- drivers/infiniband/hw/mlx5/counters.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/counters.c +6 -2
@@ -444,6 +444,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, struct ib_qp *qp) {struct mlx5_ib_dev *dev =to_mdev (qp->device); +bool new = false;int err;if (!counter->id) {
@@ -458,6 +459,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,return err; counter->id =MLX5_GET (alloc_q_counter_out, out, counter_set_id); + new = true; } err =mlx5_ib_qp_set_counter (qp, counter);
@@ -467,8 +469,10 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,return 0 ; fail_set_counter: -mlx5_ib_counter_dealloc (counter); - counter->id =0 ; +if (new) { +mlx5_ib_counter_dealloc (counter); + counter->id =0 ; + }return err; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 115/176 sunrpc: suppress warnings for unused procfs functions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit 1f7a4f98c11fbeb18ed21f3b3a497e90a50ad2e0 ]
There is a warning about unused variables when building with W=1 and no procfs:
net/sunrpc/cache.c:1660:30: error: 'cache_flush_proc_ops' defined but not used [-Werror=unused-const-variable=]
1660 | static const struct proc_ops cache_flush_proc_ops = {
| ^~~~~~~~~~~~~~~~~~~~
net/sunrpc/cache.c:1622:30: error: 'content_proc_ops' defined but not used [-Werror=unused-const-variable=]
1622 | static const struct proc_ops content_proc_ops = {
| ^~~~~~~~~~~~~~~~
net/sunrpc/cache.c:1598:30: error: 'cache_channel_proc_ops' defined but not used [-Werror=unused-const-variable=]
1598 | static const struct proc_ops cache_channel_proc_ops = {
| ^~~~~~~~~~~~~~~~~~~~~~These are used inside of an #ifdef, so replacing that with an IS_ENABLED() check lets the compiler see how they are used while still dropping them during dead code elimination.
--- net/sunrpc/cache.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
net/sunrpc/cache.c +3 -7
@@ -1675,12 +1675,14 @@ static void remove_cache_proc_entries(struct cache_detail *cd) } } -#ifdef CONFIG_PROC_FS static int create_cache_proc_entries (struct cache_detail *cd,struct net *net) {struct proc_dir_entry *p;struct sunrpc_net *sn; +if (!IS_ENABLED (CONFIG_PROC_FS )) +return 0 ; + sn =net_generic (net, sunrpc_net_id); cd->procfs =proc_mkdir (cd->name, sn->proc_net_rpc);if (cd->procfs ==NULL )
@@ -1708,12 +1710,6 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)remove_cache_proc_entries (cd);return -ENOMEM ; } -#else /* CONFIG_PROC_FS */ -static int create_cache_proc_entries (struct cache_detail *cd,struct net *net) -{ -return 0 ; -} -#endif void __init cache_initialize (void ) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 116/176 ALSA: usb-audio: Avoid dropping MIDI events at closing multiple ports
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit a3bdd8f5c2217e1cb35db02c2eed36ea20fb50f5 ]
We fixed the UAF issue in USB MIDI code by canceling the pending work at closing each MIDI output device in the commit below. However, this assumed that it's the only one that is tied with the endpoint, and it resulted in unexpected data truncations when multiple devices are assigned to a single endpoint and opened simultaneously.
For addressing the unexpected MIDI message drops, simply replace cancel_work_sync() with flush_work(). The drain callback should have been already invoked before the close callback, hence the port->active flag must be already cleared. So this just assures that the pending work is finished before freeing the resources.
--- sound/usb/midi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/midi.c +1 -1
@@ -1145,7 +1145,7 @@ static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) {struct usbmidi_out_port *port = substream->runtime->private_data; -cancel_work_sync (&port->ep->work); +flush_work (&port->ep->work);return substream_open (substream,0 ,0 ); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 117/176 Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit b25120e1d5f2ebb3db00af557709041f47f7f3d0 ]
L2CAP_ECRED_CONN_RSP needs to respond DCID in the same order received as SCID but the order is reversed due to use of list_add which actually prepend channels to the list so the response is reversed:
Quoted 1 line
ACL Data RX: Handle 16 flags
0x02dlen 26
LE L2CAP: Enhanced Credit Connection Request (0x17) ident 2 len 18
PSM: 39 (0x0027)
MTU: 256
MPS: 251
Credits: 65535
Source CID: 116
Source CID: 117
Source CID: 118
Source CID: 119
Source CID: 120< ACL Data TX: Handle 16 flags 0x00 dlen 26
LE L2CAP: Enhanced Credit Connection Response (0x18) ident 2 len 18
MTU: 517
MPS: 247
Credits: 3
Result: Connection successful (0x0000)
Destination CID: 68
Destination CID: 67
Destination CID: 66
Destination CID: 65
Destination CID: 64
Also make sure the response don't include channels that are not on BT_CONNECT2 since the chan->ident can be set to the same value as in the following trace:
< ACL Data TX: Handle 16 flags 0x00 dlen 12
LE L2CAP: LE Flow Control Credit (0x16) ident 6 len 4
Source CID: 64
Credits: 1
...
Quoted 1 line
ACL Data RX: Handle 16 flags
0x02dlen 18
LE L2CAP: Enhanced Credit Connection Request (0x17) ident 6 len 10
PSM: 39 (0x0027)
MTU: 517
MPS: 251
Credits: 255
Source CID: 70
< ACL Data TX: Handle 16 flags 0x00 dlen 20
LE L2CAP: Enhanced Credit Connection Response (0x18) ident 6 len 12
MTU: 517
MPS: 247
Credits: 3
Result: Connection successful (0x0000)
Destination CID: 64
Destination CID: 68--- net/bluetooth/l2cap_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/bluetooth/l2cap_core.c +7 -2
@@ -656,7 +656,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))hci_conn_hold (conn->hcon); -list_add (&chan->list, &conn->chan_l); +/* Append to the list since the order matters for ECRED */ +list_add_tail (&chan->list, &conn->chan_l); }void l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan)
@@ -3995,7 +3996,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) {struct l2cap_ecred_rsp_data *rsp = data; -if (test_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags)) +/* Check if channel for outgoing connection or if it wasn't deferred +* since in those cases it must be skipped. +*/ +if (test_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags) || + !test_and_clear_bit (FLAG_DEFER_SETUP , &chan->flags))return ;/* Reset ident so only one response is sent */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 118/176 afs: remove variable nr_servers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <[email protected]>
[ Upstream commit 318b83b71242998814a570c3420c042ee6165fca ]
Variable nr_servers is no longer being used, the last reference to it was removed in commit 45df8462730d ("afs: Fix server list handling") so clean up the code by removing it.
Stable-dep-of: add117e48df4 ("afs: Fix the server_list to unuse a displaced server rather than putting it")
--- fs/afs/volume.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
fs/afs/volume.c +1 -5
@@ -76,11 +76,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, {struct afs_server_list *slist;struct afs_volume *volume; -int ret = -ENOMEM , nr_servers =0 , i; - -for (i =0 ; i < vldb->nr_servers; i++) -if (vldb->fs_mask[i] & type_mask) - nr_servers++; +int ret = -ENOMEM ; volume =kzalloc (sizeof (struct afs_volume ),GFP_KERNEL );if (!volume)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 119/176 afs: Make it possible to find the volumes that are using a server
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit ca0e79a46097d54e4af46c67c852479d97af35bb ]
Make it possible to find the afs_volume structs that are using an afs_server struct to aid in breaking volume callbacks.
The way this is done is that each afs_volume already has an array of afs_server_entry records that point to the servers where that volume might be found. An afs_volume backpointer and a list node is added to each entry and each entry is then added to an RCU-traversable list on the afs_server to which it points.
Stable-dep-of: add117e48df4 ("afs: Fix the server_list to unuse a displaced server rather than putting it")
--- fs/afs/cell.c | 1 + fs/afs/internal.h | 23 +++++---- fs/afs/server.c | 1 + fs/afs/server_list.c | 112 +++++++++++++++++++++++++++++++++++++++---- fs/afs/vl_alias.c | 2 +- fs/afs/volume.c | 36 ++++++++------ 6 files changed, 143 insertions(+), 32 deletions(-)
fs/afs/cell.c +1 -0
@@ -161,6 +161,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,refcount_set (&cell->ref,1 );atomic_set (&cell->active,0 );INIT_WORK (&cell->manager, afs_manage_cell_work); +spin_lock_init (&cell->vs_lock); cell->volumes =RB_ROOT ;INIT_HLIST_HEAD (&cell->proc_volumes);seqlock_init (&cell->volume_lock);
fs/afs/internal.h +15 -8
@@ -378,6 +378,7 @@ struct afs_cell {unsigned int debug_id;/* The volumes belonging to this cell */ +spinlock_t vs_lock;/* Lock for server->volumes */ struct rb_root volumes;/* Tree of volumes on this server */ struct hlist_head proc_volumes;/* procfs volume list */ seqlock_t volume_lock;/* For volumes */
@@ -501,6 +502,7 @@ struct afs_server {struct hlist_node addr4_link;/* Link in net->fs_addresses4 */ struct hlist_node addr6_link;/* Link in net->fs_addresses6 */ struct hlist_node proc_link;/* Link in net->fs_proc */ +struct list_head volumes;/* RCU list of afs_server_entry objects */ struct work_struct initcb_work;/* Work for CB.InitCallBackState* */ struct afs_server *gc_next;/* Next server in manager's list */ time64_t unuse_time;/* Time at which last unused */
@@ -549,12 +551,14 @@ struct afs_server {*/ struct afs_server_entry {struct afs_server *server; +struct afs_volume *volume; +struct list_head slink;/* Link in server->volumes */ };struct afs_server_list {struct rcu_head rcu; -afs_volid_t vids[AFS_MAXTYPES ];/* Volume IDs */ refcount_t usage; +bool attached;/* T if attached to servers */ unsigned char nr_servers;unsigned char preferred;/* Preferred server */ unsigned short vnovol_mask;/* Servers to be skipped due to VNOVOL */
@@ -567,10 +571,9 @@ struct afs_server_list {* Live AFS volume management. */ struct afs_volume { -union { -struct rcu_head rcu; -afs_volid_t vid;/* volume ID */ - }; +struct rcu_head rcu; +afs_volid_t vid;/* The volume ID of this volume */ +afs_volid_t vids[AFS_MAXTYPES ];/* All associated volume IDs */ refcount_t ref;time64_t update_at;/* Time at which to next update */ struct afs_cell *cell;/* Cell to which belongs (pins ref) */
@@ -1450,10 +1453,14 @@ static inline struct afs_server_list *afs_get_serverlist(struct afs_server_list }extern void afs_put_serverlist (struct afs_net *,struct afs_server_list *); -extern struct afs_server_list *afs_alloc_server_list (struct afs_cell *,struct key *, -struct afs_vldb_entry *, -u8 ); +struct afs_server_list *afs_alloc_server_list (struct afs_volume *volume, +struct key *key, +struct afs_vldb_entry *vldb);extern bool afs_annotate_server_list (struct afs_server_list *,struct afs_server_list *); +void afs_attach_volume_to_servers (struct afs_volume *volume,struct afs_server_list *slist); +void afs_reattach_volume_to_servers (struct afs_volume *volume,struct afs_server_list *slist, +struct afs_server_list *old); +void afs_detach_volume_from_servers (struct afs_volume *volume,struct afs_server_list *slist);/* * super.c
fs/afs/server.c +1 -0
@@ -236,6 +236,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell, server->addr_version = alist->version; server->uuid = *uuid;rwlock_init (&server->fs_lock); +INIT_LIST_HEAD (&server->volumes);INIT_WORK (&server->initcb_work, afs_server_init_callback_work);init_waitqueue_head (&server->probe_wq);INIT_LIST_HEAD (&server->probe_link);
fs/afs/server_list.c +103 -9
154 lines not on this page · raw message
fs/afs/vl_alias.c +1 -1
@@ -126,7 +126,7 @@ static int afs_compare_volume_slists(const struct afs_volume *vol_a, lb =rcu_dereference (vol_b->servers);for (i =0 ; i <AFS_MAXTYPES ; i++) -if (la->vids[i] != lb->vids[i]) +if (vol_a->vids[i] != vol_b->vids[i])return 0 ;while (a < la->nr_servers && b < lb->nr_servers) {
fs/afs/volume.c +22 -14
@@ -72,11 +72,11 @@ static void afs_remove_volume_from_cell(struct afs_volume *volume)*/ static struct afs_volume *afs_alloc_volume (struct afs_fs_context *params,struct afs_vldb_entry *vldb, -unsigned long type_mask) +struct afs_server_list **_slist) {struct afs_server_list *slist;struct afs_volume *volume; -int ret = -ENOMEM ; +int ret = -ENOMEM , i; volume =kzalloc (sizeof (struct afs_volume ),GFP_KERNEL );if (!volume)
@@ -95,13 +95,16 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params,rwlock_init (&volume->cb_v_break_lock);memcpy (volume->name, vldb->name, vldb->name_len +1 ); - slist =afs_alloc_server_list (params->cell, params->key, vldb, type_mask); +for (i =0 ; i <AFS_MAXTYPES ; i++) + volume->vids[i] = vldb->vid[i]; + + slist =afs_alloc_server_list (volume, params->key, vldb);if (IS_ERR (slist)) { ret =PTR_ERR (slist); goto error_1; } -refcount_set (&slist->usage,1 ); + *_slist = slist;rcu_assign_pointer (volume->servers, slist);trace_afs_volume (volume->vid,1 , afs_volume_trace_alloc);return volume;
@@ -117,17 +120,19 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params,* Look up or allocate a volume record. */ static struct afs_volume *afs_lookup_volume (struct afs_fs_context *params, -struct afs_vldb_entry *vldb, -unsigned long type_mask) +struct afs_vldb_entry *vldb) { +struct afs_server_list *slist;struct afs_volume *candidate, *volume; - candidate =afs_alloc_volume (params, vldb, type_mask); + candidate =afs_alloc_volume (params, vldb, &slist);if (IS_ERR (candidate))return candidate; volume =afs_insert_volume_into_cell (params->cell, candidate); -if (volume != candidate) +if (volume == candidate) +afs_attach_volume_to_servers (volume, slist); +else afs_put_volume (params->net, candidate, afs_volume_trace_put_cell_dup);return volume; }
@@ -208,8 +213,7 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) goto error; } - type_mask =1UL << params->type; - volume =afs_lookup_volume (params, vldb, type_mask); + volume =afs_lookup_volume (params, vldb); error:kfree (vldb);
@@ -221,14 +225,17 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params)*/ static void afs_destroy_volume (struct afs_net *net,struct afs_volume *volume) { +struct afs_server_list *slist =rcu_access_pointer (volume->servers); +_enter ("%p" , volume);#ifdef CONFIG_AFS_FSCACHE ASSERTCMP(volume->cache, ==, NULL);#endif +afs_detach_volume_from_servers (volume, slist);afs_remove_volume_from_cell (volume); -afs_put_serverlist (net,rcu_access_pointer (volume->servers)); +afs_put_serverlist (net, slist);afs_put_cell (volume->cell, afs_cell_trace_put_vol);trace_afs_volume (volume->vid,refcount_read (&volume->ref), afs_volume_trace_free);
@@ -362,8 +369,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) }/* See if the volume's server list got updated. */ - new =afs_alloc_server_list (volume->cell, key, - vldb, (1 << volume->type)); + new =afs_alloc_server_list (volume, key, vldb);if (IS_ERR (new)) { ret =PTR_ERR (new); goto error_vldb;
@@ -384,9 +390,11 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) volume->update_at =ktime_get_real_seconds () + afs_volume_record_life;write_unlock (&volume->servers_lock); - ret =0 ; +if (discard == old) +afs_reattach_volume_to_servers (volume, new, old);afs_put_serverlist (volume->cell->net, discard); + ret =0 ; error_vldb:kfree (vldb); error:
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 120/176 afs: Fix the server_list to unuse a displaced server rather than putting it
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit add117e48df4788a86a21bd0515833c0a6db1ad1 ]
When allocating and building an afs_server_list struct object from a VLDB record, we look up each server address to get the server record for it - but a server may have more than one entry in the record and we discard the duplicate pointers. Currently, however, when we discard, we only put a server record, not unuse it - but the lookup got as an active-user count.
The active-user count on an afs_server_list object determines its lifetime whereas the refcount keeps the memory backing it around. Failing to reduce the active-user counter prevents the record from being cleaned up and can lead to multiple copied being seen - and pointing to deleted afs_cell objects and other such things.
Fix this by switching the incorrect 'put' to an 'unuse' instead.
Without this, occasionally, a dead server record can be seen in /proc/net/afs/servers and list corruption may be observed:
list_del corruption. prev->next should be ffff888102423e40, but was 0000000000000000. (prev=ffff88810140cd38)
--- fs/afs/server_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/afs/server_list.c +2 -2
@@ -67,8 +67,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume,break ;if (j < slist->nr_servers) {if (slist->servers[j].server == server) { -afs_put_server (volume->cell->net, server, - afs_server_trace_put_slist_isort); +afs_unuse_server (volume->cell->net, server, + afs_server_trace_put_slist_isort);continue ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 121/176 net: loopback: Avoid sending IP packets without an Ethernet header
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 0e4427f8f587c4b603475468bb3aee9418574893 ]
After commit 22600596b675 ("ipv4: give an IPv4 dev to blackhole_netdev") IPv4 neighbors can be constructed on the blackhole net device, but they are constructed with an output function (neigh_direct_output()) that simply calls dev_queue_xmit(). The latter will transmit packets via 'skb->dev' which might not be the blackhole net device if dst_dev_put() switched 'dst->dev' to the blackhole net device while another CPU was using the dst entry in ip_output(), but after it already initialized 'skb->dev' from 'dst->dev'.
Specifically, the following can happen:
CPU1 CPU2
udp_sendmsg(sk1) udp_sendmsg(sk2)udp_send_skb() [...]ip_output()
skb->dev = skb_dst(skb)->dev
dst_dev_put()
dst->dev = blackhole_netdev
ip_finish_output2()
resolves neigh on dst->devneigh_output()neigh_direct_output()dev_queue_xmit()
This will result in IPv4 packets being sent without an Ethernet header via a valid net device:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on enp9s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 22:07:02.329668 20:00:40:11:18:fb > 45:00:00:44:f4:94, ethertype Unknown (0x58c6), length 68:
0x0000: 8dda 74ca f1ae ca6c ca6c 0098 969c 0400 ..t....l.l......
0x0010: 0000 4730 3f18 6800 0000 0000 0000 9971 ..G0?.h........q
0x0020: c4c9 9055 a157 0a70 9ead bf83 38ca ab38 ...U.W.p....8..8
0x0030: 8add ab96 e052 .....RFix by making sure that neighbors are constructed on top of the blackhole net device with an output function that simply consumes the packets, in a similar fashion to dst_discard_out() and blackhole_netdev_xmit().
--- drivers/net/loopback.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/net/loopback.c +14 -0
@@ -246,8 +246,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,return NETDEV_TX_OK ; } +static int blackhole_neigh_output (struct neighbour *n,struct sk_buff *skb) +{ +kfree_skb (skb); +return 0 ; +} + +static int blackhole_neigh_construct (struct net_device *dev, +struct neighbour *n) +{ + n->output = blackhole_neigh_output; +return 0 ; +} +static const struct net_device_ops blackhole_netdev_ops = { .ndo_start_xmit = blackhole_netdev_xmit, + .ndo_neigh_construct = blackhole_neigh_construct, };/* This is a dst-dummy device used specifically for invalidated
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 122/176 net: set the minimum for net_hotdata.netdev_budget_usecs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) <[email protected]>
[ Upstream commit c180188ec02281126045414e90d08422a80f75b4 ]
Commit 7acf8a1e8a28 ("Replace 2 jiffies with sysctl netdev_budget_usecs to enable softirq tuning") added a possibility to set net_hotdata.netdev_budget_usecs, but added no lower bound checking.
Commit a4837980fd9f ("net: revert default NAPI poll timeout to 2 jiffies") made the *initial* value HZ-dependent, so the initial value is at least 2 jiffies even for lower HZ values (2 ms for 1000 Hz, 8ms for 250 Hz, 20 ms for 100 Hz).
But a user still can set improper values by a sysctl. Set .extra1 (the lower bound) for net_hotdata.netdev_budget_usecs to the same value as in the latter commit. That is to 2 jiffies.
--- net/core/sysctl_net_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/sysctl_net_core.c +2 -1
@@ -30,6 +30,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF;static int min_rcvbuf =SOCK_MIN_RCVBUF ;static int max_skb_frags =MAX_SKB_FRAGS ;static int min_mem_pcpu_rsv =SK_MEMORY_PCPU_RESERVE ; +static int netdev_budget_usecs_min =2 *USEC_PER_SEC /HZ ;static int net_msg_warn;/* Unused, but still a sysctl */
@@ -554,7 +555,7 @@ static struct ctl_table net_core_table[] = { .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, - .extra1 = SYSCTL_ZERO, + .extra1 = &netdev_budget_usecs_min, }, { .procname = "fb_tunnels_only_for_init_net",
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 123/176 net/ipv4: add tracepoint for icmp_send
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peilin He <[email protected]>
[ Upstream commit db3efdcf70c752e8a8deb16071d8e693c3ef8746 ]
Introduce a tracepoint for icmp_send, which can help users to get more detail information conveniently when icmp abnormal events happen.
1. Giving an usecase example:
=============================
When an application experiences packet loss due to an unreachable UDP destination port, the kernel will send an exception message through the icmp_send function. By adding a trace point for icmp_send, developers or system administrators can obtain detailed information about the UDP packet loss, including the type, code, source address, destination address, source port, and destination port. This facilitates the trouble-shooting of UDP packet loss issues especially for those network-service applications.
2. Operation Instructions:
==========================
Switch to the tracing directory.
cd /sys/kernel/tracing
Filter for destination port unreachable.
echo "type==3 && code==3" > events/icmp/icmp_send/filter
Enable trace event.
echo 1 > events/icmp/icmp_send/enable
3. Result View:
================
udp_client_erro-11370 [002] ...s.12 124.728002:
icmp_send: icmp_send: type=3, code=3.
From 127.0.0.1:41895 to 127.0.0.1:6666 ulen=23
skbaddr=00000000589b167a
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- include/trace/events/icmp.h | 67 +++++++++++++++++++++++++++++++++++++ net/ipv4/icmp.c | 4 +++ 2 files changed, 71 insertions(+) create mode 100644 include/trace/events/icmp.h
include/trace/events/icmp.h new file +67 -0
@@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM icmp + +#if !defined(_TRACE_ICMP_H) || defined(TRACE_HEADER_MULTI_READ ) +#define _TRACE_ICMP_H + +#include <linux/icmp.h> +#include <linux/tracepoint.h> + +TRACE_EVENT (icmp_send, + + TP_PROTO(const struct sk_buff *skb, int type, int code), + +TP_ARGS (skb, type, code), + +TP_STRUCT__entry ( + __field(const void *, skbaddr) + __field(int, type) + __field(int, code) + __array(__u8, saddr, 4) + __array(__u8, daddr, 4) + __field(__u16, sport) + __field(__u16, dport) + __field(unsigned short, ulen) + ), + +TP_fast_assign ( + struct iphdr *iph = ip_hdr(skb); + struct udphdr *uh = udp_hdr(skb); + int proto_4 = iph->protocol; + __be32 *p32; + + __entry->skbaddr = skb; + __entry->type = type; + __entry->code = code; + + if (proto_4 != IPPROTO_UDP || (u8 *)uh < skb->head || + (u8 *)uh + sizeof(struct udphdr) + > skb_tail_pointer(skb)) { + __entry->sport = 0; + __entry->dport = 0; + __entry->ulen = 0; + } else { + __entry->sport = ntohs(uh->source); + __entry->dport = ntohs(uh->dest); + __entry->ulen = ntohs(uh->len); + } + + p32 = (__be32 *) __entry->saddr; + *p32 = iph->saddr; + + p32 = (__be32 *) __entry->daddr; + *p32 = iph->daddr; + ), + +TP_printk ("icmp_send: type=%d, code=%d. From %pI4:%u to %pI4:%u ulen=%d skbaddr=%p" , + __entry->type, __entry->code, + __entry->saddr, __entry->sport, __entry->daddr, + __entry->dport, __entry->ulen, __entry->skbaddr) +); + +#endif /* _TRACE_ICMP_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> +
net/ipv4/icmp.c +4 -0
@@ -93,6 +93,8 @@#include <net/ip_fib.h> #include <net/l3mdev.h> #include <net/addrconf.h> +#define CREATE_TRACE_POINTS +#include <trace/events/icmp.h> /* * Build xmit assembly blocks
@@ -778,6 +780,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,if (!fl4.saddr) fl4.saddr =htonl (INADDR_DUMMY ); +trace_icmp_send (skb_in, type, code); +icmp_push_reply (sk, &icmp_param, &fl4, &ipc, &rt); ende:ip_rt_put (rt);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 124/176 ipv4: icmp: Pass full DS field to ip_route_input()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 1c6f50b37f711b831d78973dad0df1da99ad0014 ]
Align the ICMP code to other callers of ip_route_input() and pass the full DS field. In the future this will allow us to perform a route lookup according to the full DSCP value.
No functional changes intended since the upper DSCP bits are masked when comparing against the TOS selectors in FIB rules and routes.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- net/ipv4/icmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/icmp.c +1 -1
@@ -550,7 +550,7 @@ static struct rtable *icmp_route_lookup(struct net *net, orefdst = skb_in->_skb_refdst;/* save old refdst */ skb_dst_set (skb_in,NULL ); err =ip_route_input (skb_in, fl4_dec.daddr, fl4_dec.saddr, -RT_TOS (tos), rt2->dst.dev); + tos, rt2->dst.dev);dst_release (&rt2->dst); rt2 =skb_rtable (skb_in);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 125/176 ipv4: icmp: Unmask upper DSCP bits in icmp_route_lookup()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 4805646c42e51d2fbf142864d281473ad453ad5d ]
The function is called to resolve a route for an ICMP message that is sent in response to a situation. Based on the type of the generated ICMP message, the function is either passed the DS field of the packet that generated the ICMP message or a DS field that is derived from it.
Unmask the upper DSCP bits before resolving and output route via ip_route_output_key_hash() so that in the future the lookup could be performed according to the full DSCP value.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- net/ipv4/icmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/icmp.c +2 -1
@@ -93,6 +93,7 @@#include <net/ip_fib.h> #include <net/l3mdev.h> #include <net/addrconf.h> +#include <net/inet_dscp.h> #define CREATE_TRACE_POINTS #include <trace/events/icmp.h>
@@ -502,7 +503,7 @@ static struct rtable *icmp_route_lookup(struct net *net, fl4->saddr = saddr; fl4->flowi4_mark = mark; fl4->flowi4_uid =sock_net_uid (net,NULL ); - fl4->flowi4_tos =RT_TOS (tos); + fl4->flowi4_tos = tos &INET_DSCP_MASK ; fl4->flowi4_proto =IPPROTO_ICMP ; fl4->fl4_icmp_type = type; fl4->fl4_icmp_code = code;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 126/176 ipvlan: Unmask upper DSCP bits in ipvlan_process_v4_outbound()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 939cd1abf080c629552a9c5e6db4c0509d13e4c7 ]
Unmask the upper DSCP bits when calling ip_route_output_flow() so that in the future it could perform the FIB lookup according to the full DSCP value.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- drivers/net/ipvlan/ipvlan_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ipvlan/ipvlan_core.c +3 -1
@@ -2,6 +2,8 @@/* Copyright (c) 2014 Mahesh Bandewar <[email protected]> */ +#include <net/inet_dscp.h> +#include "ipvlan.h" static u32 ipvlan_jhash_secret__read_mostly ;
@@ -420,7 +422,7 @@ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb)int err, ret =NET_XMIT_DROP ;struct flowi4 fl4 = { .flowi4_oif = dev->ifindex, - .flowi4_tos =RT_TOS (ip4h->tos), + .flowi4_tos = ip4h->tos &INET_DSCP_MASK , .flowi4_flags =FLOWI_FLAG_ANYSRC , .flowi4_mark = skb->mark, .daddr = ip4h->daddr,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 127/176 ipv4: Convert icmp_route_lookup() to dscp_t.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 913c83a610bb7dd8e5952a2b4663e1feec0b5de6 ]
Pass a dscp_t variable to icmp_route_lookup(), instead of a plain u8, to prevent accidental setting of ECN bits in ->flowi4_tos. Rename that variable ("tos" -> "dscp") to make the intent clear.
While there, reorganise the function parameters to fill up horizontal space.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- net/ipv4/icmp.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
net/ipv4/icmp.c +9 -10
@@ -484,13 +484,11 @@ static struct net_device *icmp_get_route_lookup_dev(struct sk_buff *skb)return route_lookup_dev; } -static struct rtable *icmp_route_lookup (struct net *net, -struct flowi4 *fl4, +static struct rtable *icmp_route_lookup (struct net *net,struct flowi4 *fl4,struct sk_buff *skb_in, -const struct iphdr *iph, -__be32 saddr,u8 tos,u32 mark, -int type,int code, -struct icmp_bxm *param) +const struct iphdr *iph,__be32 saddr, +dscp_t dscp,u32 mark,int type, +int code,struct icmp_bxm *param) {struct net_device *route_lookup_dev;struct rtable *rt, *rt2;
@@ -503,7 +501,7 @@ static struct rtable *icmp_route_lookup(struct net *net, fl4->saddr = saddr; fl4->flowi4_mark = mark; fl4->flowi4_uid =sock_net_uid (net,NULL ); - fl4->flowi4_tos = tos &INET_DSCP_MASK ; + fl4->flowi4_tos =inet_dscp_to_dsfield (dscp); fl4->flowi4_proto =IPPROTO_ICMP ; fl4->fl4_icmp_type = type; fl4->fl4_icmp_code = code;
@@ -551,7 +549,7 @@ static struct rtable *icmp_route_lookup(struct net *net, orefdst = skb_in->_skb_refdst;/* save old refdst */ skb_dst_set (skb_in,NULL ); err =ip_route_input (skb_in, fl4_dec.daddr, fl4_dec.saddr, - tos, rt2->dst.dev); +inet_dscp_to_dsfield (dscp), rt2->dst.dev);dst_release (&rt2->dst); rt2 =skb_rtable (skb_in);
@@ -747,8 +745,9 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, ipc.opt = &icmp_param.replyopts.opt; ipc.sockc.mark = mark; - rt =icmp_route_lookup (net, &fl4, skb_in, iph, saddr, tos, mark, - type, code, &icmp_param); + rt =icmp_route_lookup (net, &fl4, skb_in, iph, saddr, +inet_dsfield_to_dscp (tos), mark, type, code, + &icmp_param);if (IS_ERR (rt)) goto out_unlock;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 128/176 ipv4: Convert ip_route_input() to dscp_t.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 7e863e5db6185b1add0df4cb01b31a4ed1c4b738 ]
Pass a dscp_t variable to ip_route_input(), instead of a plain u8, to prevent accidental setting of ECN bits in ->flowi4_tos.
Callers of ip_route_input() to consider are:
* input_action_end_dx4_finish() and input_action_end_dt4() in net/ipv6/seg6_local.c. These functions set the tos parameter to 0, which is already a valid dscp_t value, so they don't need to be adjusted for the new prototype.
* icmp_route_lookup(), which already has a dscp_t variable to pass as parameter. We just need to remove the inet_dscp_to_dsfield() conversion.
* br_nf_pre_routing_finish(), ip_options_rcv_srr() and ip4ip6_err(), which get the DSCP directly from IPv4 headers. Define a helper to read the .tos field of struct iphdr as dscp_t, so that these function don't have to do the conversion manually.
While there, declare *iph as const in br_nf_pre_routing_finish(), declare its local variables in reverse-christmas-tree order and move the "err = ip_route_input()" assignment out of the conditional to avoid checkpatch warning.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- include/net/ip.h | 5 +++++ include/net/route.h | 5 +++-- net/bridge/br_netfilter_hooks.c | 8 +++++--- net/ipv4/icmp.c | 2 +- net/ipv4/ip_options.c | 3 ++- net/ipv6/ip6_tunnel.c | 4 ++-- 6 files changed, 18 insertions(+), 9 deletions(-)
include/net/ip.h +5 -0
@@ -409,6 +409,11 @@ int ip_decrease_ttl(struct iphdr *iph)return --iph->ttl; } +static inline dscp_t ip4h_dscp (const struct iphdr *ip4h) +{ +return inet_dsfield_to_dscp (ip4h->tos); +} +static inline int ip_mtu_locked (const struct dst_entry *dst) {const struct rtable *rt = (const struct rtable *)dst;
include/net/route.h +3 -2
@@ -203,12 +203,13 @@ int ip_route_use_hint(struct sk_buff *skb, __be32 dst, __be32 src, const struct sk_buff *hint);static inline int ip_route_input (struct sk_buff *skb,__be32 dst,__be32 src, -u8 tos,struct net_device *devin) +dscp_t dscp,struct net_device *devin) {int err;rcu_read_lock (); - err =ip_route_input_noref (skb, dst, src, tos, devin); + err =ip_route_input_noref (skb, dst, src,inet_dscp_to_dsfield (dscp), + devin);if (!err) {skb_dst_force (skb);if (!skb_dst (skb))
net/bridge/br_netfilter_hooks.c +5 -3
@@ -366,9 +366,9 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb,*/ static int br_nf_pre_routing_finish (struct net *net,struct sock *sk,struct sk_buff *skb) { -struct net_device *dev = skb->dev, *br_indev; -struct iphdr *iph =ip_hdr (skb);struct nf_bridge_info *nf_bridge =nf_bridge_info_get (skb); +struct net_device *dev = skb->dev, *br_indev; +const struct iphdr *iph =ip_hdr (skb);struct rtable *rt;int err;
@@ -386,7 +386,9 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_ } nf_bridge->in_prerouting =0 ;if (br_nf_ipv4_daddr_was_changed (skb, nf_bridge)) { -if ((err =ip_route_input (skb, iph->daddr, iph->saddr, iph->tos, dev))) { + err =ip_route_input (skb, iph->daddr, iph->saddr, +ip4h_dscp (iph), dev); +if (err) {struct in_device *in_dev =__in_dev_get_rcu (dev);/* If err equals -EHOSTUNREACH the error is due to a
net/ipv4/icmp.c +1 -1
@@ -549,7 +549,7 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4, orefdst = skb_in->_skb_refdst;/* save old refdst */ skb_dst_set (skb_in,NULL ); err =ip_route_input (skb_in, fl4_dec.daddr, fl4_dec.saddr, -inet_dscp_to_dsfield (dscp), rt2->dst.dev); + dscp, rt2->dst.dev);dst_release (&rt2->dst); rt2 =skb_rtable (skb_in);
net/ipv4/ip_options.c +2 -1
@@ -617,7 +617,8 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) orefdst = skb->_skb_refdst;skb_dst_set (skb,NULL ); - err =ip_route_input (skb, nexthop, iph->saddr, iph->tos, dev); + err =ip_route_input (skb, nexthop, iph->saddr,ip4h_dscp (iph), + dev); rt2 =skb_rtable (skb);if (err || (rt2->rt_type !=RTN_UNICAST && rt2->rt_type !=RTN_LOCAL )) {skb_dst_drop (skb);
net/ipv6/ip6_tunnel.c +2 -2
@@ -628,8 +628,8 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, }skb_dst_set (skb2, &rt->dst); }else { -if (ip_route_input (skb2, eiph->daddr, eiph->saddr, eiph->tos, - skb2->dev) || +if (ip_route_input (skb2, eiph->daddr, eiph->saddr, +ip4h_dscp (eiph), skb2->dev) ||skb_dst (skb2)->dev->type !=ARPHRD_TUNNEL6 ) goto out; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 129/176 ipvlan: Prepare ipvlan_process_v4_outbound() to future .flowi4_tos conversion.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 0c30d6eedd1ec0c1382bcab9576d26413cd278a3 ]
Use ip4h_dscp() to get the DSCP from the IPv4 header, then convert the dscp_t value to __u8 with inet_dscp_to_dsfield().
Then, when we'll convert .flowi4_tos to dscp_t, we'll just have to drop the inet_dscp_to_dsfield() call.
Stable-dep-of: 27843ce6ba3d ("ipvlan: ensure network headers are in skb linear part")
--- drivers/net/ipvlan/ipvlan_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ipvlan/ipvlan_core.c +2 -1
@@ -3,6 +3,7 @@*/ #include <net/inet_dscp.h> +#include <net/ip.h> #include "ipvlan.h"
@@ -422,7 +423,7 @@ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb)int err, ret =NET_XMIT_DROP ;struct flowi4 fl4 = { .flowi4_oif = dev->ifindex, - .flowi4_tos = ip4h->tos &INET_DSCP_MASK , + .flowi4_tos =inet_dscp_to_dsfield (ip4h_dscp (ip4h)), .flowi4_flags =FLOWI_FLAG_ANYSRC , .flowi4_mark = skb->mark, .daddr = ip4h->daddr,
Signature · 1 line
2.39.5