6.4.10-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 6.4.10-rc1 review
This is the start of the stable review cycle for the 6.4.10 release. There are 165 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, 11 Aug 2023 10:36:10 +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.4.10-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.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.4.10-rc1
Andi Shyti <[email protected]>
drm/i915/gt: Enable the CCS_FLUSH bit in the pipe control and in the CS
Andi Shyti <[email protected]>
drm/i915/gt: Support aux invalidation on all engines
Jonathan Cavitt <[email protected]>
drm/i915/gt: Poll aux invalidation register bit on invalidation
Andi Shyti <[email protected]>
drm/i915/gt: Rename flags with bit_group_X according to the datasheet
Tejas Upadhyay <[email protected]>
drm/i915/gt: Add workaround 14016712196
Jonathan Cavitt <[email protected]>
drm/i915/gt: Ensure memory quiesced before invalidation
Andi Shyti <[email protected]>
drm/i915: Add the gen12_needs_ccs_aux_inv helper
Xu Yang <[email protected]>
ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node
Sean Christopherson <[email protected]>
selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
Lijo Lazar <[email protected]>
drm/amdgpu: Use apt name for FW reserved region
Alexander Stein <[email protected]>
drm/imx/ipuv3: Fix front porch adjustment upon hactive aligning
Aneesh Kumar K.V <[email protected]>
powerpc/mm/altmap: Fix altmap boundary check
Christophe JAILLET <[email protected]>
mtd: rawnand: fsl_upm: Fix an off-by one test in fun_exec_op()
Arnd Bergmann <[email protected]>
mtd: spi-nor: avoid holes in struct spi_mem_op
Chen-Yu Tsai <[email protected]>
clk: mediatek: mt8183: Add back SSPM related clocks
Johan Jonker <[email protected]>
mtd: rawnand: rockchip: Align hwecc vs. raw page helper layouts
Johan Jonker <[email protected]>
mtd: rawnand: rockchip: fix oobfree offset and description
Roger Quadros <[email protected]>
mtd: rawnand: omap_elm: Fix incorrect type in assignment
Pavel Begunkov <[email protected]>
io_uring: annotate offset timeout races
Chao Yu <[email protected]>
f2fs: fix to do sanity check on direct node in truncate_dnode()
Filipe Manana <[email protected]>
btrfs: remove BUG_ON()'s in add_new_free_space()
Jan Kara <[email protected]>
ext2: Drop fragment support
Jason Gunthorpe <[email protected]>
mm/gup: do not return 0 from pin_user_pages_fast() for bad args
Jan Kara <[email protected]>
fs: Protect reconfiguration of sb read-write from racing writes
Alan Stern <[email protected]>
net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb
Tetsuo Handa <[email protected]>
debugobjects: Recheck debug_objects_enabled before reporting
Sungwoo Kim <[email protected]>
Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb
Prince Kumar Maurya <[email protected]>
fs/sysv: Null check to prevent null-ptr-deref bug
Tetsuo Handa <[email protected]>
kasan,kmsan: remove __GFP_KSWAPD_RECLAIM usage from kasan/kmsan
Tetsuo Handa <[email protected]>
fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_load_attr_list()
Roman Gushchin <[email protected]>
mm: kmem: fix a NULL pointer dereference in obj_stock_flush_required()
Linus Torvalds <[email protected]>
file: reinstate f_pos locking optimization for regular files
Geert Uytterhoeven <[email protected]>
clk: imx93: Propagate correct error in imx93_clocks_probe()
Stephen Rothwell <[email protected]>
sunvnet: fix sparc64 build error after gso code split
Mike Kravetz <[email protected]>
Revert "page cache: fix page_cache_next/prev_miss off by one"
Andi Shyti <[email protected]>
drm/i915/gt: Cleanup aux invalidation registers
Janusz Krzysztofik <[email protected]>
drm/i915: Fix premature release of request's reusable memory
Guchun Chen <[email protected]>
drm/ttm: check null pointer before accessing when swapping
Aleksa Sarai <[email protected]>
open: make RESOLVE_CACHED correctly test for O_TMPFILE
Mark Brown <[email protected]>
arm64/ptrace: Don't enable SVE when setting streaming SVE
Mark Brown <[email protected]>
arm64/ptrace: Flush FP state when setting ZT0
Mark Brown <[email protected]>
arm64/fpsimd: Sync FPSIMD state with SVE for SME only systems
Mark Brown <[email protected]>
arm64/fpsimd: Clear SME state in the target task when setting the VL
Mark Brown <[email protected]>
arm64/fpsimd: Sync and zero pad FPSIMD state for streaming SVE
Mike Rapoport (IBM) <[email protected]>
parisc/mm: preallocate fixmap page tables at init
Naveen N Rao <[email protected]>
powerpc/ftrace: Create a dummy stackframe to fix stack unwind
Paulo Alcantara <[email protected]>
smb: client: fix dfs link mount against w2k8
Jiri Olsa <[email protected]>
bpf: Disable preemption in bpf_event_output
Ilya Dryomov <[email protected]>
rbd: prevent busy loop when requesting exclusive lock
Michael Kelley <[email protected]>
x86/hyperv: Disable IBT when hypercall page lacks ENDBR instruction
Paul Fertser <[email protected]>
wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)
Laszlo Ersek <[email protected]>
net: tap_open(): set sk_uid from current_fsuid()
Laszlo Ersek <[email protected]>
net: tun_chr_open(): set sk_uid from current_fsuid()
Dinh Nguyen <[email protected]>
arm64: dts: stratix10: fix incorrect I2C property for SCL signal
Jiri Olsa <[email protected]>
bpf: Disable preemption in bpf_perf_event_output
Song Shuai <[email protected]>
riscv: Export va_kernel_pa_offset in vmcoreinfo
Arseniy Krasnov <[email protected]>
mtd: rawnand: meson: fix OOB available bytes for ECC
Olivier Maignial <[email protected]>
mtd: spinand: winbond: Fix ecc_get_status
Olivier Maignial <[email protected]>
mtd: spinand: toshiba: Fix ecc_get_status
Sungjong Seo <[email protected]>
exfat: release s_lock before calling dir_emit()
Namjae Jeon <[email protected]>
exfat: check if filename entries exceeds max filename length
gaoming <[email protected]>
exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree
Krzysztof Kozlowski <[email protected]>
firmware: arm_scmi: Drop OF node reference in the transport channel setup
Xiubo Li <[email protected]>
ceph: defer stopping mdsc delayed_work
Ross Maynard <[email protected]>
USB: zaurus: Add ID for A-300/B-500/C-700
Ilya Dryomov <[email protected]>
libceph: fix potential hang in ceph_osdc_notify()
Song Shuai <[email protected]>
Documentation: kdump: Add va_kernel_pa_offset for RISCV64
Michael Kelley <[email protected]>
scsi: storvsc: Limit max_sectors for virtual Fibre Channel devices
Steffen Maier <[email protected]>
scsi: zfcp: Defer fc_rport blocking until after ADISC response
Boqun Feng <[email protected]>
rust: allocator: Prevent mis-aligned allocation
Stefano Garzarella <[email protected]>
test/vsock: remove vsock_perf executable on make clean
Eric Dumazet <[email protected]>
tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen
Eric Dumazet <[email protected]>
tcp_metrics: annotate data-races around tm->tcpm_net
Eric Dumazet <[email protected]>
tcp_metrics: annotate data-races around tm->tcpm_vals[]
Eric Dumazet <[email protected]>
tcp_metrics: annotate data-races around tm->tcpm_lock
Eric Dumazet <[email protected]>
tcp_metrics: annotate data-races around tm->tcpm_stamp
Eric Dumazet <[email protected]>
tcp_metrics: fix addr_same() helper
Jonas Gorski <[email protected]>
prestera: fix fallback to previous version on same major version
Leon Romanovsky <[email protected]>
net/mlx5e: Set proper IPsec source port in L4 selector
Jianbo Liu <[email protected]>
net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio
Jianbo Liu <[email protected]>
net/mlx5: fs_core: Make find_closest_ft more generic
Benjamin Poirier <[email protected]>
vxlan: Fix nexthop hash size
Yue Haibing <[email protected]>
ip6mr: Fix skb_under_panic in ip6mr_cache_report()
Alexandra Winter <[email protected]>
s390/qeth: Don't call dev_close/dev_open (DOWN/UP)
Lin Ma <[email protected]>
net: dcb: choose correct policy to parse DCB_ATTR_BCN
Michael Chan <[email protected]>
bnxt_en: Fix max_mtu setting for multi-buf XDP
Somnath Kotur <[email protected]>
bnxt_en: Fix page pool logic for page size >= 64K
Kuniyuki Iwashima <[email protected]>
selftest: net: Assert on a proper value in so_incoming_cpu.c.
Mark Brown <[email protected]>
net: netsec: Ignore 'phy-mode' on SynQuacer in DT mode
Yuanjun Gong <[email protected]>
net: korina: handle clk prepare error in korina_probe()
Dan Carpenter <[email protected]>
net: ll_temac: fix error checking of irq_of_parse_and_map()
Tomas Glozar <[email protected]>
bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire
valis <[email protected]>
net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free
valis <[email protected]>
net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free
valis <[email protected]>
net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after-free
Hou Tao <[email protected]>
bpf, cpumap: Handle skb as well when clean up ptr_ring
Hou Tao <[email protected]>
bpf, cpumap: Make sure kthread is running before map update returns
Andrii Nakryiko <[email protected]>
bpf: Centralize permissions checks for all BPF map types
Andrii Nakryiko <[email protected]>
bpf: Inline map creation logic in map_create() function
Andrii Nakryiko <[email protected]>
bpf: Move unprivileged checks into map_create() and bpf_prog_load()
Michal Schmidt <[email protected]>
octeon_ep: initialize mbox mutexes
Jakub Kicinski <[email protected]>
bnxt: don't handle XDP in netpoll
Rafal Rogalski <[email protected]>
ice: Fix RDMA VSI removal during queue rebuild
Duoming Zhou <[email protected]>
net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Kuniyuki Iwashima <[email protected]>
net/sched: taprio: Limit TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME to INT_MAX.
Eric Dumazet <[email protected]>
net: annotate data-races around sk->sk_priority
Eric Dumazet <[email protected]>
net: add missing data-race annotation for sk_ll_usec
Eric Dumazet <[email protected]>
net: add missing data-race annotations around sk->sk_peek_off
Eric Dumazet <[email protected]>
net: annotate data-races around sk->sk_mark
Eric Dumazet <[email protected]>
net: add missing READ_ONCE(sk->sk_rcvbuf) annotation
Eric Dumazet <[email protected]>
net: add missing READ_ONCE(sk->sk_sndbuf) annotation
Eric Dumazet <[email protected]>
net: add missing READ_ONCE(sk->sk_rcvlowat) annotation
Eric Dumazet <[email protected]>
net: annotate data-races around sk->sk_max_pacing_rate
Eric Dumazet <[email protected]>
net: annotate data-race around sk->sk_txrehash
Eric Dumazet <[email protected]>
net: annotate data-races around sk->sk_reserved_mem
Richard Gobert <[email protected]>
net: gro: fix misuse of CB in udp socket lookup
Eric Dumazet <[email protected]>
net: move gso declarations and functions to their own files
Konstantin Khorenko <[email protected]>
qed: Fix scheduling in a tasklet while getting stats
Thierry Reding <[email protected]>
net: stmmac: tegra: Properly allocate clock bulk data
Chengfeng Ye <[email protected]>
mISDN: hfcpci: Fix potential deadlock on &hc->lock
Jamal Hadi Salim <[email protected]>
net: sched: cls_u32: Fix match key mis-addressing
Georg Müller <[email protected]>
perf test uprobe_from_different_cu: Skip if there is no gcc
Yuanjun Gong <[email protected]>
net: dsa: fix value check in bcm_sf2_sw_probe()
Lin Ma <[email protected]>
rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length
Lin Ma <[email protected]>
bpf: Add length check for SK_DIAG_BPF_STORAGE_REQ_MAP_FD parsing
Shay Drory <[email protected]>
net/mlx5: Unregister devlink params in case interface is down
Chris Mi <[email protected]>
net/mlx5: fs_chains: Fix ft prio if ignore_flow_level is not supported
Jianbo Liu <[email protected]>
net/mlx5e: kTLS, Fix protection domain in use syndrome when devlink reload
Dragos Tatulea <[email protected]>
net/mlx5e: xsk: Fix crash on regular rq reactivation
Dragos Tatulea <[email protected]>
net/mlx5e: xsk: Fix invalid buffer access for legacy rq
Jianbo Liu <[email protected]>
net/mlx5e: Move representor neigh cleanup to profile cleanup_tx
Amir Tzin <[email protected]>
net/mlx5e: Fix crash moving to switchdev mode when ntuple offload is set
Chris Mi <[email protected]>
net/mlx5e: Don't hold encap tbl lock if there is no encap action
Shay Drory <[email protected]>
net/mlx5: Honor user input for migratable port fn attr
Yuanjun Gong <[email protected]>
net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer()
Zhengchao Shao <[email protected]>
net/mlx5: fix potential memory leak in mlx5e_init_rep_rx
Zhengchao Shao <[email protected]>
net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx
Zhengchao Shao <[email protected]>
net/mlx5e: fix double free in macsec_fs_tx_create_crypto_table_groups
Ilan Peer <[email protected]>
wifi: cfg80211: Fix return value in scan logic
Haixin Yu <[email protected]>
perf pmu arm64: Fix reading the PMU cpu slots in sysfs
Gao Xiang <[email protected]>
erofs: fix wrong primary bvec selection on deduplicated extents
Heiko Carstens <[email protected]>
KVM: s390: fix sthyi error handling
Sven Schnelle <[email protected]>
s390/vmem: split pages when debug pagealloc is enabled
[email protected] <[email protected]>
word-at-a-time: use the same return type for has_zero regardless of endianness
Durai Manickam KR <[email protected]>
ARM: dts: at91: sam9x60: fix the SOC detection
Claudiu Beznea <[email protected]>
ARM: dts: at91: use generic name for shutdown controller
Claudiu Beznea <[email protected]>
ARM: dts: at91: use clock-controller name for sckc nodes
Claudiu Beznea <[email protected]>
ARM: dts: at91: use clock-controller name for PMC nodes
Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix chan_free cleanup on SMC
Lucas Stach <[email protected]>
soc: imx: imx8mp-blk-ctrl: register HSIO PLL clock as bus_power_dev child
Dmitry Baryshkov <[email protected]>
ARM: dts: nxp/imx: limit sk-imx53 supported frequencies
Yury Norov <[email protected]>
lib/bitmap: workaround const_eval test build failure
Sukrut Bellary <[email protected]>
firmware: arm_scmi: Fix signed error return values handling
Punit Agrawal <[email protected]>
firmware: smccc: Fix use of uninitialised results structure
Benjamin Gaignard <[email protected]>
arm64: dts: freescale: Fix VPU G2 clock
Hugo Villeneuve <[email protected]>
arm64: dts: imx8mn-var-som: add missing pull-up for onboard PHY reset pinmux
Yashwanth Varakala <[email protected]>
arm64: dts: phycore-imx8mm: Correction in gpio-line-names
Yashwanth Varakala <[email protected]>
arm64: dts: phycore-imx8mm: Label typo-fix of VPU
Tim Harvey <[email protected]>
arm64: dts: imx8mm-venice-gw7904: disable disp_blk_ctrl
Tim Harvey <[email protected]>
arm64: dts: imx8mm-venice-gw7903: disable disp_blk_ctrl
Robin Murphy <[email protected]>
iommu/arm-smmu-v3: Document nesting-related errata
Robin Murphy <[email protected]>
iommu/arm-smmu-v3: Add explicit feature for nesting
Robin Murphy <[email protected]>
iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
Robin Murphy <[email protected]>
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
Jann Horn <[email protected]>
mm: lock_vma_under_rcu() must check vma->anon_vma under vma lock
-------------
Diffstat:
Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 + Documentation/arm64/silicon-errata.rst | 4 + Makefile | 4 +- arch/arm/boot/dts/at91-qil_a9260.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 2 +- arch/arm/boot/dts/at91rm9200.dtsi | 2 +- arch/arm/boot/dts/at91sam9260.dtsi | 4 +- arch/arm/boot/dts/at91sam9260ek.dts | 2 +- arch/arm/boot/dts/at91sam9261.dtsi | 4 +- arch/arm/boot/dts/at91sam9263.dtsi | 4 +- arch/arm/boot/dts/at91sam9g20.dtsi | 2 +- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 2 +- arch/arm/boot/dts/at91sam9g25.dtsi | 2 +- arch/arm/boot/dts/at91sam9g35.dtsi | 2 +- arch/arm/boot/dts/at91sam9g45.dtsi | 6 +- arch/arm/boot/dts/at91sam9n12.dtsi | 4 +- arch/arm/boot/dts/at91sam9rl.dtsi | 6 +- arch/arm/boot/dts/at91sam9x25.dtsi | 2 +- arch/arm/boot/dts/at91sam9x35.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5.dtsi | 6 +- arch/arm/boot/dts/imx53-sk-imx53.dts | 10 + arch/arm/boot/dts/imx6sll.dtsi | 2 +- arch/arm/boot/dts/sam9x60.dtsi | 32 +-- arch/arm/boot/dts/sama5d2.dtsi | 6 +- arch/arm/boot/dts/sama5d3.dtsi | 6 +- arch/arm/boot/dts/sama5d3_emac.dtsi | 2 +- arch/arm/boot/dts/sama5d4.dtsi | 6 +- arch/arm/boot/dts/sama7g5.dtsi | 4 +- arch/arm/boot/dts/usb_a9260.dts | 2 +- arch/arm/boot/dts/usb_a9263.dts | 2 +- .../boot/dts/altera/socfpga_stratix10_socdk.dts | 2 +- .../dts/altera/socfpga_stratix10_socdk_nand.dts | 2 +- .../dts/freescale/imx8mm-phyboard-polis-rdk.dts | 2 +- .../boot/dts/freescale/imx8mm-phycore-som.dtsi | 4 +- .../boot/dts/freescale/imx8mm-venice-gw7903.dts | 4 + .../boot/dts/freescale/imx8mm-venice-gw7904.dts | 4 + arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi | 2 +- arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 +- arch/arm64/kernel/fpsimd.c | 9 +- arch/arm64/kernel/ptrace.c | 10 +- arch/parisc/mm/fixmap.c | 3 - arch/parisc/mm/init.c | 34 +++ arch/powerpc/include/asm/word-at-a-time.h | 2 +- arch/powerpc/kernel/trace/ftrace_mprofile.S | 9 +- arch/powerpc/mm/init_64.c | 3 +- arch/riscv/kernel/crash_core.c | 2 + arch/s390/kernel/sthyi.c | 6 +- arch/s390/kvm/intercept.c | 9 +- arch/s390/mm/vmem.c | 2 + arch/x86/hyperv/hv_init.c | 21 ++ drivers/block/rbd.c | 28 ++- drivers/clk/imx/clk-imx93.c | 2 +- drivers/clk/mediatek/clk-mt8183.c | 27 ++ drivers/firmware/arm_scmi/mailbox.c | 4 +- drivers/firmware/arm_scmi/raw_mode.c | 5 +- drivers/firmware/arm_scmi/smc.c | 21 +- drivers/firmware/smccc/soc_id.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 35 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 3 +- drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 178 ++++++++++---- drivers/gpu/drm/i915/gt/gen8_engine_cs.h | 21 +- drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 2 + drivers/gpu/drm/i915/gt/intel_gt_regs.h | 16 +- drivers/gpu/drm/i915/gt/intel_lrc.c | 17 +- drivers/gpu/drm/i915/i915_active.c | 99 +++++--- drivers/gpu/drm/i915/i915_request.c | 11 + drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 3 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 50 ++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 8 + drivers/isdn/hardware/mISDN/hfcpci.c | 10 +- drivers/mtd/nand/raw/fsl_upm.c | 2 +- drivers/mtd/nand/raw/meson_nand.c | 3 +- drivers/mtd/nand/raw/omap_elm.c | 24 +- drivers/mtd/nand/raw/rockchip-nand-controller.c | 45 ++-- drivers/mtd/nand/spi/toshiba.c | 4 +- drivers/mtd/nand/spi/winbond.c | 4 +- drivers/mtd/spi-nor/spansion.c | 4 +- drivers/net/dsa/bcm_sf2.c | 8 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 85 ++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 14 +- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 2 +- drivers/net/ethernet/broadcom/tg3.c | 1 + drivers/net/ethernet/intel/ice/ice_main.c | 18 ++ drivers/net/ethernet/korina.c | 3 +- .../ethernet/marvell/octeon_ep/octep_ctrl_mbox.c | 3 + .../net/ethernet/marvell/prestera/prestera_pci.c | 3 +- .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 3 - .../net/ethernet/mellanox/mlx5/core/en/xsk/rx.c | 5 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 4 +- .../mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 4 +- .../ethernet/mellanox/mlx5/core/en_accel/ktls.c | 8 - .../ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 29 ++- .../mellanox/mlx5/core/en_accel/macsec_fs.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c | 10 + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 29 ++- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 20 +- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 21 +- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 3 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 105 ++++++-- .../ethernet/mellanox/mlx5/core/lib/fs_chains.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + .../ethernet/mellanox/mlx5/core/steering/dr_cmd.c | 5 +- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 1 + drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 16 ++ drivers/net/ethernet/qlogic/qed/qed_fcoe.c | 19 +- drivers/net/ethernet/qlogic/qed/qed_fcoe.h | 17 +- drivers/net/ethernet/qlogic/qed/qed_hw.c | 26 +- drivers/net/ethernet/qlogic/qed/qed_iscsi.c | 19 +- drivers/net/ethernet/qlogic/qed/qed_iscsi.h | 8 +- drivers/net/ethernet/qlogic/qed/qed_l2.c | 19 +- drivers/net/ethernet/qlogic/qed/qed_l2.h | 24 ++ drivers/net/ethernet/qlogic/qed/qed_main.c | 6 +- drivers/net/ethernet/sfc/siena/tx_common.c | 1 + drivers/net/ethernet/sfc/tx_common.c | 1 + drivers/net/ethernet/socionext/netsec.c | 11 + drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 3 +- drivers/net/ethernet/sun/sunvnet_common.c | 1 + drivers/net/ethernet/xilinx/ll_temac_main.c | 12 +- drivers/net/tap.c | 3 +- drivers/net/tun.c | 2 +- drivers/net/usb/cdc_ether.c | 21 ++ drivers/net/usb/lan78xx.c | 7 +- drivers/net/usb/r8152.c | 1 + drivers/net/usb/usbnet.c | 6 + drivers/net/usb/zaurus.c | 21 ++ drivers/net/wireguard/device.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 1 + drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 6 +- drivers/s390/net/qeth_core.h | 1 - drivers/s390/net/qeth_core_main.c | 2 - drivers/s390/net/qeth_l2_main.c | 9 +- drivers/s390/net/qeth_l3_main.c | 8 +- drivers/s390/scsi/zfcp_fc.c | 6 +- drivers/scsi/storvsc_drv.c | 4 + drivers/soc/imx/imx8mp-blk-ctrl.c | 2 +- fs/btrfs/block-group.c | 51 ++-- fs/btrfs/block-group.h | 4 +- fs/btrfs/free-space-tree.c | 24 +- fs/ceph/mds_client.c | 4 +- fs/ceph/mds_client.h | 5 + fs/ceph/super.c | 10 + fs/erofs/zdata.c | 7 +- fs/exfat/balloc.c | 6 +- fs/exfat/dir.c | 36 +-- fs/ext2/ext2.h | 12 - fs/ext2/super.c | 23 +- fs/f2fs/f2fs.h | 1 - fs/f2fs/file.c | 5 - fs/f2fs/node.c | 14 +- fs/file.c | 18 +- fs/ntfs3/attrlist.c | 4 +- fs/open.c | 2 +- fs/smb/client/dfs.c | 6 +- fs/super.c | 11 +- fs/sysv/itree.c | 4 + include/asm-generic/word-at-a-time.h | 2 +- include/linux/f2fs_fs.h | 1 + include/linux/netdevice.h | 26 +- include/linux/skbuff.h | 71 ------ include/linux/spi/spi-mem.h | 4 + include/net/gro.h | 44 ++++ include/net/gso.h | 109 ++++++++ include/net/inet_sock.h | 7 +- include/net/ip.h | 2 +- include/net/route.h | 4 +- include/net/udp.h | 1 + include/net/vxlan.h | 4 +- io_uring/timeout.c | 2 +- kernel/bpf/bloom_filter.c | 3 - kernel/bpf/bpf_local_storage.c | 3 - kernel/bpf/bpf_struct_ops.c | 3 - kernel/bpf/cpumap.c | 39 +-- kernel/bpf/devmap.c | 3 - kernel/bpf/hashtab.c | 6 - kernel/bpf/lpm_trie.c | 3 - kernel/bpf/queue_stack_maps.c | 4 - kernel/bpf/reuseport_array.c | 3 - kernel/bpf/stackmap.c | 3 - kernel/bpf/syscall.c | 136 ++++++---- kernel/trace/bpf_trace.c | 17 +- lib/Makefile | 6 + lib/debugobjects.c | 9 + lib/test_bitmap.c | 8 +- mm/filemap.c | 26 +- mm/gup.c | 2 +- mm/kasan/generic.c | 4 +- mm/kasan/tags.c | 2 +- mm/kmsan/core.c | 6 +- mm/kmsan/instrumentation.c | 2 +- mm/memcontrol.c | 19 +- mm/memory.c | 28 ++- net/bluetooth/l2cap_sock.c | 2 + net/can/raw.c | 2 +- net/ceph/osd_client.c | 20 +- net/core/Makefile | 2 +- net/core/bpf_sk_storage.c | 5 +- net/core/dev.c | 70 +----- net/core/gro.c | 59 +---- net/core/gso.c | 273 +++++++++++++++++++++ net/core/rtnetlink.c | 8 +- net/core/skbuff.c | 142 +---------- net/core/sock.c | 45 ++-- net/core/sock_map.c | 6 - net/dcb/dcbnl.c | 2 +- net/dccp/ipv6.c | 4 +- net/ipv4/af_inet.c | 1 + net/ipv4/esp4_offload.c | 1 + net/ipv4/gre_offload.c | 1 + net/ipv4/inet_diag.c | 4 +- net/ipv4/ip_output.c | 9 +- net/ipv4/ip_sockglue.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 4 +- net/ipv4/tcp_ipv4.c | 4 +- net/ipv4/tcp_metrics.c | 70 ++++-- net/ipv4/tcp_offload.c | 1 + net/ipv4/udp.c | 9 +- net/ipv4/udp_offload.c | 8 +- net/ipv6/esp6_offload.c | 1 + net/ipv6/ip6_offload.c | 1 + net/ipv6/ip6_output.c | 1 + net/ipv6/ip6mr.c | 2 +- net/ipv6/ping.c | 2 +- net/ipv6/raw.c | 6 +- net/ipv6/route.c | 7 +- net/ipv6/tcp_ipv6.c | 9 +- net/ipv6/udp.c | 12 +- net/ipv6/udp_offload.c | 8 +- net/l2tp/l2tp_ip6.c | 2 +- net/mac80211/tx.c | 1 + net/mpls/af_mpls.c | 1 + net/mpls/mpls_gso.c | 1 + net/mptcp/sockopt.c | 2 +- net/netfilter/nf_flow_table_ip.c | 1 + net/netfilter/nfnetlink_queue.c | 1 + net/netfilter/nft_socket.c | 2 +- net/netfilter/xt_socket.c | 4 +- net/nsh/nsh.c | 1 + net/openvswitch/actions.c | 1 + net/openvswitch/datapath.c | 1 + net/packet/af_packet.c | 12 +- net/sched/act_police.c | 1 + net/sched/cls_fw.c | 1 - net/sched/cls_route.c | 1 - net/sched/cls_u32.c | 57 ++++- net/sched/sch_cake.c | 1 + net/sched/sch_netem.c | 1 + net/sched/sch_taprio.c | 16 +- net/sched/sch_tbf.c | 1 + net/sctp/offload.c | 1 + net/smc/af_smc.c | 2 +- net/unix/af_unix.c | 2 +- net/wireless/scan.c | 2 +- net/xdp/xsk.c | 2 +- net/xdp/xskmap.c | 4 - net/xfrm/xfrm_device.c | 1 + net/xfrm/xfrm_interface_core.c | 1 + net/xfrm/xfrm_output.c | 1 + net/xfrm/xfrm_policy.c | 2 +- rust/bindings/bindings_helper.h | 1 + rust/kernel/allocator.rs | 74 ++++-- tools/perf/arch/arm64/util/pmu.c | 7 +- .../tests/shell/test_uprobe_from_different_cu.sh | 8 +- .../selftests/bpf/prog_tests/unpriv_bpf_disabled.c | 6 +- tools/testing/selftests/net/so_incoming_cpu.c | 2 +- tools/testing/selftests/rseq/rseq.c | 28 ++- .../tc-testing/tc-tests/qdiscs/taprio.json | 25 ++ tools/testing/vsock/Makefile | 2 +- 272 files changed, 2293 insertions(+), 1234 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/165 mm: lock_vma_under_rcu() must check vma->anon_vma under vma lock
From: Jann Horn <[email protected]>
commit 657b5146955eba331e01b9a6ae89ce2e716ba306 upstream.
lock_vma_under_rcu() tries to guarantee that __anon_vma_prepare() can't be called in the VMA-locked page fault path by ensuring that vma->anon_vma is set.
However, this check happens before the VMA is locked, which means a concurrent move_vma() can concurrently call unlink_anon_vmas(), which disassociates the VMA's anon_vma.
This means we can get UAF in the following scenario:
THREAD 1 THREAD 2
======== ========
<page fault>
lock_vma_under_rcu()
rcu_read_lock()
mas_walk()
check vma->anon_vma
mremap() syscall
move_vma()
vma_start_write()
unlink_anon_vmas()
<syscall end>
handle_mm_fault()
__handle_mm_fault()
handle_pte_fault()
do_pte_missing()
do_anonymous_page()
anon_vma_prepare()
__anon_vma_prepare()
find_mergeable_anon_vma()
mas_walk() [looks up VMA X]
munmap() syscall (deletes VMA X)
reusable_anon_vma() [called on freed VMA X]This is a security bug if you can hit it, although an attacker would have to win two races at once where the first race window is only a few instructions wide.
This patch is based on some previous discussion with Linus Torvalds on the security list.
--- mm/memory.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
mm/memory.c +16 -12
@@ -5410,27 +5410,28 @@ retry:if (!vma_is_anonymous (vma)) goto inval; -/* find_mergeable_anon_vma uses adjacent vmas which are not locked */ -if (!vma->anon_vma) - goto inval; -if (!vma_start_read (vma)) goto inval;/* +* find_mergeable_anon_vma uses adjacent vmas which are not locked. +* This check must happen after vma_start_read(); otherwise, a +* concurrent mremap() with MREMAP_DONTUNMAP could dissociate the VMA +* from its anon_vma. +*/ +if (unlikely (!vma->anon_vma)) + goto inval_end_read; + +/* * Due to the possibility of userfault handler dropping mmap_lock, avoid * it for now and fall back to page fault handling under mmap_lock. */ -if (userfaultfd_armed (vma)) { -vma_end_read (vma); - goto inval; - } +if (userfaultfd_armed (vma)) + goto inval_end_read;/* Check since vm_start/vm_end might change before we lock the VMA */ -if (unlikely (address < vma->vm_start || address >= vma->vm_end)) { -vma_end_read (vma); - goto inval; - } +if (unlikely (address < vma->vm_start || address >= vma->vm_end)) + goto inval_end_read;/* Check if the VMA got isolated after we found it */ if (vma->detached) {
@@ -5442,6 +5443,9 @@ retry:rcu_read_unlock ();return vma; + +inval_end_read: +vma_end_read (vma); inval:rcu_read_unlock ();count_vm_vma_lock_event (VMA_LOCK_ABORT );
Greg Kroah-Hartman
maintainerPATCH 2/165 iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
commit f322e8af35c7f23a8c08b595c38d6c855b2d836f upstream
MMU-600 versions prior to r1p0 fail to correctly generate a WFE wakeup event when the command queue transitions fom full to non-full. We can easily work around this by simply hiding the SEV capability such that we fall back to polling for space in the queue - since MMU-600 implements MSIs we wouldn't expect to need SEV for sync completion either, so this should have little to no impact.
--- Documentation/arm64/silicon-errata.rst | 2 + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 ++++++++++++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +++++ 3 files changed, 37 insertions(+)
Documentation/arm64/silicon-errata.rst +2 -0
@@ -143,6 +143,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | MMU-600 | #1076982 | N/A | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | +----------------+-----------------+-----------------+-----------------------------+
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +29 -0
@@ -3429,6 +3429,33 @@ static int arm_smmu_device_reset(structreturn 0 ; } +#define IIDR_IMPLEMENTER_ARM 0x43b +#define IIDR_PRODUCTID_ARM_MMU_600 0x483 + +static void arm_smmu_device_iidr_probe (struct arm_smmu_device *smmu) +{ +u32 reg; +unsigned int implementer, productid, variant, revision; + + reg =readl_relaxed (smmu->base +ARM_SMMU_IIDR ); + implementer =FIELD_GET (IIDR_IMPLEMENTER , reg); + productid =FIELD_GET (IIDR_PRODUCTID , reg); + variant =FIELD_GET (IIDR_VARIANT , reg); + revision =FIELD_GET (IIDR_REVISION , reg); + +switch (implementer) { +case IIDR_IMPLEMENTER_ARM : +switch (productid) { +case IIDR_PRODUCTID_ARM_MMU_600 : +/* Arm erratum 1076982 */ +if (variant ==0 && revision <=2 ) + smmu->features &= ~ARM_SMMU_FEAT_SEV ; +break ; + } +break ; + } +} +static int arm_smmu_device_hw_probe (struct arm_smmu_device *smmu) {u32 reg;
@@ -3635,6 +3662,8 @@ static int arm_smmu_device_hw_probe(stru smmu->ias =max (smmu->ias, smmu->oas); +arm_smmu_device_iidr_probe (smmu); +if (arm_smmu_sva_supported (smmu)) smmu->features |=ARM_SMMU_FEAT_SVA ;
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +6 -0
@@ -69,6 +69,12 @@#define IDR5_VAX GENMASK(11, 10)#define IDR5_VAX_52_BIT 1 +#define ARM_SMMU_IIDR 0x18 +#define IIDR_PRODUCTID GENMASK(31, 20) +#define IIDR_VARIANT GENMASK(19, 16) +#define IIDR_REVISION GENMASK(15, 12) +#define IIDR_IMPLEMENTER GENMASK(11, 0) +#define ARM_SMMU_CR0 0x20#define CR0_ATSCHK (1 << 4)#define CR0_CMDQEN (1 << 3)
Greg Kroah-Hartman
maintainerPATCH 3/165 iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
commit 309a15cb16bb075da1c99d46fb457db6a1a2669e upstream
To work around MMU-700 erratum 2812531 we need to ensure that certain sequences of commands cannot be issued without an intervening sync. In practice this falls out of our current command-batching machinery anyway - each batch only contains a single type of invalidation command, and ends with a sync. The only exception is when a batch is sufficiently large to need issuing across multiple command queue slots, wherein the earlier slots will not contain a sync and thus may in theory interleave with another batch being issued in parallel to create an affected sequence across the slot boundary.
Since MMU-700 supports range invalidate commands and thus we will prefer to use them (which also happens to avoid conditions for other errata), I'm not entirely sure it's even possible for a single high-level invalidate call to generate a batch of more than 63 commands, but for the sake of robustness and documentation, wire up an option to enforce that a sync is always inserted for every slot issued.
The other aspect is that the relative order of DVM commands cannot be controlled, so DVM cannot be used. Again that is already the status quo, but since we have at least defined ARM_SMMU_FEAT_BTM, we can explicitly disable it for documentation purposes even if it's not wired up anywhere yet.
--- Documentation/arm64/silicon-errata.rst | 2 ++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 12 ++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 3 files changed, 15 insertions(+)
Documentation/arm64/silicon-errata.rst +2 -0
@@ -145,6 +145,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-600 | #1076982 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | MMU-700 | #2812531 | N/A | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | +----------------+-----------------+-----------------+-----------------------------+
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +12 -0
@@ -894,6 +894,12 @@ static void arm_smmu_cmdq_batch_add(stru {int index; +if (cmds->num ==CMDQ_BATCH_ENTRIES -1 && + (smmu->options &ARM_SMMU_OPT_CMDQ_FORCE_SYNC )) { +arm_smmu_cmdq_issue_cmdlist (smmu, cmds->cmds, cmds->num, true); + cmds->num =0 ; + } +if (cmds->num ==CMDQ_BATCH_ENTRIES ) {arm_smmu_cmdq_issue_cmdlist (smmu, cmds->cmds, cmds->num, false); cmds->num =0 ;
@@ -3431,6 +3437,7 @@ static int arm_smmu_device_reset(struct#define IIDR_IMPLEMENTER_ARM 0x43b#define IIDR_PRODUCTID_ARM_MMU_600 0x483 +#define IIDR_PRODUCTID_ARM_MMU_700 0x487static void arm_smmu_device_iidr_probe (struct arm_smmu_device *smmu) {
@@ -3451,6 +3458,11 @@ static void arm_smmu_device_iidr_probe(sif (variant ==0 && revision <=2 ) smmu->features &= ~ARM_SMMU_FEAT_SEV ;break ; +case IIDR_PRODUCTID_ARM_MMU_700 : +/* Arm erratum 2812531 */ + smmu->features &= ~ARM_SMMU_FEAT_BTM ; + smmu->options |=ARM_SMMU_OPT_CMDQ_FORCE_SYNC ; +break ; }break ; }
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -0
@@ -650,6 +650,7 @@ struct arm_smmu_device {#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)#define ARM_SMMU_OPT_MSIPOLL (1 << 2) +#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3)u32 options;struct arm_smmu_cmdq cmdq;
Greg Kroah-Hartman
maintainerPATCH 4/165 iommu/arm-smmu-v3: Add explicit feature for nesting
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
commit 1d9777b9f3d55b4b6faf186ba4f1d6fb560c0523 upstream
In certain cases we may want to refuse to allow nested translation even when both stages are implemented, so let's add an explicit feature for nesting support which we can control in its own right. For now this merely serves as documentation, but it means a nice convenient check will be ready and waiting for the future nesting code.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 2 files changed, 5 insertions(+)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +4 -0
@@ -3674,6 +3674,10 @@ static int arm_smmu_device_hw_probe(stru smmu->ias =max (smmu->ias, smmu->oas); +if ((smmu->features &ARM_SMMU_FEAT_TRANS_S1 ) && + (smmu->features &ARM_SMMU_FEAT_TRANS_S2 )) + smmu->features |=ARM_SMMU_FEAT_NESTING ; +arm_smmu_device_iidr_probe (smmu);if (arm_smmu_sva_supported (smmu))
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -0
@@ -645,6 +645,7 @@ struct arm_smmu_device {#define ARM_SMMU_FEAT_BTM (1 << 16)#define ARM_SMMU_FEAT_SVA (1 << 17)#define ARM_SMMU_FEAT_E2H (1 << 18) +#define ARM_SMMU_FEAT_NESTING (1 << 19)u32 features;#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
Greg Kroah-Hartman
maintainerPATCH 5/165 iommu/arm-smmu-v3: Document nesting-related errata
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
commit 0bfbfc526c70606bf0fad302e4821087cbecfaf4 upstream
Both MMU-600 and MMU-700 have similar errata around TLB invalidation while both stages of translation are active, which will need some consideration once nesting support is implemented. For now, though, it's very easy to make our implicit lack of nesting support explicit for those cases, so they're less likely to be missed in future.
--- Documentation/arm64/silicon-errata.rst | 4 ++-- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-)
Documentation/arm64/silicon-errata.rst +2 -2
@@ -143,9 +143,9 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ -| ARM | MMU-600 | #1076982 | N/A | +| ARM | MMU-600 | #1076982,1209401| N/A | +----------------+-----------------+-----------------+-----------------------------+ -| ARM | MMU-700 | #2812531 | N/A | +| ARM | MMU-700 | #2268618,2812531| N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +5 -0
@@ -3457,11 +3457,16 @@ static void arm_smmu_device_iidr_probe(s/* Arm erratum 1076982 */ if (variant ==0 && revision <=2 ) smmu->features &= ~ARM_SMMU_FEAT_SEV ; +/* Arm erratum 1209401 */ +if (variant <2 ) + smmu->features &= ~ARM_SMMU_FEAT_NESTING ;break ;case IIDR_PRODUCTID_ARM_MMU_700 :/* Arm erratum 2812531 */ smmu->features &= ~ARM_SMMU_FEAT_BTM ; smmu->options |=ARM_SMMU_OPT_CMDQ_FORCE_SYNC ; +/* Arm errata 2268618, 2812531 */ + smmu->features &= ~ARM_SMMU_FEAT_NESTING ;break ; }break ;
Greg Kroah-Hartman
maintainerPATCH 6/165 arm64: dts: imx8mm-venice-gw7903: disable disp_blk_ctrl
In reply to Greg Kroah-HartmanFrom: Tim Harvey <[email protected]>
[ Upstream commit 3e7d3c5e13b05dda9db92d98803a626378e75438 ]
The GW7903 does not connect the VDD_MIPI power rails thus MIPI is
disabled. However we must also disable disp_blk_ctrl as it uses thepgc_mipi power domain and without it being disabled imx8m-blk-ctrl will
fail to probe:
imx8m-blk-ctrl 32e28000.blk-ctrl: error -ETIMEDOUT: failed to attach power domain "mipi-dsi"
imx8m-blk-ctrl: probe of 32e28000.blk-ctrl failed with error -110
--- arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts +4 -0
@@ -567,6 +567,10 @@ status = "okay"; }; +&disp_blk_ctrl { + status = "disabled"; +}; + &pgc_mipi { status = "disabled"; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 7/165 arm64: dts: imx8mm-venice-gw7904: disable disp_blk_ctrl
In reply to Greg Kroah-HartmanFrom: Tim Harvey <[email protected]>
[ Upstream commit f7a0b57524cf811ac06257a5099f1b7c19ee7310 ]
The GW7904 does not connect the VDD_MIPI power rails thus MIPI is disabled. However we must also disable disp_blk_ctrl as it uses the pgc_mipi power domain and without it being disabled imx8m-blk-ctrl will fail to probe:
imx8m-blk-ctrl 32e28000.blk-ctrl: error -ETIMEDOUT: failed to attach power domain "mipi-dsi"
imx8m-blk-ctrl: probe of 32e28000.blk-ctrl failed with error -110
--- arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts +4 -0
@@ -628,6 +628,10 @@ status = "okay"; }; +&disp_blk_ctrl { + status = "disabled"; +}; + &pgc_mipi { status = "disabled"; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 8/165 arm64: dts: phycore-imx8mm: Label typo-fix of VPU
In reply to Greg Kroah-HartmanFrom: Yashwanth Varakala <[email protected]>
[ Upstream commit cddeefc1663294fb74b31ff5029a83c0e819ff3a ]
Corrected the label of the VPU regulator node (buck 3) from reg_vdd_gpu to reg_vdd_vpu.
--- arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi +1 -1
@@ -210,7 +210,7 @@ }; }; - reg_vdd_gpu: buck3 { + reg_vdd_vpu: buck3 { regulator-always-on; regulator-boot-on; regulator-max-microvolt = <1000000>;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 9/165 arm64: dts: phycore-imx8mm: Correction in gpio-line-names
In reply to Greg Kroah-HartmanFrom: Yashwanth Varakala <[email protected]>
[ Upstream commit 1ef0aa137a96c5f0564f2db0c556a4f0f60ce8f5 ]
Remove unused nINT_ETHPHY entry from gpio-line-names in gpio1 nodes of phyCORE-i.MX8MM and phyBOARD-Polis-i.MX8MM devicetrees.
--- arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts | 2 +- arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts +1 -1
@@ -141,7 +141,7 @@ }; &gpio1 { - gpio-line-names = "nINT_ETHPHY", "LED_RED", "WDOG_INT", "X_RTC_INT", + gpio-line-names = "", "LED_RED", "WDOG_INT", "X_RTC_INT", "", "", "", "RESET_ETHPHY", "CAN_nINT", "CAN_EN", "nENABLE_FLATLINK", "", "USB_OTG_VBUS_EN", "", "LED_GREEN", "LED_BLUE";
arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi +1 -1
@@ -111,7 +111,7 @@ }; &gpio1 { - gpio-line-names = "nINT_ETHPHY", "", "WDOG_INT", "X_RTC_INT", + gpio-line-names = "", "", "WDOG_INT", "X_RTC_INT", "", "", "", "RESET_ETHPHY", "", "", "nENABLE_FLATLINK"; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 10/165 arm64: dts: imx8mn-var-som: add missing pull-up for onboard PHY reset pinmux
In reply to Greg Kroah-HartmanFrom: Hugo Villeneuve <[email protected]>
[ Upstream commit 253be5b53c2792fb4384f8005b05421e6f040ee3 ]
For SOMs with an onboard PHY, the RESET_N pull-up resistor is currently deactivated in the pinmux configuration. When the pinmux code selects the GPIO function for this pin, with a default direction of input, this prevents the RESET_N pin from being taken to the proper 3.3V level (deasserted), and this results in the PHY being not detected since it is held in reset.
Taken from RESET_N pin description in ADIN13000 datasheet:
This pin requires a 1K pull-up resistor to AVDD_3P3.
Activate the pull-up resistor to fix the issue.
--- arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi +1 -1
@@ -351,7 +351,7 @@ MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f - MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x159 >; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 11/165 arm64: dts: freescale: Fix VPU G2 clock
In reply to Greg Kroah-HartmanFrom: Benjamin Gaignard <[email protected]>
[ Upstream commit b27bfc5103c72f84859bd32731b6a09eafdeda05 ]
Set VPU G2 clock to 300MHz like described in documentation. This fixes pixels error occurring with large resolution ( >= 2560x1600) HEVC test stream when using the postprocessor to produce NV12.
--- arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mq.dtsi +1 -1
@@ -770,7 +770,7 @@ <&clk IMX8MQ_SYS1_PLL_800M>, <&clk IMX8MQ_VPU_PLL>; assigned-clock-rates = <600000000>, - <600000000>, + <300000000>, <800000000>, <0>; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 12/165 firmware: smccc: Fix use of uninitialised results structure
In reply to Greg Kroah-HartmanFrom: Punit Agrawal <[email protected]>
[ Upstream commit d05799d7b4a39fa71c65aa277128ac7c843ffcdc ]
Commit 35727af2b15d ("irqchip/gicv3: Workaround for NVIDIA erratum T241-FABRIC-4") moved the initialisation of the SoC version to arm_smccc_version_init() but forgot to update the results structure and it's usage.
Fix the use of the uninitialised results structure and update the error strings.
--- drivers/firmware/smccc/soc_id.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/firmware/smccc/soc_id.c +2 -3
@@ -34,7 +34,6 @@ static struct soc_device_attribute *soc_dev_attr;static int __init smccc_soc_init (void ) { -struct arm_smccc_res res;int soc_id_rev, soc_id_version;static char soc_id_str[20 ], soc_id_rev_str[12 ];static char soc_id_jep106_id_str[12 ];
@@ -49,13 +48,13 @@ static int __init smccc_soc_init(void) }if (soc_id_version <0 ) { -pr_err ("ARCH_SOC_ID(0) returned error: %lx\n" , res.a0); +pr_err ("Invalid SoC Version: %x\n" , soc_id_version);return -EINVAL ; } soc_id_rev =arm_smccc_get_soc_id_revision ();if (soc_id_rev <0 ) { -pr_err ("ARCH_SOC_ID(1) returned error: %lx\n" , res.a0); +pr_err ("Invalid SoC Revision: %x\n" , soc_id_rev);return -EINVAL ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 13/165 firmware: arm_scmi: Fix signed error return values handling
In reply to Greg Kroah-HartmanFrom: Sukrut Bellary <[email protected]>
[ Upstream commit 81b233b8dd72f2d1df3da8bd4bd4f8c5e84937b9 ]
Handle signed error return values returned by simple_write_to_buffer(). In case of an error, return the error code.
--- drivers/firmware/arm_scmi/raw_mode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/firmware/arm_scmi/raw_mode.c +4 -1
@@ -818,10 +818,13 @@ static ssize_t scmi_dbg_raw_mode_common_write(struct file *filp,* before sending it with a single RAW xfer. */ if (rd->tx_size < rd->tx_req_size) { -size_t cnt; +ssize_t cnt; cnt =simple_write_to_buffer (rd->tx.buf, rd->tx.len, ppos, buf, count); +if (cnt <0 ) +return cnt; + rd->tx_size += cnt;if (cnt < count)return cnt;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 14/165 lib/bitmap: workaround const_eval test build failure
In reply to Greg Kroah-HartmanFrom: Yury Norov <[email protected]>
[ Upstream commit 2356d198d2b4ddec24efea98271cb3be230bc787 ]
When building with Clang, and when KASAN and GCOV_PROFILE_ALL are both enabled, the test fails to build [1]:
Quoted 1 line
Quoted 1 line
lib/test_bitmap.c:920:2: error: call to '__compiletime_assert_239' declared with 'error' attribute:BUILD_BUG_ONfailed: !__builtin_constant_p(res)
BUILD_BUG_ON(!__builtin_constant_p(res));
^
include/linux/build_bug.h:50:2: note: expanded from macro 'BUILD_BUG_ON'
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
^
include/linux/build_bug.h:39:37: note: expanded from macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/compiler_types.h:352:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:340:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:333:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^ <scratch space>:185:1: note: expanded from here __compiletime_assert_239
Originally it was attributed to s390, which now looks seemingly wrong. The issue is not related to bitmap code itself, but it breaks build for a given configuration.
Disabling the const_eval test under that config may potentially hide other bugs. Instead, workaround it by disabling GCOV for the test_bitmap unless the compiler will get fixed.
[1] https://github.com/ClangBuiltLinux/linux/issues/1874
--- lib/Makefile | 6 ++++++ lib/test_bitmap.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-)
lib/Makefile +6 -0
@@ -82,7 +82,13 @@ obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o obj-$(CONFIG_TEST_PRINTF) += test_printf.o obj-$(CONFIG_TEST_SCANF) += test_scanf.o + obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o +ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_KASAN),yy) +# FIXME: Clang breaks test_bitmap_const_eval when KASAN and GCOV are enabled +GCOV_PROFILE_test_bitmap.o := n +endif + obj-$(CONFIG_TEST_UUID) += test_uuid.o obj-$(CONFIG_TEST_XARRAY) += test_xarray.o obj-$(CONFIG_TEST_MAPLE_TREE) += test_maple_tree.o
lib/test_bitmap.c +4 -4
@@ -1149,6 +1149,10 @@ static void __init test_bitmap_print_buf(void) } } +/* +* FIXME: Clang breaks compile-time evaluations when KASAN and GCOV are enabled. +* To workaround it, GCOV is force-disabled in Makefile for this configuration. +*/ static void __init test_bitmap_const_eval (void ) {DECLARE_BITMAP (bitmap,BITS_PER_LONG );
@@ -1174,11 +1178,7 @@ static void __init test_bitmap_const_eval(void)* the compiler is fixed. */ bitmap_clear (bitmap,0 ,BITS_PER_LONG ); -#if defined(__s390__) && defined(__clang__) -if (!const_test_bit (7 , bitmap)) -#elseif (!test_bit (7 , bitmap)) -#endif bitmap_set (bitmap,5 ,2 );/* Equals to `unsigned long bitopvar = BIT(20)` */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 15/165 ARM: dts: nxp/imx: limit sk-imx53 supported frequencies
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit c486762fb17c99fd642beea3e1e4744d093c262a ]
The SK-IMX53 board, bearing i.MX536A CPU, is not stable when running at 1.2 GHz (default iMX53 maximum). The SoC is only rated up to 800 MHz. Disable 1.2 GHz and 1 GHz frequencies.
--- arch/arm/boot/dts/imx53-sk-imx53.dts | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm/boot/dts/imx53-sk-imx53.dts +10 -0
@@ -60,6 +60,16 @@ status = "okay"; }; +&cpu0 { + /* CPU rated to 800 MHz, not the default 1.2GHz. */ + operating-points = < + /* kHz uV */ + 166666 850000 + 400000 900000 + 800000 1050000 + >; +}; + &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 16/165 soc: imx: imx8mp-blk-ctrl: register HSIO PLL clock as bus_power_dev child
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
[ Upstream commit 53cab4d871690c49fac87c657cbf459e39c5b93b ]
The blk-ctrl device is deliberately placed outside of the GPC power domain as it needs to control the power sequencing of the blk-ctrl domains together with the GPC domains.
Clock runtime PM works by operating on the clock parent device, which doesn't translate into the neccessary GPC power domain action if the clk parent is not part of the GPC power domain. Use the bus_power_device as the parent for the clock to trigger the proper GPC domain actions on clock runtime power management.
--- drivers/soc/imx/imx8mp-blk-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soc/imx/imx8mp-blk-ctrl.c +1 -1
@@ -164,7 +164,7 @@ static int imx8mp_hsio_blk_ctrl_probe(struct imx8mp_blk_ctrl *bc) clk_hsio_pll->hw.init = &init; hw = &clk_hsio_pll->hw; - ret =devm_clk_hw_register (bc->dev, hw); + ret =devm_clk_hw_register (bc->bus_power_dev, hw);if (ret)return ret;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 17/165 firmware: arm_scmi: Fix chan_free cleanup on SMC
In reply to Greg Kroah-HartmanFrom: Cristian Marussi <[email protected]>
[ Upstream commit d1ff11d7ad8704f8d615f6446041c221b2d2ec4d ]
SCMI transport based on SMC can optionally use an additional IRQ to signal message completion. The associated interrupt handler is currently allocated using devres but on shutdown the core SCMI stack will call .chan_free() well before any managed cleanup is invoked by devres. As a consequence, the arrival of a late reply to an in-flight pending transaction could still trigger the interrupt handler well after the SCMI core has cleaned up the channels, with unpleasant results.
Inhibit further message processing on the IRQ path by explicitly freeing the IRQ inside .chan_free() callback itself.
--- drivers/firmware/arm_scmi/smc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/firmware/arm_scmi/smc.c +11 -6
@@ -23,6 +23,7 @@/** * struct scmi_smc - Structure representing a SCMI smc transport * +* @irq: An optional IRQ for completion * @cinfo: SCMI channel info * @shmem: Transmit/Receive shared memory area * @shmem_lock: Lock to protect access to Tx/Rx shared memory area.
@@ -33,6 +34,7 @@*/ struct scmi_smc { +int irq;struct scmi_chan_info *cinfo;struct scmi_shared_mem __iomem *shmem;/* Protect access to shmem area */
@@ -106,7 +108,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,struct resource res;struct device_node *np;u32 func_id; -int ret, irq; +int ret;if (!tx)return -ENODEV ;
@@ -142,11 +144,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,* completion of a message is signaled by an interrupt rather than by * the return of the SMC call. */ - irq =of_irq_get_byname (cdev->of_node,"a2p" ); -if (irq >0 ) { - ret =devm_request_irq (dev, irq, smc_msg_done_isr, -IRQF_NO_SUSPEND , -dev_name (dev), scmi_info); + scmi_info->irq =of_irq_get_byname (cdev->of_node,"a2p" ); +if (scmi_info->irq >0 ) { + ret =request_irq (scmi_info->irq, smc_msg_done_isr, +IRQF_NO_SUSPEND ,dev_name (dev), scmi_info);if (ret) {dev_err (dev,"failed to setup SCMI smc irq\n" );return ret;
@@ -168,6 +169,10 @@ static int smc_chan_free(int id, void *p, void *data)struct scmi_chan_info *cinfo = p;struct scmi_smc *scmi_info = cinfo->transport_info; +/* Ignore any possible further reception on the IRQ path */ +if (scmi_info->irq >0 ) +free_irq (scmi_info->irq, scmi_info); + cinfo->transport_info =NULL ; scmi_info->cinfo =NULL ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 18/165 ARM: dts: at91: use clock-controller name for PMC nodes
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit d08f92bdfb2dc4a2a14237cfd8a22c568781797c ]
Use clock-controller generic name for PMC nodes.
Stable-dep-of: f6ad3c13f1b8 ("ARM: dts: at91: sam9x60: fix the SOC detection")
--- arch/arm/boot/dts/at91rm9200.dtsi | 2 +- arch/arm/boot/dts/at91sam9260.dtsi | 2 +- arch/arm/boot/dts/at91sam9261.dtsi | 2 +- arch/arm/boot/dts/at91sam9263.dtsi | 2 +- arch/arm/boot/dts/at91sam9g20.dtsi | 2 +- arch/arm/boot/dts/at91sam9g25.dtsi | 2 +- arch/arm/boot/dts/at91sam9g35.dtsi | 2 +- arch/arm/boot/dts/at91sam9g45.dtsi | 2 +- arch/arm/boot/dts/at91sam9n12.dtsi | 2 +- arch/arm/boot/dts/at91sam9rl.dtsi | 2 +- arch/arm/boot/dts/at91sam9x25.dtsi | 2 +- arch/arm/boot/dts/at91sam9x35.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5.dtsi | 2 +- arch/arm/boot/dts/sam9x60.dtsi | 2 +- arch/arm/boot/dts/sama5d2.dtsi | 2 +- arch/arm/boot/dts/sama5d3.dtsi | 2 +- arch/arm/boot/dts/sama5d3_emac.dtsi | 2 +- arch/arm/boot/dts/sama5d4.dtsi | 2 +- arch/arm/boot/dts/sama7g5.dtsi | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-)
arch/arm/boot/dts/at91rm9200.dtsi +1 -1
@@ -102,7 +102,7 @@ reg = <0xffffff00 0x100>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91rm9200-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9260.dtsi +1 -1
@@ -115,7 +115,7 @@ reg = <0xffffee00 0x200>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9260-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9261.dtsi +1 -1
@@ -599,7 +599,7 @@ }; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9261-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9263.dtsi +1 -1
@@ -101,7 +101,7 @@ atmel,external-irqs = <30 31>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9263-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9g20.dtsi +1 -1
@@ -41,7 +41,7 @@ atmel,adc-startup-time = <40>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9g20-pmc", "atmel,at91sam9260-pmc", "syscon"; }; };
arch/arm/boot/dts/at91sam9g25.dtsi +1 -1
@@ -26,7 +26,7 @@ >; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9g25-pmc", "atmel,at91sam9x5-pmc", "syscon"; }; };
arch/arm/boot/dts/at91sam9g35.dtsi +1 -1
@@ -25,7 +25,7 @@ >; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9g35-pmc", "atmel,at91sam9x5-pmc", "syscon"; }; };
arch/arm/boot/dts/at91sam9g45.dtsi +1 -1
@@ -129,7 +129,7 @@ reg = <0xffffea00 0x200>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9g45-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9n12.dtsi +1 -1
@@ -118,7 +118,7 @@ reg = <0xffffea00 0x200>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9n12-pmc", "syscon"; reg = <0xfffffc00 0x200>; #clock-cells = <2>;
arch/arm/boot/dts/at91sam9rl.dtsi +1 -1
@@ -763,7 +763,7 @@ }; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9rl-pmc", "syscon"; reg = <0xfffffc00 0x100>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/at91sam9x25.dtsi +1 -1
@@ -27,7 +27,7 @@ >; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9x25-pmc", "atmel,at91sam9x5-pmc", "syscon"; }; };
arch/arm/boot/dts/at91sam9x35.dtsi +1 -1
@@ -26,7 +26,7 @@ >; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9x35-pmc", "atmel,at91sam9x5-pmc", "syscon"; }; };
arch/arm/boot/dts/at91sam9x5.dtsi +1 -1
@@ -126,7 +126,7 @@ reg = <0xffffea00 0x200>; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,at91sam9x5-pmc", "syscon"; reg = <0xfffffc00 0x200>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/sam9x60.dtsi +1 -1
@@ -1282,7 +1282,7 @@ }; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "microchip,sam9x60-pmc", "syscon"; reg = <0xfffffc00 0x200>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/sama5d2.dtsi +1 -1
@@ -284,7 +284,7 @@ clock-names = "dma_clk"; }; - pmc: pmc@f0014000 { + pmc: clock-controller@f0014000 { compatible = "atmel,sama5d2-pmc", "syscon"; reg = <0xf0014000 0x160>; interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/sama5d3.dtsi +1 -1
@@ -1001,7 +1001,7 @@ }; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { compatible = "atmel,sama5d3-pmc", "syscon"; reg = <0xfffffc00 0x120>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/sama5d3_emac.dtsi +1 -1
@@ -30,7 +30,7 @@ }; }; - pmc: pmc@fffffc00 { + pmc: clock-controller@fffffc00 { }; macb1: ethernet@f802c000 {
arch/arm/boot/dts/sama5d4.dtsi +1 -1
@@ -250,7 +250,7 @@ clock-names = "dma_clk"; }; - pmc: pmc@f0018000 { + pmc: clock-controller@f0018000 { compatible = "atmel,sama5d4-pmc", "syscon"; reg = <0xf0018000 0x120>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
arch/arm/boot/dts/sama7g5.dtsi +1 -1
@@ -241,7 +241,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; }; - pmc: pmc@e0018000 { + pmc: clock-controller@e0018000 { compatible = "microchip,sama7g5-pmc", "syscon"; reg = <0xe0018000 0x200>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 19/165 ARM: dts: at91: use clock-controller name for sckc nodes
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit 3ecb546333089195b6a1508cb58627b0797a26ca ]
Use clock-controller generic name for slow clock controller nodes.
Stable-dep-of: f6ad3c13f1b8 ("ARM: dts: at91: sam9x60: fix the SOC detection")
--- arch/arm/boot/dts/at91sam9g45.dtsi | 2 +- arch/arm/boot/dts/at91sam9rl.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5.dtsi | 2 +- arch/arm/boot/dts/sam9x60.dtsi | 2 +- arch/arm/boot/dts/sama5d2.dtsi | 2 +- arch/arm/boot/dts/sama5d3.dtsi | 2 +- arch/arm/boot/dts/sama5d4.dtsi | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-)
arch/arm/boot/dts/at91sam9g45.dtsi +1 -1
@@ -923,7 +923,7 @@ status = "disabled"; }; - clk32k: sckc@fffffd50 { + clk32k: clock-controller@fffffd50 { compatible = "atmel,at91sam9x5-sckc"; reg = <0xfffffd50 0x4>; clocks = <&slow_xtal>;
arch/arm/boot/dts/at91sam9rl.dtsi +1 -1
@@ -799,7 +799,7 @@ status = "disabled"; }; - clk32k: sckc@fffffd50 { + clk32k: clock-controller@fffffd50 { compatible = "atmel,at91sam9x5-sckc"; reg = <0xfffffd50 0x4>; clocks = <&slow_xtal>;
arch/arm/boot/dts/at91sam9x5.dtsi +1 -1
@@ -154,7 +154,7 @@ clocks = <&pmc PMC_TYPE_CORE PMC_MCK>; }; - clk32k: sckc@fffffe50 { + clk32k: clock-controller@fffffe50 { compatible = "atmel,at91sam9x5-sckc"; reg = <0xfffffe50 0x4>; clocks = <&slow_xtal>;
arch/arm/boot/dts/sam9x60.dtsi +1 -1
@@ -1322,7 +1322,7 @@ clocks = <&pmc PMC_TYPE_CORE PMC_MCK>; }; - clk32k: sckc@fffffe50 { + clk32k: clock-controller@fffffe50 { compatible = "microchip,sam9x60-sckc"; reg = <0xfffffe50 0x4>; clocks = <&slow_xtal>;
arch/arm/boot/dts/sama5d2.dtsi +1 -1
@@ -704,7 +704,7 @@ status = "disabled"; }; - clk32k: sckc@f8048050 { + clk32k: clock-controller@f8048050 { compatible = "atmel,sama5d4-sckc"; reg = <0xf8048050 0x4>;
arch/arm/boot/dts/sama5d3.dtsi +1 -1
@@ -1040,7 +1040,7 @@ status = "disabled"; }; - clk32k: sckc@fffffe50 { + clk32k: clock-controller@fffffe50 { compatible = "atmel,sama5d3-sckc"; reg = <0xfffffe50 0x4>; clocks = <&slow_xtal>;
arch/arm/boot/dts/sama5d4.dtsi +1 -1
@@ -761,7 +761,7 @@ status = "disabled"; }; - clk32k: sckc@fc068650 { + clk32k: clock-controller@fc068650 { compatible = "atmel,sama5d4-sckc"; reg = <0xfc068650 0x4>; #clock-cells = <0>;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 20/165 ARM: dts: at91: use generic name for shutdown controller
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit 327ca228e58be498446244eb7cf39b892adda5d7 ]
Use poweroff generic name for shdwc node to cope with device tree specifications.
Stable-dep-of: f6ad3c13f1b8 ("ARM: dts: at91: sam9x60: fix the SOC detection")
--- arch/arm/boot/dts/at91-qil_a9260.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 2 +- arch/arm/boot/dts/at91sam9260.dtsi | 2 +- arch/arm/boot/dts/at91sam9260ek.dts | 2 +- arch/arm/boot/dts/at91sam9261.dtsi | 2 +- arch/arm/boot/dts/at91sam9263.dtsi | 2 +- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 2 +- arch/arm/boot/dts/at91sam9g45.dtsi | 2 +- arch/arm/boot/dts/at91sam9n12.dtsi | 2 +- arch/arm/boot/dts/at91sam9rl.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5.dtsi | 2 +- arch/arm/boot/dts/sam9x60.dtsi | 2 +- arch/arm/boot/dts/sama5d2.dtsi | 2 +- arch/arm/boot/dts/sama5d3.dtsi | 2 +- arch/arm/boot/dts/sama5d4.dtsi | 2 +- arch/arm/boot/dts/sama7g5.dtsi | 2 +- arch/arm/boot/dts/usb_a9260.dts | 2 +- arch/arm/boot/dts/usb_a9263.dts | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-)
arch/arm/boot/dts/at91-qil_a9260.dts +1 -1
@@ -108,7 +108,7 @@ status = "okay"; }; - shdwc@fffffd10 { + shdwc: poweroff@fffffd10 { atmel,wakeup-counter = <10>; atmel,wakeup-rtt-timer; };
arch/arm/boot/dts/at91-sama5d27_som1_ek.dts +1 -1
@@ -139,7 +139,7 @@ }; }; - shdwc@f8048010 { + poweroff@f8048010 { debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts +1 -1
@@ -204,7 +204,7 @@ }; }; - shdwc@f8048010 { + poweroff@f8048010 { debounce-delay-us = <976>; input@0 {
arch/arm/boot/dts/at91-sama5d2_xplained.dts +1 -1
@@ -348,7 +348,7 @@ }; }; - shdwc@f8048010 { + poweroff@f8048010 { debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
arch/arm/boot/dts/at91sam9260.dtsi +1 -1
@@ -130,7 +130,7 @@ clocks = <&pmc PMC_TYPE_CORE PMC_SLOW>; }; - shdwc@fffffd10 { + shdwc: poweroff@fffffd10 { compatible = "atmel,at91sam9260-shdwc"; reg = <0xfffffd10 0x10>; clocks = <&pmc PMC_TYPE_CORE PMC_SLOW>;
arch/arm/boot/dts/at91sam9260ek.dts +1 -1
@@ -112,7 +112,7 @@ }; }; - shdwc@fffffd10 { + shdwc: poweroff@fffffd10 { atmel,wakeup-counter = <10>; atmel,wakeup-rtt-timer; };
arch/arm/boot/dts/at91sam9261.dtsi +1 -1
@@ -614,7 +614,7 @@ clocks = <&slow_xtal>; }; - shdwc@fffffd10 { + poweroff@fffffd10 { compatible = "atmel,at91sam9260-shdwc"; reg = <0xfffffd10 0x10>; clocks = <&slow_xtal>;
arch/arm/boot/dts/at91sam9263.dtsi +1 -1
@@ -158,7 +158,7 @@ clocks = <&slow_xtal>; }; - shdwc@fffffd10 { + poweroff@fffffd10 { compatible = "atmel,at91sam9260-shdwc"; reg = <0xfffffd10 0x10>; clocks = <&slow_xtal>;
arch/arm/boot/dts/at91sam9g20ek_common.dtsi +1 -1
@@ -126,7 +126,7 @@ }; }; - shdwc@fffffd10 { + shdwc: poweroff@fffffd10 { atmel,wakeup-counter = <10>; atmel,wakeup-rtt-timer; };
arch/arm/boot/dts/at91sam9g45.dtsi +1 -1
@@ -152,7 +152,7 @@ }; - shdwc@fffffd10 { + poweroff@fffffd10 { compatible = "atmel,at91sam9rl-shdwc"; reg = <0xfffffd10 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/at91sam9n12.dtsi +1 -1
@@ -140,7 +140,7 @@ clocks = <&pmc PMC_TYPE_CORE PMC_MCK>; }; - shdwc@fffffe10 { + poweroff@fffffe10 { compatible = "atmel,at91sam9x5-shdwc"; reg = <0xfffffe10 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/at91sam9rl.dtsi +1 -1
@@ -778,7 +778,7 @@ clocks = <&clk32k>; }; - shdwc@fffffd10 { + poweroff@fffffd10 { compatible = "atmel,at91sam9260-shdwc"; reg = <0xfffffd10 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/at91sam9x5.dtsi +1 -1
@@ -141,7 +141,7 @@ clocks = <&clk32k>; }; - shutdown_controller: shdwc@fffffe10 { + shutdown_controller: poweroff@fffffe10 { compatible = "atmel,at91sam9x5-shdwc"; reg = <0xfffffe10 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/sam9x60.dtsi +1 -1
@@ -1297,7 +1297,7 @@ clocks = <&clk32k 0>; }; - shutdown_controller: shdwc@fffffe10 { + shutdown_controller: poweroff@fffffe10 { compatible = "microchip,sam9x60-shdwc"; reg = <0xfffffe10 0x10>; clocks = <&clk32k 0>;
arch/arm/boot/dts/sama5d2.dtsi +1 -1
@@ -680,7 +680,7 @@ clocks = <&clk32k>; }; - shutdown_controller: shdwc@f8048010 { + shutdown_controller: poweroff@f8048010 { compatible = "atmel,sama5d2-shdwc"; reg = <0xf8048010 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/sama5d3.dtsi +1 -1
@@ -1016,7 +1016,7 @@ clocks = <&clk32k>; }; - shutdown_controller: shutdown-controller@fffffe10 { + shutdown_controller: poweroff@fffffe10 { compatible = "atmel,at91sam9x5-shdwc"; reg = <0xfffffe10 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/sama5d4.dtsi +1 -1
@@ -740,7 +740,7 @@ clocks = <&clk32k>; }; - shutdown_controller: shdwc@fc068610 { + shutdown_controller: poweroff@fc068610 { compatible = "atmel,at91sam9x5-shdwc"; reg = <0xfc068610 0x10>; clocks = <&clk32k>;
arch/arm/boot/dts/sama7g5.dtsi +1 -1
@@ -257,7 +257,7 @@ clocks = <&clk32k 0>; }; - shdwc: shdwc@e001d010 { + shdwc: poweroff@e001d010 { compatible = "microchip,sama7g5-shdwc", "syscon"; reg = <0xe001d010 0x10>; clocks = <&clk32k 0>;
arch/arm/boot/dts/usb_a9260.dts +1 -1
@@ -22,7 +22,7 @@ ahb { apb { - shdwc@fffffd10 { + shdwc: poweroff@fffffd10 { atmel,wakeup-counter = <10>; atmel,wakeup-rtt-timer; };
arch/arm/boot/dts/usb_a9263.dts +1 -1
@@ -67,7 +67,7 @@ }; }; - shdwc@fffffd10 { + poweroff@fffffd10 { atmel,wakeup-counter = <10>; atmel,wakeup-rtt-timer; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 21/165 ARM: dts: at91: sam9x60: fix the SOC detection
In reply to Greg Kroah-HartmanFrom: Durai Manickam KR <[email protected]>
[ Upstream commit f6ad3c13f1b8c4e785cb7bd423887197142f47b0 ]
Remove the dbgu compatible strings in the UART submodule of the flexcom for the proper SOC detection.
--- arch/arm/boot/dts/sam9x60.dtsi | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
arch/arm/boot/dts/sam9x60.dtsi +13 -13
@@ -172,7 +172,7 @@ status = "disabled"; uart4: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -240,7 +240,7 @@ status = "disabled"; uart5: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; atmel,usart-mode = <AT91_USART_MODE_SERIAL>; interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>;
@@ -370,7 +370,7 @@ status = "disabled"; uart11: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -419,7 +419,7 @@ status = "disabled"; uart12: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <33 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -576,7 +576,7 @@ status = "disabled"; uart6: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <9 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -625,7 +625,7 @@ status = "disabled"; uart7: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <10 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -674,7 +674,7 @@ status = "disabled"; uart8: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -723,7 +723,7 @@ status = "disabled"; uart0: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -791,7 +791,7 @@ status = "disabled"; uart1: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <6 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -859,7 +859,7 @@ status = "disabled"; uart2: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <7 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -927,7 +927,7 @@ status = "disabled"; uart3: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <8 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -1050,7 +1050,7 @@ status = "disabled"; uart9: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <15 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
@@ -1099,7 +1099,7 @@ status = "disabled"; uart10: serial@200 { - compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; + compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart"; reg = <0x200 0x200>; interrupts = <16 IRQ_TYPE_LEVEL_HIGH 7>; dmas = <&dma0
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 22/165 word-at-a-time: use the same return type for has_zero regardless of endianness
In reply to Greg Kroah-HartmanFrom: [email protected] <[email protected]>
[ Upstream commit 79e8328e5acbe691bbde029a52c89d70dcbc22f3 ]
Compiling big-endian targets with Clang produces the diagnostic:
fs/namei.c:2173:13: warning: use of bitwise '|' with boolean operands [-Wbitwise-instead-of-logical]
} while (!(has_zero(a, &adata, &constants) | has_zero(b, &bdata, &constants)));
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|| fs/namei.c:2173:13: note: cast one or both operands to int to silence this warning
It appears that when has_zero was introduced, two definitions were produced with different signatures (in particular different return types).
Looking at the usage in hash_name() in fs/namei.c, I suspect that has_zero() is meant to be invoked twice per while loop iteration; using logical-or would not update bdata when a did not have zeros. So I think it's preferred to always return an unsigned long rather than a bool than update the while loop in hash_name() to use a logical-or rather than bitwise-or.
[ Also changed powerpc version to do the same - Linus ]
--- arch/powerpc/include/asm/word-at-a-time.h | 2 +- include/asm-generic/word-at-a-time.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/word-at-a-time.h +1 -1
@@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask)return leading_zero_bits >>3 ; } -static inline bool has_zero (unsigned long val,unsigned long *data,const struct word_at_a_time *c) +static inline unsigned long has_zero (unsigned long val,unsigned long *data,const struct word_at_a_time *c) {unsigned long rhs = val | c->low_bits; *data = rhs;
include/asm-generic/word-at-a-time.h +1 -1
@@ -38,7 +38,7 @@ static inline long find_zero(unsigned long mask)return (mask >>8 ) ? byte : byte +1 ; } -static inline bool has_zero (unsigned long val,unsigned long *data,const struct word_at_a_time *c) +static inline unsigned long has_zero (unsigned long val,unsigned long *data,const struct word_at_a_time *c) {unsigned long rhs = val | c->low_bits; *data = rhs;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 23/165 s390/vmem: split pages when debug pagealloc is enabled
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
[ Upstream commit edc1e4b6e26536868ef819a735e04a5b32c10589 ]
Since commit bb1520d581a3 ("s390/mm: start kernel with DAT enabled") the kernel crashes early during boot when debug pagealloc is enabled:
mem auto-init: stack:off, heap alloc:off, heap free:off addressing exception: 0005 ilc:2 [#1] SMP DEBUG_PAGEALLOC
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 6.5.0-rc3-09759-gc5666c912155 #630
[..]
Krnl Code: 00000000001325f6: ec5600248064 cgrj %r5,%r6,8,000000000013263e
00000000001325fc: eb880002000c srlg %r8,%r8,2
#0000000000132602: b2210051 ipte %r5,%r1,%r0,0
>0000000000132606: b90400d1 lgr %r13,%r1
000000000013260a: 41605008 la %r6,8(%r5)
000000000013260e: a7db1000 aghi %r13,4096
0000000000132612: b221006d ipte %r6,%r13,%r0,0
0000000000132616: e3d0d0000171 lay %r13,4096(%r13)Call Trace: __kernel_map_pages+0x14e/0x320 __free_pages_ok+0x23a/0x5a8) free_low_memory_core_early+0x214/0x2c8 memblock_free_all+0x28/0x58 mem_init+0xb6/0x228 mm_core_init+0xb6/0x3b0 start_kernel+0x1d2/0x5a8 startup_continue+0x36/0x40 Kernel panic - not syncing: Fatal exception: panic_on_oops
This is caused by using large mappings on machines with EDAT1/EDAT2. Add the code to split the mappings into 4k pages if debug pagealloc is enabled by CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT or the debug_pagealloc kernel command line option.
--- arch/s390/mm/vmem.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/mm/vmem.c +2 -0
@@ -761,6 +761,8 @@ void __init vmem_map_init(void)if (static_key_enabled (&cpu_has_bear))set_memory_nx (0 ,1 );set_memory_nx (PAGE_SIZE ,1 ); +if (debug_pagealloc_enabled ()) +set_memory_4k (0 , ident_map_size >>PAGE_SHIFT );pr_info ("Write protected kernel read-only data: %luk\n" , (unsigned long )(__end_rodata - _stext) >>10 );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 24/165 KVM: s390: fix sthyi error handling
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
[ Upstream commit 0c02cc576eac161601927b41634f80bfd55bfa9e ]
Commit 9fb6c9b3fea1 ("s390/sthyi: add cache to store hypervisor info") added cache handling for store hypervisor info. This also changed the possible return code for sthyi_fill().
Instead of only returning a condition code like the sthyi instruction would do, it can now also return a negative error value (-ENOMEM). handle_styhi() was not changed accordingly. In case of an error, the negative error value would incorrectly injected into the guest PSW.
Add proper error handling to prevent this, and update the comment which describes the possible return values of sthyi_fill().
--- arch/s390/kernel/sthyi.c | 6 +++--- arch/s390/kvm/intercept.c | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-)
arch/s390/kernel/sthyi.c +3 -3
@@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc)* * Fills the destination with system information returned by the STHYI * instruction. The data is generated by emulation or execution of STHYI, -* if available. The return value is the condition code that would be -* returned, the rc parameter is the return code which is passed in -* register R2 + 1. +* if available. The return value is either a negative error value or +* the condition code that would be returned, the rc parameter is the +* return code which is passed in register R2 + 1. */ int sthyi_fill (void *dst,u64 *rc) {
arch/s390/kvm/intercept.c +6 -3
@@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)*/ int handle_sthyi (struct kvm_vcpu *vcpu) { -int reg1, reg2, r =0 ; -u64 code, addr, cc =0 , rc =0 ; +int reg1, reg2, cc =0 , r =0 ; +u64 code, addr, rc =0 ;struct sthyi_sctns *sctns =NULL ;if (!test_kvm_facility (vcpu->kvm,74 ))
@@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu)return -ENOMEM ; cc =sthyi_fill (sctns, &rc); - +if (cc <0 ) { +free_page ((unsigned long )sctns); +return cc; + } out:if (!cc) {if (kvm_s390_pv_cpu_is_protected (vcpu)) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 25/165 erofs: fix wrong primary bvec selection on deduplicated extents
In reply to Greg Kroah-HartmanFrom: Gao Xiang <[email protected]>
[ Upstream commit 94c43de73521d8ed7ebcfc6191d9dace1cbf7caa ]
When handling deduplicated compressed data, there can be multiple decompressed extents pointing to the same compressed data in one shot.
In such cases, the bvecs which belong to the longest extent will be selected as the primary bvecs for real decompressors to decode and the other duplicated bvecs will be directly copied from the primary bvecs.
Previously, only relative offsets of the longest extent were checked to decompress the primary bvecs. On rare occasions, it can be incorrect if there are several extents with the same start relative offset. As a result, some short bvecs could be selected for decompression and then cause data corruption.
For example, as Shijie Sun reported off-list, considering the following extents of a file:
117: 903345.. 915250 | 11905 : 385024.. 389120 | 4096 ... 119: 919729.. 930323 | 10594 : 385024.. 389120 | 4096 ... 124: 968881.. 980786 | 11905 : 385024.. 389120 | 4096
The start relative offset is the same: 2225, but extent 119 (919729.. 930323) is shorter than the others.
Let's restrict the bvec length in addition to the start offset if bvecs are not full.
Tested-by Shijie Sun <[email protected]>
--- fs/erofs/zdata.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/erofs/zdata.c +4 -3
@@ -1110,10 +1110,11 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be, struct z_erofs_bvec *bvec) {struct z_erofs_bvec_item *item; +unsigned int pgnr; -if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK )) { -unsigned int pgnr; - +if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK ) && + (bvec->end ==PAGE_SIZE || + bvec->offset + bvec->end == be->pcl->length)) { pgnr = (bvec->offset + be->pcl->pageofs_out) >>PAGE_SHIFT ;DBG_BUGON (pgnr >= be->nr_pages);if (!be->decompressed_pages[pgnr]) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 26/165 perf pmu arm64: Fix reading the PMU cpu slots in sysfs
In reply to Greg Kroah-HartmanFrom: Haixin Yu <[email protected]>
[ Upstream commit 9754353d0ab123d71bf572a483ecc8b330ef36a3 ]
Commit f8ad6018ce3c065a ("perf pmu: Remove duplication around EVENT_SOURCE_DEVICE_PATH") uses sysfs__read_ull() to read a full sysfs path, which will never succeeds as it already comes with the sysfs mount point in it, which sysfs__read_ull() will add again.
Fix it by reading the file using filename__read_ull(), that will not add the sysfs mount point.
--- tools/perf/arch/arm64/util/pmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/perf/arch/arm64/util/pmu.c +4 -3
@@ -56,10 +56,11 @@ double perf_pmu__cpu_slots_per_cycle(void)perf_pmu__pathname_scnprintf (path,sizeof (path), pmu->name,"caps/slots" );/* -* The value of slots is not greater than 32 bits, but sysfs__read_int -* can't read value with 0x prefix, so use sysfs__read_ull instead. +* The value of slots is not greater than 32 bits, but +* filename__read_int can't read value with 0x prefix, +* so use filename__read_ull instead. */ -sysfs__read_ull (path, &slots); +filename__read_ull (path, &slots); }return slots ? (double )slots :NAN ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 27/165 wifi: cfg80211: Fix return value in scan logic
In reply to Greg Kroah-HartmanFrom: Ilan Peer <[email protected]>
[ Upstream commit fd7f08d92fcd7cc3eca0dd6c853f722a4c6176df ]
The reporter noticed a warning when running iwlwifi:
WARNING: CPU: 8 PID: 659 at mm/page_alloc.c:4453 __alloc_pages+0x329/0x340
As cfg80211_parse_colocated_ap() is not expected to return a negative value return 0 and not a negative value if cfg80211_calc_short_ssid() fails.
--- net/wireless/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/scan.c +1 -1
@@ -640,7 +640,7 @@ static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, ret =cfg80211_calc_short_ssid (ies, &ssid_elem, &s_ssid_tmp);if (ret) -return ret; +return 0 ;/* RNR IE may contain more than one NEIGHBOR_AP_INFO */ while (pos +sizeof (*ap_info) <= end) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 28/165 net/mlx5e: fix double free in macsec_fs_tx_create_crypto_table_groups
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit aeb660171b0663847fa04806a96302ac6112ad26 ]
In function macsec_fs_tx_create_crypto_table_groups(), when the ft->g memory is successfully allocated but the 'in' memory fails to be allocated, the memory pointed to by ft->g is released once. And in function macsec_fs_tx_create(), macsec_fs_tx_destroy() is called to release the memory pointed to by ft->g again. This will cause double free problem.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c +1 -0
@@ -161,6 +161,7 @@ static int macsec_fs_tx_create_crypto_table_groups(struct mlx5e_flow_table *ft)if (!in) {kfree (ft->g); + ft->g =NULL ;return -ENOMEM ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 29/165 net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 5dd77585dd9d0e03dd1bceb95f0269a7eaf6b936 ]
when mlx5_cmd_exec failed in mlx5dr_cmd_create_reformat_ctx, the memory pointed by 'in' is not released, which will cause memory leak. Move memory release after mlx5_cmd_exec.
--- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +3 -2
@@ -562,11 +562,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev, err =mlx5_cmd_exec (mdev, in, inlen, out,sizeof (out));if (err) -return err; + goto err_free_in; *reformat_id =MLX5_GET (alloc_packet_reformat_context_out, out, packet_reformat_id); -kvfree (in); +err_free_in: +kvfree (in);return err; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 30/165 net/mlx5: fix potential memory leak in mlx5e_init_rep_rx
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit c6cf0b6097bf1bf1b2a89b521e9ecd26b581a93a ]
The memory pointed to by the priv->rx_res pointer is not freed in the error path of mlx5e_init_rep_rx, which can lead to a memory leak. Fix by freeing the memory in the error path, thereby making the error path identical to mlx5e_cleanup_rep_rx().
--- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +2 -1
@@ -964,7 +964,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) err =mlx5e_open_drop_rq (priv, &priv->drop_rq);if (err) {mlx5_core_err (mdev,"open drop rq failed, %d\n" , err); -return err; + goto err_rx_res_free; } err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
@@ -998,6 +998,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)mlx5e_rx_res_destroy (priv->rx_res); err_close_drop_rq:mlx5e_close_drop_rq (&priv->drop_rq); +err_rx_res_free:mlx5e_rx_res_free (priv->rx_res); priv->rx_res =NULL ; err_free_fs:
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 31/165 net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit e5bcb7564d3bd0c88613c76963c5349be9c511c5 ]
mlx5e_ipsec_remove_trailer() should return an error code if function pskb_trim() returns an unexpected value.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +3 -1
@@ -58,7 +58,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x) trailer_len = alen + plen +2 ; -pskb_trim (skb, skb->len - trailer_len); + ret =pskb_trim (skb, skb->len - trailer_len); +if (unlikely (ret)) +return ret;if (skb->protocol ==htons (ETH_P_IP )) { ipv4hdr->tot_len =htons (ntohs (ipv4hdr->tot_len) - trailer_len);ip_send_check (ipv4hdr);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 32/165 net/mlx5: Honor user input for migratable port fn attr
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
[ Upstream commit 0507f2c8be0d345fe7014147c027cea6dc1c00a4 ]
Currently, whenever a user is setting migratable port fn attr, the driver is always turn migratable capability on.
Fix it by honor the user input
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +1 -1
@@ -4073,7 +4073,7 @@ int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable, } hca_caps =MLX5_ADDR_OF (query_hca_cap_out, query_ctx, capability); -MLX5_SET (cmd_hca_cap_2, hca_caps, migratable,1 ); +MLX5_SET (cmd_hca_cap_2, hca_caps, migratable, enable); err =mlx5_vport_set_other_func_cap (esw->dev, hca_caps, vport->vport,MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2 );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 33/165 net/mlx5e: Dont hold encap tbl lock if there is no encap action
In reply to Greg Kroah-HartmanFrom: Chris Mi <[email protected]>
[ Upstream commit 93a331939d1d1c6c3422bc09ec43cac658594b34 ]
The cited commit holds encap tbl lock unconditionally when setting up dests. But it may cause the following deadlock:
PID: 1063722 TASK: ffffa062ca5d0000 CPU: 13 COMMAND: "handler8"
#0 [ffffb14de05b7368] __schedule at ffffffffa1d5aa91
#1 [ffffb14de05b7410] schedule at ffffffffa1d5afdb
#2 [ffffb14de05b7430] schedule_preempt_disabled at ffffffffa1d5b528 #3 [ffffb14de05b7440] __mutex_lock at ffffffffa1d5d6cb
#4 [ffffb14de05b74e8] mutex_lock_nested at ffffffffa1d5ddeb
#5 [ffffb14de05b74f8] mlx5e_tc_tun_encap_dests_set at ffffffffc12f2096 [mlx5_core] #6 [ffffb14de05b7568] post_process_attr at ffffffffc12d9fc5 [mlx5_core] #7 [ffffb14de05b75a0] mlx5e_tc_add_fdb_flow at ffffffffc12de877 [mlx5_core] #8 [ffffb14de05b75f0] __mlx5e_add_fdb_flow at ffffffffc12e0eef [mlx5_core] #9 [ffffb14de05b7660] mlx5e_tc_add_flow at ffffffffc12e12f7 [mlx5_core]
#10 [ffffb14de05b76b8] mlx5e_configure_flower at ffffffffc12e1686 [mlx5_core] #11 [ffffb14de05b7720] mlx5e_rep_indr_offload at ffffffffc12e3817 [mlx5_core] #12 [ffffb14de05b7730] mlx5e_rep_indr_setup_tc_cb at ffffffffc12e388a [mlx5_core] #13 [ffffb14de05b7740] tc_setup_cb_add at ffffffffa1ab2ba8
#14 [ffffb14de05b77a0] fl_hw_replace_filter at ffffffffc0bdec2f [cls_flower] #15 [ffffb14de05b7868] fl_change at ffffffffc0be6caa [cls_flower]
#16 [ffffb14de05b7908] tc_new_tfilter at ffffffffa1ab71f0
[1031218.028143] wait_for_completion+0x24/0x30 [1031218.028589] mlx5e_update_route_decap_flows+0x9a/0x1e0 [mlx5_core] [1031218.029256] mlx5e_tc_fib_event_work+0x1ad/0x300 [mlx5_core] [1031218.029885] process_one_work+0x24e/0x510
Actually no need to hold encap tbl lock if there is no encap action. Fix it by checking if encap action exists or not before holding encap tbl lock.
--- .../mellanox/mlx5/core/en/tc_tun_encap.c | 3 --- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 21 ++++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +0 -3
@@ -1030,9 +1030,6 @@ int mlx5e_tc_tun_encap_dests_set(struct mlx5e_priv *priv,int out_index;int err =0 ; -if (!mlx5e_is_eswitch_flow (flow)) -return 0 ; - parse_attr = attr->parse_attr; esw_attr = attr->esw_attr; *vf_tun = false;
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +18 -3
@@ -1725,6 +1725,19 @@ verify_attr_actions(u32 actions, struct netlink_ext_ack *extack)return 0 ; } +static bool +has_encap_dests (struct mlx5_flow_attr *attr) +{ +struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; +int out_index; + +for (out_index =0 ; out_index <MLX5_MAX_FLOW_FWD_VPORTS ; out_index++) +if (esw_attr->dests[out_index].flags &MLX5_ESW_DEST_ENCAP ) +return true; + +return false; +} + static int post_process_attr(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr,
@@ -1737,9 +1750,11 @@ post_process_attr(struct mlx5e_tc_flow *flow,if (err) goto err_out; - err =mlx5e_tc_tun_encap_dests_set (flow->priv, flow, attr, extack, &vf_tun); -if (err) - goto err_out; +if (mlx5e_is_eswitch_flow (flow) &&has_encap_dests (attr)) { + err =mlx5e_tc_tun_encap_dests_set (flow->priv, flow, attr, extack, &vf_tun); +if (err) + goto err_out; + }if (attr->action &MLX5_FLOW_CONTEXT_ACTION_MOD_HDR ) { err =mlx5e_tc_attach_mod_hdr (flow->priv, flow, attr);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 34/165 net/mlx5e: Fix crash moving to switchdev mode when ntuple offload is set
In reply to Greg Kroah-HartmanFrom: Amir Tzin <[email protected]>
[ Upstream commit 3ec43c1b082a8804472430e1253544d75f4b540e ]
Moving to switchdev mode with ntuple offload on causes the kernel to crash since fs->arfs is freed during nic profile cleanup flow.
Ntuple offload is not supported in switchdev mode and it is already unset by mlx5 fix feature ndo in switchdev mode. Verify fs->arfs is valid before disabling it.
trace:
[] RIP: 0010:_raw_spin_lock_bh+0x17/0x30
[] arfs_del_rules+0x44/0x1a0 [mlx5_core]
[] mlx5e_arfs_disable+0xe/0x20 [mlx5_core]
[] mlx5e_handle_feature+0x3d/0xb0 [mlx5_core] [] ? __rtnl_unlock+0x25/0x50
[] mlx5e_set_features+0xfe/0x160 [mlx5_core]
[] __netdev_update_features+0x278/0xa50
[] ? netdev_run_todo+0x5e/0x2a0
[] netdev_update_features+0x22/0x70
[] ? _cond_resched+0x15/0x30
[] mlx5e_attach_netdev+0x12a/0x1e0 [mlx5_core] [] mlx5e_netdev_attach_profile+0xa1/0xc0 [mlx5_core] [] mlx5e_netdev_change_profile+0x77/0xe0 [mlx5_core] [] mlx5e_vport_rep_load+0x1ed/0x290 [mlx5_core] [] mlx5_esw_offloads_rep_load+0x88/0xd0 [mlx5_core] [] esw_offloads_load_rep.part.38+0x31/0x50 [mlx5_core] [] esw_offloads_enable+0x6c5/0x710 [mlx5_core] [] mlx5_eswitch_enable_locked+0x1bb/0x290 [mlx5_core] [] mlx5_devlink_eswitch_mode_set+0x14f/0x320 [mlx5_core] [] devlink_nl_cmd_eswitch_set_doit+0x94/0x120 [] genl_family_rcv_msg_doit.isra.17+0x113/0x150 [] genl_family_rcv_msg+0xb7/0x170
[] ? devlink_nl_cmd_port_split_doit+0x100/0x100 [] genl_rcv_msg+0x47/0xa0
[] ? genl_family_rcv_msg+0x170/0x170
[] netlink_rcv_skb+0x4c/0x130
[] genl_rcv+0x24/0x40
[] netlink_unicast+0x19a/0x230
[] netlink_sendmsg+0x204/0x3d0
[] sock_sendmsg+0x50/0x60
--- drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +10 -0
@@ -135,6 +135,16 @@ static void arfs_del_rules(struct mlx5e_flow_steering *fs);int mlx5e_arfs_disable (struct mlx5e_flow_steering *fs) { +/* Moving to switchdev mode, fs->arfs is freed by mlx5e_nic_profile +* cleanup_rx callback and it is not recreated when +* mlx5e_uplink_rep_profile is loaded as mlx5e_create_flow_steering() +* is not called by the uplink_rep profile init_rx callback. Thus, if +* ntuple is set, moving to switchdev flow will enter this function +* with fs->arfs nullified. +*/ +if (!mlx5e_fs_get_arfs (fs)) +return 0 ; +arfs_del_rules (fs);return arfs_disable (fs);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 35/165 net/mlx5e: Move representor neigh cleanup to profile cleanup_tx
In reply to Greg Kroah-HartmanFrom: Jianbo Liu <[email protected]>
[ Upstream commit d03b6e6f31820b84f7449cca022047f36c42bc3f ]
For IP tunnel encapsulation in ECMP (Equal-Cost Multipath) mode, as the flow is duplicated to the peer eswitch, the related neighbour information on the peer uplink representor is created as well.
In the cited commit, eswitch devcom unpair is moved to uplink unload API, specifically the profile->cleanup_tx. If there is a encap rule offloaded in ECMP mode, when one eswitch does unpair (because of unloading the driver, for instance), and the peer rule from the peer eswitch is going to be deleted, the use-after-free error is triggered while accessing neigh info, as it is already cleaned up in uplink's profile->disable, which is before its profile->cleanup_tx.
To fix this issue, move the neigh cleanup to profile's cleanup_tx callback, and after mlx5e_cleanup_uplink_rep_tx is called. The neigh init is moved to init_tx for symmeter.
[ 2453.376299] BUG: KASAN: slab-use-after-free in mlx5e_rep_neigh_entry_release+0x109/0x3a0 [mlx5_core] [ 2453.379125] Read of size 4 at addr ffff888127af9008 by task modprobe/2496
[ 2453.381542] CPU: 7 PID: 2496 Comm: modprobe Tainted: G B 6.4.0-rc7+ #15 [ 2453.383386] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [ 2453.384335] Call Trace: [ 2453.384625] <TASK> [ 2453.384891] dump_stack_lvl+0x33/0x50 [ 2453.385285] print_report+0xc2/0x610 [ 2453.385667] ? __virt_addr_valid+0xb1/0x130 [ 2453.386091] ? mlx5e_rep_neigh_entry_release+0x109/0x3a0 [mlx5_core] [ 2453.386757] kasan_report+0xae/0xe0 [ 2453.387123] ? mlx5e_rep_neigh_entry_release+0x109/0x3a0 [mlx5_core] [ 2453.387798] mlx5e_rep_neigh_entry_release+0x109/0x3a0 [mlx5_core] [ 2453.388465] mlx5e_rep_encap_entry_detach+0xa6/0xe0 [mlx5_core] [ 2453.389111] mlx5e_encap_dealloc+0xa7/0x100 [mlx5_core] [ 2453.389706] mlx5e_tc_tun_encap_dests_unset+0x61/0xb0 [mlx5_core] [ 2453.390361] mlx5_free_flow_attr_actions+0x11e/0x340 [mlx5_core] [ 2453.391015] ? complete_all+0x43/0xd0 [ 2453.391398] ? free_flow_post_acts+0x38/0x120 [mlx5_core] [ 2453.392004] mlx5e_tc_del_fdb_flow+0x4ae/0x690 [mlx5_core] [ 2453.392618] mlx5e_tc_del_fdb_peers_flow+0x308/0x370 [mlx5_core] [ 2453.393276] mlx5e_tc_clean_fdb_peer_flows+0xf5/0x140 [mlx5_core] [ 2453.393925] mlx5_esw_offloads_unpair+0x86/0x540 [mlx5_core] [ 2453.394546] ? mlx5_esw_offloads_set_ns_peer.isra.0+0x180/0x180 [mlx5_core] [ 2453.395268] ? down_write+0xaa/0x100 [ 2453.395652] mlx5_esw_offloads_devcom_event+0x203/0x530 [mlx5_core] [ 2453.396317] mlx5_devcom_send_event+0xbb/0x190 [mlx5_core] [ 2453.396917] mlx5_esw_offloads_devcom_cleanup+0xb0/0xd0 [mlx5_core] [ 2453.397582] mlx5e_tc_esw_cleanup+0x42/0x120 [mlx5_core] [ 2453.398182] mlx5e_rep_tc_cleanup+0x15/0x30 [mlx5_core] [ 2453.398768] mlx5e_cleanup_rep_tx+0x6c/0x80 [mlx5_core] [ 2453.399367] mlx5e_detach_netdev+0xee/0x120 [mlx5_core] [ 2453.399957] mlx5e_netdev_change_profile+0x84/0x170 [mlx5_core] [ 2453.400598] mlx5e_vport_rep_unload+0xe0/0xf0 [mlx5_core] [ 2453.403781] mlx5_eswitch_unregister_vport_reps+0x15e/0x190 [mlx5_core] [ 2453.404479] ? mlx5_eswitch_register_vport_reps+0x200/0x200 [mlx5_core] [ 2453.405170] ? up_write+0x39/0x60 [ 2453.405529] ? kernfs_remove_by_name_ns+0xb7/0xe0 [ 2453.405985] auxiliary_bus_remove+0x2e/0x40 [ 2453.406405] device_release_driver_internal+0x243/0x2d0 [ 2453.406900] ? kobject_put+0x42/0x2d0 [ 2453.407284] bus_remove_device+0x128/0x1d0 [ 2453.407687] device_del+0x240/0x550 [ 2453.408053] ? waiting_for_supplier_show+0xe0/0xe0 [ 2453.408511] ? kobject_put+0xfa/0x2d0 [ 2453.408889] ? __kmem_cache_free+0x14d/0x280 [ 2453.409310] mlx5_rescan_drivers_locked.part.0+0xcd/0x2b0 [mlx5_core] [ 2453.409973] mlx5_unregister_device+0x40/0x50 [mlx5_core] [ 2453.410561] mlx5_uninit_one+0x3d/0x110 [mlx5_core] [ 2453.411111] remove_one+0x89/0x130 [mlx5_core] [ 2453.411628] pci_device_remove+0x59/0xf0 [ 2453.412026] device_release_driver_internal+0x243/0x2d0 [ 2453.412511] ? parse_option_str+0x14/0x90 [ 2453.412915] driver_detach+0x7b/0xf0 [ 2453.413289] bus_remove_driver+0xb5/0x160 [ 2453.413685] pci_unregister_driver+0x3f/0xf0 [ 2453.414104] mlx5_cleanup+0xc/0x20 [mlx5_core]
--- .../net/ethernet/mellanox/mlx5/core/en_rep.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +7 -10
@@ -1112,6 +1112,10 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)return err; } + err =mlx5e_rep_neigh_init (rpriv); +if (err) + goto err_neigh_init; +if (rpriv->rep->vport ==MLX5_VPORT_UPLINK ) { err =mlx5e_init_uplink_rep_tx (rpriv);if (err)
@@ -1128,6 +1132,8 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)if (rpriv->rep->vport ==MLX5_VPORT_UPLINK )mlx5e_cleanup_uplink_rep_tx (rpriv); err_init_tx: +mlx5e_rep_neigh_cleanup (rpriv); +err_neigh_init:mlx5e_destroy_tises (priv);return err; }
@@ -1141,22 +1147,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)if (rpriv->rep->vport ==MLX5_VPORT_UPLINK )mlx5e_cleanup_uplink_rep_tx (rpriv); +mlx5e_rep_neigh_cleanup (rpriv);mlx5e_destroy_tises (priv); }static void mlx5e_rep_enable (struct mlx5e_priv *priv) { -struct mlx5e_rep_priv *rpriv = priv->ppriv; -mlx5e_set_netdev_mtu_boundaries (priv); -mlx5e_rep_neigh_init (rpriv); }static void mlx5e_rep_disable (struct mlx5e_priv *priv) { -struct mlx5e_rep_priv *rpriv = priv->ppriv; - -mlx5e_rep_neigh_cleanup (rpriv); }static int mlx5e_update_rep_rx (struct mlx5e_priv *priv)
@@ -1206,7 +1207,6 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long eventstatic void mlx5e_uplink_rep_enable (struct mlx5e_priv *priv) { -struct mlx5e_rep_priv *rpriv = priv->ppriv;struct net_device *netdev = priv->netdev;struct mlx5_core_dev *mdev = priv->mdev;u16 max_mtu;
@@ -1228,7 +1228,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)mlx5_notifier_register (mdev, &priv->events_nb);mlx5e_dcbnl_initialize (priv);mlx5e_dcbnl_init_app (priv); -mlx5e_rep_neigh_init (rpriv);mlx5e_rep_bridge_init (priv); netdev->wanted_features |=NETIF_F_HW_TC ;
@@ -1243,7 +1242,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)static void mlx5e_uplink_rep_disable (struct mlx5e_priv *priv) { -struct mlx5e_rep_priv *rpriv = priv->ppriv;struct mlx5_core_dev *mdev = priv->mdev;rtnl_lock ();
@@ -1253,7 +1251,6 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)rtnl_unlock ();mlx5e_rep_bridge_cleanup (priv); -mlx5e_rep_neigh_cleanup (rpriv);mlx5e_dcbnl_delete_app (priv);mlx5_notifier_unregister (mdev, &priv->events_nb);mlx5e_rep_tc_disable (priv);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 36/165 net/mlx5e: xsk: Fix invalid buffer access for legacy rq
In reply to Greg Kroah-HartmanFrom: Dragos Tatulea <[email protected]>
[ Upstream commit e0f52298fee449fec37e3e3c32df60008b509b16 ]
The below crash can be encountered when using xdpsock in rx mode for legacy rq: the buffer gets released in the XDP_REDIRECT path, and then once again in the driver. This fix sets the flag to avoid releasing on the driver side.
XSK handling of buffers for legacy rq was relying on the caller to set the skip release flag. But the referenced fix started using fragment counts for pages instead of the skip flag.
Crash log:
general protection fault, probably for non-canonical address 0xffff8881217e3a: 0000 [#1] SMP CPU: 0 PID: 14 Comm: ksoftirqd/0 Not tainted 6.5.0-rc1+ #31 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:bpf_prog_03b13f331978c78c+0xf/0x28 Code: ... RSP: 0018:ffff88810082fc98 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888138404901 RCX: c0ffffc900027cbc RDX: ffffffffa000b514 RSI: 00ffff8881217e32 RDI: ffff888138404901 RBP: ffff88810082fc98 R08: 0000000000091100 R09: 0000000000000006 R10: 0000000000000800 R11: 0000000000000800 R12: ffffc9000027a000 R13: ffff8881217e2dc0 R14: ffff8881217e2910 R15: ffff8881217e2f00 FS: 0000000000000000(0000) GS:ffff88852c800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000564cb2e2cde0 CR3: 000000010e603004 CR4: 0000000000370eb0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? die_addr+0x32/0x80 ? exc_general_protection+0x192/0x390 ? asm_exc_general_protection+0x22/0x30 ? 0xffffffffa000b514 ? bpf_prog_03b13f331978c78c+0xf/0x28 mlx5e_xdp_handle+0x48/0x670 [mlx5_core] ? dev_gro_receive+0x3b5/0x6e0 mlx5e_xsk_skb_from_cqe_linear+0x6e/0x90 [mlx5_core] mlx5e_handle_rx_cqe+0x55/0x100 [mlx5_core] mlx5e_poll_rx_cq+0x87/0x6e0 [mlx5_core] mlx5e_napi_poll+0x45e/0x6b0 [mlx5_core] __napi_poll+0x25/0x1a0 net_rx_action+0x28a/0x300 __do_softirq+0xcd/0x279 ? sort_range+0x20/0x20 run_ksoftirqd+0x1a/0x20 smpboot_thread_fn+0xa2/0x130 kthread+0xc9/0xf0 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 </TASK> Modules linked in: mlx5_ib mlx5_core rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm ib_uverbs ib_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter overlay zram zsmalloc fuse [last unloaded: mlx5_core] ---[ end trace 0000000000000000 ]---
--- drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c +4 -1
@@ -323,8 +323,11 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_linear(struct mlx5e_rq *rq,net_prefetch (mxbuf->xdp.data); prog =rcu_dereference (rq->xdp_prog); -if (likely (prog &&mlx5e_xdp_handle (rq, prog, mxbuf))) +if (likely (prog &&mlx5e_xdp_handle (rq, prog, mxbuf))) { +if (likely (__test_and_clear_bit (MLX5E_RQ_FLAG_XDP_XMIT , rq->flags))) + wi->flags |=BIT (MLX5E_WQE_FRAG_SKIP_RELEASE );return NULL ;/* page/packet was consumed by XDP */ + }/* XDP_PASS: copy the data from the UMEM to a new SKB. The frame reuse * will be handled by mlx5e_free_rx_wqe.
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 37/165 net/mlx5e: xsk: Fix crash on regular rq reactivation
In reply to Greg Kroah-HartmanFrom: Dragos Tatulea <[email protected]>
[ Upstream commit 39646d9bcd1a65d2396328026626859a1dab59d7 ]
When the regular rq is reactivated after the XSK socket is closed it could be reading stale cqes which eventually corrupts the rq. This leads to no more traffic being received on the regular rq and a crash on the next close or deactivation of the rq.
Kal Cuttler Conely reported this issue as a crash on the release path when the xdpsock sample program is stopped (killed) and restarted in sequence while traffic is running.
This patch flushes all cqes when during the rq flush. The cqe flushing is done in the reset state of the rq. mlx5e_rq_to_ready code is moved into the flush function to allow for this.
--- .../net/ethernet/mellanox/mlx5/core/en_main.c | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +21 -8
@@ -1036,7 +1036,23 @@ static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_sreturn err; } -static int mlx5e_rq_to_ready (struct mlx5e_rq *rq,int curr_state) +static void mlx5e_flush_rq_cq (struct mlx5e_rq *rq) +{ +struct mlx5_cqwq *cqwq = &rq->cq.wq; +struct mlx5_cqe64 *cqe; + +if (test_bit (MLX5E_RQ_STATE_MINI_CQE_ENHANCED , &rq->state)) { +while ((cqe =mlx5_cqwq_get_cqe_enahnced_comp (cqwq))) +mlx5_cqwq_pop (cqwq); + }else { +while ((cqe =mlx5_cqwq_get_cqe (cqwq))) +mlx5_cqwq_pop (cqwq); + } + +mlx5_cqwq_update_db_record (cqwq); +} + +int mlx5e_flush_rq (struct mlx5e_rq *rq,int curr_state) {struct net_device *dev = rq->netdev;int err;
@@ -1046,6 +1062,10 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)netdev_err (dev,"Failed to move rq 0x%x to reset\n" , rq->rqn);return err; } + +mlx5e_free_rx_descs (rq); +mlx5e_flush_rq_cq (rq); + err =mlx5e_modify_rq_state (rq,MLX5_RQC_STATE_RST ,MLX5_RQC_STATE_RDY );if (err) {netdev_err (dev,"Failed to move rq 0x%x to ready\n" , rq->rqn);
@@ -1055,13 +1075,6 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)return 0 ; } -int mlx5e_flush_rq (struct mlx5e_rq *rq,int curr_state) -{ -mlx5e_free_rx_descs (rq); - -return mlx5e_rq_to_ready (rq, curr_state); -} -static int mlx5e_modify_rq_vsd (struct mlx5e_rq *rq,bool vsd) {struct mlx5_core_dev *mdev = rq->mdev;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 38/165 net/mlx5e: kTLS, Fix protection domain in use syndrome when devlink reload
In reply to Greg Kroah-HartmanFrom: Jianbo Liu <[email protected]>
[ Upstream commit 3e4cf1dd2ce413f4be3e2c9062fb470e2ad2be88 ]
There are DEK objects cached in DEK pool after kTLS is used, and they are freed only in mlx5e_ktls_cleanup().
mlx5e_destroy_mdev_resources() is called in mlx5e_suspend() to free mdev resources, including protection domain (PD). However, PD is still referenced by the cached DEK objects in this case, because profile->cleanup() (and therefore mlx5e_ktls_cleanup()) is called after mlx5e_suspend() during devlink reload. So the following FW syndrome is generated:
mlx5_cmd_out_err:803:(pid 12948): DEALLOC_PD(0x801) op_mod(0x0) failed,
status bad resource state(0x9), syndrome (0xef0c8a), err(-22)
To avoid this syndrome, move DEK pool destruction to mlx5e_ktls_cleanup_tx(), which is called by profile->cleanup_tx(). And move pool creation to mlx5e_ktls_init_tx() for symmetry.
--- .../mellanox/mlx5/core/en_accel/ktls.c | 8 ----- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 29 +++++++++++++++++-- 2 files changed, 26 insertions(+), 11 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +0 -8
@@ -188,7 +188,6 @@ static void mlx5e_tls_debugfs_init(struct mlx5e_tls *tls,int mlx5e_ktls_init (struct mlx5e_priv *priv) { -struct mlx5_crypto_dek_pool *dek_pool;struct mlx5e_tls *tls;if (!mlx5e_is_ktls_device (priv->mdev))
@@ -199,12 +198,6 @@ int mlx5e_ktls_init(struct mlx5e_priv *priv)return -ENOMEM ; tls->mdev = priv->mdev; - dek_pool =mlx5_crypto_dek_pool_create (priv->mdev,MLX5_ACCEL_OBJ_TLS_KEY ); -if (IS_ERR (dek_pool)) { -kfree (tls); -return PTR_ERR (dek_pool); - } - tls->dek_pool = dek_pool; priv->tls = tls;mlx5e_tls_debugfs_init (tls, priv->dfs_root);
@@ -222,7 +215,6 @@ void mlx5e_ktls_cleanup(struct mlx5e_priv *priv)debugfs_remove_recursive (tls->debugfs.dfs); tls->debugfs.dfs =NULL ; -mlx5_crypto_dek_pool_destroy (tls->dek_pool);kfree (priv->tls); priv->tls =NULL ; }
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +26 -3
@@ -908,28 +908,51 @@ static void mlx5e_tls_tx_debugfs_init(struct mlx5e_tls *tls,int mlx5e_ktls_init_tx (struct mlx5e_priv *priv) { +struct mlx5_crypto_dek_pool *dek_pool;struct mlx5e_tls *tls = priv->tls; +int err; + +if (!mlx5e_is_ktls_device (priv->mdev)) +return 0 ; + +/* DEK pool could be used by either or both of TX and RX. But we have to +* put the creation here to avoid syndrome when doing devlink reload. +*/ + dek_pool =mlx5_crypto_dek_pool_create (priv->mdev,MLX5_ACCEL_OBJ_TLS_KEY ); +if (IS_ERR (dek_pool)) +return PTR_ERR (dek_pool); + tls->dek_pool = dek_pool;if (!mlx5e_is_ktls_tx (priv->mdev))return 0 ; priv->tls->tx_pool =mlx5e_tls_tx_pool_init (priv->mdev, &priv->tls->sw_stats); -if (!priv->tls->tx_pool) -return -ENOMEM ; +if (!priv->tls->tx_pool) { + err = -ENOMEM ; + goto err_tx_pool_init; + }mlx5e_tls_tx_debugfs_init (tls, tls->debugfs.dfs);return 0 ; + +err_tx_pool_init: +mlx5_crypto_dek_pool_destroy (dek_pool); +return err; }void mlx5e_ktls_cleanup_tx (struct mlx5e_priv *priv) {if (!mlx5e_is_ktls_tx (priv->mdev)) -return ; + goto dek_pool_destroy;debugfs_remove_recursive (priv->tls->debugfs.dfs_tx); priv->tls->debugfs.dfs_tx =NULL ;mlx5e_tls_tx_pool_cleanup (priv->tls->tx_pool); priv->tls->tx_pool =NULL ; + +dek_pool_destroy: +if (mlx5e_is_ktls_device (priv->mdev)) +mlx5_crypto_dek_pool_destroy (priv->tls->dek_pool); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 39/165 net/mlx5: fs_chains: Fix ft prio if ignore_flow_level is not supported
In reply to Greg Kroah-HartmanFrom: Chris Mi <[email protected]>
[ Upstream commit 61eab651f6e96791cfad6db45f1107c398699b2d ]
The cited commit sets ft prio to fs_base_prio. But if ignore_flow_level it not supported, ft prio must be set based on tc filter prio. Otherwise, all the ft prio are the same on the same chain. It is invalid if ignore_flow_level is not supported.
Fix it by setting ft prio based on tc filter prio and setting fs_base_prio to 0 for fdb.
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 1 - drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +0 -1
@@ -1376,7 +1376,6 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb)esw_init_chains_offload_flags (esw, &attr.flags); attr.ns =MLX5_FLOW_NAMESPACE_FDB ; - attr.fs_base_prio =FDB_TC_OFFLOAD ; attr.max_grp_num = esw->params.large_group_num; attr.default_ft = miss_fdb; attr.mapping = esw->offloads.reg_c0_obj_pool;
drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +1 -1
@@ -178,7 +178,7 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains,if (!mlx5_chains_ignore_flow_level_supported (chains) || (chain ==0 && prio ==1 && level ==0 )) { ft_attr.level = chains->fs_base_level; - ft_attr.prio = chains->fs_base_prio; + ft_attr.prio = chains->fs_base_prio + prio -1 ; ns = (chains->ns ==MLX5_FLOW_NAMESPACE_FDB ) ?mlx5_get_fdb_sub_ns (chains->dev, chain) :mlx5_get_flow_namespace (chains->dev, chains->ns);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 40/165 net/mlx5: Unregister devlink params in case interface is down
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
[ Upstream commit 53d737dfd3d7b023fa9fa445ea3f3db0ac9da402 ]
Currently, in case an interface is down, mlx5 driver doesn't unregister its devlink params, which leads to this WARN[1]. Fix it by unregistering devlink params in that case as well.
[1]
[ 295.244769 ] WARNING: CPU: 15 PID: 1 at net/core/devlink.c:9042 devlink_free+0x174/0x1fc [ 295.488379 ] CPU: 15 PID: 1 Comm: shutdown Tainted: G S OE 5.15.0-1017.19.3.g0677e61-bluefield #g0677e61 [ 295.509330 ] Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS 4.2.0.12761 Jun 6 2023 [ 295.543096 ] pc : devlink_free+0x174/0x1fc [ 295.551104 ] lr : mlx5_devlink_free+0x18/0x2c [mlx5_core] [ 295.561816 ] sp : ffff80000809b850 [ 295.711155 ] Call trace: [ 295.716030 ] devlink_free+0x174/0x1fc [ 295.723346 ] mlx5_devlink_free+0x18/0x2c [mlx5_core] [ 295.733351 ] mlx5_sf_dev_remove+0x98/0xb0 [mlx5_core] [ 295.743534 ] auxiliary_bus_remove+0x2c/0x50 [ 295.751893 ] __device_release_driver+0x19c/0x280 [ 295.761120 ] device_release_driver+0x34/0x50 [ 295.769649 ] bus_remove_device+0xdc/0x170 [ 295.777656 ] device_del+0x17c/0x3a4 [ 295.784620 ] mlx5_sf_dev_remove+0x28/0xf0 [mlx5_core] [ 295.794800 ] mlx5_sf_dev_table_destroy+0x98/0x110 [mlx5_core] [ 295.806375 ] mlx5_unload+0x34/0xd0 [mlx5_core] [ 295.815339 ] mlx5_unload_one+0x70/0xe4 [mlx5_core] [ 295.824998 ] shutdown+0xb0/0xd8 [mlx5_core] [ 295.833439 ] pci_device_shutdown+0x3c/0xa0 [ 295.841651 ] device_shutdown+0x170/0x340 [ 295.849486 ] __do_sys_reboot+0x1f4/0x2a0 [ 295.857322 ] __arm64_sys_reboot+0x2c/0x40 [ 295.865329 ] invoke_syscall+0x78/0x100 [ 295.872817 ] el0_svc_common.constprop.0+0x54/0x184 [ 295.882392 ] do_el0_svc+0x30/0xac [ 295.889008 ] el0_svc+0x48/0x160 [ 295.895278 ] el0t_64_sync_handler+0xa4/0x130 [ 295.903807 ] el0t_64_sync+0x1a4/0x1a8 [ 295.911120 ] ---[ end trace 4f1d2381d00d9dce ]---
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -0
@@ -1456,6 +1456,7 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)if (!test_bit (MLX5_INTERFACE_STATE_UP , &dev->intf_state)) {mlx5_core_warn (dev,"%s: interface is down, NOP\n" , __func__); +mlx5_devlink_params_unregister (priv_to_devlink (dev));mlx5_cleanup_once (dev); goto out; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 41/165 bpf: Add length check for SK_DIAG_BPF_STORAGE_REQ_MAP_FD parsing
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
[ Upstream commit bcc29b7f5af6797702c2306a7aacb831fc5ce9cb ]
The nla_for_each_nested parsing in function bpf_sk_storage_diag_alloc does not check the length of the nested attribute. This can lead to an out-of-attribute read and allow a malformed nlattr (e.g., length 0) to be viewed as a 4 byte integer.
This patch adds an additional check when the nlattr is getting counted. This makes sure the latter nla_get_u32 can access the attributes with the correct length.
--- net/core/bpf_sk_storage.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/core/bpf_sk_storage.c +4 -1
@@ -496,8 +496,11 @@ bpf_sk_storage_diag_alloc(const struct nlattr *nla_stgs)return ERR_PTR (-EPERM );nla_for_each_nested (nla, nla_stgs, rem) { -if (nla_type (nla) ==SK_DIAG_BPF_STORAGE_REQ_MAP_FD ) +if (nla_type (nla) ==SK_DIAG_BPF_STORAGE_REQ_MAP_FD ) { +if (nla_len (nla) !=sizeof (u32)) +return ERR_PTR (-EINVAL ); nr_maps++; + } } diag =kzalloc (struct_size (diag, maps, nr_maps),GFP_KERNEL );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 42/165 rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
[ Upstream commit d73ef2d69c0dba5f5a1cb9600045c873bab1fb7f ]
There are totally 9 ndo_bridge_setlink handlers in the current kernel, which are 1) bnxt_bridge_setlink, 2) be_ndo_bridge_setlink 3) i40e_ndo_bridge_setlink 4) ice_bridge_setlink 5) ixgbe_ndo_bridge_setlink 6) mlx5e_bridge_setlink 7) nfp_net_bridge_setlink 8) qeth_l2_bridge_setlink 9) br_setlink.
By investigating the code, we find that 1-7 parse and use nlattr IFLA_BRIDGE_MODE but 3 and 4 forget to do the nla_len check. This can lead to an out-of-attribute read and allow a malformed nlattr (e.g., length 0) to be viewed as a 2 byte integer.
To avoid such issues, also for other ndo_bridge_setlink handlers in the future. This patch adds the nla_len check in rtnl_bridge_setlink and does an early error return if length mismatches. To make it works, the break is removed from the parsing for IFLA_BRIDGE_FLAGS to make sure this nla_for_each_nested iterates every attribute.
--- net/core/rtnetlink.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/core/rtnetlink.c +6 -2
@@ -5139,13 +5139,17 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, br_spec =nlmsg_find_attr (nlh,sizeof (struct ifinfomsg ),IFLA_AF_SPEC );if (br_spec) {nla_for_each_nested (attr, br_spec, rem) { -if (nla_type (attr) ==IFLA_BRIDGE_FLAGS ) { +if (nla_type (attr) ==IFLA_BRIDGE_FLAGS && !have_flags) {if (nla_len (attr) <sizeof (flags))return -EINVAL ; have_flags = true; flags =nla_get_u16 (attr); -break ; + } + +if (nla_type (attr) ==IFLA_BRIDGE_MODE ) { +if (nla_len (attr) <sizeof (u16)) +return -EINVAL ; } } }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 43/165 net: dsa: fix value check in bcm_sf2_sw_probe()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit dadc5b86cc9459581f37fe755b431adc399ea393 ]
in bcm_sf2_sw_probe(), check the return value of clk_prepare_enable() and return the error code if clk_prepare_enable() returns an unexpected value.
--- drivers/net/dsa/bcm_sf2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/dsa/bcm_sf2.c +6 -2
@@ -1436,7 +1436,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)if (IS_ERR (priv->clk))return PTR_ERR (priv->clk); -clk_prepare_enable (priv->clk); + ret =clk_prepare_enable (priv->clk); +if (ret) +return ret; priv->clk_mdiv =devm_clk_get_optional (&pdev->dev,"sw_switch_mdiv" );if (IS_ERR (priv->clk_mdiv)) {
@@ -1444,7 +1446,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) goto out_clk; } -clk_prepare_enable (priv->clk_mdiv); + ret =clk_prepare_enable (priv->clk_mdiv); +if (ret) + goto out_clk; ret =bcm_sf2_sw_rst (priv);if (ret) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 44/165 perf test uprobe_from_different_cu: Skip if there is no gcc
In reply to Greg Kroah-HartmanFrom: Georg Müller <[email protected]>
[ Upstream commit 98ce8e4a9dcfb448b30a2d7a16190f4a00382377 ]
Without gcc, the test will fail.
On cleanup, ignore probe removal errors. Otherwise, in case of an error adding the probe, the temporary directory is not removed.
--- tools/perf/tests/shell/test_uprobe_from_different_cu.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
tools/perf/tests/shell/test_uprobe_from_different_cu.sh +7 -1
@@ -4,6 +4,12 @@ set -e +# skip if there's no gcc +if ! [ -x "$(command -v gcc)" ]; then + echo "failed: no gcc compiler" + exit 2 +fi + temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX) cleanup()
@@ -11,7 +17,7 @@ cleanup() trap - EXIT TERM INT if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then echo "--- Cleaning up ---" - perf probe -x ${temp_dir}/testfile -d foo + perf probe -x ${temp_dir}/testfile -d foo || true rm -f "${temp_dir}/"* rmdir "${temp_dir}" fi
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 45/165 net: sched: cls_u32: Fix match key mis-addressing
In reply to Greg Kroah-HartmanFrom: Jamal Hadi Salim <[email protected]>
[ Upstream commit e68409db995380d1badacba41ff24996bd396171 ]
A match entry is uniquely identified with an "address" or "path" in the form of: hashtable ID(12b):bucketid(8b):nodeid(12b).
When creating table match entries all of hash table id, bucket id and node (match entry id) are needed to be either specified by the user or reasonable in-kernel defaults are used. The in-kernel default for a table id is 0x800(omnipresent root table); for bucketid it is 0x0. Prior to this fix there was none for a nodeid i.e. the code assumed that the user passed the correct nodeid and if the user passes a nodeid of 0 (as Mingi Cho did) then that is what was used. But nodeid of 0 is reserved for identifying the table. This is not a problem until we dump. The dump code notices that the nodeid is zero and assumes it is referencing a table and therefore references table struct tc_u_hnode instead of what was created i.e match entry struct tc_u_knode.
Ming does an equivalent of:
tc filter add dev dummy0 parent 10: prio 1 handle 0x1000 \
protocol ip u32 match ip src 10.0.0.1/32 classid 10:1 action ok
Essentially specifying a table id 0, bucketid 1 and nodeid of zero Tableid 0 is remapped to the default of 0x800.
Bucketid 1 is ignored and defaults to 0x00.
Nodeid was assumed to be what Ming passed - 0x000
dumping before fix shows:
~$ tc filter ls dev dummy0 parent 10:
filter protocol ip pref 1 u32 chain 0
filter protocol ip pref 1 u32 chain 0 fh 800: ht divisor 1 filter protocol ip pref 1 u32 chain 0 fh 800: ht divisor -30591
Note that the last line reports a table instead of a match entry (you can tell this because it says "ht divisor...").
As a result of reporting the wrong data type (misinterpretting of struct tc_u_knode as being struct tc_u_hnode) the divisor is reported with value of -30591. Ming identified this as part of the heap address (physmap_base is 0xffff8880 (-30591 - 1)).
The fix is to ensure that when table entry matches are added and no nodeid is specified (i.e nodeid == 0) then we get the next available nodeid from the table's pool.
After the fix, this is what the dump shows:
$ tc filter ls dev dummy0 parent 10: filter protocol ip pref 1 u32 chain 0 filter protocol ip pref 1 u32 chain 0 fh 800: ht divisor 1 filter protocol ip pref 1 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 10:1 not_in_hw match 0a000001/ffffffff at 12 action order 1: gact action pass random type none pass val 0 index 1 ref 1 bind 1
--- net/sched/cls_u32.c | 56 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-)
net/sched/cls_u32.c +50 -6
@@ -1024,18 +1024,62 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,return -EINVAL ; } +/* At this point, we need to derive the new handle that will be used to +* uniquely map the identity of this table match entry. The +* identity of the entry that we need to construct is 32 bits made of: +* htid(12b):bucketid(8b):node/entryid(12b) +* +* At this point _we have the table(ht)_ in which we will insert this +* entry. We carry the table's id in variable "htid". +* Note that earlier code picked the ht selection either by a) the user +* providing the htid specified via TCA_U32_HASH attribute or b) when +* no such attribute is passed then the root ht, is default to at ID +* 0x[800][00][000]. Rule: the root table has a single bucket with ID 0. +* If OTOH the user passed us the htid, they may also pass a bucketid of +* choice. 0 is fine. For example a user htid is 0x[600][01][000] it is +* indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be +* passed via the htid, so even if it was non-zero it will be ignored. +* +* We may also have a handle, if the user passed one. The handle also +* carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b). +* Rule: the bucketid on the handle is ignored even if one was passed; +* rather the value on "htid" is always assumed to be the bucketid. +*/ if (handle) { +/* Rule: The htid from handle and tableid from htid must match */ if (TC_U32_HTID (handle) &&TC_U32_HTID (handle ^ htid)) {NL_SET_ERR_MSG_MOD (extack,"Handle specified hash table address mismatch" );return -EINVAL ; } - handle = htid |TC_U32_NODE (handle); - err =idr_alloc_u32 (&ht->handle_idr,NULL , &handle, handle, -GFP_KERNEL ); -if (err) -return err; - }else +/* Ok, so far we have a valid htid(12b):bucketid(8b) but we +* need to finalize the table entry identification with the last +* part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for +* entries. Rule: nodeid of 0 is reserved only for tables(see +* earlier code which processes TC_U32_DIVISOR attribute). +* Rule: The nodeid can only be derived from the handle (and not +* htid). +* Rule: if the handle specified zero for the node id example +* 0x60000000, then pick a new nodeid from the pool of IDs +* this hash table has been allocating from. +* If OTOH it is specified (i.e for example the user passed a +* handle such as 0x60000123), then we use it generate our final +* handle which is used to uniquely identify the match entry. +*/ +if (!TC_U32_NODE (handle)) { + handle =gen_new_kid (ht, htid); + }else { + handle = htid |TC_U32_NODE (handle); + err =idr_alloc_u32 (&ht->handle_idr,NULL , &handle, + handle,GFP_KERNEL ); +if (err) +return err; + } + }else { +/* The user did not give us a handle; lets just generate one +* from the table's pool of nodeids. +*/ handle =gen_new_kid (ht, htid); + }if (tb[TCA_U32_SEL ] ==NULL ) {NL_SET_ERR_MSG_MOD (extack,"Selector not specified" );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 46/165 mISDN: hfcpci: Fix potential deadlock on &hc->lock
In reply to Greg Kroah-HartmanFrom: Chengfeng Ye <[email protected]>
[ Upstream commit 56c6be35fcbed54279df0a2c9e60480a61841d6f ]
As &hc->lock is acquired by both timer _hfcpci_softirq() and hardirq hfcpci_int(), the timer should disable irq before lock acquisition otherwise deadlock could happen if the timmer is preemtped by the hadr irq.
Possible deadlock scenario:hfcpci_softirq() (timer)
-> _hfcpci_softirq()
-> spin_lock(&hc->lock);
<irq interruption>
-> hfcpci_int()
-> spin_lock(&hc->lock); (deadlock here)This flaw was found by an experimental static analysis tool I am developing for irq-related deadlock.
The tentative patch fixes the potential deadlock by spin_lock_irq() in timer.
--- drivers/isdn/hardware/mISDN/hfcpci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/isdn/hardware/mISDN/hfcpci.c +5 -5
@@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch) *z1t =cpu_to_le16 (new_z1);/* now send data */ if (bch->tx_idx < bch->tx_skb->len)return ; -dev_kfree_skb (bch->tx_skb); +dev_kfree_skb_any (bch->tx_skb);if (get_next_bframe (bch)) goto next_t_frame;return ;
@@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch) } bz->za[new_f1].z1 =cpu_to_le16 (new_z1);/* for next buffer */ bz->f1 = new_f1;/* next frame */ -dev_kfree_skb (bch->tx_skb); +dev_kfree_skb_any (bch->tx_skb);get_next_bframe (bch); }
@@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch)if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)hfcpci_fill_fifo (bch);else { -dev_kfree_skb (bch->tx_skb); +dev_kfree_skb_any (bch->tx_skb);if (get_next_bframe (bch))hfcpci_fill_fifo (bch); }
@@ -2277,7 +2277,7 @@ _hfcpci_softirq(struct device *dev, void *unused)return 0 ;if (hc->hw.int_m2 &HFCPCI_IRQ_ENABLE ) { -spin_lock (&hc->lock); +spin_lock_irq (&hc->lock); bch =Sel_BCS (hc, hc->hw.bswapped ?2 :1 );if (bch && bch->state ==ISDN_P_B_RAW ) {/* B1 rx&tx */ main_rec_hfcpci (bch);
@@ -2288,7 +2288,7 @@ _hfcpci_softirq(struct device *dev, void *unused)main_rec_hfcpci (bch);tx_birq (bch); } -spin_unlock (&hc->lock); +spin_unlock_irq (&hc->lock); }return 0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 47/165 net: stmmac: tegra: Properly allocate clock bulk data
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit a0b1b2055be34c0ec1371764d040164cde1ead79 ]
The clock data is an array of struct clk_bulk_data, so make sure to allocate enough memory.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c +2 -1
@@ -234,7 +234,8 @@ static int tegra_mgbe_probe(struct platform_device *pdev) res.addr = mgbe->regs; res.irq = irq; - mgbe->clks =devm_kzalloc (&pdev->dev,sizeof (*mgbe->clks),GFP_KERNEL ); + mgbe->clks =devm_kcalloc (&pdev->dev,ARRAY_SIZE (mgbe_clks), +sizeof (*mgbe->clks),GFP_KERNEL );if (!mgbe->clks)return -ENOMEM ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 48/165 qed: Fix scheduling in a tasklet while getting stats
In reply to Greg Kroah-HartmanFrom: Konstantin Khorenko <[email protected]>
[ Upstream commit e346e231b42bcae6822a6326acfb7b741e9e6026 ]
Here we've got to a situation when tasklet called usleep_range() in PTT acquire logic, thus welcome to the "scheduling while atomic" BUG().
BUG: scheduling while atomic: swapper/24/0/0x00000100
[<ffffffffb41c6199>] schedule+0x29/0x70
[<ffffffffb41c5512>] schedule_hrtimeout_range_clock+0xb2/0x150
[<ffffffffb41c55c3>] schedule_hrtimeout_range+0x13/0x20
[<ffffffffb41c3bcf>] usleep_range+0x4f/0x70
[<ffffffffc08d3e58>] qed_ptt_acquire+0x38/0x100 [qed]
[<ffffffffc08eac48>] _qed_get_vport_stats+0x458/0x580 [qed]
[<ffffffffc08ead8c>] qed_get_vport_stats+0x1c/0xd0 [qed]
[<ffffffffc08dffd3>] qed_get_protocol_stats+0x93/0x100 [qed]
qed_mcp_send_protocol_stats
case MFW_DRV_MSG_GET_LAN_STATS:
case MFW_DRV_MSG_GET_FCOE_STATS:
case MFW_DRV_MSG_GET_ISCSI_STATS:
case MFW_DRV_MSG_GET_RDMA_STATS:
[<ffffffffc08e36d8>] qed_mcp_handle_events+0x2d8/0x890 [qed]
qed_int_assertion
qed_int_attentions
[<ffffffffc08d9490>] qed_int_sp_dpc+0xa50/0xdc0 [qed]
[<ffffffffb3aa7623>] tasklet_action+0x83/0x140
[<ffffffffb41d9125>] __do_softirq+0x125/0x2bb
[<ffffffffb41d560c>] call_softirq+0x1c/0x30
[<ffffffffb3a30645>] do_softirq+0x65/0xa0
[<ffffffffb3aa78d5>] irq_exit+0x105/0x110
[<ffffffffb41d8996>] do_IRQ+0x56/0xf0Fix this by making caller to provide the context whether it could be in atomic context flow or not when getting stats from QED driver. QED driver based on the context provided decide to schedule out or not when acquiring the PTT BAR window.
We faced the BUG_ON() while getting vport stats, but according to the code same issue could happen for fcoe and iscsi statistics as well, so fixing them too.
--- drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 16 ++++++++++++ drivers/net/ethernet/qlogic/qed/qed_fcoe.c | 19 ++++++++++---- drivers/net/ethernet/qlogic/qed/qed_fcoe.h | 17 ++++++++++-- drivers/net/ethernet/qlogic/qed/qed_hw.c | 26 ++++++++++++++++--- drivers/net/ethernet/qlogic/qed/qed_iscsi.c | 19 ++++++++++---- drivers/net/ethernet/qlogic/qed/qed_iscsi.h | 8 ++++-- drivers/net/ethernet/qlogic/qed/qed_l2.c | 19 ++++++++++---- drivers/net/ethernet/qlogic/qed/qed_l2.h | 24 +++++++++++++++++ drivers/net/ethernet/qlogic/qed/qed_main.c | 6 ++--- 9 files changed, 128 insertions(+), 26 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_dev_api.h +16 -0
@@ -193,6 +193,22 @@ void qed_hw_remove(struct qed_dev *cdev);*/ struct qed_ptt *qed_ptt_acquire (struct qed_hwfn *p_hwfn); +/** +* qed_ptt_acquire_context(): Allocate a PTT window honoring the context +* atomicy. +* +* @p_hwfn: HW device data. +* @is_atomic: Hint from the caller - if the func can sleep or not. +* +* Context: The function should not sleep in case is_atomic == true. +* Return: struct qed_ptt. +* +* Should be called at the entry point to the driver +* (at the beginning of an exported function). +*/ +struct qed_ptt *qed_ptt_acquire_context (struct qed_hwfn *p_hwfn, +bool is_atomic); +/** * qed_ptt_release(): Release PTT Window. *
drivers/net/ethernet/qlogic/qed/qed_fcoe.c +14 -5
@@ -693,13 +693,14 @@ static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn, }static int qed_fcoe_get_stats (struct qed_hwfn *p_hwfn, -struct qed_fcoe_stats *p_stats) +struct qed_fcoe_stats *p_stats, +bool is_atomic) {struct qed_ptt *p_ptt;memset (p_stats,0 ,sizeof (*p_stats)); - p_ptt =qed_ptt_acquire (p_hwfn); + p_ptt =qed_ptt_acquire_context (p_hwfn, is_atomic);if (!p_ptt) {DP_ERR (p_hwfn,"Failed to acquire ptt\n" );
@@ -973,19 +974,27 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev, QED_SPQ_MODE_EBLOCK, NULL); } +static int qed_fcoe_stats_context (struct qed_dev *cdev, +struct qed_fcoe_stats *stats, +bool is_atomic) +{ +return qed_fcoe_get_stats (QED_AFFIN_HWFN (cdev), stats, is_atomic); +} +static int qed_fcoe_stats (struct qed_dev *cdev,struct qed_fcoe_stats *stats) { -return qed_fcoe_get_stats (QED_AFFIN_HWFN (cdev), stats); +return qed_fcoe_stats_context (cdev, stats, false); }void qed_get_protocol_stats_fcoe (struct qed_dev *cdev, -struct qed_mcp_fcoe_stats *stats) +struct qed_mcp_fcoe_stats *stats, +bool is_atomic) {struct qed_fcoe_stats proto_stats;/* Retrieve FW statistics */ memset (&proto_stats,0 ,sizeof (proto_stats)); -if (qed_fcoe_stats (cdev, &proto_stats)) { +if (qed_fcoe_stats_context (cdev, &proto_stats, is_atomic)) {DP_VERBOSE (cdev,QED_MSG_STORAGE ,"Failed to collect FCoE statistics\n" );return ;
drivers/net/ethernet/qlogic/qed/qed_fcoe.h +15 -2
@@ -28,8 +28,20 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn);void qed_fcoe_setup (struct qed_hwfn *p_hwfn);void qed_fcoe_free (struct qed_hwfn *p_hwfn); +/** +* qed_get_protocol_stats_fcoe(): Fills provided statistics +* struct with statistics. +* +* @cdev: Qed dev pointer. +* @stats: Points to struct that will be filled with statistics. +* @is_atomic: Hint from the caller - if the func can sleep or not. +* +* Context: The function should not sleep in case is_atomic == true. +* Return: Void. +*/ void qed_get_protocol_stats_fcoe (struct qed_dev *cdev, -struct qed_mcp_fcoe_stats *stats); +struct qed_mcp_fcoe_stats *stats, +bool is_atomic);#else /* CONFIG_QED_FCOE */ static inline int qed_fcoe_alloc (struct qed_hwfn *p_hwfn) {
@@ -40,7 +52,8 @@ static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {}static inline void qed_fcoe_free (struct qed_hwfn *p_hwfn) {}static inline void qed_get_protocol_stats_fcoe (struct qed_dev *cdev, -struct qed_mcp_fcoe_stats *stats) +struct qed_mcp_fcoe_stats *stats, +bool is_atomic) { }#endif /* CONFIG_QED_FCOE */
drivers/net/ethernet/qlogic/qed/qed_hw.c +22 -4
@@ -23,7 +23,10 @@#include "qed_reg_addr.h" #include "qed_sriov.h" -#define QED_BAR_ACQUIRE_TIMEOUT 1000 +#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT 1000 +#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP 1000 +#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT 100000 +#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY 10/* Invalid values */ #define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1))
@@ -84,12 +87,22 @@ void qed_ptt_pool_free(struct qed_hwfn *p_hwfn) }struct qed_ptt *qed_ptt_acquire (struct qed_hwfn *p_hwfn) +{ +return qed_ptt_acquire_context (p_hwfn, false); +} + +struct qed_ptt *qed_ptt_acquire_context (struct qed_hwfn *p_hwfn,bool is_atomic) {struct qed_ptt *p_ptt; -unsigned int i; +unsigned int i, count; + +if (is_atomic) + count =QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT ; +else + count =QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT ;/* Take the free PTT from the list */ -for (i =0 ; i <QED_BAR_ACQUIRE_TIMEOUT ; i++) { +for (i =0 ; i < count; i++) {spin_lock_bh (&p_hwfn->p_ptt_pool->lock);if (!list_empty (&p_hwfn->p_ptt_pool->free_list)) {
@@ -105,7 +118,12 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) }spin_unlock_bh (&p_hwfn->p_ptt_pool->lock); -usleep_range (1000 ,2000 ); + +if (is_atomic) +udelay (QED_BAR_ACQUIRE_TIMEOUT_UDELAY ); +else +usleep_range (QED_BAR_ACQUIRE_TIMEOUT_USLEEP , +QED_BAR_ACQUIRE_TIMEOUT_USLEEP *2 ); }DP_NOTICE (p_hwfn,"PTT acquire timeout - failed to allocate PTT\n" );
drivers/net/ethernet/qlogic/qed/qed_iscsi.c +14 -5
@@ -999,13 +999,14 @@ static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn, }static int qed_iscsi_get_stats (struct qed_hwfn *p_hwfn, -struct qed_iscsi_stats *stats) +struct qed_iscsi_stats *stats, +bool is_atomic) {struct qed_ptt *p_ptt;memset (stats,0 ,sizeof (*stats)); - p_ptt =qed_ptt_acquire (p_hwfn); + p_ptt =qed_ptt_acquire_context (p_hwfn, is_atomic);if (!p_ptt) {DP_ERR (p_hwfn,"Failed to acquire ptt\n" );return -EAGAIN ;
@@ -1336,9 +1337,16 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev, QED_SPQ_MODE_EBLOCK, NULL); } +static int qed_iscsi_stats_context (struct qed_dev *cdev, +struct qed_iscsi_stats *stats, +bool is_atomic) +{ +return qed_iscsi_get_stats (QED_AFFIN_HWFN (cdev), stats, is_atomic); +} +static int qed_iscsi_stats (struct qed_dev *cdev,struct qed_iscsi_stats *stats) { -return qed_iscsi_get_stats (QED_AFFIN_HWFN (cdev), stats); +return qed_iscsi_stats_context (cdev, stats, false); } static int qed_iscsi_change_mac(struct qed_dev *cdev,
@@ -1358,13 +1366,14 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev, }void qed_get_protocol_stats_iscsi (struct qed_dev *cdev, -struct qed_mcp_iscsi_stats *stats) +struct qed_mcp_iscsi_stats *stats, +bool is_atomic) {struct qed_iscsi_stats proto_stats;/* Retrieve FW statistics */ memset (&proto_stats,0 ,sizeof (proto_stats)); -if (qed_iscsi_stats (cdev, &proto_stats)) { +if (qed_iscsi_stats_context (cdev, &proto_stats, is_atomic)) {DP_VERBOSE (cdev,QED_MSG_STORAGE ,"Failed to collect ISCSI statistics\n" );return ;
drivers/net/ethernet/qlogic/qed/qed_iscsi.h +6 -2
@@ -39,11 +39,14 @@ void qed_iscsi_free(struct qed_hwfn *p_hwfn);* * @cdev: Qed dev pointer. * @stats: Points to struct that will be filled with statistics. +* @is_atomic: Hint from the caller - if the func can sleep or not. * +* Context: The function should not sleep in case is_atomic == true. * Return: Void. */ void qed_get_protocol_stats_iscsi (struct qed_dev *cdev, -struct qed_mcp_iscsi_stats *stats); +struct qed_mcp_iscsi_stats *stats, +bool is_atomic);#else /* IS_ENABLED(CONFIG_QED_ISCSI) */ static inline int qed_iscsi_alloc (struct qed_hwfn *p_hwfn) {
@@ -56,7 +59,8 @@ static inline void qed_iscsi_free(struct qed_hwfn *p_hwfn) {}static inline void qed_get_protocol_stats_iscsi (struct qed_dev *cdev, -struct qed_mcp_iscsi_stats *stats) {} +struct qed_mcp_iscsi_stats *stats, +bool is_atomic) {}#endif /* IS_ENABLED(CONFIG_QED_ISCSI) */ #endif
drivers/net/ethernet/qlogic/qed/qed_l2.c +14 -5
@@ -1863,7 +1863,8 @@ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn, }static void _qed_get_vport_stats (struct qed_dev *cdev, -struct qed_eth_stats *stats) +struct qed_eth_stats *stats, +bool is_atomic) {u8 fw_vport =0 ;int i;
@@ -1872,10 +1873,11 @@ static void _qed_get_vport_stats(struct qed_dev *cdev,for_each_hwfn (cdev, i) {struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; -struct qed_ptt *p_ptt =IS_PF (cdev) ?qed_ptt_acquire (p_hwfn) - :NULL ; +struct qed_ptt *p_ptt;bool b_get_port_stats; + p_ptt =IS_PF (cdev) ?qed_ptt_acquire_context (p_hwfn, is_atomic) + :NULL ;if (IS_PF (cdev)) {/* The main vport index is relative first */ if (qed_fw_vport (p_hwfn,0 , &fw_vport)) {
@@ -1900,6 +1902,13 @@ static void _qed_get_vport_stats(struct qed_dev *cdev, }void qed_get_vport_stats (struct qed_dev *cdev,struct qed_eth_stats *stats) +{ +qed_get_vport_stats_context (cdev, stats, false); +} + +void qed_get_vport_stats_context (struct qed_dev *cdev, +struct qed_eth_stats *stats, +bool is_atomic) {u32 i;
@@ -1908,7 +1917,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats)return ; } -_qed_get_vport_stats (cdev, stats); +_qed_get_vport_stats (cdev, stats, is_atomic);if (!cdev->reset_stats)return ;
@@ -1960,7 +1969,7 @@ void qed_reset_vport_stats(struct qed_dev *cdev)if (!cdev->reset_stats) {DP_INFO (cdev,"Reset stats not allocated\n" ); }else { -_qed_get_vport_stats (cdev, cdev->reset_stats); +_qed_get_vport_stats (cdev, cdev->reset_stats, false); cdev->reset_stats->common.link_change_count =0 ; } }
drivers/net/ethernet/qlogic/qed/qed_l2.h +24 -0
@@ -249,8 +249,32 @@ qed_sp_eth_rx_queues_update(struct qed_hwfn *p_hwfn,enum spq_mode comp_mode, struct qed_spq_comp_cb *p_comp_data); +/** +* qed_get_vport_stats(): Fills provided statistics +* struct with statistics. +* +* @cdev: Qed dev pointer. +* @stats: Points to struct that will be filled with statistics. +* +* Return: Void. +*/ void qed_get_vport_stats (struct qed_dev *cdev,struct qed_eth_stats *stats); +/** +* qed_get_vport_stats_context(): Fills provided statistics +* struct with statistics. +* +* @cdev: Qed dev pointer. +* @stats: Points to struct that will be filled with statistics. +* @is_atomic: Hint from the caller - if the func can sleep or not. +* +* Context: The function should not sleep in case is_atomic == true. +* Return: Void. +*/ +void qed_get_vport_stats_context (struct qed_dev *cdev, +struct qed_eth_stats *stats, +bool is_atomic); +void qed_reset_vport_stats (struct qed_dev *cdev);/**
drivers/net/ethernet/qlogic/qed/qed_main.c +3 -3
@@ -3092,7 +3092,7 @@ void qed_get_protocol_stats(struct qed_dev *cdev,switch (type) {case QED_MCP_LAN_STATS : -qed_get_vport_stats (cdev, ð_stats); +qed_get_vport_stats_context (cdev, ð_stats, true); stats->lan_stats.ucast_rx_pkts = eth_stats.common.rx_ucast_pkts; stats->lan_stats.ucast_tx_pkts =
@@ -3100,10 +3100,10 @@ void qed_get_protocol_stats(struct qed_dev *cdev, stats->lan_stats.fcs_err =-1 ;break ;case QED_MCP_FCOE_STATS : -qed_get_protocol_stats_fcoe (cdev, &stats->fcoe_stats); +qed_get_protocol_stats_fcoe (cdev, &stats->fcoe_stats, true);break ;case QED_MCP_ISCSI_STATS : -qed_get_protocol_stats_iscsi (cdev, &stats->iscsi_stats); +qed_get_protocol_stats_iscsi (cdev, &stats->iscsi_stats, true);break ;default : DP_VERBOSE(cdev, QED_MSG_SP,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 49/165 net: move gso declarations and functions to their own files
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit d457a0e329b0bfd3a1450e0b1a18cd2b47a25a08 ]
Move declarations into include/net/gso.h and code into net/core/gso.c
Stable-dep-of: 7938cd154368 ("net: gro: fix misuse of CB in udp socket lookup")
--- drivers/net/ethernet/broadcom/tg3.c | 1 + .../net/ethernet/myricom/myri10ge/myri10ge.c | 1 + drivers/net/ethernet/sfc/siena/tx_common.c | 1 + drivers/net/ethernet/sfc/tx_common.c | 1 + drivers/net/tap.c | 1 + drivers/net/usb/r8152.c | 1 + drivers/net/wireguard/device.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 1 + include/linux/netdevice.h | 26 +- include/linux/skbuff.h | 71 ----- include/net/gro.h | 1 + include/net/gso.h | 109 +++++++ include/net/udp.h | 1 + net/core/Makefile | 2 +- net/core/dev.c | 70 +---- net/core/gro.c | 59 +--- net/core/gso.c | 273 ++++++++++++++++++ net/core/skbuff.c | 142 +-------- net/ipv4/af_inet.c | 1 + net/ipv4/esp4_offload.c | 1 + net/ipv4/gre_offload.c | 1 + net/ipv4/ip_output.c | 1 + net/ipv4/tcp_offload.c | 1 + net/ipv4/udp.c | 1 + net/ipv4/udp_offload.c | 1 + net/ipv6/esp6_offload.c | 1 + net/ipv6/ip6_offload.c | 1 + net/ipv6/ip6_output.c | 1 + net/ipv6/udp_offload.c | 1 + net/mac80211/tx.c | 1 + net/mpls/af_mpls.c | 1 + net/mpls/mpls_gso.c | 1 + net/netfilter/nf_flow_table_ip.c | 1 + net/netfilter/nfnetlink_queue.c | 1 + net/nsh/nsh.c | 1 + net/openvswitch/actions.c | 1 + net/openvswitch/datapath.c | 1 + net/sched/act_police.c | 1 + net/sched/sch_cake.c | 1 + net/sched/sch_netem.c | 1 + net/sched/sch_taprio.c | 1 + net/sched/sch_tbf.c | 1 + net/sctp/offload.c | 1 + net/xfrm/xfrm_device.c | 1 + net/xfrm/xfrm_interface_core.c | 1 + net/xfrm/xfrm_output.c | 1 + 46 files changed, 425 insertions(+), 365 deletions(-) create mode 100644 include/net/gso.h create mode 100644 net/core/gso.c
drivers/net/ethernet/broadcom/tg3.c +1 -0
@@ -57,6 +57,7 @@#include <linux/crc32poly.h> #include <net/checksum.h> +#include <net/gso.h> #include <net/ip.h> #include <linux/io.h>
drivers/net/ethernet/myricom/myri10ge/myri10ge.c +1 -0
@@ -66,6 +66,7 @@#include <linux/slab.h> #include <linux/prefetch.h> #include <net/checksum.h> +#include <net/gso.h> #include <net/ip.h> #include <net/tcp.h> #include <asm/byteorder.h>
drivers/net/ethernet/sfc/siena/tx_common.c +1 -0
@@ -12,6 +12,7 @@#include "efx.h" #include "nic_common.h" #include "tx_common.h" +#include <net/gso.h> static unsigned int efx_tx_cb_page_count (struct efx_tx_queue *tx_queue) {
drivers/net/ethernet/sfc/tx_common.c +1 -0
@@ -12,6 +12,7 @@#include "efx.h" #include "nic_common.h" #include "tx_common.h" +#include <net/gso.h> static unsigned int efx_tx_cb_page_count (struct efx_tx_queue *tx_queue) {
drivers/net/tap.c +1 -0
@@ -18,6 +18,7 @@#include <linux/fs.h> #include <linux/uio.h> +#include <net/gso.h> #include <net/net_namespace.h> #include <net/rtnetlink.h> #include <net/sock.h>
drivers/net/usb/r8152.c +1 -0
@@ -27,6 +27,7 @@#include <linux/firmware.h> #include <crypto/hash.h> #include <linux/usb/r8152.h> +#include <net/gso.h> /* Information for net-next */ #define NETNEXT_VERSION "12"
drivers/net/wireguard/device.c +1 -0
@@ -20,6 +20,7 @@#include <linux/icmp.h> #include <linux/suspend.h> #include <net/dst_metadata.h> +#include <net/gso.h> #include <net/icmp.h> #include <net/rtnetlink.h> #include <net/ip_tunnels.h>
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +1 -0
@@ -7,6 +7,7 @@#include <linux/ieee80211.h> #include <linux/etherdevice.h> #include <linux/tcp.h> +#include <net/gso.h> #include <net/ip.h> #include <net/ipv6.h>
include/linux/netdevice.h +1 -25
@@ -4827,13 +4827,6 @@ int skb_crc32c_csum_help(struct sk_buff *skb);int skb_csum_hwoffload_help (struct sk_buff *skb,const netdev_features_t features); -struct sk_buff *__skb_gso_segment (struct sk_buff *skb, -netdev_features_t features,bool tx_path); -struct sk_buff *skb_eth_gso_segment (struct sk_buff *skb, -netdev_features_t features,__be16 type); -struct sk_buff *skb_mac_gso_segment (struct sk_buff *skb, -netdev_features_t features); -struct netdev_bonding_info {ifslave slave;ifbond master;
@@ -4856,11 +4849,6 @@ static inline void ethtool_notify(struct net_device *dev, unsigned int cmd, }#endif -static inline -struct sk_buff *skb_gso_segment (struct sk_buff *skb,netdev_features_t features) -{ -return __skb_gso_segment (skb, features, true); -}__be16 skb_network_protocol (struct sk_buff *skb,int *depth); static inline bool can_checksum_protocol(netdev_features_t features,
@@ -4987,6 +4975,7 @@ netdev_features_t passthru_features_check(struct sk_buff *skb,struct net_device *dev, netdev_features_t features);netdev_features_t netif_skb_features (struct sk_buff *skb); +void skb_warn_bad_offload (const struct sk_buff *skb);static inline bool net_gso_ok (netdev_features_t features,int gso_type) {
@@ -5035,19 +5024,6 @@ void netif_set_tso_max_segs(struct net_device *dev, unsigned int segs);void netif_inherit_tso_max (struct net_device *to,const struct net_device *from); -static inline void skb_gso_error_unwind (struct sk_buff *skb,__be16 protocol, -int pulled_hlen,u16 mac_offset, -int mac_len) -{ - skb->protocol = protocol; - skb->encapsulation =1 ; -skb_push (skb, pulled_hlen); -skb_reset_transport_header (skb); - skb->mac_header = mac_offset; - skb->network_header = skb->mac_header + mac_len; - skb->mac_len = mac_len; -} -static inline bool netif_is_macsec (const struct net_device *dev) {return dev->priv_flags &IFF_MACSEC ;
include/linux/skbuff.h +0 -71
83 lines not on this page · raw message
include/net/gro.h +1 -0
@@ -446,5 +446,6 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb, gro_normal_list(napi); } +extern struct list_head offload_base;#endif /* _NET_IPV6_GRO_H */
include/net/gso.h new file +109 -0
109 lines not on this page · raw message
include/net/udp.h +1 -0
@@ -21,6 +21,7 @@#include <linux/list.h> #include <linux/bug.h> #include <net/inet_sock.h> +#include <net/gso.h> #include <net/sock.h> #include <net/snmp.h> #include <net/ip.h>
net/core/Makefile +1 -1
@@ -13,7 +13,7 @@ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ fib_notifier.o xdp.o flow_offload.o gro.o \ - netdev-genl.o netdev-genl-gen.o + netdev-genl.o netdev-genl-gen.o gso.o obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
net/core/dev.c +1 -69
82 lines not on this page · raw message
net/core/gro.c +1 -58
71 lines not on this page · raw message
net/core/gso.c new file +273 -0
273 lines not on this page · raw message
net/core/skbuff.c +1 -141
154 lines not on this page · raw message
net/ipv4/af_inet.c +1 -0
@@ -100,6 +100,7 @@#include <net/ip_fib.h> #include <net/inet_connection_sock.h> #include <net/gro.h> +#include <net/gso.h> #include <net/tcp.h> #include <net/udp.h> #include <net/udplite.h>
net/ipv4/esp4_offload.c +1 -0
@@ -17,6 +17,7 @@#include <linux/err.h> #include <linux/module.h> #include <net/gro.h> +#include <net/gso.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/esp.h>
net/ipv4/gre_offload.c +1 -0
@@ -11,6 +11,7 @@#include <net/protocol.h> #include <net/gre.h> #include <net/gro.h> +#include <net/gso.h> static struct sk_buff *gre_gso_segment (struct sk_buff *skb,netdev_features_t features)
net/ipv4/ip_output.c +1 -0
@@ -73,6 +73,7 @@#include <net/arp.h> #include <net/icmp.h> #include <net/checksum.h> +#include <net/gso.h> #include <net/inetpeer.h> #include <net/inet_ecn.h> #include <net/lwtunnel.h>
net/ipv4/tcp_offload.c +1 -0
@@ -9,6 +9,7 @@#include <linux/indirect_call_wrapper.h> #include <linux/skbuff.h> #include <net/gro.h> +#include <net/gso.h> #include <net/tcp.h> #include <net/protocol.h>
net/ipv4/udp.c +1 -0
@@ -103,6 +103,7 @@#include <net/ip_tunnels.h> #include <net/route.h> #include <net/checksum.h> +#include <net/gso.h> #include <net/xfrm.h> #include <trace/events/udp.h> #include <linux/static_key.h>
net/ipv4/udp_offload.c +1 -0
@@ -8,6 +8,7 @@#include <linux/skbuff.h> #include <net/gro.h> +#include <net/gso.h> #include <net/udp.h> #include <net/protocol.h> #include <net/inet_common.h>
net/ipv6/esp6_offload.c +1 -0
@@ -17,6 +17,7 @@#include <linux/err.h> #include <linux/module.h> #include <net/gro.h> +#include <net/gso.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/esp.h>
net/ipv6/ip6_offload.c +1 -0
@@ -16,6 +16,7 @@#include <net/tcp.h> #include <net/udp.h> #include <net/gro.h> +#include <net/gso.h> #include "ip6_offload.h"
net/ipv6/ip6_output.c +1 -0
@@ -42,6 +42,7 @@#include <net/sock.h> #include <net/snmp.h> +#include <net/gso.h> #include <net/ipv6.h> #include <net/ndisc.h> #include <net/protocol.h>
net/ipv6/udp_offload.c +1 -0
@@ -14,6 +14,7 @@#include <net/ip6_checksum.h> #include "ip6_offload.h" #include <net/gro.h> +#include <net/gso.h> static struct sk_buff *udp6_ufo_fragment (struct sk_buff *skb,netdev_features_t features)
net/mac80211/tx.c +1 -0
@@ -26,6 +26,7 @@#include <net/codel_impl.h> #include <asm/unaligned.h> #include <net/fq_impl.h> +#include <net/gso.h> #include "ieee80211_i.h" #include "driver-ops.h"
net/mpls/af_mpls.c +1 -0
@@ -12,6 +12,7 @@#include <linux/nospec.h> #include <linux/vmalloc.h> #include <linux/percpu.h> +#include <net/gso.h> #include <net/ip.h> #include <net/dst.h> #include <net/sock.h>
net/mpls/mpls_gso.c +1 -0
@@ -14,6 +14,7 @@#include <linux/netdev_features.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <net/gso.h> #include <net/mpls.h> static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
net/netfilter/nf_flow_table_ip.c +1 -0
@@ -8,6 +8,7 @@#include <linux/ipv6.h> #include <linux/netdevice.h> #include <linux/if_ether.h> +#include <net/gso.h> #include <net/ip.h> #include <net/ipv6.h> #include <net/ip6_route.h>
net/netfilter/nfnetlink_queue.c +1 -0
@@ -30,6 +30,7 @@#include <linux/netfilter/nf_conntrack_common.h> #include <linux/list.h> #include <linux/cgroup-defs.h> +#include <net/gso.h> #include <net/sock.h> #include <net/tcp_states.h> #include <net/netfilter/nf_queue.h>
net/nsh/nsh.c +1 -0
@@ -8,6 +8,7 @@#include <linux/module.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <net/gso.h> #include <net/nsh.h> #include <net/tun_proto.h>
net/openvswitch/actions.c +1 -0
@@ -17,6 +17,7 @@#include <linux/if_vlan.h> #include <net/dst.h> +#include <net/gso.h> #include <net/ip.h> #include <net/ipv6.h> #include <net/ip6_fib.h>
net/openvswitch/datapath.c +1 -0
@@ -35,6 +35,7 @@#include <linux/rculist.h> #include <linux/dmi.h> #include <net/genetlink.h> +#include <net/gso.h> #include <net/net_namespace.h> #include <net/netns/generic.h> #include <net/pkt_cls.h>
net/sched/act_police.c +1 -0
@@ -16,6 +16,7 @@#include <linux/init.h> #include <linux/slab.h> #include <net/act_api.h> +#include <net/gso.h> #include <net/netlink.h> #include <net/pkt_cls.h> #include <net/tc_act/tc_police.h>
net/sched/sch_cake.c +1 -0
@@ -65,6 +65,7 @@#include <linux/reciprocal_div.h> #include <net/netlink.h> #include <linux/if_vlan.h> +#include <net/gso.h> #include <net/pkt_sched.h> #include <net/pkt_cls.h> #include <net/tcp.h>
net/sched/sch_netem.c +1 -0
@@ -21,6 +21,7 @@#include <linux/reciprocal_div.h> #include <linux/rbtree.h> +#include <net/gso.h> #include <net/netlink.h> #include <net/pkt_sched.h> #include <net/inet_ecn.h>
net/sched/sch_taprio.c +1 -0
@@ -20,6 +20,7 @@#include <linux/spinlock.h> #include <linux/rcupdate.h> #include <linux/time.h> +#include <net/gso.h> #include <net/netlink.h> #include <net/pkt_sched.h> #include <net/pkt_cls.h>
net/sched/sch_tbf.c +1 -0
@@ -13,6 +13,7 @@#include <linux/string.h> #include <linux/errno.h> #include <linux/skbuff.h> +#include <net/gso.h> #include <net/netlink.h> #include <net/sch_generic.h> #include <net/pkt_cls.h>
net/sctp/offload.c +1 -0
@@ -22,6 +22,7 @@#include <net/sctp/sctp.h> #include <net/sctp/checksum.h> #include <net/protocol.h> +#include <net/gso.h> static __le32 sctp_gso_make_checksum (struct sk_buff *skb) {
net/xfrm/xfrm_device.c +1 -0
@@ -15,6 +15,7 @@#include <linux/slab.h> #include <linux/spinlock.h> #include <net/dst.h> +#include <net/gso.h> #include <net/xfrm.h> #include <linux/notifier.h>
net/xfrm/xfrm_interface_core.c +1 -0
@@ -33,6 +33,7 @@#include <linux/uaccess.h> #include <linux/atomic.h> +#include <net/gso.h> #include <net/icmp.h> #include <net/ip.h> #include <net/ipv6.h>
net/xfrm/xfrm_output.c +1 -0
@@ -13,6 +13,7 @@#include <linux/slab.h> #include <linux/spinlock.h> #include <net/dst.h> +#include <net/gso.h> #include <net/icmp.h> #include <net/inet_ecn.h> #include <net/xfrm.h>
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 50/165 net: gro: fix misuse of CB in udp socket lookup
In reply to Greg Kroah-HartmanFrom: Richard Gobert <[email protected]>
[ Upstream commit 7938cd15436873f649f31cb867bac2d88ca564d0 ]
This patch fixes a misuse of IP{6}CB(skb) in GRO, while calling to udp6_lib_lookup2 when handling udp tunnels. udp6_lib_lookup2 fetch the device from CB. The fix changes it to fetch the device from skb->dev. l3mdev case requires special attention since it has a master and a slave device.
--- include/net/gro.h | 43 ++++++++++++++++++++++++++++++++++++++++++ net/ipv4/udp.c | 8 ++++++-- net/ipv4/udp_offload.c | 7 +++++-- net/ipv6/udp.c | 8 ++++++-- net/ipv6/udp_offload.c | 7 +++++-- 5 files changed, 65 insertions(+), 8 deletions(-)
include/net/gro.h +43 -0
@@ -446,6 +446,49 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb, gro_normal_list(napi); } +/* This function is the alternative of 'inet_iif' and 'inet_sdif' +* functions in case we can not rely on fields of IPCB. +* +* The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. +* The caller must hold the RCU read lock. +*/ +static inline void inet_get_iif_sdif (const struct sk_buff *skb,int *iif,int *sdif) +{ + *iif =inet_iif (skb) ?: skb->dev->ifindex; + *sdif =0 ; + +#if IS_ENABLED (CONFIG_NET_L3_MASTER_DEV ) +if (netif_is_l3_slave (skb->dev)) { +struct net_device *master =netdev_master_upper_dev_get_rcu (skb->dev); + + *sdif = *iif; + *iif = master ? master->ifindex :0 ; + } +#endif +} + +/* This function is the alternative of 'inet6_iif' and 'inet6_sdif' +* functions in case we can not rely on fields of IP6CB. +* +* The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. +* The caller must hold the RCU read lock. +*/ +static inline void inet6_get_iif_sdif (const struct sk_buff *skb,int *iif,int *sdif) +{ +/* using skb->dev->ifindex because skb_dst(skb) is not initialized */ + *iif = skb->dev->ifindex; + *sdif =0 ; + +#if IS_ENABLED (CONFIG_NET_L3_MASTER_DEV ) +if (netif_is_l3_slave (skb->dev)) { +struct net_device *master =netdev_master_upper_dev_get_rcu (skb->dev); + + *sdif = *iif; + *iif = master ? master->ifindex :0 ; + } +#endif +} +extern struct list_head offload_base;#endif /* _NET_IPV6_GRO_H */
net/ipv4/udp.c +6 -2
@@ -114,6 +114,7 @@#include <net/sock_reuseport.h> #include <net/addrconf.h> #include <net/udp_tunnel.h> +#include <net/gro.h> #if IS_ENABLED (CONFIG_IPV6 )#include <net/ipv6_stubs.h> #endif
@@ -555,10 +556,13 @@ struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb, {const struct iphdr *iph =ip_hdr (skb);struct net *net =dev_net (skb->dev); +int iif, sdif; + +inet_get_iif_sdif (skb, &iif, &sdif);return __udp4_lib_lookup (net, iph->saddr, sport, - iph->daddr, dport,inet_iif (skb), -inet_sdif (skb), net->ipv4.udp_table,NULL ); + iph->daddr, dport, iif, + sdif, net->ipv4.udp_table,NULL ); }/* Must be called under rcu_read_lock().
net/ipv4/udp_offload.c +5 -2
@@ -609,10 +609,13 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport, {const struct iphdr *iph =skb_gro_network_header (skb);struct net *net =dev_net (skb->dev); +int iif, sdif; + +inet_get_iif_sdif (skb, &iif, &sdif);return __udp4_lib_lookup (net, iph->saddr, sport, - iph->daddr, dport,inet_iif (skb), -inet_sdif (skb), net->ipv4.udp_table,NULL ); + iph->daddr, dport, iif, + sdif, net->ipv4.udp_table,NULL ); }INDIRECT_CALLABLE_SCOPE
net/ipv6/udp.c +6 -2
@@ -51,6 +51,7 @@#include <net/inet6_hashtables.h> #include <net/busy_poll.h> #include <net/sock_reuseport.h> +#include <net/gro.h> #include <linux/proc_fs.h> #include <linux/seq_file.h>
@@ -300,10 +301,13 @@ struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, {const struct ipv6hdr *iph =ipv6_hdr (skb);struct net *net =dev_net (skb->dev); +int iif, sdif; + +inet6_get_iif_sdif (skb, &iif, &sdif);return __udp6_lib_lookup (net, &iph->saddr, sport, - &iph->daddr, dport,inet6_iif (skb), -inet6_sdif (skb), net->ipv4.udp_table,NULL ); + &iph->daddr, dport, iif, + sdif, net->ipv4.udp_table,NULL ); }/* Must be called under rcu_read_lock().
net/ipv6/udp_offload.c +5 -2
@@ -118,10 +118,13 @@ static struct sock *udp6_gro_lookup_skb(struct sk_buff *skb, __be16 sport, {const struct ipv6hdr *iph =skb_gro_network_header (skb);struct net *net =dev_net (skb->dev); +int iif, sdif; + +inet6_get_iif_sdif (skb, &iif, &sdif);return __udp6_lib_lookup (net, &iph->saddr, sport, - &iph->daddr, dport,inet6_iif (skb), -inet6_sdif (skb), net->ipv4.udp_table,NULL ); + &iph->daddr, dport, iif, + sdif, net->ipv4.udp_table,NULL ); }INDIRECT_CALLABLE_SCOPE
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 51/165 net: annotate data-races around sk->sk_reserved_mem
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit fe11fdcb4207907d80cda2e73777465d68131e66 ]
sk_getsockopt() runs locklessly. This means sk->sk_reserved_mem can be read while other threads are changing its value.
Add missing annotations where they are needed.
--- net/core/sock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/core/sock.c +4 -3
@@ -1003,7 +1003,7 @@ static void sock_release_reserved_memory(struct sock *sk, int bytes) bytes =round_down (bytes,PAGE_SIZE );WARN_ON (bytes > sk->sk_reserved_mem); - sk->sk_reserved_mem -= bytes; +WRITE_ONCE (sk->sk_reserved_mem, sk->sk_reserved_mem - bytes);sk_mem_reclaim (sk); }
@@ -1040,7 +1040,8 @@ static int sock_reserve_memory(struct sock *sk, int bytes) } sk->sk_forward_alloc += pages <<PAGE_SHIFT ; - sk->sk_reserved_mem += pages <<PAGE_SHIFT ; +WRITE_ONCE (sk->sk_reserved_mem, + sk->sk_reserved_mem + (pages <<PAGE_SHIFT ));return 0 ; }
@@ -1925,7 +1926,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_RESERVE_MEM : - v.val = sk->sk_reserved_mem; + v.val =READ_ONCE (sk->sk_reserved_mem);break ;case SO_TXREHASH :
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 52/165 net: annotate data-race around sk->sk_txrehash
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit c76a0328899bbe226f8adeb88b8da9e4167bd316 ]
sk_getsockopt() runs locklessly. This means sk->sk_txrehash can be read while other threads are changing its value.
Other locations were handled in commit cb6cd2cec799 ("tcp: Change SYN ACK retransmit behaviour to account for rehash")
--- net/core/sock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/core/sock.c +5 -2
@@ -1523,7 +1523,9 @@ int sk_setsockopt(struct sock *sk, int level, int optname, }if ((u8 )val ==SOCK_TXREHASH_DEFAULT ) val =READ_ONCE (sock_net (sk)->core.sysctl_txrehash); -/* Paired with READ_ONCE() in tcp_rtx_synack() */ +/* Paired with READ_ONCE() in tcp_rtx_synack() +* and sk_getsockopt(). +*/ WRITE_ONCE (sk->sk_txrehash, (u8 )val);break ;
@@ -1930,7 +1932,8 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_TXREHASH : - v.val = sk->sk_txrehash; +/* Paired with WRITE_ONCE() in sk_setsockopt() */ + v.val =READ_ONCE (sk->sk_txrehash);break ;default :
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 53/165 net: annotate data-races around sk->sk_max_pacing_rate
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit ea7f45ef77b39e72244d282e47f6cb1ef4135cd2 ]
sk_getsockopt() runs locklessly. This means sk->sk_max_pacing_rate can be read while other threads are changing its value.
--- net/core/sock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/core/sock.c +6 -3
@@ -1428,7 +1428,8 @@ int sk_setsockopt(struct sock *sk, int level, int optname,cmpxchg (&sk->sk_pacing_status,SK_PACING_NONE ,SK_PACING_NEEDED ); - sk->sk_max_pacing_rate = ulval; +/* Pairs with READ_ONCE() from sk_getsockopt() */ +WRITE_ONCE (sk->sk_max_pacing_rate, ulval); sk->sk_pacing_rate =min (sk->sk_pacing_rate, ulval);break ; }
@@ -1855,12 +1856,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname,#endif case SO_MAX_PACING_RATE : +/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */ if (sizeof (v.ulval) !=sizeof (v.val) && len >=sizeof (v.ulval)) { lv =sizeof (v.ulval); - v.ulval = sk->sk_max_pacing_rate; + v.ulval =READ_ONCE (sk->sk_max_pacing_rate); }else {/* 32bit version */ - v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); + v.val = min_t(unsigned long, ~0U, +READ_ONCE (sk->sk_max_pacing_rate)); }break ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 54/165 net: add missing READ_ONCE(sk->sk_rcvlowat) annotation
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e6d12bdb435d23ff6c1890c852d85408a2f496ee ]
In a prior commit, I forgot to change sk_getsockopt() when reading sk->sk_rcvlowat locklessly.
--- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/sock.c +1 -1
@@ -1719,7 +1719,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_RCVLOWAT : - v.val = sk->sk_rcvlowat; + v.val =READ_ONCE (sk->sk_rcvlowat);break ;case SO_SNDLOWAT :
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 55/165 net: add missing READ_ONCE(sk->sk_sndbuf) annotation
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 74bc084327c643499474ba75df485607da37dd6e ]
In a prior commit, I forgot to change sk_getsockopt() when reading sk->sk_sndbuf locklessly.
--- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/sock.c +1 -1
@@ -1626,7 +1626,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_SNDBUF : - v.val = sk->sk_sndbuf; + v.val =READ_ONCE (sk->sk_sndbuf);break ;case SO_RCVBUF :
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 56/165 net: add missing READ_ONCE(sk->sk_rcvbuf) annotation
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit b4b553253091cafe9ec38994acf42795e073bef5 ]
In a prior commit, I forgot to change sk_getsockopt() when reading sk->sk_rcvbuf locklessly.
--- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/sock.c +1 -1
@@ -1630,7 +1630,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_RCVBUF : - v.val = sk->sk_rcvbuf; + v.val =READ_ONCE (sk->sk_rcvbuf);break ;case SO_REUSEADDR :
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 57/165 net: annotate data-races around sk->sk_mark
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 3c5b4d69c358a9275a8de98f87caf6eda644b086 ]
sk->sk_mark is often read while another thread could change the value.
--- include/net/inet_sock.h | 7 ++++--- include/net/ip.h | 2 +- include/net/route.h | 4 ++-- net/can/raw.c | 2 +- net/core/sock.c | 4 ++-- net/dccp/ipv6.c | 4 ++-- net/ipv4/inet_diag.c | 4 ++-- net/ipv4/ip_output.c | 4 ++-- net/ipv4/route.c | 4 ++-- net/ipv4/tcp_ipv4.c | 2 +- net/ipv6/ping.c | 2 +- net/ipv6/raw.c | 4 ++-- net/ipv6/route.c | 7 ++++--- net/ipv6/tcp_ipv6.c | 6 +++--- net/ipv6/udp.c | 4 ++-- net/l2tp/l2tp_ip6.c | 2 +- net/mptcp/sockopt.c | 2 +- net/netfilter/nft_socket.c | 2 +- net/netfilter/xt_socket.c | 4 ++-- net/packet/af_packet.c | 6 +++--- net/smc/af_smc.c | 2 +- net/xdp/xsk.c | 2 +- net/xfrm/xfrm_policy.c | 2 +- 23 files changed, 42 insertions(+), 40 deletions(-)
include/net/inet_sock.h +4 -3
@@ -107,11 +107,12 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)static inline u32 inet_request_mark (const struct sock *sk,struct sk_buff *skb) { -if (!sk->sk_mark && -READ_ONCE (sock_net (sk)->ipv4.sysctl_tcp_fwmark_accept)) +u32 mark =READ_ONCE (sk->sk_mark); + +if (!mark &&READ_ONCE (sock_net (sk)->ipv4.sysctl_tcp_fwmark_accept))return skb->mark; -return sk->sk_mark; +return mark; } static inline int inet_request_bound_dev_if(const struct sock *sk,
include/net/ip.h +1 -1
@@ -93,7 +93,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, {ipcm_init (ipcm); - ipcm->sockc.mark = inet->sk.sk_mark; + ipcm->sockc.mark =READ_ONCE (inet->sk.sk_mark); ipcm->sockc.tsflags = inet->sk.sk_tsflags; ipcm->oif =READ_ONCE (inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr;
include/net/route.h +2 -2
@@ -168,7 +168,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi __be16 dport, __be16 sport, __u8 proto, __u8 tos, int oif) { - flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos, + flowi4_init_output(fl4, oif, sk ? READ_ONCE(sk->sk_mark) : 0, tos,RT_SCOPE_UNIVERSE ,proto , sk ? inet_sk_flowi_flags(sk) : 0,daddr ,saddr ,dport ,sport ,sock_net_uid (net ,sk ));
@@ -301,7 +301,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst,if (inet_sk (sk)->transparent) flow_flags |=FLOWI_FLAG_ANYSRC ; -flowi4_init_output (fl4, oif, sk->sk_mark,ip_sock_rt_tos (sk), +flowi4_init_output (fl4, oif,READ_ONCE (sk->sk_mark),ip_sock_rt_tos (sk),ip_sock_rt_scope (sk), protocol, flow_flags, dst, src, dport, sport, sk->sk_uid); }
net/can/raw.c +1 -1
@@ -873,7 +873,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) skb->dev = dev; skb->priority = sk->sk_priority; - skb->mark = sk->sk_mark; + skb->mark =READ_ONCE (sk->sk_mark); skb->tstamp = sockc.transmit_time;skb_setup_tx_timestamp (skb, sockc.tsflags);
net/core/sock.c +2 -2
@@ -984,7 +984,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf);static void __sock_set_mark (struct sock *sk,u32 val) {if (val != sk->sk_mark) { - sk->sk_mark = val; +WRITE_ONCE (sk->sk_mark, val);sk_dst_reset (sk); } }
@@ -1799,7 +1799,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, optval, optlen, len);case SO_MARK : - v.val = sk->sk_mark; + v.val =READ_ONCE (sk->sk_mark);break ;case SO_RCVMARK :
net/dccp/ipv6.c +2 -2
@@ -238,8 +238,8 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req opt = ireq->ipv6_opt;if (!opt) opt =rcu_dereference (np->opt); - err =ip6_xmit (sk, skb, &fl6, sk->sk_mark, opt, np->tclass, - sk->sk_priority); + err =ip6_xmit (sk, skb, &fl6,READ_ONCE (sk->sk_mark), opt, + np->tclass, sk->sk_priority);rcu_read_unlock (); err =net_xmit_eval (err); }
net/ipv4/inet_diag.c +2 -2
@@ -150,7 +150,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, }#endif -if (net_admin &&nla_put_u32 (skb,INET_DIAG_MARK , sk->sk_mark)) +if (net_admin &&nla_put_u32 (skb,INET_DIAG_MARK ,READ_ONCE (sk->sk_mark))) goto errout; if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
@@ -799,7 +799,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) entry.ifindex = sk->sk_bound_dev_if; entry.userlocks =sk_fullsock (sk) ? sk->sk_userlocks :0 ;if (sk_fullsock (sk)) - entry.mark = sk->sk_mark; + entry.mark =READ_ONCE (sk->sk_mark);else if (sk->sk_state ==TCP_NEW_SYN_RECV ) entry.mark =inet_rsk (inet_reqsk (sk))->ir_mark;else if (sk->sk_state ==TCP_TIME_WAIT )
net/ipv4/ip_output.c +2 -2
@@ -186,7 +186,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, skb->priority = sk->sk_priority;if (!skb->mark) - skb->mark = sk->sk_mark; + skb->mark =READ_ONCE (sk->sk_mark);/* Send it out. */ return ip_local_out (net, skb->sk, skb);
@@ -529,7 +529,7 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,/* TODO : should we use skb->sk here instead of sk ? */ skb->priority = sk->sk_priority; - skb->mark = sk->sk_mark; + skb->mark =READ_ONCE (sk->sk_mark); res =ip_local_out (net, sk, skb);rcu_read_unlock ();
net/ipv4/route.c +2 -2
@@ -518,7 +518,7 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4,const struct inet_sock *inet =inet_sk (sk); oif = sk->sk_bound_dev_if; - mark = sk->sk_mark; + mark =READ_ONCE (sk->sk_mark); tos =ip_sock_rt_tos (sk); scope =ip_sock_rt_scope (sk); prot = inet->hdrincl ?IPPROTO_RAW : sk->sk_protocol;
@@ -552,7 +552,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk) inet_opt =rcu_dereference (inet->inet_opt);if (inet_opt && inet_opt->opt.srr) daddr = inet_opt->opt.faddr; - flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, + flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk) & IPTOS_RT_MASK, ip_sock_rt_scope(sk), inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
net/ipv4/tcp_ipv4.c +1 -1
@@ -931,7 +931,7 @@ static void tcp_v4_send_ack(const struct sock *sk, ctl_sk =this_cpu_read (ipv4_tcp_sk);sock_net_set (ctl_sk, net); ctl_sk->sk_mark = (sk->sk_state ==TCP_TIME_WAIT ) ? -inet_twsk (sk)->tw_mark : sk->sk_mark; +inet_twsk (sk)->tw_mark :READ_ONCE (sk->sk_mark); ctl_sk->sk_priority = (sk->sk_state ==TCP_TIME_WAIT ) ?inet_twsk (sk)->tw_priority : sk->sk_priority; transmit_time =tcp_transmit_time (sk);
net/ipv6/ping.c +1 -1
@@ -120,7 +120,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)ipcm6_init_sk (&ipc6, np); ipc6.sockc.tsflags = sk->sk_tsflags; - ipc6.sockc.mark = sk->sk_mark; + ipc6.sockc.mark =READ_ONCE (sk->sk_mark); fl6.flowi6_oif = oif;
net/ipv6/raw.c +2 -2
@@ -774,12 +774,12 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)*/ memset (&fl6,0 ,sizeof (fl6)); - fl6.flowi6_mark = sk->sk_mark; + fl6.flowi6_mark =READ_ONCE (sk->sk_mark); fl6.flowi6_uid = sk->sk_uid;ipcm6_init (&ipc6); ipc6.sockc.tsflags = sk->sk_tsflags; - ipc6.sockc.mark = sk->sk_mark; + ipc6.sockc.mark = fl6.flowi6_mark;if (sin6) {if (addr_len <SIN6_LEN_RFC2133 )
net/ipv6/route.c +4 -3
@@ -2951,7 +2951,8 @@ void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)if (!oif && skb->dev) oif =l3mdev_master_ifindex (skb->dev); -ip6_update_pmtu (skb,sock_net (sk), mtu, oif, sk->sk_mark, sk->sk_uid); +ip6_update_pmtu (skb,sock_net (sk), mtu, oif,READ_ONCE (sk->sk_mark), + sk->sk_uid); dst =__sk_dst_get (sk); if (!dst || !dst->obsolete ||
@@ -3172,8 +3173,8 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif)void ip6_sk_redirect (struct sk_buff *skb,struct sock *sk) { -ip6_redirect (skb,sock_net (sk), sk->sk_bound_dev_if, sk->sk_mark, - sk->sk_uid); +ip6_redirect (skb,sock_net (sk), sk->sk_bound_dev_if, +READ_ONCE (sk->sk_mark), sk->sk_uid); }EXPORT_SYMBOL_GPL (ip6_sk_redirect);
net/ipv6/tcp_ipv6.c +3 -3
@@ -568,8 +568,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, opt = ireq->ipv6_opt;if (!opt) opt =rcu_dereference (np->opt); - err =ip6_xmit (sk, skb, fl6, skb->mark ? : sk->sk_mark, opt, - tclass, sk->sk_priority); + err =ip6_xmit (sk, skb, fl6, skb->mark ? :READ_ONCE (sk->sk_mark), + opt, tclass, sk->sk_priority);rcu_read_unlock (); err =net_xmit_eval (err); }
@@ -943,7 +943,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32if (sk->sk_state ==TCP_TIME_WAIT ) mark =inet_twsk (sk)->tw_mark;else - mark = sk->sk_mark; + mark =READ_ONCE (sk->sk_mark);skb_set_delivery_time (buff,tcp_transmit_time (sk), true); }if (txhash) {
net/ipv6/udp.c +2 -2
@@ -628,7 +628,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,if (type ==NDISC_REDIRECT ) {if (tunnel) {ip6_redirect (skb,sock_net (sk),inet6_iif (skb), - sk->sk_mark, sk->sk_uid); +READ_ONCE (sk->sk_mark), sk->sk_uid); }else {ip6_sk_redirect (skb, sk); }
@@ -1360,7 +1360,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)ipcm6_init (&ipc6); ipc6.gso_size =READ_ONCE (up->gso_size); ipc6.sockc.tsflags = sk->sk_tsflags; - ipc6.sockc.mark = sk->sk_mark; + ipc6.sockc.mark =READ_ONCE (sk->sk_mark);/* destination address check */ if (sin6) {
net/l2tp/l2tp_ip6.c +1 -1
@@ -519,7 +519,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)/* Get and verify the address */ memset (&fl6,0 ,sizeof (fl6)); - fl6.flowi6_mark = sk->sk_mark; + fl6.flowi6_mark =READ_ONCE (sk->sk_mark); fl6.flowi6_uid = sk->sk_uid;ipcm6_init (&ipc6);
net/mptcp/sockopt.c +1 -1
@@ -102,7 +102,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, inbreak ;case SO_MARK :if (READ_ONCE (ssk->sk_mark) != sk->sk_mark) { - ssk->sk_mark = sk->sk_mark; +WRITE_ONCE (ssk->sk_mark, sk->sk_mark);sk_dst_reset (ssk); }break ;
net/netfilter/nft_socket.c +1 -1
@@ -107,7 +107,7 @@ static void nft_socket_eval(const struct nft_expr *expr,break ;case NFT_SOCKET_MARK :if (sk_fullsock (sk)) { - *dest = sk->sk_mark; + *dest =READ_ONCE (sk->sk_mark); }else { regs->verdict.code =NFT_BREAK ;return ;
net/netfilter/xt_socket.c +2 -2
@@ -77,7 +77,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,if (info->flags &XT_SOCKET_RESTORESKMARK && !wildcard && transparent &&sk_fullsock (sk)) - pskb->mark = sk->sk_mark; + pskb->mark =READ_ONCE (sk->sk_mark);if (sk != skb->sk)sock_gen_put (sk);
@@ -138,7 +138,7 @@ socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)if (info->flags &XT_SOCKET_RESTORESKMARK && !wildcard && transparent &&sk_fullsock (sk)) - pskb->mark = sk->sk_mark; + pskb->mark =READ_ONCE (sk->sk_mark);if (sk != skb->sk)sock_gen_put (sk);
net/packet/af_packet.c +3 -3
@@ -2051,7 +2051,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, skb->protocol = proto; skb->dev = dev; skb->priority = sk->sk_priority; - skb->mark = sk->sk_mark; + skb->mark =READ_ONCE (sk->sk_mark); skb->tstamp = sockc.transmit_time;skb_setup_tx_timestamp (skb, sockc.tsflags);
@@ -2586,7 +2586,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, skb->protocol = proto; skb->dev = dev; skb->priority = po->sk.sk_priority; - skb->mark = po->sk.sk_mark; + skb->mark =READ_ONCE (po->sk.sk_mark); skb->tstamp = sockc->transmit_time;skb_setup_tx_timestamp (skb, sockc->tsflags);skb_zcopy_set_nouarg (skb, ph.raw);
@@ -2988,7 +2988,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) goto out_unlock;sockcm_init (&sockc, sk); - sockc.mark = sk->sk_mark; + sockc.mark =READ_ONCE (sk->sk_mark);if (msg->msg_controllen) { err =sock_cmsg_send (sk, msg, &sockc);if (unlikely (err))
net/smc/af_smc.c +1 -1
@@ -445,7 +445,7 @@ static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk, nsk->sk_rcvbuf = osk->sk_rcvbuf; nsk->sk_sndtimeo = osk->sk_sndtimeo; nsk->sk_rcvtimeo = osk->sk_rcvtimeo; - nsk->sk_mark = osk->sk_mark; + nsk->sk_mark =READ_ONCE (osk->sk_mark); nsk->sk_priority = osk->sk_priority; nsk->sk_rcvlowat = osk->sk_rcvlowat; nsk->sk_bound_dev_if = osk->sk_bound_dev_if;
net/xdp/xsk.c +1 -1
@@ -505,7 +505,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, skb->dev = dev; skb->priority = xs->sk.sk_priority; - skb->mark = xs->sk.sk_mark; + skb->mark =READ_ONCE (xs->sk.sk_mark);skb_shinfo (skb)->destructor_arg = (void *)(long )desc->addr; skb->destructor = xsk_destruct_skb;
net/xfrm/xfrm_policy.c +1 -1
@@ -2250,7 +2250,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, match =xfrm_selector_match (&pol->selector, fl, family);if (match) { -if ((sk->sk_mark & pol->mark.m) != pol->mark.v || +if ((READ_ONCE (sk->sk_mark) & pol->mark.m) != pol->mark.v || pol->if_id != if_id) { pol =NULL ; goto out;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 58/165 net: add missing data-race annotations around sk->sk_peek_off
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 11695c6e966b0ec7ed1d16777d294cef865a5c91 ]
sk_getsockopt() runs locklessly, thus we need to annotate the read of sk->sk_peek_off.
While we are at it, add corresponding annotations to sk_set_peek_off() and unix_set_peek_off().
--- net/core/sock.c | 4 ++-- net/unix/af_unix.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
net/core/sock.c +2 -2
@@ -1818,7 +1818,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,if (!sock->ops->set_peek_off)return -EOPNOTSUPP ; - v.val = sk->sk_peek_off; + v.val =READ_ONCE (sk->sk_peek_off);break ;case SO_NOFCS : v.val =sock_flag (sk,SOCK_NOFCS );
@@ -3127,7 +3127,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim);int sk_set_peek_off (struct sock *sk,int val) { - sk->sk_peek_off = val; +WRITE_ONCE (sk->sk_peek_off, val);return 0 ; }EXPORT_SYMBOL_GPL (sk_set_peek_off);
net/unix/af_unix.c +1 -1
@@ -780,7 +780,7 @@ static int unix_set_peek_off(struct sock *sk, int val)if (mutex_lock_interruptible (&u->iolock))return -EINTR ; - sk->sk_peek_off = val; +WRITE_ONCE (sk->sk_peek_off, val);mutex_unlock (&u->iolock);return 0 ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 59/165 net: add missing data-race annotation for sk_ll_usec
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e5f0d2dd3c2faa671711dac6d3ff3cef307bcfe3 ]
In a prior commit I forgot that sk_getsockopt() reads sk->sk_ll_usec without holding a lock.
--- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/sock.c +1 -1
@@ -1848,7 +1848,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,#ifdef CONFIG_NET_RX_BUSY_POLL case SO_BUSY_POLL : - v.val = sk->sk_ll_usec; + v.val =READ_ONCE (sk->sk_ll_usec);break ;case SO_PREFER_BUSY_POLL : v.val =READ_ONCE (sk->sk_prefer_busy_poll);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 60/165 net: annotate data-races around sk->sk_priority
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 8bf43be799d4b242ea552a14db10456446be843e ]
sk_getsockopt() runs locklessly. This means sk->sk_priority can be read while other threads are changing its value.
Other reads also happen without socket lock being held.
Add missing annotations where needed.
--- net/core/sock.c | 6 +++--- net/ipv4/ip_output.c | 4 ++-- net/ipv4/ip_sockglue.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/tcp_ipv4.c | 2 +- net/ipv6/raw.c | 2 +- net/ipv6/tcp_ipv6.c | 3 ++- net/packet/af_packet.c | 6 +++--- 8 files changed, 14 insertions(+), 13 deletions(-)
net/core/sock.c +3 -3
@@ -800,7 +800,7 @@ EXPORT_SYMBOL(sock_no_linger);void sock_set_priority (struct sock *sk,u32 priority) {lock_sock (sk); - sk->sk_priority = priority; +WRITE_ONCE (sk->sk_priority, priority);release_sock (sk); }EXPORT_SYMBOL (sock_set_priority);
@@ -1210,7 +1210,7 @@ int sk_setsockopt(struct sock *sk, int level, int optname,if ((val >=0 && val <=6 ) ||sockopt_ns_capable (sock_net (sk)->user_ns,CAP_NET_RAW ) ||sockopt_ns_capable (sock_net (sk)->user_ns,CAP_NET_ADMIN )) - sk->sk_priority = val; +WRITE_ONCE (sk->sk_priority, val);else ret = -EPERM ;break ;
@@ -1672,7 +1672,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,break ;case SO_PRIORITY : - v.val = sk->sk_priority; + v.val =READ_ONCE (sk->sk_priority);break ;case SO_LINGER :
net/ipv4/ip_output.c +2 -2
@@ -184,7 +184,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,ip_options_build (skb, &opt->opt, daddr, rt); } - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority);if (!skb->mark) skb->mark =READ_ONCE (sk->sk_mark);
@@ -528,7 +528,7 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, skb_shinfo(skb)->gso_segs ?: 1);/* TODO : should we use skb->sk here instead of sk ? */ - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority); skb->mark =READ_ONCE (sk->sk_mark); res =ip_local_out (net, sk, skb);
net/ipv4/ip_sockglue.c +1 -1
@@ -592,7 +592,7 @@ void __ip_sock_set_tos(struct sock *sk, int val) }if (inet_sk (sk)->tos != val) {inet_sk (sk)->tos = val; - sk->sk_priority =rt_tos2priority (val); +WRITE_ONCE (sk->sk_priority,rt_tos2priority (val));sk_dst_reset (sk); } }
net/ipv4/raw.c +1 -1
@@ -348,7 +348,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, goto error;skb_reserve (skb, hlen); - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority); skb->mark = sockc->mark; skb->tstamp = sockc->transmit_time;skb_dst_set (skb, &rt->dst);
net/ipv4/tcp_ipv4.c +1 -1
@@ -933,7 +933,7 @@ static void tcp_v4_send_ack(const struct sock *sk, ctl_sk->sk_mark = (sk->sk_state ==TCP_TIME_WAIT ) ?inet_twsk (sk)->tw_mark :READ_ONCE (sk->sk_mark); ctl_sk->sk_priority = (sk->sk_state ==TCP_TIME_WAIT ) ? -inet_twsk (sk)->tw_priority : sk->sk_priority; +inet_twsk (sk)->tw_priority :READ_ONCE (sk->sk_priority); transmit_time =tcp_transmit_time (sk); ip_send_unicast_reply(ctl_sk, skb, &TCP_SKB_CB(skb)->header.h4.opt,
net/ipv6/raw.c +1 -1
@@ -614,7 +614,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,skb_reserve (skb, hlen); skb->protocol =htons (ETH_P_IPV6 ); - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority); skb->mark = sockc->mark; skb->tstamp = sockc->transmit_time;
net/ipv6/tcp_ipv6.c +2 -1
@@ -1132,7 +1132,8 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,tcp_time_stamp_raw () +tcp_rsk (req)->ts_off,READ_ONCE (req->ts_recent), sk->sk_bound_dev_if,tcp_v6_md5_do_lookup (sk, &ipv6_hdr (skb)->saddr, l3index), -ipv6_get_dsfield (ipv6_hdr (skb)),0 , sk->sk_priority, +ipv6_get_dsfield (ipv6_hdr (skb)),0 , +READ_ONCE (sk->sk_priority), READ_ONCE(tcp_rsk(req)->txhash)); }
net/packet/af_packet.c +3 -3
@@ -2050,7 +2050,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, skb->protocol = proto; skb->dev = dev; - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority); skb->mark =READ_ONCE (sk->sk_mark); skb->tstamp = sockc.transmit_time;
@@ -2585,7 +2585,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, skb->protocol = proto; skb->dev = dev; - skb->priority = po->sk.sk_priority; + skb->priority =READ_ONCE (po->sk.sk_priority); skb->mark =READ_ONCE (po->sk.sk_mark); skb->tstamp = sockc->transmit_time;skb_setup_tx_timestamp (skb, sockc->tsflags);
@@ -3061,7 +3061,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) skb->protocol = proto; skb->dev = dev; - skb->priority = sk->sk_priority; + skb->priority =READ_ONCE (sk->sk_priority); skb->mark = sockc.mark; skb->tstamp = sockc.transmit_time;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 61/165 net/sched: taprio: Limit TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME to INT_MAX.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e739718444f7bf2fa3d70d101761ad83056ca628 ]
syzkaller found zero division error [0] in div_s64_rem() called from get_cycle_time_elapsed(), where sched->cycle_time is the divisor.
We have tests in parse_taprio_schedule() so that cycle_time will never be 0, and actually cycle_time is not 0 in get_cycle_time_elapsed().
The problem is that the types of divisor are different; cycle_time is s64, but the argument of div_s64_rem() is s32.
syzkaller fed this input and 0x100000000 is cast to s32 to be 0.
@TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME={0xc, 0x8, 0x100000000}
We use s64 for cycle_time to cast it to ktime_t, so let's keep it and set max for cycle_time.
While at it, we prevent overflow in setup_txtime() and add another test in parse_taprio_schedule() to check if cycle_time overflows.
Also, we add a new tdc test case for this issue.
[0]:
divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 1 PID: 103 Comm: kworker/1:3 Not tainted 6.5.0-rc1-00330-g60cc1f7d0605 #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 Workqueue: ipv6_addrconf addrconf_dad_work RIP: 0010:div_s64_rem include/linux/math64.h:42 [inline] RIP: 0010:get_cycle_time_elapsed net/sched/sch_taprio.c:223 [inline] RIP: 0010:find_entry_to_transmit+0x252/0x7e0 net/sched/sch_taprio.c:344 Code: 3c 02 00 0f 85 5e 05 00 00 48 8b 4c 24 08 4d 8b bd 40 01 00 00 48 8b 7c 24 48 48 89 c8 4c 29 f8 48 63 f7 48 99 48 89 74 24 70 <48> f7 fe 48 29 d1 48 8d 04 0f 49 89 cc 48 89 44 24 20 49 8d 85 10 RSP: 0018:ffffc90000acf260 EFLAGS: 00010206 RAX: 177450e0347560cf RBX: 0000000000000000 RCX: 177450e0347560cf RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000100000000 RBP: 0000000000000056 R08: 0000000000000000 R09: ffffed10020a0934 R10: ffff8880105049a7 R11: ffff88806cf3a520 R12: ffff888010504800 R13: ffff88800c00d800 R14: ffff8880105049a0 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88806cf00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f0edf84f0e8 CR3: 000000000d73c002 CR4: 0000000000770ee0 PKRU: 55555554 Call Trace: <TASK> get_packet_txtime net/sched/sch_taprio.c:508 [inline] taprio_enqueue_one+0x900/0xff0 net/sched/sch_taprio.c:577 taprio_enqueue+0x378/0xae0 net/sched/sch_taprio.c:658 dev_qdisc_enqueue+0x46/0x170 net/core/dev.c:3732 __dev_xmit_skb net/core/dev.c:3821 [inline] __dev_queue_xmit+0x1b2f/0x3000 net/core/dev.c:4169 dev_queue_xmit include/linux/netdevice.h:3088 [inline] neigh_resolve_output net/core/neighbour.c:1552 [inline] neigh_resolve_output+0x4a7/0x780 net/core/neighbour.c:1532 neigh_output include/net/neighbour.h:544 [inline] ip6_finish_output2+0x924/0x17d0 net/ipv6/ip6_output.c:135 __ip6_finish_output+0x620/0xaa0 net/ipv6/ip6_output.c:196 ip6_finish_output net/ipv6/ip6_output.c:207 [inline] NF_HOOK_COND include/linux/netfilter.h:292 [inline] ip6_output+0x206/0x410 net/ipv6/ip6_output.c:228 dst_output include/net/dst.h:458 [inline] NF_HOOK.constprop.0+0xea/0x260 include/linux/netfilter.h:303 ndisc_send_skb+0x872/0xe80 net/ipv6/ndisc.c:508 ndisc_send_ns+0xb5/0x130 net/ipv6/ndisc.c:666 addrconf_dad_work+0xc14/0x13f0 net/ipv6/addrconf.c:4175 process_one_work+0x92c/0x13a0 kernel/workqueue.c:2597 worker_thread+0x60f/0x1240 kernel/workqueue.c:2748 kthread+0x2fe/0x3f0 kernel/kthread.c:389 ret_from_fork+0x2c/0x50 arch/x86/entry/entry_64.S:308 </TASK> Modules linked in:
--- net/sched/sch_taprio.c | 15 +++++++++-- .../tc-testing/tc-tests/qdiscs/taprio.json | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-)
net/sched/sch_taprio.c +13 -2
@@ -1013,6 +1013,11 @@ static const struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = { TC_FP_PREEMPTIBLE), }; +static struct netlink_range_validation_signed taprio_cycle_time_range = { + .min =0 , + .max =INT_MAX , +}; +static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX +1 ] = { [TCA_TAPRIO_ATTR_PRIOMAP ] = { .len =sizeof (struct tc_mqprio_qopt )
@@ -1021,7 +1026,8 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = { [TCA_TAPRIO_ATTR_SCHED_BASE_TIME] = { .type = NLA_S64 }, [TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY] = { .type = NLA_NESTED }, [TCA_TAPRIO_ATTR_SCHED_CLOCKID] = { .type = NLA_S32 }, - [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME] = { .type = NLA_S64 }, + [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME ] = + NLA_POLICY_FULL_RANGE_SIGNED(NLA_S64, &taprio_cycle_time_range), [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION] = { .type = NLA_S64 }, [TCA_TAPRIO_ATTR_FLAGS] = { .type = NLA_U32 }, [TCA_TAPRIO_ATTR_TXTIME_DELAY] = { .type = NLA_U32 },
@@ -1157,6 +1163,11 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,return -EINVAL ; } +if (cycle <0 || cycle >INT_MAX ) { +NL_SET_ERR_MSG (extack,"'cycle_time' is too big" ); +return -EINVAL ; + } + new->cycle_time = cycle; }
@@ -1345,7 +1356,7 @@ static void setup_txtime(struct taprio_sched *q, struct sched_gate_list *sched, ktime_t base) {struct sched_entry *entry; -u32 interval =0 ; +u64 interval =0 ;list_for_each_entry (entry, &sched->entries, list) { entry->next_txtime =ktime_add_ns (base, interval);
tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json +25 -0
@@ -131,5 +131,30 @@ "teardown": [ "echo \"1\" > /sys/bus/netdevsim/del_device" ] + }, + { + "id": "3e1e", + "name": "Add taprio Qdisc with an invalid cycle-time", + "category": [ + "qdisc", + "taprio" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + "echo \"1 1 8\" > /sys/bus/netdevsim/new_device", + "$TC qdisc add dev $ETH root handle 1: taprio num_tc 3 map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@0 1@0 base-time 1000000000 sched-entry S 01 300000 flags 0x1 clockid CLOCK_TAI cycle-time 4294967296 || /bin/true", + "$IP link set dev $ETH up", + "$IP addr add 10.10.10.10/24 dev $ETH" + ], + "cmdUnderTest": "/bin/true", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $ETH", + "matchPattern": "qdisc taprio 1: root refcnt", + "matchCount": "0", + "teardown": [ + "echo \"1\" > /sys/bus/netdevsim/del_device" + ] } ]
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 62/165 net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3 ]
The timer dev->stat_monitor can schedule the delayed work dev->wq and the delayed work dev->wq can also arm the dev->stat_monitor timer.
When the device is detaching, the net_device will be deallocated. but the net_device private data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.
One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |
Although we use cancel_delayed_work_sync() to cancel the delayed work in lan78xx_disconnect(), it could still be scheduled in timer handler lan78xx_stat_monitor().
Another racy situation is shown below:
(Thread 1) | (Thread 2)
lan78xx_delayedwork |
mod_timer() | lan78xx_disconnect()
| cancel_delayed_work_sync()
(wait some time) | if (timer_pending(&dev->stat_monitor))
| del_timer_sync(&dev->stat_monitor);
lan78xx_stat_monitor() | ...
lan78xx_defer_kevent() | free_netdev(net); //free
//use net_device private data|
dev-> //use |Although we use del_timer_sync() to delete the timer, the function timer_pending() returns 0 when the timer is activated. As a result, the del_timer_sync() will not be executed and the timer could be re-armed.
In order to mitigate this bug, We use timer_shutdown_sync() to shutdown the timer and then use cancel_delayed_work_sync() to cancel the delayed work. As a result, the net_device could be deallocated safely.
What's more, the dev->flags is set to EVENT_DEV_DISCONNECT in lan78xx_disconnect(). But it could still be set to EVENT_STAT_UPDATE in lan78xx_stat_monitor(). So this patch put the set_bit() behind timer_shutdown_sync().
--- drivers/net/usb/lan78xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/usb/lan78xx.c +2 -5
@@ -4224,8 +4224,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)if (!dev)return ; -set_bit (EVENT_DEV_DISCONNECT , &dev->flags); -netif_napi_del (&dev->napi); udev =interface_to_usbdev (intf);
@@ -4233,6 +4231,8 @@ static void lan78xx_disconnect(struct usb_interface *intf)unregister_netdev (net); +timer_shutdown_sync (&dev->stat_monitor); +set_bit (EVENT_DEV_DISCONNECT , &dev->flags);cancel_delayed_work_sync (&dev->wq); phydev = net->phydev;
@@ -4247,9 +4247,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)usb_scuttle_anchored_urbs (&dev->deferred); -if (timer_pending (&dev->stat_monitor)) -del_timer_sync (&dev->stat_monitor); -lan78xx_unbind (dev, intf);lan78xx_free_tx_resources (dev);
Signature · 1 line
2.40.1
Re: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 50 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.
Quoted 6 lines
What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")
Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.
Quoted 6 lines
Signed-off-by Duoming Zhou <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/usb/lan78xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
Signature · 1 line
Lee Jones [李琼斯]
Greg Kroah-Hartman
maintainerRe: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 57 lines · Lee Jones
Quoted 55 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().
Quoted 6 lines
Quoted 1 line
Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.
Did you try to build it:
drivers/net/usb/lan78xx.c: In function ‘lan78xx_disconnect’:
drivers/net/usb/lan78xx.c:4234:9: error: implicit declaration of function ‘timer_shutdown_sync’ [-Werror=implicit-function-declaration]
4234 | timer_shutdown_sync(&dev->stat_monitor);
| ^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
That's a good reason to not include it...
Also, is it really an issue or just showing up on a CVE-checker somewhere? (odds on the latter, based on the author of this commit...)
If anyone really cares about it, I figured they would submit a working patch :)
thanks,
greg k-h
Re: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 58 lines · Greg Kroah-Hartman
Quoted 57 lines · Lee Jones
Quoted 55 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.Did you try to build it:
No, I just noticed that it was missing.
Quoted 7 lines
drivers/net/usb/lan78xx.c: In function ‘lan78xx_disconnect’:
drivers/net/usb/lan78xx.c:4234:9: error: implicit declaration of function ‘timer_shutdown_sync’ [-Werror=implicit-function-declaration]
4234 |timer_shutdown_sync(&dev->stat_monitor);
| ^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errorsThat's a good reason to not include it...
It's a perfect reason not to include it.
The issue is not that the patch is not present. It's more the lack of transparency in terms of searchable information on why it was not included.
I was under the impression that a report is usually sent out when a patch failed to apply for any reason?
[...]
Signature · 1 line
Lee Jones [李琼斯]
Greg Kroah-Hartman
maintainerRe: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 79 lines · Lee Jones
Quoted 58 lines · Greg Kroah-Hartman
Quoted 57 lines · Lee Jones
Quoted 55 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.Did you try to build it:
No, I just noticed that it was missing.
Quoted 7 lines
drivers/net/usb/lan78xx.c: In function ‘lan78xx_disconnect’:
drivers/net/usb/lan78xx.c:4234:9: error: implicit declaration of function ‘timer_shutdown_sync’ [-Werror=implicit-function-declaration]
4234 |timer_shutdown_sync(&dev->stat_monitor);
| ^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errorsThat's a good reason to not include it...
Quoted 8 lines
It's a perfect reason not to include it.
The issue is not that the patch is not present. It's more the lack of transparency in terms of searchable information on why it was not included.
I was under the impression that a report is usually sent out when a patch failed to apply for any reason?
For patches that are explicitly tagged for stable inclusion, yes, that will happen. That is not the case for this commit.
For patches that only have a "Fixes:" tag on it, those are gotten to on a "best effort" basis when we get a chance, as those were obviously not explicitly asked to be backported. And when they are backported, if they fail, they will fail silently as the author/maintainer was not explicitly asking them to be applied to a stable tree, so it would just be noise to complain about it.
So, it's lucky that this patch was backported at all to any stable tree :)
thanks,
greg k-h
Re: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 92 lines · Greg Kroah-Hartman
Quoted 79 lines · Lee Jones
Quoted 58 lines · Greg Kroah-Hartman
Quoted 57 lines · Lee Jones
Quoted 55 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.Did you try to build it:
No, I just noticed that it was missing.
Quoted 7 lines
drivers/net/usb/lan78xx.c: In function ‘lan78xx_disconnect’:
drivers/net/usb/lan78xx.c:4234:9: error: implicit declaration of function ‘timer_shutdown_sync’ [-Werror=implicit-function-declaration]
4234 |timer_shutdown_sync(&dev->stat_monitor);
| ^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errorsThat's a good reason to not include it...
Quoted 8 lines
It's a perfect reason not to include it.
The issue is not that the patch is not present. It's more the lack of transparency in terms of searchable information on why it was not included.
I was under the impression that a report is usually sent out when a patch failed to apply for any reason?
For patches that are explicitly tagged for stable inclusion, yes, that will happen. That is not the case for this commit.
Quoted 8 lines
For patches that only have a "Fixes:" tag on it, those are gotten to on a "best effort" basis when we get a chance, as those were obviously not explicitly asked to be backported. And when they are backported, if they fail, they will fail silently as the author/maintainer was not explicitly asking them to be applied to a stable tree, so it would just be noise to complain about it.
So, it's lucky that this patch was backported at all to any stable tree :)
That's fair to a point.
Just know that if there are no other means to determine the actions taken place behind closed doors, then these queries are likely to reoccur.
It would be far nicer if an automated mail was sent out when a failed backport attempt were made in all cases. Even if we drop the individual contributor/maintainer addresses and only ping the mailing lists, since at least it then becomes helpfully searchable on LORE. Is it really more work to duplicate the workflow between intended Stable inclusions and any other attempt?
Signature · 1 line
Lee Jones [李琼斯]
Greg Kroah-Hartman
maintainerRe: [PATCH 6.4 062/165] net: usb: lan78xx: reorder cleanup operations to avoid UAF bugs
Quoted 101 lines · Lee Jones
Quoted 99 lines · Greg Kroah-Hartman
Quoted 79 lines · Lee Jones
Quoted 58 lines · Greg Kroah-Hartman
Quoted 57 lines · Lee Jones
Quoted 55 lines · Greg Kroah-Hartman
From: Duoming Zhou <[email protected]>
[ Upstream commit
1e7417c188d0a83fb385ba2dbe35fd2563f2b6f3]The timer
dev->stat_monitorcan schedule the delayed workdev->wqand the delayed workdev->wqcan also arm thedev->stat_monitortimer.When the device is detaching, the
net_devicewill be deallocated. but thenet_deviceprivate data could still be dereferenced in delayed work or timer handler. As a result, the UAF bugs will happen.One racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_stat_monitor() | ... | lan78xx_disconnect() lan78xx_defer_kevent() | ... ... | cancel_delayed_work_sync(&dev->wq); schedule_delayed_work() | ... (wait some time) | free_netdev(net); //free net_device lan78xx_delayedwork() | //use net_device private data | dev-> //use |Although we use
cancel_delayed_work_sync()to cancel the delayed work inlan78xx_disconnect(), it could still be scheduled in timer handlerlan78xx_stat_monitor().Another racy situation is shown below:
(Thread 1) | (Thread 2) lan78xx_delayedwork | mod_timer() | lan78xx_disconnect() | cancel_delayed_work_sync() (wait some time) | if (timer_pending(&dev->stat_monitor)) | del_timer_sync(&dev->stat_monitor); lan78xx_stat_monitor() | ... lan78xx_defer_kevent() | free_netdev(net); //free //use net_device private data| dev-> //use |Although we use
del_timer_sync()to delete the timer, the functiontimer_pending()returns 0 when the timer is activated. As a result, thedel_timer_sync()will not be executed and the timer could be re-armed.In order to mitigate this bug, We use
timer_shutdown_sync()to shutdown the timer and then usecancel_delayed_work_sync()to cancel the delayed work. As a result, thenet_devicecould be deallocated safely.What's more, the
dev->flagsis set toEVENT_DEV_DISCONNECTinlan78xx_disconnect(). But it could still be set toEVENT_STAT_UPDATEinlan78xx_stat_monitor(). So this patch put theset_bit()behindtimer_shutdown_sync().Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Fixes 77dfff5bb7e2 ("lan78xx: Fix race condition in disconnect handling")Any idea why this stopped at linux-6.4.y? The aforementioned Fixes:
commit also exists in linux-6.1.y and linux-5.15.y. I don't see any earlier backport attempts or failure reports that would otherwise explain this.Did you try to build it:
No, I just noticed that it was missing.
Quoted 7 lines
drivers/net/usb/lan78xx.c: In function ‘lan78xx_disconnect’:
drivers/net/usb/lan78xx.c:4234:9: error: implicit declaration of function ‘timer_shutdown_sync’ [-Werror=implicit-function-declaration]
4234 |timer_shutdown_sync(&dev->stat_monitor);
| ^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errorsThat's a good reason to not include it...
Quoted 8 lines
It's a perfect reason not to include it.
The issue is not that the patch is not present. It's more the lack of transparency in terms of searchable information on why it was not included.
I was under the impression that a report is usually sent out when a patch failed to apply for any reason?
For patches that are explicitly tagged for stable inclusion, yes, that will happen. That is not the case for this commit.
For patches that only have a "Fixes:" tag on it, those are gotten to on a "best effort" basis when we get a chance, as those were obviously not explicitly asked to be backported. And when they are backported, if they fail, they will fail silently as the author/maintainer was not explicitly asking them to be applied to a stable tree, so it would just be noise to complain about it.
Quoted 7 lines
Quoted 1 line
So, it's lucky that this patch was backported at all to any stable tree :)
That's fair to a point.
Just know that if there are no other means to determine the actions taken place behind closed doors, then these queries are likely to reoccur.
There are no "closed doors" here, everything we apply is sent to the public, so the lack of an email will mean it was not applied. We can't spam the lists with "well I tried this patch on this tree and it didn't work" messages all the time, as that would be a mess, especially as changes like this were NOT asked to be backported, we just took the time to attempt to do so on our own accord.
Again, patches that are explicitly asked to be applied, and fail, will be notified if they fail. Patches that are not asked to be applied, and we try to do so anyway because it looks like they might be relevant, and they fail, will not be applied as it would seem that the original author was correct in that it shouldn't have been applied.
Quoted 6 lines
It would be far nicer if an automated mail was sent out when a failed backport attempt were made in all cases. Even if we drop the individual contributor/maintainer addresses and only ping the mailing lists, since at least it then becomes helpfully searchable on LORE. Is it really more work to duplicate the workflow between intended Stable inclusions and any other attempt?
It's a different patch stream and workflow. One that some people have suggested that we maybe just stop doing entirely (i.e. don't take anything that is not explicitly marked), but that would mean that many subsystems would never get any backports done for them because they never mark anything. So we do the best that we can, and do not bother the subsystems that do not want to be part of the stable backport process, which is totally legitimate as it is extra effort on their part and that is the first rule of the stable kernel process when we created them:
- we will not impose any extra work on any maintainer or developer if they do not want to do it.
Also, when asking "why wasn't this patch applied?", 90% of the time a simple "let me go apply it and build it" will show that it either doesn't apply, or breaks the build, which will save people a round-trip in emails as that's the obvious answer :)
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 63/165 ice: Fix RDMA VSI removal during queue rebuild
In reply to Greg Kroah-HartmanFrom: Rafal Rogalski <[email protected]>
[ Upstream commit 4b31fd4d77ffa430d0b74ba1885ea0a41594f202 ]
During qdisc create/delete, it is necessary to rebuild the queue of VSIs. An error occurred because the VSIs created by RDMA were still active.
Added check if RDMA is active. If yes, it disallows qdisc changes and writes a message in the system logs.
--- drivers/net/ethernet/intel/ice/ice_main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/net/ethernet/intel/ice/ice_main.c +18 -0
@@ -9055,6 +9055,7 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, {struct ice_netdev_priv *np =netdev_priv (netdev);struct ice_pf *pf = np->vsi->back; +bool locked = false;int err;switch (type) {
@@ -9064,10 +9065,27 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, ice_setup_tc_block_cb, np, np, true);case TC_SETUP_QDISC_MQPRIO : +if (pf->adev) { +mutex_lock (&pf->adev_mutex); +device_lock (&pf->adev->dev); + locked = true; +if (pf->adev->dev.driver) { +netdev_err (netdev,"Cannot change qdisc when RDMA is active\n" ); + err = -EBUSY ; + goto adev_unlock; + } + } +/* setup traffic classifier for receive side */ mutex_lock (&pf->tc_mutex); err =ice_setup_tc_mqprio_qdisc (netdev, type_data);mutex_unlock (&pf->tc_mutex); + +adev_unlock: +if (locked) { +device_unlock (&pf->adev->dev); +mutex_unlock (&pf->adev_mutex); + }return err;default :return -EOPNOTSUPP ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 64/165 bnxt: dont handle XDP in netpoll
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit 37b61cda9c1606cd8b6445d900ca9dc03185e8b6 ]
Similarly to other recently fixed drivers make sure we don't try to access XDP or page pool APIs when NAPI budget is 0. NAPI budget of 0 may mean that we are in netpoll.
This may result in running software IRQs in hard IRQ context, leading to deadlocks or crashes.
To make sure bnapi->tx_pkts don't get wiped without handling the events, move clearing the field into the handler itself. Remember to clear tx_pkts after reset (bnxt_enable_napi()) as it's technically possible that netpoll will accumulate some tx_pkts and then a reset will happen, leaving tx_pkts out of sync with reality.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 26 +++++++++++-------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 8 +++++- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +15 -11
@@ -633,12 +633,13 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)return NETDEV_TX_OK ; } -static void bnxt_tx_int (struct bnxt *bp,struct bnxt_napi *bnapi,int nr_pkts) +static void bnxt_tx_int (struct bnxt *bp,struct bnxt_napi *bnapi,int budget) {struct bnxt_tx_ring_info *txr = bnapi->tx_ring;struct netdev_queue *txq =netdev_get_tx_queue (bp->dev, txr->txq_index);u16 cons = txr->tx_cons;struct pci_dev *pdev = bp->pdev; +int nr_pkts = bnapi->tx_pkts;int i;unsigned int tx_bytes =0 ;
@@ -688,6 +689,7 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)dev_kfree_skb_any (skb); } + bnapi->tx_pkts =0 ;WRITE_ONCE (txr->tx_cons, cons); __netif_txq_completed_wake(txq, nr_pkts, tx_bytes,
@@ -2573,12 +2575,11 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,return rx_pkts; } -static void __bnxt_poll_work_done (struct bnxt *bp,struct bnxt_napi *bnapi) +static void __bnxt_poll_work_done (struct bnxt *bp,struct bnxt_napi *bnapi, +int budget) { -if (bnapi->tx_pkts) { - bnapi->tx_int (bp, bnapi, bnapi->tx_pkts); - bnapi->tx_pkts =0 ; - } +if (bnapi->tx_pkts) + bnapi->tx_int (bp, bnapi, budget);if ((bnapi->events &BNXT_RX_EVENT ) && !(bnapi->in_reset)) {struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
@@ -2607,7 +2608,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,*/ bnxt_db_cq (bp, &cpr->cp_db, cpr->cp_raw_cons); -__bnxt_poll_work_done (bp, bnapi); +__bnxt_poll_work_done (bp, bnapi, budget);return rx_pkts; }
@@ -2738,7 +2739,7 @@ static int __bnxt_poll_cqs(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) }static void __bnxt_poll_cqs_done (struct bnxt *bp,struct bnxt_napi *bnapi, -u64 dbr_type) +u64 dbr_type,int budget) {struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;int i;
@@ -2754,7 +2755,7 @@ static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi, cpr2->had_work_done =0 ; } } -__bnxt_poll_work_done (bp, bnapi); +__bnxt_poll_work_done (bp, bnapi, budget); }static int bnxt_poll_p5 (struct napi_struct *napi,int budget)
@@ -2784,7 +2785,8 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)if (cpr->has_more_work)break ; -__bnxt_poll_cqs_done (bp, bnapi,DBR_TYPE_CQ_ARMALL ); +__bnxt_poll_cqs_done (bp, bnapi,DBR_TYPE_CQ_ARMALL , + budget); cpr->cp_raw_cons = raw_cons;if (napi_complete_done (napi, work_done)) BNXT_DB_NQ_ARM_P5(&cpr->cp_db,
@@ -2814,7 +2816,7 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget) } raw_cons =NEXT_RAW_CMP (raw_cons); } -__bnxt_poll_cqs_done (bp, bnapi,DBR_TYPE_CQ ); +__bnxt_poll_cqs_done (bp, bnapi,DBR_TYPE_CQ , budget);if (raw_cons != cpr->cp_raw_cons) { cpr->cp_raw_cons = raw_cons;BNXT_DB_NQ_P5 (&cpr->cp_db, raw_cons);
@@ -9433,6 +9435,8 @@ static void bnxt_enable_napi(struct bnxt *bp) cpr->sw_stats.rx.rx_resets++; bnapi->in_reset = false; + bnapi->tx_pkts =0 ; +if (bnapi->rx_ring) {INIT_WORK (&cpr->dim.work, bnxt_dim_work); cpr->dim.mode =DIM_CQ_PERIOD_MODE_START_FROM_EQE ;
drivers/net/ethernet/broadcom/bnxt/bnxt.h +1 -1
@@ -1005,7 +1005,7 @@ struct bnxt_napi {struct bnxt_tx_ring_info *tx_ring;void (*tx_int)(struct bnxt *,struct bnxt_napi *, -int ); +int budget);int tx_pkts;u8 events;
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +7 -1
@@ -125,16 +125,20 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp,dma_unmap_len_set (tx_buf, len,0 ); } -void bnxt_tx_int_xdp (struct bnxt *bp,struct bnxt_napi *bnapi,int nr_pkts) +void bnxt_tx_int_xdp (struct bnxt *bp,struct bnxt_napi *bnapi,int budget) {struct bnxt_tx_ring_info *txr = bnapi->tx_ring;struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;bool rx_doorbell_needed = false; +int nr_pkts = bnapi->tx_pkts;struct bnxt_sw_tx_bd *tx_buf;u16 tx_cons = txr->tx_cons;u16 last_tx_cons = tx_cons;int i, j, frags; +if (!budget) +return ; +for (i =0 ; i < nr_pkts; i++) { tx_buf = &txr->tx_buf_ring[tx_cons];
@@ -161,6 +165,8 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) } tx_cons =NEXT_TX (tx_cons); } + + bnapi->tx_pkts =0 ;WRITE_ONCE (txr->tx_cons, tx_cons);if (rx_doorbell_needed) { tx_buf = &txr->tx_buf_ring[last_tx_cons];
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h +1 -1
@@ -16,7 +16,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,struct bnxt_tx_ring_info *txr, dma_addr_t mapping, u32 len, struct xdp_buff *xdp); -void bnxt_tx_int_xdp (struct bnxt *bp,struct bnxt_napi *bnapi,int nr_pkts); +void bnxt_tx_int_xdp (struct bnxt *bp,struct bnxt_napi *bnapi,int budget);bool bnxt_rx_xdp (struct bnxt *bp,struct bnxt_rx_ring_info *rxr,u16 cons,struct xdp_buff xdp,struct page *page,u8 **data_ptr,unsigned int *len,u8 *event);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 65/165 octeon_ep: initialize mbox mutexes
In reply to Greg Kroah-HartmanFrom: Michal Schmidt <[email protected]>
[ Upstream commit 611e1b016c7beceec5ae82ac62d4a7ca224c8f9d ]
The two mbox-related mutexes are destroyed in octep_ctrl_mbox_uninit(), but the corresponding mutex_init calls were missing.
A "DEBUG_LOCKS_WARN_ON(lock->magic != lock)" warning was emitted with CONFIG_DEBUG_MUTEXES on.
Initialize the two mutexes in octep_ctrl_mbox_init().
--- drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c +3 -0
@@ -98,6 +98,9 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)writeq (OCTEP_CTRL_MBOX_STATUS_INIT ,OCTEP_CTRL_MBOX_INFO_HOST_STATUS (mbox->barmem)); +mutex_init (&mbox->h2fq_lock); +mutex_init (&mbox->f2hq_lock); + mbox->h2fq.sz =readl (OCTEP_CTRL_MBOX_H2FQ_SZ (mbox->barmem)); mbox->h2fq.hw_prod =OCTEP_CTRL_MBOX_H2FQ_PROD (mbox->barmem); mbox->h2fq.hw_cons =OCTEP_CTRL_MBOX_H2FQ_CONS (mbox->barmem);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 66/165 bpf: Move unprivileged checks into map_create() and bpf_prog_load()
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 1d28635abcf1914425d6516e641978011984c58a ]
Make each bpf() syscall command a bit more self-contained, making it easier to further enhance it. We move sysctl_unprivileged_bpf_disabled handling down to map_create() and bpf_prog_load(), two special commands in this regard.
Also swap the order of checks, calling bpf_capable() only if sysctl_unprivileged_bpf_disabled is true, avoiding unnecessary audit messages.
Stable-dep-of: 640a604585aa ("bpf, cpumap: Make sure kthread is running before map update returns")
--- kernel/bpf/syscall.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
kernel/bpf/syscall.c +19 -15
@@ -1157,6 +1157,15 @@ static int map_create(union bpf_attr *attr) !node_online(numa_node)))return -EINVAL ; +/* Intent here is for unprivileged_bpf_disabled to block BPF map +* creation for unprivileged users; other actions depend +* on fd availability and access to bpffs, so are dependent on +* object creation success. Even with unprivileged BPF disabled, +* capability checks are still carried out. +*/ +if (sysctl_unprivileged_bpf_disabled && !bpf_capable ()) +return -EPERM ; +/* find map type and init map: hashtable vs rbtree vs bloom vs ... */ map =find_and_alloc_map (attr);if (IS_ERR (map))
@@ -2535,6 +2544,16 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)/* eBPF programs must be GPL compatible to use GPL-ed functions */ is_gpl =license_is_gpl_compatible (license); +/* Intent here is for unprivileged_bpf_disabled to block BPF program +* creation for unprivileged users; other actions depend +* on fd availability and access to bpffs, so are dependent on +* object creation success. Even with unprivileged BPF disabled, +* capability checks are still carried out for these +* and other operations. +*/ +if (sysctl_unprivileged_bpf_disabled && !bpf_capable ()) +return -EPERM ; +if (attr->insn_cnt ==0 || attr->insn_cnt > (bpf_capable () ?BPF_COMPLEXITY_LIMIT_INSNS :BPF_MAXINSNS ))return -E2BIG ;
@@ -5018,23 +5037,8 @@ static int bpf_prog_bind_map(union bpf_attr *attr)static int __sys_bpf (int cmd,bpfptr_t uattr,unsigned int size) {union bpf_attr attr; -bool capable;int err; - capable =bpf_capable () || !sysctl_unprivileged_bpf_disabled; - -/* Intent here is for unprivileged_bpf_disabled to block key object -* creation commands for unprivileged users; other actions depend -* of fd availability and access to bpffs, so are dependent on -* object creation success. Capabilities are later verified for -* operations such as load and map create, so even with unprivileged -* BPF disabled, capability checks are still carried out for these -* and other operations. -*/ -if (!capable && - (cmd ==BPF_MAP_CREATE || cmd ==BPF_PROG_LOAD )) -return -EPERM ; - err =bpf_check_uarg_tail_zero (uattr,sizeof (attr), size);if (err)return err;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 67/165 bpf: Inline map creation logic in map_create() function
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 22db41226b679768df8f0a4ff5de8e58f625f45b ]
Currently find_and_alloc_map() performs two separate functions: some argument sanity checking and partial map creation workflow hanling. Neither of those functions are self-sufficient and are augmented by further checks and initialization logic in the caller (map_create() function). So unify all the sanity checks, permission checks, and creation and initialization logic in one linear piece of code in map_create() instead. This also make it easier to further enhance permission checks and keep them located in one place.
Stable-dep-of: 640a604585aa ("bpf, cpumap: Make sure kthread is running before map update returns")
--- kernel/bpf/syscall.c | 57 +++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 33 deletions(-)
kernel/bpf/syscall.c +24 -33
@@ -109,37 +109,6 @@ const struct bpf_map_ops bpf_map_offload_ops = { .map_mem_usage = bpf_map_offload_map_mem_usage, }; -static struct bpf_map *find_and_alloc_map (union bpf_attr *attr) -{ -const struct bpf_map_ops *ops; -u32 type = attr->map_type; -struct bpf_map *map; -int err; - -if (type >=ARRAY_SIZE (bpf_map_types)) -return ERR_PTR (-EINVAL ); - type =array_index_nospec (type,ARRAY_SIZE (bpf_map_types)); - ops = bpf_map_types[type]; -if (!ops) -return ERR_PTR (-EINVAL ); - -if (ops->map_alloc_check) { - err = ops->map_alloc_check (attr); -if (err) -return ERR_PTR (err); - } -if (attr->map_ifindex) - ops = &bpf_map_offload_ops; -if (!ops->map_mem_usage) -return ERR_PTR (-EINVAL ); - map = ops->map_alloc (attr); -if (IS_ERR (map)) -return map; - map->ops = ops; - map->map_type = type; -return map; -} -static void bpf_map_write_active_inc (struct bpf_map *map) {atomic64_inc (&map->writecnt);
@@ -1127,7 +1096,9 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,/* called via syscall */ static int map_create (union bpf_attr *attr) { +const struct bpf_map_ops *ops;int numa_node =bpf_map_attr_numa_node (attr); +u32 map_type = attr->map_type;struct bpf_map *map;int f_flags;int err;
@@ -1157,6 +1128,25 @@ static int map_create(union bpf_attr *attr) !node_online(numa_node)))return -EINVAL ; +/* find map type and init map: hashtable vs rbtree vs bloom vs ... */ + map_type = attr->map_type; +if (map_type >=ARRAY_SIZE (bpf_map_types)) +return -EINVAL ; + map_type =array_index_nospec (map_type,ARRAY_SIZE (bpf_map_types)); + ops = bpf_map_types[map_type]; +if (!ops) +return -EINVAL ; + +if (ops->map_alloc_check) { + err = ops->map_alloc_check (attr); +if (err) +return err; + } +if (attr->map_ifindex) + ops = &bpf_map_offload_ops; +if (!ops->map_mem_usage) +return -EINVAL ; +/* Intent here is for unprivileged_bpf_disabled to block BPF map * creation for unprivileged users; other actions depend * on fd availability and access to bpffs, so are dependent on
@@ -1166,10 +1156,11 @@ static int map_create(union bpf_attr *attr)if (sysctl_unprivileged_bpf_disabled && !bpf_capable ())return -EPERM ; -/* find map type and init map: hashtable vs rbtree vs bloom vs ... */ - map =find_and_alloc_map (attr); + map = ops->map_alloc (attr);if (IS_ERR (map))return PTR_ERR (map); + map->ops = ops; + map->map_type = map_type; err =bpf_obj_name_cpy (map->name, attr->map_name,sizeof (attr->map_name));
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 68/165 bpf: Centralize permissions checks for all BPF map types
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 6c3eba1c5e283fd2bb1c076dbfcb47f569c3bfde ]
This allows to do more centralized decisions later on, and generally makes it very explicit which maps are privileged and which are not (e.g., LRU_HASH and LRU_PERCPU_HASH, which are privileged HASH variants, as opposed to unprivileged HASH and HASH_PERCPU; now this is explicit and easy to verify).
Stable-dep-of: 640a604585aa ("bpf, cpumap: Make sure kthread is running before map update returns")
--- kernel/bpf/bloom_filter.c | 3 -- kernel/bpf/bpf_local_storage.c | 3 -- kernel/bpf/bpf_struct_ops.c | 3 -- kernel/bpf/cpumap.c | 4 -- kernel/bpf/devmap.c | 3 -- kernel/bpf/hashtab.c | 6 --- kernel/bpf/lpm_trie.c | 3 -- kernel/bpf/queue_stack_maps.c | 4 -- kernel/bpf/reuseport_array.c | 3 -- kernel/bpf/stackmap.c | 3 -- kernel/bpf/syscall.c | 47 +++++++++++++++++++ net/core/sock_map.c | 4 -- net/xdp/xskmap.c | 4 -- .../bpf/prog_tests/unpriv_bpf_disabled.c | 6 ++- 14 files changed, 52 insertions(+), 44 deletions(-)
kernel/bpf/bloom_filter.c +0 -3
@@ -86,9 +86,6 @@ static struct bpf_map *bloom_map_alloc(union bpf_attr *attr)int numa_node =bpf_map_attr_numa_node (attr);struct bpf_bloom_filter *bloom; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); - if (attr->key_size != 0 || attr->value_size == 0 || attr->max_entries == 0 || attr->map_flags & ~BLOOM_CREATE_FLAG_MASK ||
kernel/bpf/bpf_local_storage.c +0 -3
@@ -723,9 +723,6 @@ int bpf_local_storage_map_alloc_check(union bpf_attr *attr) !attr->btf_key_type_id || !attr->btf_value_type_id)return -EINVAL ; -if (!bpf_capable ()) -return -EPERM ; -if (attr->value_size >BPF_LOCAL_STORAGE_MAX_VALUE_SIZE )return -E2BIG ;
kernel/bpf/bpf_struct_ops.c +0 -3
@@ -655,9 +655,6 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)const struct btf_type *t, *vt;struct bpf_map *map; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); - st_ops =bpf_struct_ops_find_value (attr->btf_vmlinux_value_type_id);if (!st_ops)return ERR_PTR (-ENOTSUPP );
kernel/bpf/cpumap.c +0 -4
@@ -28,7 +28,6 @@#include <linux/sched.h> #include <linux/workqueue.h> #include <linux/kthread.h> -#include <linux/capability.h> #include <trace/events/xdp.h> #include <linux/btf_ids.h>
@@ -89,9 +88,6 @@ static struct bpf_map *cpu_map_alloc(union bpf_attr *attr)u32 value_size = attr->value_size;struct bpf_cpu_map *cmap; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); -/* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || (value_size != offsetofend(struct bpf_cpumap_val, qsize) &&
kernel/bpf/devmap.c +0 -3
@@ -160,9 +160,6 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)struct bpf_dtab *dtab;int err; -if (!capable (CAP_NET_ADMIN )) -return ERR_PTR (-EPERM ); - dtab =bpf_map_area_alloc (sizeof (*dtab),NUMA_NO_NODE );if (!dtab)return ERR_PTR (-ENOMEM );
kernel/bpf/hashtab.c +0 -6
@@ -422,12 +422,6 @@ static int htab_map_alloc_check(union bpf_attr *attr) BUILD_BUG_ON(offsetof(struct htab_elem, fnode.next) != offsetof(struct htab_elem, hash_node.pprev)); -if (lru && !bpf_capable ()) -/* LRU implementation is much complicated than other -* maps. Hence, limit to CAP_BPF. -*/ -return -EPERM ; -if (zero_seed && !capable (CAP_SYS_ADMIN ))/* Guard against local DoS, and discourage production use. */ return -EPERM ;
kernel/bpf/lpm_trie.c +0 -3
@@ -544,9 +544,6 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) {struct lpm_trie *trie; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); -/* check sanity of attributes */ if (attr->max_entries == 0 || !(attr->map_flags & BPF_F_NO_PREALLOC) ||
kernel/bpf/queue_stack_maps.c +0 -4
@@ -7,7 +7,6 @@#include <linux/bpf.h> #include <linux/list.h> #include <linux/slab.h> -#include <linux/capability.h> #include <linux/btf_ids.h> #include "percpu_freelist.h"
@@ -46,9 +45,6 @@ static bool queue_stack_map_is_full(struct bpf_queue_stack *qs)/* Called from syscall */ static int queue_stack_map_alloc_check (union bpf_attr *attr) { -if (!bpf_capable ()) -return -EPERM ; -/* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 0 || attr->value_size == 0 ||
kernel/bpf/reuseport_array.c +0 -3
@@ -151,9 +151,6 @@ static struct bpf_map *reuseport_array_alloc(union bpf_attr *attr)int numa_node =bpf_map_attr_numa_node (attr);struct reuseport_array *array; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); -/* allocate all map elements and zero-initialize them */ array =bpf_map_area_alloc (struct_size (array, ptrs, attr->max_entries), numa_node);if (!array)
kernel/bpf/stackmap.c +0 -3
@@ -74,9 +74,6 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)u64 cost, n_buckets;int err; -if (!bpf_capable ()) -return ERR_PTR (-EPERM ); -if (attr->map_flags & ~STACK_CREATE_FLAG_MASK )return ERR_PTR (-EINVAL );
kernel/bpf/syscall.c +47 -0
53 lines not on this page · raw message
net/core/sock_map.c +0 -4
@@ -32,8 +32,6 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr) {struct bpf_stab *stab; -if (!capable (CAP_NET_ADMIN )) -return ERR_PTR (-EPERM ); if (attr->max_entries == 0 || attr->key_size != 4 || (attr->value_size != sizeof(u32) &&
@@ -1085,8 +1083,6 @@ static struct bpf_map *sock_hash_alloc(union bpf_attr *attr)struct bpf_shtab *htab;int i, err; -if (!capable (CAP_NET_ADMIN )) -return ERR_PTR (-EPERM ); if (attr->max_entries == 0 || attr->key_size == 0 || (attr->value_size != sizeof(u32) &&
net/xdp/xskmap.c +0 -4
@@ -5,7 +5,6 @@#include <linux/bpf.h> #include <linux/filter.h> -#include <linux/capability.h> #include <net/xdp_sock.h> #include <linux/slab.h> #include <linux/sched.h>
@@ -68,9 +67,6 @@ static struct bpf_map *xsk_map_alloc(union bpf_attr *attr)int numa_node;u64 size; -if (!capable (CAP_NET_ADMIN )) -return ERR_PTR (-EPERM ); -if (attr->max_entries ==0 || attr->key_size !=4 || attr->value_size !=4 || attr->map_flags & ~(BPF_F_NUMA_NODE |BPF_F_RDONLY |BPF_F_WRONLY ))
tools/testing/selftests/bpf/prog_tests/unpriv_bpf_disabled.c +5 -1
@@ -171,7 +171,11 @@ static void test_unpriv_bpf_disabled_negative(struct test_unpriv_bpf_disabled *s prog_insns, prog_insn_cnt, &load_opts), -EPERM, "prog_load_fails"); -for (i =BPF_MAP_TYPE_HASH ; i <=BPF_MAP_TYPE_BLOOM_FILTER ; i++) +/* some map types require particular correct parameters which could be +* sanity-checked before enforcing -EPERM, so only validate that +* the simple ARRAY and HASH maps are failing with -EPERM +*/ +for (i =BPF_MAP_TYPE_HASH ; i <=BPF_MAP_TYPE_ARRAY ; i++)ASSERT_EQ (bpf_map_create (i,NULL ,sizeof (int ),sizeof (int ),1 ,NULL ), -EPERM ,"map_create_fails" );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 69/165 bpf, cpumap: Make sure kthread is running before map update returns
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 640a604585aa30f93e39b17d4d6ba69fcb1e66c9 ]
The following warning was reported when running stress-mode enabled xdp_redirect_cpu with some RT threads:
------------[ cut here ]------------ WARNING: CPU: 4 PID: 65 at kernel/bpf/cpumap.c:135 CPU: 4 PID: 65 Comm: kworker/4:1 Not tainted 6.5.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Workqueue: events cpu_map_kthread_stop RIP: 0010:put_cpu_map_entry+0xda/0x220 ...... Call Trace: <TASK> ? show_regs+0x65/0x70 ? __warn+0xa5/0x240 ...... ? put_cpu_map_entry+0xda/0x220 cpu_map_kthread_stop+0x41/0x60 process_one_work+0x6b0/0xb80 worker_thread+0x96/0x720 kthread+0x1a5/0x1f0 ret_from_fork+0x3a/0x70 ret_from_fork_asm+0x1b/0x30 </TASK>
The root cause is the same as commit 436901649731 ("bpf: cpumap: Fix memory leak in cpu_map_update_elem"). The kthread is stopped prematurely by kthread_stop() in cpu_map_kthread_stop(), and kthread() doesn't call cpu_map_kthread_run() at all but XDP program has already queued some frames or skbs into ptr_ring. So when __cpu_map_ring_cleanup() checks the ptr_ring, it will find it was not emptied and report a warning.
An alternative fix is to use __cpu_map_ring_cleanup() to drop these pending frames or skbs when kthread_stop() returns -EINTR, but it may confuse the user, because these frames or skbs have been handled correctly by XDP program. So instead of dropping these frames or skbs, just make sure the per-cpu kthread is running before __cpu_map_entry_alloc() returns.
After apply the fix, the error handle for kthread_stop() will be unnecessary because it will always return 0, so just remove it.
--- kernel/bpf/cpumap.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
kernel/bpf/cpumap.c +11 -10
@@ -28,6 +28,7 @@#include <linux/sched.h> #include <linux/workqueue.h> #include <linux/kthread.h> +#include <linux/completion.h> #include <trace/events/xdp.h> #include <linux/btf_ids.h>
@@ -73,6 +74,7 @@ struct bpf_cpu_map_entry {struct rcu_head rcu;struct work_struct kthread_stop_wq; +struct completion kthread_running; };struct bpf_cpu_map {
@@ -153,7 +155,6 @@ static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)static void cpu_map_kthread_stop (struct work_struct *work) {struct bpf_cpu_map_entry *rcpu; -int err; rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq);
@@ -163,14 +164,7 @@ static void cpu_map_kthread_stop(struct work_struct *work)rcu_barrier ();/* kthread_stop will wake_up_process and wait for it to complete */ - err =kthread_stop (rcpu->kthread); -if (err) { -/* kthread_stop may be called before cpu_map_kthread_run -* is executed, so we need to release the memory related -* to rcpu. -*/ -put_cpu_map_entry (rcpu); - } +kthread_stop (rcpu->kthread); } static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu,
@@ -298,11 +292,11 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,return nframes; } -static int cpu_map_kthread_run (void *data) {struct bpf_cpu_map_entry *rcpu = data; +complete (&rcpu->kthread_running);set_current_state (TASK_INTERRUPTIBLE );/* When kthread gives stop order, then rcpu have been disconnected
@@ -467,6 +461,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value, goto free_ptr_ring;/* Setup kthread */ +init_completion (&rcpu->kthread_running); rcpu->kthread =kthread_create_on_node (cpu_map_kthread_run, rcpu, numa,"cpumap/%d/map:%d" , cpu, map->id);
@@ -480,6 +475,12 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,kthread_bind (rcpu->kthread, cpu);wake_up_process (rcpu->kthread); +/* Make sure kthread has been running, so kthread_stop() will not +* stop the kthread prematurely and all pending frames or skbs +* will be handled by the kthread before kthread_stop() returns. +*/ +wait_for_completion (&rcpu->kthread_running); +return rcpu; free_prog:
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 70/165 bpf, cpumap: Handle skb as well when clean up ptr_ring
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 7c62b75cd1a792e14b037fa4f61f9b18914e7de1 ]
The following warning was reported when running xdp_redirect_cpu with both skb-mode and stress-mode enabled:
------------[ cut here ]------------ Incorrect XDP memory type (-2128176192) usage WARNING: CPU: 7 PID: 1442 at net/core/xdp.c:405 Modules linked in: CPU: 7 PID: 1442 Comm: kworker/7:0 Tainted: G 6.5.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Workqueue: events __cpu_map_entry_free RIP: 0010:__xdp_return+0x1e4/0x4a0 ...... Call Trace: <TASK> ? show_regs+0x65/0x70 ? __warn+0xa5/0x240 ? __xdp_return+0x1e4/0x4a0 ...... xdp_return_frame+0x4d/0x150 __cpu_map_entry_free+0xf9/0x230 process_one_work+0x6b0/0xb80 worker_thread+0x96/0x720 kthread+0x1a5/0x1f0 ret_from_fork+0x3a/0x70 ret_from_fork_asm+0x1b/0x30 </TASK>
The reason for the warning is twofold. One is due to the kthread cpu_map_kthread_run() is stopped prematurely. Another one is __cpu_map_ring_cleanup() doesn't handle skb mode and treats skbs in ptr_ring as XDP frames.
Prematurely-stopped kthread will be fixed by the preceding patch and ptr_ring will be empty when __cpu_map_ring_cleanup() is called. But as the comments in __cpu_map_ring_cleanup() said, handling and freeing skbs in ptr_ring as well to "catch any broken behaviour gracefully".
--- kernel/bpf/cpumap.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
kernel/bpf/cpumap.c +10 -4
@@ -131,11 +131,17 @@ static void __cpu_map_ring_cleanup(struct ptr_ring *ring)* invoked cpu_map_kthread_stop(). Catch any broken behaviour * gracefully and warn once. */ -struct xdp_frame *xdpf; +void *ptr; -while ((xdpf =ptr_ring_consume (ring))) -if (WARN_ON_ONCE (xdpf)) -xdp_return_frame (xdpf); +while ((ptr =ptr_ring_consume (ring))) { +WARN_ON_ONCE (1 ); +if (unlikely (__ptr_test_bit (0 , &ptr))) { +__ptr_clear_bit (0 , &ptr); +kfree_skb (ptr); +continue ; + } +xdp_return_frame (ptr); + } }static void put_cpu_map_entry (struct bpf_cpu_map_entry *rcpu)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 71/165 net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after-free
In reply to Greg Kroah-HartmanFrom: valis <[email protected]>
[ Upstream commit 3044b16e7c6fe5d24b1cdbcf1bd0a9d92d1ebd81 ]
When u32_change() is called on an existing filter, the whole tcf_result struct is always copied into the new instance of the filter.
This causes a problem when updating a filter bound to a class, as tcf_unbind_filter() is always called on the old instance in the success path, decreasing filter_cnt of the still referenced class and allowing it to be deleted, leading to a use-after-free.
Fix this by no longer copying the tcf_result struct from the old filter.
--- net/sched/cls_u32.c | 1 - 1 file changed, 1 deletion(-)
net/sched/cls_u32.c +0 -1
@@ -826,7 +826,6 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp, new->ifindex = n->ifindex; new->fshift = n->fshift; - new->res = n->res; new->flags = n->flags;RCU_INIT_POINTER (new->ht_down, ht);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 72/165 net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free
In reply to Greg Kroah-HartmanFrom: valis <[email protected]>
[ Upstream commit 76e42ae831991c828cffa8c37736ebfb831ad5ec ]
When fw_change() is called on an existing filter, the whole tcf_result struct is always copied into the new instance of the filter.
This causes a problem when updating a filter bound to a class, as tcf_unbind_filter() is always called on the old instance in the success path, decreasing filter_cnt of the still referenced class and allowing it to be deleted, leading to a use-after-free.
Fix this by no longer copying the tcf_result struct from the old filter.
--- net/sched/cls_fw.c | 1 - 1 file changed, 1 deletion(-)
net/sched/cls_fw.c +0 -1
@@ -267,7 +267,6 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,return -ENOBUFS ; fnew->id = f->id; - fnew->res = f->res; fnew->ifindex = f->ifindex; fnew->tp = f->tp;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 73/165 net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free
In reply to Greg Kroah-HartmanFrom: valis <[email protected]>
[ Upstream commit b80b829e9e2c1b3f7aae34855e04d8f6ecaf13c8 ]
When route4_change() is called on an existing filter, the whole tcf_result struct is always copied into the new instance of the filter.
This causes a problem when updating a filter bound to a class, as tcf_unbind_filter() is always called on the old instance in the success path, decreasing filter_cnt of the still referenced class and allowing it to be deleted, leading to a use-after-free.
Fix this by no longer copying the tcf_result struct from the old filter.
--- net/sched/cls_route.c | 1 - 1 file changed, 1 deletion(-)
net/sched/cls_route.c +0 -1
@@ -513,7 +513,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,if (fold) { f->id = fold->id; f->iif = fold->iif; - f->res = fold->res; f->handle = fold->handle; f->tp = fold->tp;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 74/165 bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire
In reply to Greg Kroah-HartmanFrom: Tomas Glozar <[email protected]>
[ Upstream commit 13d2618b48f15966d1adfe1ff6a1985f5eef40ba ]
Disabling preemption in sock_map_sk_acquire conflicts with GFP_ATOMIC allocation later in sk_psock_init_link on PREEMPT_RT kernels, since GFP_ATOMIC might sleep on RT (see bpf: Make BPF and PREEMPT_RT co-exist patchset notes for details).
This causes calling bpf_map_update_elem on BPF_MAP_TYPE_SOCKMAP maps to BUG (sleeping function called from invalid context) on RT kernels.
preempt_disable was introduced together with lock_sk and rcu_read_lock in commit 99ba2b5aba24e ("bpf: sockhash, disallow bpf_tcp_close and update in parallel"), probably to match disabled migration of BPF programs, and is no longer necessary.
Remove preempt_disable to fix BUG in sock_map_update_common on RT.
--- net/core/sock_map.c | 2 -- 1 file changed, 2 deletions(-)
net/core/sock_map.c +0 -2
@@ -115,7 +115,6 @@ static void sock_map_sk_acquire(struct sock *sk) __acquires(&sk->sk_lock.slock) {lock_sock (sk); -preempt_disable ();rcu_read_lock (); }
@@ -123,7 +122,6 @@ static void sock_map_sk_release(struct sock *sk) __releases(&sk->sk_lock.slock) {rcu_read_unlock (); -preempt_enable ();release_sock (sk); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 75/165 net: ll_temac: fix error checking of irq_of_parse_and_map()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ef45e8400f5bb66b03cc949f76c80e2a118447de ]
Most kernel functions return negative error codes but some irq functions return zero on error. In this code irq_of_parse_and_map(), returns zero and platform_get_irq() returns negative error codes. We need to handle both cases appropriately.
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +8 -4
@@ -1567,12 +1567,16 @@ static int temac_probe(struct platform_device *pdev) }/* Error handle returned DMA RX and TX interrupts */ -if (lp->rx_irq <0 ) -return dev_err_probe (&pdev->dev, lp->rx_irq, +if (lp->rx_irq <=0 ) { + rc = lp->rx_irq ?: -EINVAL ; +return dev_err_probe (&pdev->dev, rc,"could not get DMA RX irq\n" ); -if (lp->tx_irq <0 ) -return dev_err_probe (&pdev->dev, lp->tx_irq, + } +if (lp->tx_irq <=0 ) { + rc = lp->tx_irq ?: -EINVAL ; +return dev_err_probe (&pdev->dev, rc,"could not get DMA TX irq\n" ); + }if (temac_np) {/* Retrieve the MAC address */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 76/165 net: korina: handle clk prepare error in korina_probe()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit 0b6291ad1940c403734312d0e453e8dac9148f69 ]
in korina_probe(), the return value of clk_prepare_enable() should be checked since it might fail. we can use devm_clk_get_optional_enabled() instead of devm_clk_get_optional() and clk_prepare_enable() to automatically handle the error.
--- drivers/net/ethernet/korina.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/korina.c +1 -2
@@ -1302,11 +1302,10 @@ static int korina_probe(struct platform_device *pdev)else if (of_get_ethdev_address (pdev->dev.of_node, dev) <0 )eth_hw_addr_random (dev); - clk =devm_clk_get_optional (&pdev->dev,"mdioclk" ); + clk =devm_clk_get_optional_enabled (&pdev->dev,"mdioclk" );if (IS_ERR (clk))return PTR_ERR (clk);if (clk) { -clk_prepare_enable (clk); lp->mii_clock_freq =clk_get_rate (clk); }else { lp->mii_clock_freq =200000000 ;/* max possible input clk */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 77/165 net: netsec: Ignore phy-mode on SynQuacer in DT mode
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
[ Upstream commit f3bb7759a924713bc54d15f6d0d70733b5935fad ]
As documented in acd7aaf51b20 ("netsec: ignore 'phy-mode' device property on ACPI systems") the SocioNext SynQuacer platform ships with firmware defining the PHY mode as RGMII even though the physical configuration of the PHY is for TX and RX delays. Since bbc4d71d63549bc ("net: phy: realtek: fix rtl8211e rx/tx delay config") this has caused misconfiguration of the PHY, rendering the network unusable.
This was worked around for ACPI by ignoring the phy-mode property but the system is also used with DT. For DT instead if we're running on a SynQuacer force a working PHY mode, as well as the standard EDK2 firmware with DT there are also some of these systems that use u-boot and might not initialise the PHY if not netbooting. Newer firmware imagaes for at least EDK2 are available from Linaro so print a warning when doing this.
--- drivers/net/ethernet/socionext/netsec.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/net/ethernet/socionext/netsec.c +11 -0
@@ -1851,6 +1851,17 @@ static int netsec_of_probe(struct platform_device *pdev,return err; } +/* +* SynQuacer is physically configured with TX and RX delays +* but the standard firmware claimed otherwise for a long +* time, ignore it. +*/ +if (of_machine_is_compatible ("socionext,developer-box" ) && + priv->phy_interface !=PHY_INTERFACE_MODE_RGMII_ID ) { +dev_warn (&pdev->dev,"Outdated firmware reports incorrect PHY mode, overriding\n" ); + priv->phy_interface =PHY_INTERFACE_MODE_RGMII_ID ; + } + priv->phy_np =of_parse_phandle (pdev->dev.of_node,"phy-handle" ,0 );if (!priv->phy_np) {dev_err (&pdev->dev,"missing required property 'phy-handle'\n" );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 78/165 selftest: net: Assert on a proper value in so_incoming_cpu.c.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 3ff1617450eceb290ac17120fc172815e09a93cf ]
Dan Carpenter reported an error spotted by Smatch.
./tools/testing/selftests/net/so_incoming_cpu.c:163 create_clients()
error: uninitialized symbol 'ret'.
The returned value of sched_setaffinity() should be checked with ASSERT_EQ(), but the value was not saved in a proper variable, resulting in an error above.
Let's save the returned value of with sched_setaffinity().
--- tools/testing/selftests/net/so_incoming_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/so_incoming_cpu.c +1 -1
@@ -159,7 +159,7 @@ void create_clients(struct __test_metadata *_metadata,/* Make sure SYN will be processed on the i-th CPU * and finally distributed to the i-th listener. */ -sched_setaffinity (0 ,sizeof (cpu_set), &cpu_set); + ret =sched_setaffinity (0 ,sizeof (cpu_set), &cpu_set);ASSERT_EQ (ret,0 );for (j =0 ; j <CLIENT_PER_SERVER ; j++) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 79/165 bnxt_en: Fix page pool logic for page size >= 64K
In reply to Greg Kroah-HartmanFrom: Somnath Kotur <[email protected]>
[ Upstream commit f6974b4c2d8e1062b5a52228ee47293c15b4ee1e ]
The RXBD length field on all bnxt chips is 16-bit and so we cannot support a full page when the native page size is 64K or greater. The non-XDP (non page pool) code path has logic to handle this but the XDP page pool code path does not handle this. Add the missing logic to use page_pool_dev_alloc_frag() to allocate 32K chunks if the page size is 64K or greater.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 42 ++++++++++++------- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 6 +-- 2 files changed, 29 insertions(+), 19 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +26 -16
@@ -699,17 +699,24 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)static struct page *__bnxt_alloc_rx_page (struct bnxt *bp,dma_addr_t *mapping,struct bnxt_rx_ring_info *rxr, +unsigned int *offset,gfp_t gfp) {struct device *dev = &bp->pdev->dev;struct page *page; - page =page_pool_dev_alloc_pages (rxr->page_pool); +if (PAGE_SIZE >BNXT_RX_PAGE_SIZE ) { + page =page_pool_dev_alloc_frag (rxr->page_pool, offset, +BNXT_RX_PAGE_SIZE ); + }else { + page =page_pool_dev_alloc_pages (rxr->page_pool); + *offset =0 ; + }if (!page)return NULL ; - *mapping =dma_map_page_attrs (dev, page,0 ,PAGE_SIZE , bp->rx_dir, -DMA_ATTR_WEAK_ORDERING ); + *mapping =dma_map_page_attrs (dev, page, *offset,BNXT_RX_PAGE_SIZE , + bp->rx_dir,DMA_ATTR_WEAK_ORDERING );if (dma_mapping_error (dev, *mapping)) {page_pool_recycle_direct (rxr->page_pool, page);return NULL ;
@@ -749,15 +756,16 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,dma_addr_t mapping;if (BNXT_RX_PAGE_MODE (bp)) { +unsigned int offset;struct page *page = -__bnxt_alloc_rx_page (bp, &mapping, rxr, gfp); +__bnxt_alloc_rx_page (bp, &mapping, rxr, &offset, gfp);if (!page)return -ENOMEM ; mapping += bp->rx_dma_offset; rx_buf->data = page; - rx_buf->data_ptr =page_address (page) + bp->rx_offset; + rx_buf->data_ptr =page_address (page) + offset + bp->rx_offset; }else {u8 *data =__bnxt_alloc_rx_frag (bp, &mapping, gfp);
@@ -817,7 +825,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp,unsigned int offset =0 ;if (BNXT_RX_PAGE_MODE (bp)) { - page =__bnxt_alloc_rx_page (bp, &mapping, rxr, gfp); + page =__bnxt_alloc_rx_page (bp, &mapping, rxr, &offset, gfp);if (!page)return -ENOMEM ;
@@ -964,15 +972,15 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,return NULL ; } dma_addr -= bp->rx_dma_offset; -dma_unmap_page_attrs (&bp->pdev->dev, dma_addr,PAGE_SIZE , bp->rx_dir, -DMA_ATTR_WEAK_ORDERING ); - skb =build_skb (page_address (page),PAGE_SIZE ); +dma_unmap_page_attrs (&bp->pdev->dev, dma_addr,BNXT_RX_PAGE_SIZE , + bp->rx_dir,DMA_ATTR_WEAK_ORDERING ); + skb =build_skb (data_ptr - bp->rx_offset,BNXT_RX_PAGE_SIZE );if (!skb) {page_pool_recycle_direct (rxr->page_pool, page);return NULL ; }skb_mark_for_recycle (skb); -skb_reserve (skb, bp->rx_dma_offset); +skb_reserve (skb, bp->rx_offset);__skb_put (skb, len);return skb;
@@ -998,8 +1006,8 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,return NULL ; } dma_addr -= bp->rx_dma_offset; -dma_unmap_page_attrs (&bp->pdev->dev, dma_addr,PAGE_SIZE , bp->rx_dir, -DMA_ATTR_WEAK_ORDERING ); +dma_unmap_page_attrs (&bp->pdev->dev, dma_addr,BNXT_RX_PAGE_SIZE , + bp->rx_dir,DMA_ATTR_WEAK_ORDERING );if (unlikely (!payload)) payload =eth_get_headlen (bp->dev, data_ptr, len);
@@ -1012,7 +1020,7 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,skb_mark_for_recycle (skb); off = (void *)data_ptr -page_address (page); -skb_add_rx_frag (skb,0 , page, off, len,PAGE_SIZE ); +skb_add_rx_frag (skb,0 , page, off, len,BNXT_RX_PAGE_SIZE );memcpy (skb->data -NET_IP_ALIGN , data_ptr -NET_IP_ALIGN , payload +NET_IP_ALIGN );
@@ -1147,7 +1155,7 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp, skb->data_len += total_frag_len; skb->len += total_frag_len; - skb->truesize +=PAGE_SIZE * agg_bufs; + skb->truesize +=BNXT_RX_PAGE_SIZE * agg_bufs;return skb; }
@@ -2949,8 +2957,8 @@ static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr) rx_buf->data =NULL ;if (BNXT_RX_PAGE_MODE (bp)) { mapping -= bp->rx_dma_offset; -dma_unmap_page_attrs (&pdev->dev, mapping,PAGE_SIZE , - bp->rx_dir, +dma_unmap_page_attrs (&pdev->dev, mapping, +BNXT_RX_PAGE_SIZE , bp->rx_dir,DMA_ATTR_WEAK_ORDERING );page_pool_recycle_direct (rxr->page_pool, data); }else {
@@ -3219,6 +3227,8 @@ static int bnxt_alloc_rx_page_pool(struct bnxt *bp, pp.napi = &rxr->bnapi->napi; pp.dev = &bp->pdev->dev; pp.dma_dir =DMA_BIDIRECTIONAL ; +if (PAGE_SIZE >BNXT_RX_PAGE_SIZE ) + pp.flags |=PP_FLAG_PAGE_FRAG ; rxr->page_pool =page_pool_create (&pp);if (IS_ERR (rxr->page_pool)) {
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +3 -3
@@ -186,8 +186,8 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, u8 *data_ptr, unsigned int len, struct xdp_buff *xdp) { + u32 buflen = BNXT_RX_PAGE_SIZE;struct bnxt_sw_rx_bd *rx_buf; -u32 buflen =PAGE_SIZE ;struct pci_dev *pdev;dma_addr_t mapping;u32 offset;
@@ -303,7 +303,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, rx_buf = &rxr->rx_buf_ring[cons]; mapping = rx_buf->mapping - bp->rx_dma_offset;dma_unmap_page_attrs (&pdev->dev, mapping, -PAGE_SIZE , bp->rx_dir, +BNXT_RX_PAGE_SIZE , bp->rx_dir,DMA_ATTR_WEAK_ORDERING );/* if we are unable to allocate a new buffer, abort and reuse */
@@ -486,7 +486,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags, }xdp_update_skb_shared_info (skb, num_frags, sinfo->xdp_frags_size, -PAGE_SIZE * sinfo->nr_frags, +BNXT_RX_PAGE_SIZE * sinfo->nr_frags,xdp_buff_is_frag_pfmemalloc (xdp));return skb; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 80/165 bnxt_en: Fix max_mtu setting for multi-buf XDP
In reply to Greg Kroah-HartmanFrom: Michael Chan <[email protected]>
[ Upstream commit 08450ea98ae98d5a35145b675b76db616046ea11 ]
The existing code does not allow the MTU to be set to the maximum even after an XDP program supporting multiple buffers is attached. Fix it to set the netdev->max_mtu to the maximum value if the attached XDP program supports mutiple buffers, regardless of the current MTU value.
Also use a local variable dev instead of repeatedly using bp->dev.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +10 -7
@@ -4005,26 +4005,29 @@ void bnxt_set_ring_params(struct bnxt *bp)*/ int bnxt_set_rx_skb_mode (struct bnxt *bp,bool page_mode) { +struct net_device *dev = bp->dev; +if (page_mode) { bp->flags &= ~BNXT_FLAG_AGG_RINGS ; bp->flags |=BNXT_FLAG_RX_PAGE_MODE ; -if (bp->dev->mtu >BNXT_MAX_PAGE_MODE_MTU ) { +if (bp->xdp_prog->aux->xdp_has_frags) + dev->max_mtu =min_t (u16, bp->max_mtu,BNXT_MAX_MTU ); +else + dev->max_mtu = +min_t (u16, bp->max_mtu,BNXT_MAX_PAGE_MODE_MTU ); +if (dev->mtu >BNXT_MAX_PAGE_MODE_MTU ) { bp->flags |=BNXT_FLAG_JUMBO ; bp->rx_skb_func = bnxt_rx_multi_page_skb; - bp->dev->max_mtu = -min_t (u16, bp->max_mtu,BNXT_MAX_MTU ); }else { bp->flags |=BNXT_FLAG_NO_AGG_RINGS ; bp->rx_skb_func = bnxt_rx_page_skb; - bp->dev->max_mtu = -min_t (u16, bp->max_mtu,BNXT_MAX_PAGE_MODE_MTU ); } bp->rx_dir =DMA_BIDIRECTIONAL ;/* Disable LRO or GRO_HW */ -netdev_update_features (bp->dev); +netdev_update_features (dev); }else { - bp->dev->max_mtu = bp->max_mtu; + dev->max_mtu = bp->max_mtu; bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE ; bp->rx_dir =DMA_FROM_DEVICE ; bp->rx_skb_func = bnxt_rx_skb;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 81/165 net: dcb: choose correct policy to parse DCB_ATTR_BCN
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
[ Upstream commit 31d49ba033095f6e8158c60f69714a500922e0c3 ]
The dcbnl_bcn_setcfg uses erroneous policy to parse tb[DCB_ATTR_BCN], which is introduced in commit 859ee3c43812 ("DCB: Add support for DCB BCN"). Please see the comment in below code
static int dcbnl_bcn_setcfg(...)
{
...
ret = nla_parse_nested_deprecated(..., dcbnl_pfc_up_nest, .. ) // !!! dcbnl_pfc_up_nest for attributes
// DCB_PFC_UP_ATTR_0 to DCB_PFC_UP_ATTR_ALL in enum dcbnl_pfc_up_attrs
...
for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { // !!! DCB_BCN_ATTR_RP_0 to DCB_BCN_ATTR_RP_7 in enum dcbnl_bcn_attrs
...
value_byte = nla_get_u8(data[i]);
...
}
...
for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) {
// !!! DCB_BCN_ATTR_BCNA_0 to DCB_BCN_ATTR_RI in enum dcbnl_bcn_attrs
...
value_int = nla_get_u32(data[i]); ...
}
...
}
That is, the nla_parse_nested_deprecated uses dcbnl_pfc_up_nest attributes to parse nlattr defined in dcbnl_pfc_up_attrs. But the following access code fetch each nlattr as dcbnl_bcn_attrs attributes. By looking up the associated nla_policy for dcbnl_bcn_attrs. We can find the beginning part of these two policies are "same".
static const struct nla_policy dcbnl_pfc_up_nest[...] = {
[DCB_PFC_UP_ATTR_0] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_1] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_2] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_3] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_4] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_5] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_6] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_7] = {.type = NLA_U8},
[DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG},
};static const struct nla_policy dcbnl_bcn_nest[...] = {
[DCB_BCN_ATTR_RP_0] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_1] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_2] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_3] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_4] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_5] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_6] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_7] = {.type = NLA_U8},
[DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG},
// from here is somewhat different
[DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32},
...
[DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG},
};Therefore, the current code is buggy and this nla_parse_nested_deprecated could overflow the dcbnl_pfc_up_nest and use the adjacent nla_policy to parse attributes from DCB_BCN_ATTR_BCNA_0.
Hence use the correct policy dcbnl_bcn_nest to parse the nested tb[DCB_ATTR_BCN] TLV.
--- net/dcb/dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/dcb/dcbnl.c +1 -1
@@ -980,7 +980,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,return -EOPNOTSUPP ; ret =nla_parse_nested_deprecated (data,DCB_BCN_ATTR_MAX , - tb[DCB_ATTR_BCN ], dcbnl_pfc_up_nest, + tb[DCB_ATTR_BCN ], dcbnl_bcn_nest,NULL );if (ret)return ret;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 82/165 s390/qeth: Dont call dev_close/dev_open (DOWN/UP)
In reply to Greg Kroah-HartmanFrom: Alexandra Winter <[email protected]>
[ Upstream commit 1cfef80d4c2b2c599189f36f36320b205d9447d9 ]
dev_close() and dev_open() are issued to change the interface state to DOWN or UP (dev->flags IFF_UP). When the netdev is set DOWN it loses e.g its Ipv6 addresses and routes. We don't want this in cases of device recovery (triggered by hardware or software) or when the qeth device is set offline.
Setting a qeth device offline or online and device recovery actions call netif_device_detach() and/or netif_device_attach(). That will reset or set the LOWER_UP indication i.e. change the dev->state Bit __LINK_STATE_PRESENT. That is enough to e.g. cause bond failovers, and still preserves the interface settings that are handled by the network stack.
Don't call dev_open() nor dev_close() from the qeth device driver. Let the network stack handle this.
--- drivers/s390/net/qeth_core.h | 1 - drivers/s390/net/qeth_core_main.c | 2 -- drivers/s390/net/qeth_l2_main.c | 9 ++++++--- drivers/s390/net/qeth_l3_main.c | 8 +++++--- 4 files changed, 11 insertions(+), 9 deletions(-)
drivers/s390/net/qeth_core.h +0 -1
@@ -716,7 +716,6 @@ struct qeth_card_info {u16 chid; u8 ids_valid:1; /* cssid,iid,chid */ u8 dev_addr_is_registered:1; - u8 open_when_online:1; u8 promisc_mode:1; u8 use_v1_blkt:1; u8 is_vm_nic:1;
drivers/s390/net/qeth_core_main.c +0 -2
@@ -5373,8 +5373,6 @@ int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,qeth_clear_ipacmd_list (card);rtnl_lock (); - card->info.open_when_online = card->dev->flags &IFF_UP ; -dev_close (card->dev);netif_device_detach (card->dev);netif_carrier_off (card->dev);rtnl_unlock ();
drivers/s390/net/qeth_l2_main.c +6 -3
@@ -2388,9 +2388,12 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok)qeth_enable_hw_features (dev);qeth_l2_enable_brport_features (card); -if (card->info.open_when_online) { - card->info.open_when_online =0 ; -dev_open (dev,NULL ); +if (netif_running (dev)) { +local_bh_disable (); +napi_schedule (&card->napi); +/* kick-start the NAPI softirq: */ +local_bh_enable (); +qeth_l2_set_rx_mode (dev); }rtnl_unlock (); }
drivers/s390/net/qeth_l3_main.c +5 -3
@@ -2018,9 +2018,11 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok)netif_device_attach (dev);qeth_enable_hw_features (dev); -if (card->info.open_when_online) { - card->info.open_when_online =0 ; -dev_open (dev,NULL ); +if (netif_running (dev)) { +local_bh_disable (); +napi_schedule (&card->napi); +/* kick-start the NAPI softirq: */ +local_bh_enable (); }rtnl_unlock (); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 83/165 ip6mr: Fix skb_under_panic in ip6mr_cache_report()
In reply to Greg Kroah-HartmanFrom: Yue Haibing <[email protected]>
[ Upstream commit 30e0191b16e8a58e4620fa3e2839ddc7b9d4281c ]
skbuff: skb_under_panic: text:ffffffff88771f69 len:56 put:-4
head:ffff88805f86a800 data:ffff887f5f86a850 tail:0x88 end:0x2c0 dev:pim6reg
------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:192! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 2 PID: 22968 Comm: kworker/2:11 Not tainted 6.5.0-rc3-00044-g0a8db05b571a #236 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Workqueue: ipv6_addrconf addrconf_dad_work RIP: 0010:skb_panic+0x152/0x1d0 Call Trace: <TASK> skb_push+0xc4/0xe0 ip6mr_cache_report+0xd69/0x19b0 reg_vif_xmit+0x406/0x690 dev_hard_start_xmit+0x17e/0x6e0 __dev_queue_xmit+0x2d6a/0x3d20 vlan_dev_hard_start_xmit+0x3ab/0x5c0 dev_hard_start_xmit+0x17e/0x6e0 __dev_queue_xmit+0x2d6a/0x3d20 neigh_connected_output+0x3ed/0x570 ip6_finish_output2+0x5b5/0x1950 ip6_finish_output+0x693/0x11c0 ip6_output+0x24b/0x880 NF_HOOK.constprop.0+0xfd/0x530 ndisc_send_skb+0x9db/0x1400 ndisc_send_rs+0x12a/0x6c0 addrconf_dad_completed+0x3c9/0xea0 addrconf_dad_work+0x849/0x1420 process_one_work+0xa22/0x16e0 worker_thread+0x679/0x10c0 ret_from_fork+0x28/0x60 ret_from_fork_asm+0x11/0x20
When setup a vlan device on dev pim6reg, DAD ns packet may sent on reg_vif_xmit(). reg_vif_xmit()
ip6mr_cache_report()
skb_push(skb, -skb_network_offset(pkt));//skb_network_offset(pkt) is 4
And skb_push declared as:
void *skb_push(struct sk_buff *skb, unsigned int len); skb->data -= len; //0xffff88805f86a84c - 0xfffffffc = 0xffff887f5f86a850
skb->data is set to 0xffff887f5f86a850, which is invalid mem addr, lead to skb_push() fails.
--- net/ipv6/ip6mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/ip6mr.c +1 -1
@@ -1073,7 +1073,7 @@ static int ip6mr_cache_report(const struct mr_table *mrt, struct sk_buff *pkt,And all this only to mangle msg->im6_msgtype and to set msg->im6_mbz to "mbz" :-) */ -skb_push (skb, -skb_network_offset (pkt)); +__skb_pull (skb,skb_network_offset (pkt));skb_push (skb,sizeof (*msg));skb_reset_transport_header (skb);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 84/165 vxlan: Fix nexthop hash size
In reply to Greg Kroah-HartmanFrom: Benjamin Poirier <[email protected]>
[ Upstream commit 0756384fb1bd38adb2ebcfd1307422f433a1d772 ]
The nexthop code expects a 31 bit hash, such as what is returned by fib_multipath_hash() and rt6_multipath_hash(). Passing the 32 bit hash returned by skb_get_hash() can lead to problems related to the fact that 'int hash' is a negative number when the MSB is set.
In the case of hash threshold nexthop groups, nexthop_select_path_hthr() will disproportionately select the first nexthop group entry. In the case of resilient nexthop groups, nexthop_select_path_res() may do an out of bounds access in nh_buckets[], for example:
hash = -912054133
num_nh_buckets = 2
bucket_index = 65535which leads to the following panic:
BUG: unable to handle page fault for address: ffffc900025910c8 PGD 100000067 P4D 100000067 PUD 10026b067 PMD 0 Oops: 0002 [#1] PREEMPT SMP KASAN NOPTI CPU: 4 PID: 856 Comm: kworker/4:3 Not tainted 6.5.0-rc2+ #34 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 Workqueue: ipv6_addrconf addrconf_dad_work RIP: 0010:nexthop_select_path+0x197/0xbf0 Code: c1 e4 05 be 08 00 00 00 4c 8b 35 a4 14 7e 01 4e 8d 6c 25 00 4a 8d 7c 25 08 48 01 dd e8 c2 25 15 ff 49 8d 7d 08 e8 39 13 15 ff <4d> 89 75 08 48 89 ef e8 7d 12 15 ff 48 8b 5d 00 e8 14 55 2f 00 85 RSP: 0018:ffff88810c36f260 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000002000c0 RCX: ffffffffaf02dd77 RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffffc900025910c8 RBP: ffffc900025910c0 R08: 0000000000000001 R09: fffff520004b2219 R10: ffffc900025910cf R11: 31392d2068736168 R12: 00000000002000c0 R13: ffffc900025910c0 R14: 00000000fffef608 R15: ffff88811840e900 FS: 0000000000000000(0000) GS:ffff8881f7000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffc900025910c8 CR3: 0000000129d00000 CR4: 0000000000750ee0 PKRU: 55555554 Call Trace: <TASK> ? __die+0x23/0x70 ? page_fault_oops+0x1ee/0x5c0 ? __pfx_is_prefetch.constprop.0+0x10/0x10 ? __pfx_page_fault_oops+0x10/0x10 ? search_bpf_extables+0xfe/0x1c0 ? fixup_exception+0x3b/0x470 ? exc_page_fault+0xf6/0x110 ? asm_exc_page_fault+0x26/0x30 ? nexthop_select_path+0x197/0xbf0 ? nexthop_select_path+0x197/0xbf0 ? lock_is_held_type+0xe7/0x140 vxlan_xmit+0x5b2/0x2340 ? __lock_acquire+0x92b/0x3370 ? __pfx_vxlan_xmit+0x10/0x10 ? __pfx___lock_acquire+0x10/0x10 ? __pfx_register_lock_class+0x10/0x10 ? skb_network_protocol+0xce/0x2d0 ? dev_hard_start_xmit+0xca/0x350 ? __pfx_vxlan_xmit+0x10/0x10 dev_hard_start_xmit+0xca/0x350 __dev_queue_xmit+0x513/0x1e20 ? __pfx___dev_queue_xmit+0x10/0x10 ? __pfx_lock_release+0x10/0x10 ? mark_held_locks+0x44/0x90 ? skb_push+0x4c/0x80 ? eth_header+0x81/0xe0 ? __pfx_eth_header+0x10/0x10 ? neigh_resolve_output+0x215/0x310 ? ip6_finish_output2+0x2ba/0xc90 ip6_finish_output2+0x2ba/0xc90 ? lock_release+0x236/0x3e0 ? ip6_mtu+0xbb/0x240 ? __pfx_ip6_finish_output2+0x10/0x10 ? find_held_lock+0x83/0xa0 ? lock_is_held_type+0xe7/0x140 ip6_finish_output+0x1ee/0x780 ip6_output+0x138/0x460 ? __pfx_ip6_output+0x10/0x10 ? __pfx___lock_acquire+0x10/0x10 ? __pfx_ip6_finish_output+0x10/0x10 NF_HOOK.constprop.0+0xc0/0x420 ? __pfx_NF_HOOK.constprop.0+0x10/0x10 ? ndisc_send_skb+0x2c0/0x960 ? __pfx_lock_release+0x10/0x10 ? __local_bh_enable_ip+0x93/0x110 ? lock_is_held_type+0xe7/0x140 ndisc_send_skb+0x4be/0x960 ? __pfx_ndisc_send_skb+0x10/0x10 ? mark_held_locks+0x65/0x90 ? find_held_lock+0x83/0xa0 ndisc_send_ns+0xb0/0x110 ? __pfx_ndisc_send_ns+0x10/0x10 addrconf_dad_work+0x631/0x8e0 ? lock_acquire+0x180/0x3f0 ? __pfx_addrconf_dad_work+0x10/0x10 ? mark_held_locks+0x24/0x90 process_one_work+0x582/0x9c0 ? __pfx_process_one_work+0x10/0x10 ? __pfx_do_raw_spin_lock+0x10/0x10 ? mark_held_locks+0x24/0x90 worker_thread+0x93/0x630 ? __kthread_parkme+0xdc/0x100 ? __pfx_worker_thread+0x10/0x10 kthread+0x1a5/0x1e0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x34/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1b/0x30 RIP: 0000:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0000:0000000000000000 EFLAGS: 00000000 ORIG_RAX: 0000000000000000 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK> Modules linked in: CR2: ffffc900025910c8 ---[ end trace 0000000000000000 ]--- RIP: 0010:nexthop_select_path+0x197/0xbf0 Code: c1 e4 05 be 08 00 00 00 4c 8b 35 a4 14 7e 01 4e 8d 6c 25 00 4a 8d 7c 25 08 48 01 dd e8 c2 25 15 ff 49 8d 7d 08 e8 39 13 15 ff <4d> 89 75 08 48 89 ef e8 7d 12 15 ff 48 8b 5d 00 e8 14 55 2f 00 85 RSP: 0018:ffff88810c36f260 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000002000c0 RCX: ffffffffaf02dd77 RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffffc900025910c8 RBP: ffffc900025910c0 R08: 0000000000000001 R09: fffff520004b2219 R10: ffffc900025910cf R11: 31392d2068736168 R12: 00000000002000c0 R13: ffffc900025910c0 R14: 00000000fffef608 R15: ffff88811840e900 FS: 0000000000000000(0000) GS:ffff8881f7000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 0000000129d00000 CR4: 0000000000750ee0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception in interrupt Kernel Offset: 0x2ca00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
Fix this problem by ensuring the MSB of hash is 0 using a right shift - the same approach used in fib_multipath_hash() and rt6_multipath_hash().
--- include/net/vxlan.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/net/vxlan.h +2 -2
@@ -554,12 +554,12 @@ static inline void vxlan_flag_attr_error(int attrtype, }static inline bool vxlan_fdb_nh_path_select (struct nexthop *nh, -int hash, +u32 hash,struct vxlan_rdst *rdst) {struct fib_nh_common *nhc; - nhc =nexthop_path_fdb_result (nh, hash); + nhc =nexthop_path_fdb_result (nh, hash >>1 );if (unlikely (!nhc))return false;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 85/165 net/mlx5: fs_core: Make find_closest_ft more generic
In reply to Greg Kroah-HartmanFrom: Jianbo Liu <[email protected]>
[ Upstream commit 618d28a535a0582617465d14e05f3881736a2962 ]
As find_closest_ft_recursive is called to find the closest FT, the first parameter of find_closest_ft can be changed from fs_prio to fs_node. Thus this function is extended to find the closest FT for the nodes of any type, not only prios, but also the sub namespaces.
Stable-dep-of: c635ca45a7a2 ("net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio")
--- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +14 -15
@@ -905,18 +905,17 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,return ft; } -/* If reverse is false then return the first flow table in next priority of -* prio in the tree, else return the last flow table in the previous priority -* of prio in the tree. +/* If reverse is false then return the first flow table next to the passed node +* in the tree, else return the last flow table before the node in the tree. */ -static struct mlx5_flow_table *find_closest_ft (struct fs_prio *prio,bool reverse) +static struct mlx5_flow_table *find_closest_ft (struct fs_node *node,bool reverse) {struct mlx5_flow_table *ft =NULL ;struct fs_node *curr_node;struct fs_node *parent; - parent = prio->node.parent; - curr_node = &prio->node; + parent = node->parent; + curr_node = node;while (!ft && parent) { ft =find_closest_ft_recursive (parent, &curr_node->list, reverse); curr_node = parent;
@@ -926,15 +925,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers }/* Assuming all the tree is locked by mutex chain lock */ -static struct mlx5_flow_table *find_next_chained_ft (struct fs_prio *prio) +static struct mlx5_flow_table *find_next_chained_ft (struct fs_node *node) { -return find_closest_ft (prio, false); +return find_closest_ft (node, false); }/* Assuming all the tree is locked by mutex chain lock */ -static struct mlx5_flow_table *find_prev_chained_ft (struct fs_prio *prio) +static struct mlx5_flow_table *find_prev_chained_ft (struct fs_node *node) { -return find_closest_ft (prio, true); +return find_closest_ft (node, true); } static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
@@ -946,7 +945,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, next_ns = flow_act->action &MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS ;fs_get_obj (prio, next_ns ? ft->ns->node.parent : ft->node.parent); -return find_next_chained_ft (prio); +return find_next_chained_ft (&prio->node); } static int connect_fts_in_prio(struct mlx5_core_dev *dev,
@@ -977,7 +976,7 @@ static int connect_prev_fts(struct mlx5_core_dev *dev, {struct mlx5_flow_table *prev_ft; - prev_ft =find_prev_chained_ft (prio); + prev_ft =find_prev_chained_ft (&prio->node);if (prev_ft) {struct fs_prio *prev_prio;
@@ -1123,7 +1122,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_tableif (err)return err; - next_ft = first_ft ? first_ft :find_next_chained_ft (prio); + next_ft = first_ft ? first_ft :find_next_chained_ft (&prio->node); err =connect_fwd_rules (dev, ft, next_ft);if (err)return err;
@@ -1198,7 +1197,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespatree_init_node (&ft->node, del_hw_flow_table, del_sw_flow_table); next_ft = unmanaged ? ft_attr->next_ft : -find_next_chained_ft (fs_prio); +find_next_chained_ft (&fs_prio->node); ft->def_miss_action = ns->def_miss_action; ft->ns = ns; err = root->cmds->create_flow_table (root, ft, ft_attr, next_ft);
@@ -2201,7 +2200,7 @@ static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)if (!list_is_last (&ft->node.list, &prio->node.children))return list_next_entry (ft, node.list); -return find_next_chained_ft (prio); +return find_next_chained_ft (&prio->node); }static int update_root_ft_destroy (struct mlx5_flow_table *ft)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 86/165 net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio
In reply to Greg Kroah-HartmanFrom: Jianbo Liu <[email protected]>
[ Upstream commit c635ca45a7a2023904a1f851e99319af7b87017d ]
In the cited commit, new type of FS_TYPE_PRIO_CHAINS fs_prio was added to support multiple parallel namespaces for multi-chains. And we skip all the flow tables under the fs_node of this type unconditionally, when searching for the next or previous flow table to connect for a new table.
As this search function is also used for find new root table when the old one is being deleted, it will skip the entire FS_TYPE_PRIO_CHAINS fs_node next to the old root. However, new root table should be chosen from it if there is any table in it. Fix it by skipping only the flow tables in the same FS_TYPE_PRIO_CHAINS fs_node when finding the closest FT for a fs_node.
Besides, complete the connecting from FTs of previous priority of prio because there should be multiple prevs after this fs_prio type is introduced. And also the next FT should be chosen from the first flow table next to the prio in the same FS_TYPE_PRIO_CHAINS fs_prio, if this prio is the first child.
--- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 80 +++++++++++++++++-- 1 file changed, 72 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +72 -8
@@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root, struct fs_node *iter = list_entry(start, struct fs_node, list);struct mlx5_flow_table *ft =NULL ; -if (!root || root->type ==FS_TYPE_PRIO_CHAINS ) +if (!root)return NULL ;list_for_each_advance_continue (iter, &root->children, reverse) {
@@ -905,19 +905,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,return ft; } +static struct fs_node *find_prio_chains_parent (struct fs_node *parent, +struct fs_node **child) +{ +struct fs_node *node =NULL ; + +while (parent && parent->type !=FS_TYPE_PRIO_CHAINS ) { + node = parent; + parent = parent->parent; + } + +if (child) + *child = node; + +return parent; +} +/* If reverse is false then return the first flow table next to the passed node * in the tree, else return the last flow table before the node in the tree. +* If skip is true, skip the flow tables in the same prio_chains prio. */ -static struct mlx5_flow_table *find_closest_ft (struct fs_node *node,bool reverse) +static struct mlx5_flow_table *find_closest_ft (struct fs_node *node,bool reverse, +bool skip) { +struct fs_node *prio_chains_parent =NULL ;struct mlx5_flow_table *ft =NULL ;struct fs_node *curr_node;struct fs_node *parent; +if (skip) + prio_chains_parent =find_prio_chains_parent (node,NULL ); parent = node->parent; curr_node = node;while (!ft && parent) { - ft =find_closest_ft_recursive (parent, &curr_node->list, reverse); +if (parent != prio_chains_parent) + ft =find_closest_ft_recursive (parent, &curr_node->list, + reverse); curr_node = parent; parent = curr_node->parent; }
@@ -927,13 +950,13 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool revers/* Assuming all the tree is locked by mutex chain lock */ static struct mlx5_flow_table *find_next_chained_ft (struct fs_node *node) { -return find_closest_ft (node, false); +return find_closest_ft (node, false, true); }/* Assuming all the tree is locked by mutex chain lock */ static struct mlx5_flow_table *find_prev_chained_ft (struct fs_node *node) { -return find_closest_ft (node, true); +return find_closest_ft (node, true, true); } static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
@@ -969,21 +992,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,return 0 ; } +static struct mlx5_flow_table *find_closet_ft_prio_chains (struct fs_node *node, +struct fs_node *parent, +struct fs_node **child, +bool reverse) +{ +struct mlx5_flow_table *ft; + + ft =find_closest_ft (node, reverse, false); + +if (ft && parent ==find_prio_chains_parent (&ft->node, child)) +return ft; + +return NULL ; +} +/* Connect flow tables from previous priority of prio to ft */ static int connect_prev_fts (struct mlx5_core_dev *dev,struct mlx5_flow_table *ft,struct fs_prio *prio) { +struct fs_node *prio_parent, *parent =NULL , *child, *node;struct mlx5_flow_table *prev_ft; +int err =0 ; + + prio_parent =find_prio_chains_parent (&prio->node, &child); + +/* return directly if not under the first sub ns of prio_chains prio */ +if (prio_parent && !list_is_first (&child->list, &prio_parent->children)) +return 0 ; prev_ft =find_prev_chained_ft (&prio->node); -if (prev_ft) { +while (prev_ft) {struct fs_prio *prev_prio;fs_get_obj (prev_prio, prev_ft->node.parent); -return connect_fts_in_prio (dev, prev_prio, ft); + err =connect_fts_in_prio (dev, prev_prio, ft); +if (err) +break ; + +if (!parent) { + parent =find_prio_chains_parent (&prev_prio->node, &child); +if (!parent) +break ; + } + + node = child; + prev_ft =find_closet_ft_prio_chains (node, parent, &child, true); } -return 0 ; +return err; } static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
@@ -2194,12 +2251,19 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);/* Assuming prio->node.children(flow tables) is sorted by level */ static struct mlx5_flow_table *find_next_ft (struct mlx5_flow_table *ft) { +struct fs_node *prio_parent, *child;struct fs_prio *prio;fs_get_obj (prio, ft->node.parent);if (!list_is_last (&ft->node.list, &prio->node.children))return list_next_entry (ft, node.list); + + prio_parent =find_prio_chains_parent (&prio->node, &child); + +if (prio_parent &&list_is_first (&child->list, &prio_parent->children)) +return find_closest_ft (&prio->node, false, false); +return find_next_chained_ft (&prio->node); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 87/165 net/mlx5e: Set proper IPsec source port in L4 selector
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
[ Upstream commit 62da08331f1a2bef9d0148613133ce8e640a2f8d ]
Fix typo in setup_fte_upper_proto_match() where destination UDP port was used instead of source port.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +2 -2
@@ -808,9 +808,9 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp }if (upspec->sport) { -MLX5_SET (fte_match_set_lyr_2_4, spec->match_criteria, udp_dport, +MLX5_SET (fte_match_set_lyr_2_4, spec->match_criteria, udp_sport, upspec->sport_mask); -MLX5_SET (fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport); +MLX5_SET (fte_match_set_lyr_2_4, spec->match_value, udp_sport, upspec->sport); } }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 88/165 prestera: fix fallback to previous version on same major version
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
[ Upstream commit b755c25fbcd568821a3bb0e0d5c2daa5fcb00bba ]
When both supported and previous version have the same major version, and the firmwares are missing, the driver ends in a loop requesting the same (previous) version over and over again:
[ 76.327413] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.1.img firmware, fall-back to previous 4.0 version
[ 76.339802] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.352162] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.364502] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.376848] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.389183] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.401522] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.413860] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
[ 76.426199] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.0.img firmware, fall-back to previous 4.0 version
...Fix this by inverting the check to that we aren't yet at the previous version, and also check the minor version.
This also catches the case where both versions are the same, as it was after commit bb5dbf2cc64d ("net: marvell: prestera: add firmware v4.0 support").
With this fix applied:
[ 88.499622] Prestera DX 0000:01:00.0: missing latest mrvl/prestera/mvsw_prestera_fw-v4.1.img firmware, fall-back to previous 4.0 version
[ 88.511995] Prestera DX 0000:01:00.0: failed to request previous firmware: mrvl/prestera/mvsw_prestera_fw-v4.0.img
[ 88.522403] Prestera DX: probe of 0000:01:00.0 failed with error -2--- drivers/net/ethernet/marvell/prestera/prestera_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/marvell/prestera/prestera_pci.c +2 -1
@@ -727,7 +727,8 @@ static int prestera_fw_get(struct prestera_fw *fw) err =request_firmware_direct (&fw->bin, fw_path, fw->dev.dev);if (err) { -if (ver_maj ==PRESTERA_SUPP_FW_MAJ_VER ) { +if (ver_maj !=PRESTERA_PREV_FW_MAJ_VER || + ver_min !=PRESTERA_PREV_FW_MIN_VER ) { ver_maj =PRESTERA_PREV_FW_MAJ_VER ; ver_min =PRESTERA_PREV_FW_MIN_VER ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 89/165 tcp_metrics: fix addr_same() helper
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e6638094d7af6c7b9dcca05ad009e79e31b4f670 ]
Because v4 and v6 families use separate inetpeer trees (respectively net->ipv4.peers and net->ipv6.peers), inetpeer_addr_cmp(a, b) assumes a & b share the same family.
tcp_metrics use a common hash table, where entries can have different families.
We must therefore make sure to not call inetpeer_addr_cmp() if the families do not match.
--- net/ipv4/tcp_metrics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp_metrics.c +1 -1
@@ -78,7 +78,7 @@ static void tcp_metric_set(struct tcp_metrics_block *tm,static bool addr_same (const struct inetpeer_addr *a,const struct inetpeer_addr *b) { -return inetpeer_addr_cmp (a, b) ==0 ; +return (a->family == b->family) && !inetpeer_addr_cmp (a, b); }struct tcpm_hash_bucket {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 90/165 tcp_metrics: annotate data-races around tm->tcpm_stamp
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 949ad62a5d5311d36fce2e14fe5fed3f936da51c ]
tm->tcpm_stamp can be read or written locklessly.
Add needed READ_ONCE()/WRITE_ONCE() to document this.
Also constify tcpm_check_stamp() dst argument.
--- net/ipv4/tcp_metrics.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
net/ipv4/tcp_metrics.c +13 -6
@@ -97,7 +97,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,u32 msval;u32 val; - tm->tcpm_stamp = jiffies; +WRITE_ONCE (tm->tcpm_stamp, jiffies); val =0 ;if (dst_metric_locked (dst,RTAX_RTT ))
@@ -131,9 +131,15 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,#define TCP_METRICS_TIMEOUT (60 * 60 * HZ) -static void tcpm_check_stamp (struct tcp_metrics_block *tm,struct dst_entry *dst) +static void tcpm_check_stamp (struct tcp_metrics_block *tm, +const struct dst_entry *dst) { -if (tm &&unlikely (time_after (jiffies, tm->tcpm_stamp +TCP_METRICS_TIMEOUT ))) +unsigned long limit; + +if (!tm) +return ; + limit =READ_ONCE (tm->tcpm_stamp) +TCP_METRICS_TIMEOUT ; +if (unlikely (time_after (jiffies, limit)))tcpm_suck_dst (tm, dst, false); }
@@ -174,7 +180,8 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, oldest =deref_locked (tcp_metrics_hash[hash].chain);for (tm =deref_locked (oldest->tcpm_next); tm; tm =deref_locked (tm->tcpm_next)) { -if (time_before (tm->tcpm_stamp, oldest->tcpm_stamp)) +if (time_before (READ_ONCE (tm->tcpm_stamp), +READ_ONCE (oldest->tcpm_stamp))) oldest = tm; } tm = oldest;
@@ -434,7 +441,7 @@ void tcp_update_metrics(struct sock *sk) tp->reordering); } } - tm->tcpm_stamp = jiffies; +WRITE_ONCE (tm->tcpm_stamp, jiffies); out_unlock:rcu_read_unlock (); }
@@ -647,7 +654,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, }if (nla_put_msecs (msg,TCP_METRICS_ATTR_AGE , - jiffies - tm->tcpm_stamp, + jiffies -READ_ONCE (tm->tcpm_stamp),TCP_METRICS_ATTR_PAD ) <0 ) goto nla_put_failure;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 91/165 tcp_metrics: annotate data-races around tm->tcpm_lock
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 285ce119a3c6c4502585936650143e54c8692788 ]
tm->tcpm_lock can be read or written locklessly.
Add needed READ_ONCE()/WRITE_ONCE() to document this.
--- net/ipv4/tcp_metrics.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/ipv4/tcp_metrics.c +4 -2
@@ -59,7 +59,8 @@ static inline struct net *tm_net(struct tcp_metrics_block *tm)static bool tcp_metric_locked (struct tcp_metrics_block *tm,enum tcp_metric_index idx) { -return tm->tcpm_lock & (1 << idx); +/* Paired with WRITE_ONCE() in tcpm_suck_dst() */ +return READ_ONCE (tm->tcpm_lock) & (1 << idx); } static u32 tcp_metric_get(struct tcp_metrics_block *tm,
@@ -110,7 +111,8 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, val |=1 <<TCP_METRIC_CWND ;if (dst_metric_locked (dst,RTAX_REORDERING )) val |=1 <<TCP_METRIC_REORDERING ; - tm->tcpm_lock = val; +/* Paired with READ_ONCE() in tcp_metric_locked() */ +WRITE_ONCE (tm->tcpm_lock, val); msval =dst_metric_raw (dst,RTAX_RTT ); tm->tcpm_vals[TCP_METRIC_RTT ] = msval *USEC_PER_MSEC ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 92/165 tcp_metrics: annotate data-races around tm->tcpm_vals[]
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 8c4d04f6b443869d25e59822f7cec88d647028a9 ]
tm->tcpm_vals[] values can be read or written locklessly.
Add needed READ_ONCE()/WRITE_ONCE() to document this, and force use of tcp_metric_get() and tcp_metric_set()
--- net/ipv4/tcp_metrics.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
net/ipv4/tcp_metrics.c +14 -9
@@ -63,17 +63,19 @@ static bool tcp_metric_locked(struct tcp_metrics_block *tm,return READ_ONCE (tm->tcpm_lock) & (1 << idx); } -static u32 tcp_metric_get (struct tcp_metrics_block *tm, +static u32 tcp_metric_get (const struct tcp_metrics_block *tm,enum tcp_metric_index idx) { -return tm->tcpm_vals[idx]; +/* Paired with WRITE_ONCE() in tcp_metric_set() */ +return READ_ONCE (tm->tcpm_vals[idx]); }static void tcp_metric_set (struct tcp_metrics_block *tm,enum tcp_metric_index idx,u32 val) { - tm->tcpm_vals[idx] = val; +/* Paired with READ_ONCE() in tcp_metric_get() */ +WRITE_ONCE (tm->tcpm_vals[idx], val); } static bool addr_same(const struct inetpeer_addr *a,
@@ -115,13 +117,16 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,WRITE_ONCE (tm->tcpm_lock, val); msval =dst_metric_raw (dst,RTAX_RTT ); - tm->tcpm_vals[TCP_METRIC_RTT ] = msval *USEC_PER_MSEC ; +tcp_metric_set (tm,TCP_METRIC_RTT , msval *USEC_PER_MSEC ); msval =dst_metric_raw (dst,RTAX_RTTVAR ); - tm->tcpm_vals[TCP_METRIC_RTTVAR ] = msval *USEC_PER_MSEC ; - tm->tcpm_vals[TCP_METRIC_SSTHRESH ] =dst_metric_raw (dst,RTAX_SSTHRESH ); - tm->tcpm_vals[TCP_METRIC_CWND ] =dst_metric_raw (dst,RTAX_CWND ); - tm->tcpm_vals[TCP_METRIC_REORDERING ] =dst_metric_raw (dst,RTAX_REORDERING ); +tcp_metric_set (tm,TCP_METRIC_RTTVAR , msval *USEC_PER_MSEC ); +tcp_metric_set (tm,TCP_METRIC_SSTHRESH , +dst_metric_raw (dst,RTAX_SSTHRESH )); +tcp_metric_set (tm,TCP_METRIC_CWND , +dst_metric_raw (dst,RTAX_CWND )); +tcp_metric_set (tm,TCP_METRIC_REORDERING , +dst_metric_raw (dst,RTAX_REORDERING ));if (fastopen_clear) { tm->tcpm_fastopen.mss =0 ; tm->tcpm_fastopen.syn_loss =0 ;
@@ -667,7 +672,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,if (!nest) goto nla_put_failure;for (i =0 ; i <TCP_METRIC_MAX_KERNEL +1 ; i++) { -u32 val = tm->tcpm_vals[i]; +u32 val =tcp_metric_get (tm, i);if (!val)continue ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 93/165 tcp_metrics: annotate data-races around tm->tcpm_net
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit d5d986ce42c71a7562d32c4e21e026b0f87befec ]
tm->tcpm_net can be read or written locklessly.
Instead of changing write_pnet() and read_pnet() and potentially hurt performance, add the needed READ_ONCE()/WRITE_ONCE() in tm_net() and tcpm_new().
--- net/ipv4/tcp_metrics.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/ipv4/tcp_metrics.c +7 -4
@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics {struct tcp_metrics_block {struct tcp_metrics_block __rcu *tcpm_next; -possible_net_t tcpm_net; +struct net *tcpm_net;struct inetpeer_addr tcpm_saddr;struct inetpeer_addr tcpm_daddr;unsigned long tcpm_stamp;
@@ -51,9 +51,10 @@ struct tcp_metrics_block {struct rcu_head rcu_head; }; -static inline struct net *tm_net (struct tcp_metrics_block *tm) +static inline struct net *tm_net (const struct tcp_metrics_block *tm) { -return read_pnet (&tm->tcpm_net); +/* Paired with the WRITE_ONCE() in tcpm_new() */ +return READ_ONCE (tm->tcpm_net); } static bool tcp_metric_locked(struct tcp_metrics_block *tm,
@@ -197,7 +198,9 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,if (!tm) goto out_unlock; } -write_pnet (&tm->tcpm_net, net); +/* Paired with the READ_ONCE() in tm_net() */ +WRITE_ONCE (tm->tcpm_net, net); + tm->tcpm_saddr = *saddr; tm->tcpm_daddr = *daddr;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 94/165 tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit ddf251fa2bc1d3699eec0bae6ed0bc373b8fda79 ]
Whenever tcpm_new() reclaims an old entry, tcpm_suck_dst() would overwrite data that could be read from tcp_fastopen_cache_get() or tcp_metrics_fill_info().
We need to acquire fastopen_seqlock to maintain consistency.
For newly allocated objects, tcpm_new() can switch to kzalloc() to avoid an extra fastopen_seqlock acquisition.
--- net/ipv4/tcp_metrics.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
net/ipv4/tcp_metrics.c +5 -4
@@ -93,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly;static unsigned int tcp_metrics_hash_log__read_mostly ;static DEFINE_SPINLOCK (tcp_metrics_lock); +static DEFINE_SEQLOCK (fastopen_seqlock); static void tcpm_suck_dst(struct tcp_metrics_block *tm, const struct dst_entry *dst,
@@ -129,11 +130,13 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,tcp_metric_set (tm,TCP_METRIC_REORDERING ,dst_metric_raw (dst,RTAX_REORDERING ));if (fastopen_clear) { +write_seqlock (&fastopen_seqlock); tm->tcpm_fastopen.mss =0 ; tm->tcpm_fastopen.syn_loss =0 ; tm->tcpm_fastopen.try_exp =0 ; tm->tcpm_fastopen.cookie.exp = false; tm->tcpm_fastopen.cookie.len =0 ; +write_sequnlock (&fastopen_seqlock); } }
@@ -194,7 +197,7 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, } tm = oldest; }else { - tm =kmalloc (sizeof (*tm),GFP_ATOMIC ); + tm =kzalloc (sizeof (*tm),GFP_ATOMIC );if (!tm) goto out_unlock; }
@@ -204,7 +207,7 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, tm->tcpm_saddr = *saddr; tm->tcpm_daddr = *daddr; -tcpm_suck_dst (tm, dst, true); +tcpm_suck_dst (tm, dst, reclaim);if (likely (!reclaim)) { tm->tcpm_next = tcp_metrics_hash[hash].chain;
@@ -556,8 +559,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst)return ret; } -static DEFINE_SEQLOCK (fastopen_seqlock); -void tcp_fastopen_cache_get (struct sock *sk,u16 *mss,struct tcp_fastopen_cookie *cookie) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 95/165 test/vsock: remove vsock_perf executable on `make clean`
In reply to Greg Kroah-HartmanFrom: Stefano Garzarella <[email protected]>
[ Upstream commit 3c50c8b240390907c9a33c86d25d850520db6dfa ]
We forgot to add vsock_perf to the rm command in the clean target, so now we have a left over after make clean in tools/testing/vsock.
--- tools/testing/vsock/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/vsock/Makefile +1 -1
@@ -8,5 +8,5 @@ vsock_perf: vsock_perf.o CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE .PHONY: all test clean clean: - ${RM} *.o *.d vsock_test vsock_diag_test + ${RM} *.o *.d vsock_test vsock_diag_test vsock_perf -include *.d
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 96/165 rust: allocator: Prevent mis-aligned allocation
In reply to Greg Kroah-HartmanFrom: Boqun Feng <[email protected]>
commit b3d8aa84bbfe9b58ccc5332cacf8ea17200af310 upstream.
Currently the rust allocator simply passes the size of the type Layout to krealloc(), and in theory the alignment requirement from the type Layout may be larger than the guarantee provided by SLAB, which means the allocated object is mis-aligned.
Fix this by adjusting the allocation size to the nearest power of two, which SLAB always guarantees a size-aligned allocation. And because Rust guarantees that the original size must be a multiple of alignment and the alignment must be a power of two, then the alignment requirement is satisfied.
--- rust/bindings/bindings_helper.h | 1 rust/kernel/allocator.rs | 74 +++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 15 deletions(-)
rust/bindings/bindings_helper.h +1 -0
@@ -12,5 +12,6 @@#include <linux/sched.h> /* `bindgen` gets confused at certain things. */ +const size_t BINDINGS_ARCH_SLAB_MINALIGN =ARCH_SLAB_MINALIGN ;const gfp_t BINDINGS_GFP_KERNEL =GFP_KERNEL ;const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
rust/kernel/allocator.rs +59 -15
98 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 97/165 scsi: zfcp: Defer fc_rport blocking until after ADISC response
In reply to Greg Kroah-HartmanFrom: Steffen Maier <[email protected]>
commit e65851989001c0c9ba9177564b13b38201c0854c upstream.
Storage devices are free to send RSCNs, e.g. for internal state changes. If this happens on all connected paths, zfcp risks temporarily losing all paths at the same time. This has strong requirements on multipath configuration such as "no_path_retry queue".
Avoid such situations by deferring fc_rport blocking until after the ADISC response, when any actual state change of the remote port became clear. The already existing port recovery triggers explicitly block the fc_rport. The triggers are: on ADISC reject or timeout (typical cable pull case), and on ADISC indicating that the remote port has changed its WWPN or the port is meanwhile no longer open.
As a side effect, this also removes a confusing direct function call to another work item function zfcp_scsi_rport_work() instead of scheduling that other work item. It was probably done that way to have the rport block side effect immediate and synchronous to the caller.
--- drivers/s390/scsi/zfcp_fc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/s390/scsi/zfcp_fc.c +1 -5
@@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void */* re-init to undo drop from zfcp_fc_adisc() */ port->d_id =ntoh24 (adisc_resp->adisc_port_id); -/* port is good, unblock rport without going through erp */ -zfcp_scsi_schedule_rport_register (port); +/* port is still good, nothing to do */ out:atomic_andnot (ZFCP_STATUS_PORT_LINK_TEST , &port->status);put_device (&port->dev);
@@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_int retval;set_worker_desc ("zadisc%16llx" , port->wwpn);/* < WORKER_DESC_LEN=24 */ -get_device (&port->dev); - port->rport_task =RPORT_DEL ; -zfcp_scsi_rport_work (&port->rport_work);/* only issue one test command at one time per port */ if (atomic_read (&port->status) &ZFCP_STATUS_PORT_LINK_TEST )
Greg Kroah-Hartman
maintainerPATCH 98/165 scsi: storvsc: Limit max_sectors for virtual Fibre Channel devices
In reply to Greg Kroah-HartmanFrom: Michael Kelley <[email protected]>
commit 010c1e1c5741365dbbf44a5a5bb9f30192875c4c upstream.
The Hyper-V host is queried to get the max transfer size that it supports, and this value is used to set max_sectors for the synthetic SCSI controller. However, this max transfer size may be too large for virtual Fibre Channel devices, which are limited to 512 Kbytes. If a larger transfer size is used with a vFC device, Hyper-V always returns an error, and storvsc logs a message like this where the SRB status and SCSI status are both zero:
hv_storvsc <GUID>: tag#197 cmd 0x8a status: scsi 0x0 srb 0x0 hv 0xc0000001
Add logic to limit the max transfer size to 512 Kbytes for vFC devices.
--- drivers/scsi/storvsc_drv.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/storvsc_drv.c +4 -0
@@ -365,6 +365,7 @@ static void storvsc_on_channel_callback(#define STORVSC_FC_MAX_LUNS_PER_TARGET 255#define STORVSC_FC_MAX_TARGETS 128#define STORVSC_FC_MAX_CHANNELS 8 +#define STORVSC_FC_MAX_XFER_SIZE ((u32)(512 * 1024))#define STORVSC_IDE_MAX_LUNS_PER_TARGET 64#define STORVSC_IDE_MAX_TARGETS 1
@@ -2004,6 +2005,9 @@ static int storvsc_probe(struct hv_devic* protecting it from any weird value. */ max_xfer_bytes =round_down (stor_device->max_transfer_bytes,HV_HYP_PAGE_SIZE ); +if (is_fc) + max_xfer_bytes =min (max_xfer_bytes,STORVSC_FC_MAX_XFER_SIZE ); +/* max_hw_sectors_kb */ host->max_sectors = max_xfer_bytes >>9 ;/*
Greg Kroah-Hartman
maintainerPATCH 99/165 Documentation: kdump: Add va_kernel_pa_offset for RISCV64
In reply to Greg Kroah-HartmanFrom: Song Shuai <[email protected]>
commit 640c503d7dbd7d34a62099c933f4db0ed77ccbec upstream.
RISC-V Linux exports "va_kernel_pa_offset" in vmcoreinfo to help Crash-utility translate the kernel virtual address correctly.
Here adds the definition of "va_kernel_pa_offset".
--- Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 ++++++ 1 file changed, 6 insertions(+)
Documentation/admin-guide/kdump/vmcoreinfo.rst +6 -0
@@ -624,3 +624,9 @@ Used to get the correct ranges: * VMALLOC_START ~ VMALLOC_END : vmalloc() / ioremap() space. * VMEMMAP_START ~ VMEMMAP_END : vmemmap space, used for struct page array. * KERNEL_LINK_ADDR : start address of Kernel link and BPF + +va_kernel_pa_offset +------------------- + +Indicates the offset between the kernel virtual and physical mappings. +Used to translate virtual to physical addresses.
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 100/165 libceph: fix potential hang in ceph_osdc_notify()
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit e6e2843230799230fc5deb8279728a7218b0d63c upstream.
If the cluster becomes unavailable, ceph_osdc_notify() may hang even with osd_request_timeout option set because linger_notify_finish_wait() waits for MWatchNotify NOTIFY_COMPLETE message with no associated OSD request in flight -- it's completely asynchronous.
Introduce an additional timeout, derived from the specified notify timeout. While at it, switch both waits to killable which is more correct.
--- net/ceph/osd_client.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
net/ceph/osd_client.c +14 -6
@@ -3334,17 +3334,24 @@ static int linger_reg_commit_wait(structint ret;dout ("%s lreq %p linger_id %llu\n" , __func__, lreq, lreq->linger_id); - ret =wait_for_completion_interruptible (&lreq->reg_commit_wait); + ret =wait_for_completion_killable (&lreq->reg_commit_wait);return ret ?: lreq->reg_commit_error; } -static int linger_notify_finish_wait (struct ceph_osd_linger_request *lreq) +static int linger_notify_finish_wait (struct ceph_osd_linger_request *lreq, +unsigned long timeout) { -int ret; +long left;dout ("%s lreq %p linger_id %llu\n" , __func__, lreq, lreq->linger_id); - ret =wait_for_completion_interruptible (&lreq->notify_finish_wait); -return ret ?: lreq->notify_finish_error; + left =wait_for_completion_killable_timeout (&lreq->notify_finish_wait, +ceph_timeout_jiffies (timeout)); +if (left <=0 ) + left = left ?: -ETIMEDOUT ; +else + left = lreq->notify_finish_error;/* completed */ + +return left; }/*
@@ -4896,7 +4903,8 @@ int ceph_osdc_notify(struct ceph_osd_clilinger_submit (lreq); ret =linger_reg_commit_wait (lreq);if (!ret) - ret =linger_notify_finish_wait (lreq); + ret =linger_notify_finish_wait (lreq, +msecs_to_jiffies (2 * timeout *MSEC_PER_SEC ));else dout ("lreq %p failed to initiate notify %d\n" , lreq, ret);
Greg Kroah-Hartman
maintainerPATCH 101/165 USB: zaurus: Add ID for A-300/B-500/C-700
In reply to Greg Kroah-HartmanFrom: Ross Maynard <[email protected]>
commit b99225b4fe297d07400f9e2332ecd7347b224f8d upstream.
The SL-A300, B500/5600, and C700 devices no longer auto-load because of "usbnet: Remove over-broad module alias from zaurus."
This patch adds IDs for those 3 devices.
--- drivers/net/usb/cdc_ether.c | 21 +++++++++++++++++++++ drivers/net/usb/zaurus.c | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+)
drivers/net/usb/cdc_ether.c +21 -0
@@ -618,6 +618,13 @@ static const struct usb_device_id produc .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct =0x8005 ,/* A-300 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = 0, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO + |USB_DEVICE_ID_MATCH_DEVICE , + .idVendor = 0x04DD, .idProduct = 0x8006, /* B-500/SL-5600 */ZAURUS_MASTER_INTERFACE , .driver_info = 0,
@@ -625,11 +632,25 @@ static const struct usb_device_id produc .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct =0x8006 ,/* B-500/SL-5600 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = 0, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO + |USB_DEVICE_ID_MATCH_DEVICE , + .idVendor = 0x04DD, .idProduct = 0x8007, /* C-700 */ZAURUS_MASTER_INTERFACE , .driver_info = 0, }, { .match_flags =USB_DEVICE_ID_MATCH_INT_INFO + |USB_DEVICE_ID_MATCH_DEVICE , + .idVendor = 0x04DD, + .idProduct = 0x8007, /* C-700 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = 0, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO |USB_DEVICE_ID_MATCH_DEVICE , .idVendor = 0x04DD, .idProduct = 0x9031, /* C-750 C-760 */
drivers/net/usb/zaurus.c +21 -0
@@ -289,11 +289,25 @@ static const struct usb_device_id produc .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct =0x8005 ,/* A-300 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO + |USB_DEVICE_ID_MATCH_DEVICE , + .idVendor = 0x04DD, .idProduct = 0x8006, /* B-500/SL-5600 */ZAURUS_MASTER_INTERFACE , .driver_info = ZAURUS_PXA_INFO, }, { .match_flags =USB_DEVICE_ID_MATCH_INT_INFO + |USB_DEVICE_ID_MATCH_DEVICE , + .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO |USB_DEVICE_ID_MATCH_DEVICE , .idVendor = 0x04DD, .idProduct = 0x8007, /* C-700 */
@@ -301,6 +315,13 @@ static const struct usb_device_id produc .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct =0x8007 ,/* C-700 */ +ZAURUS_FAKE_INTERFACE , + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags =USB_DEVICE_ID_MATCH_INT_INFO |USB_DEVICE_ID_MATCH_DEVICE , .idVendor = 0x04DD, .idProduct = 0x9031, /* C-750 C-760 */
Greg Kroah-Hartman
maintainerPATCH 102/165 ceph: defer stopping mdsc delayed_work
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
commit e7e607bd00481745550389a29ecabe33e13d67cf upstream.
Flushing the dirty buffer may take a long time if the cluster is overloaded or if there is network issue. So we should ping the MDSs periodically to keep alive, else the MDS will blocklist the kclient.
--- fs/ceph/mds_client.c | 4 ++-- fs/ceph/mds_client.h | 5 +++++ fs/ceph/super.c | 10 ++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-)
fs/ceph/mds_client.c +2 -2
@@ -4762,7 +4762,7 @@ static void delayed_work(struct work_strdout ("mdsc delayed_work\n" ); -if (mdsc->stopping) +if (mdsc->stopping >=CEPH_MDSC_STOPPING_FLUSHED )return ;mutex_lock (&mdsc->mutex);
@@ -4941,7 +4941,7 @@ void send_flush_mdlog(struct ceph_mds_sevoid ceph_mdsc_pre_umount (struct ceph_mds_client *mdsc) {dout ("pre_umount\n" ); - mdsc->stopping =1 ; + mdsc->stopping =CEPH_MDSC_STOPPING_BEGIN ;ceph_mdsc_iterate_sessions (mdsc, send_flush_mdlog, true);ceph_mdsc_iterate_sessions (mdsc, lock_unlock_session, false);
fs/ceph/mds_client.h +5 -0
@@ -380,6 +380,11 @@ struct cap_wait {int want; }; +enum { +CEPH_MDSC_STOPPING_BEGIN =1 , +CEPH_MDSC_STOPPING_FLUSHED =2 , +}; +/* * mds client state */
fs/ceph/super.c +10 -0
@@ -1374,6 +1374,16 @@ static void ceph_kill_sb(struct super_blceph_mdsc_pre_umount (fsc->mdsc);flush_fs_workqueues (fsc); +/* +* Though the kill_anon_super() will finally trigger the +* sync_filesystem() anyway, we still need to do it here +* and then bump the stage of shutdown to stop the work +* queue as earlier as possible. +*/ +sync_filesystem (s); + + fsc->mdsc->stopping =CEPH_MDSC_STOPPING_FLUSHED ; +kill_anon_super (s); fsc->client->extra_mon_dispatch =NULL ;
Greg Kroah-Hartman
maintainerPATCH 103/165 firmware: arm_scmi: Drop OF node reference in the transport channel setup
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit da042eb4f061a0b54aedadcaa15391490c48e1ad upstream.
The OF node reference obtained from of_parse_phandle() should be dropped if node is not compatible with arm,scmi-shmem.
--- drivers/firmware/arm_scmi/mailbox.c | 4 +++- drivers/firmware/arm_scmi/smc.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/firmware/arm_scmi/mailbox.c +3 -1
@@ -166,8 +166,10 @@ static int mailbox_chan_setup(struct scmreturn -ENOMEM ; shmem =of_parse_phandle (cdev->of_node,"shmem" , idx); -if (!of_device_is_compatible (shmem,"arm,scmi-shmem" )) +if (!of_device_is_compatible (shmem,"arm,scmi-shmem" )) { +of_node_put (shmem);return -ENXIO ; + } ret =of_address_to_resource (shmem,0 , &res);of_node_put (shmem);
drivers/firmware/arm_scmi/smc.c +3 -1
@@ -118,8 +118,10 @@ static int smc_chan_setup(struct scmi_chreturn -ENOMEM ; np =of_parse_phandle (cdev->of_node,"shmem" ,0 ); -if (!of_device_is_compatible (np,"arm,scmi-shmem" )) +if (!of_device_is_compatible (np,"arm,scmi-shmem" )) { +of_node_put (np);return -ENXIO ; + } ret =of_address_to_resource (np,0 , &res);of_node_put (np);
Greg Kroah-Hartman
maintainerPATCH 104/165 exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree
In reply to Greg Kroah-HartmanFrom: gaoming <[email protected]>
commit daf60d6cca26e50d65dac374db92e58de745ad26 upstream.
The call stack shown below is a scenario in the Linux 4.19 kernel. Allocating memory failed where exfat fs use kmalloc_array due to system memory fragmentation, while the u-disk was inserted without recognition.
Devices such as u-disk using the exfat file system are pluggable and may be insert into the system at any time.
However, long-term running systems cannot guarantee the continuity of physical memory. Therefore, it's necessary to address this issue.
Binder:2632_6: page allocation failure: order:4,
mode:0x6040c0(GFP_KERNEL|__GFP_COMP), nodemask=(null)
Call trace: [242178.097582] dump_backtrace+0x0/0x4 [242178.097589] dump_stack+0xf4/0x134 [242178.097598] warn_alloc+0xd8/0x144 [242178.097603] __alloc_pages_nodemask+0x1364/0x1384 [242178.097608] kmalloc_order+0x2c/0x510 [242178.097612] kmalloc_order_trace+0x40/0x16c [242178.097618] __kmalloc+0x360/0x408 [242178.097624] load_alloc_bitmap+0x160/0x284 [242178.097628] exfat_fill_super+0xa3c/0xe7c [242178.097635] mount_bdev+0x2e8/0x3a0 [242178.097638] exfat_fs_mount+0x40/0x50 [242178.097643] mount_fs+0x138/0x2e8 [242178.097649] vfs_kern_mount+0x90/0x270 [242178.097655] do_mount+0x798/0x173c [242178.097659] ksys_mount+0x114/0x1ac [242178.097665] __arm64_sys_mount+0x24/0x34 [242178.097671] el0_svc_common+0xb8/0x1b8 [242178.097676] el0_svc_handler+0x74/0x90 [242178.097681] el0_svc+0x8/0x340
By analyzing the exfat code,we found that continuous physical memory is not required here,so kvmalloc_array is used can solve this problem.
--- fs/exfat/balloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/exfat/balloc.c +3 -3
@@ -69,7 +69,7 @@ static int exfat_allocate_bitmap(struct } sbi->map_sectors = ((need_map_size -1 ) >> (sb->s_blocksize_bits)) +1 ; - sbi->vol_amap =kmalloc_array (sbi->map_sectors, + sbi->vol_amap =kvmalloc_array (sbi->map_sectors,sizeof (struct buffer_head *),GFP_KERNEL );if (!sbi->vol_amap)return -ENOMEM ;
@@ -84,7 +84,7 @@ static int exfat_allocate_bitmap(structwhile (j < i)brelse (sbi->vol_amap[j++]); -kfree (sbi->vol_amap); +kvfree (sbi->vol_amap); sbi->vol_amap =NULL ;return -EIO ; }
@@ -138,7 +138,7 @@ void exfat_free_bitmap(struct exfat_sb_ifor (i =0 ; i < sbi->map_sectors; i++)__brelse (sbi->vol_amap[i]); -kfree (sbi->vol_amap); +kvfree (sbi->vol_amap); }int exfat_set_bitmap (struct inode *inode,unsigned int clu,bool sync)
Greg Kroah-Hartman
maintainerPATCH 105/165 exfat: check if filename entries exceeds max filename length
In reply to Greg Kroah-HartmanFrom: Namjae Jeon <[email protected]>
commit d42334578eba1390859012ebb91e1e556d51db49 upstream.
exfat_extract_uni_name copies characters from a given file name entry into the 'uniname' variable. This variable is actually defined on the stack of the exfat_readdir() function. According to the definition of the 'exfat_uni_name' type, the file name should be limited 255 characters (+ null teminator space), but the exfat_get_uniname_from_ext_entry() function can write more characters because there is no check if filename entries exceeds max filename length. This patch add the check not to copy filename characters when exceeding max filename length.
--- fs/exfat/dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
fs/exfat/dir.c +7 -2
@@ -34,6 +34,7 @@ static int exfat_get_uniname_from_ext_en {int i, err;struct exfat_entry_set_cache es; +unsigned int uni_len =0 , len; err =exfat_get_dentry_set (&es, sb, p_dir, entry,ES_ALL_ENTRIES );if (err)
@@ -52,7 +53,10 @@ static int exfat_get_uniname_from_ext_enif (exfat_get_entry_type (ep) !=TYPE_EXTEND )break ; -exfat_extract_uni_name (ep, uniname); + len =exfat_extract_uni_name (ep, uniname); + uni_len += len; +if (len !=EXFAT_FILE_NAME_LEN || uni_len >=MAX_NAME_LENGTH ) +break ; uniname +=EXFAT_FILE_NAME_LEN ; }
@@ -1079,7 +1083,8 @@ rewind:if (entry_type ==TYPE_EXTEND ) {unsigned short entry_uniname[16 ], unichar; -if (step !=DIRENT_STEP_NAME ) { +if (step !=DIRENT_STEP_NAME || + name_len >=MAX_NAME_LENGTH ) { step =DIRENT_STEP_FILE ;continue ; }
Greg Kroah-Hartman
maintainerPATCH 106/165 exfat: release s_lock before calling dir_emit()
In reply to Greg Kroah-HartmanFrom: Sungjong Seo <[email protected]>
commit ff84772fd45d486e4fc78c82e2f70ce5333543e6 upstream.
There is a potential deadlock reported by syzbot as below:
======================================================
WARNING: possible circular locking dependency detected
6.4.0-next-20230707-syzkaller #0 Not tainted
------------------------------------------------------
syz-executor330/5073 is trying to acquire lock:ffff8880218527a0 (&mm->mmap_lock){++++}-{3:3}, at: mmap_read_lock_killable include/linux/mmap_lock.h:151 [inline] ffff8880218527a0 (&mm->mmap_lock){++++}-{3:3}, at: get_mmap_lock_carefully mm/memory.c:5293 [inline] ffff8880218527a0 (&mm->mmap_lock){++++}-{3:3}, at: lock_mm_and_find_vma+0x369/0x510 mm/memory.c:5344 but task is already holding lock:ffff888019f760e0 (&sbi->s_lock){+.+.}-{3:3}, at: exfat_iterate+0x117/0xb50 fs/exfat/dir.c:232
which lock already depends on the new lock.
Chain exists of: &mm->mmap_lock --> mapping.invalidate_lock#3 --> &sbi->s_lock Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&sbi->s_lock);
lock(mapping.invalidate_lock#3);
lock(&sbi->s_lock); rlock(&mm->mmap_lock);
Let's try to avoid above potential deadlock condition by moving dir_emit*() out of sbi->s_lock coverage.
--- fs/exfat/dir.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
fs/exfat/dir.c +12 -15
@@ -218,7 +218,10 @@ static void exfat_free_namebuf(struct exexfat_init_namebuf (nb); } -/* skip iterating emit_dots when dir is empty */ +/* +* Before calling dir_emit*(), sbi->s_lock should be released +* because page fault can occur in dir_emit*(). +*/ #define ITER_POS_FILLED_DOTS (2)static int exfat_iterate (struct file *file,struct dir_context *ctx) {
@@ -233,11 +236,10 @@ static int exfat_iterate(struct file *fiint err =0 , fake_offset =0 ;exfat_init_namebuf (nb); -mutex_lock (&EXFAT_SB (sb)->s_lock); cpos = ctx->pos;if (!dir_emit_dots (file, ctx)) - goto unlock; + goto out;if (ctx->pos ==ITER_POS_FILLED_DOTS ) { cpos =0 ;
@@ -249,16 +251,18 @@ static int exfat_iterate(struct file *fi/* name buffer should be allocated before use */ err =exfat_alloc_namebuf (nb);if (err) - goto unlock; + goto out; get_new: +mutex_lock (&EXFAT_SB (sb)->s_lock); +if (ei->flags ==ALLOC_NO_FAT_CHAIN && cpos >=i_size_read (inode)) goto end_of_dir; err =exfat_readdir (inode, &cpos, &de);if (err) {/* -* At least we tried to read a sector. Move cpos to next sector -* position (should be aligned). +* At least we tried to read a sector. +* Move cpos to next sector position (should be aligned). */ if (err == -EIO ) { cpos +=1 << (sb->s_blocksize_bits);
@@ -281,16 +285,10 @@ get_new: inum =iunique (sb,EXFAT_ROOT_INO ); } -/* -* Before calling dir_emit(), sb_lock should be released. -* Because page fault can occur in dir_emit() when the size -* of buffer given from user is larger than one page size. -*/ mutex_unlock (&EXFAT_SB (sb)->s_lock);if (!dir_emit (ctx, nb->lfn,strlen (nb->lfn), inum, (de.attr &ATTR_SUBDIR ) ?DT_DIR :DT_REG )) - goto out_unlocked; -mutex_lock (&EXFAT_SB (sb)->s_lock); + goto out; ctx->pos = cpos; goto get_new;
@@ -298,9 +296,8 @@ end_of_dir:if (!cpos && fake_offset) cpos =ITER_POS_FILLED_DOTS ; ctx->pos = cpos; -unlock:mutex_unlock (&EXFAT_SB (sb)->s_lock); -out_unlocked: +out:/* * To improve performance, free namebuf after unlock sb_lock. * If namebuf is not allocated, this function do nothing
Greg Kroah-Hartman
maintainerPATCH 107/165 mtd: spinand: toshiba: Fix ecc_get_status
In reply to Greg Kroah-HartmanFrom: Olivier Maignial <[email protected]>
commit 8544cda94dae6be3f1359539079c68bb731428b1 upstream.
Reading ECC status is failing.
tx58cxgxsxraix_ecc_get_status() is using on-stack buffer for SPINAND_GET_FEATURE_OP() output. It is not suitable for DMA needs of spi-mem.
Fix this by using the spi-mem operations dedicated buffer spinand->scratchbuf.
Seespinand->scratchbuf:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418spi_mem_check_op():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199
--- drivers/mtd/nand/spi/toshiba.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/nand/spi/toshiba.c +2 -2
@@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status {struct nand_device *nand =spinand_to_nand (spinand);u8 mbf =0 ; -struct spi_mem_op op =SPINAND_GET_FEATURE_OP (0x30 , &mbf); +struct spi_mem_op op =SPINAND_GET_FEATURE_OP (0x30 , spinand->scratchbuf);switch (status &STATUS_ECC_MASK ) {case STATUS_ECC_NO_BITFLIPS :
@@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_statusif (spi_mem_exec_op (spinand->spimem, &op))return nanddev_get_ecc_conf (nand)->strength; - mbf >>=4 ; + mbf = *(spinand->scratchbuf) >>4 ;if (WARN_ON (mbf >nanddev_get_ecc_conf (nand)->strength || !mbf))return nanddev_get_ecc_conf (nand)->strength;
Greg Kroah-Hartman
maintainerPATCH 108/165 mtd: spinand: winbond: Fix ecc_get_status
In reply to Greg Kroah-HartmanFrom: Olivier Maignial <[email protected]>
commit f5a05060670a4d8d6523afc7963eb559c2e3615f upstream.
Reading ECC status is failing.
w25n02kv_ecc_get_status() is using on-stack buffer for SPINAND_GET_FEATURE_OP() output. It is not suitable for DMA needs of spi-mem.
Fix this by using the spi-mem operations dedicated buffer spinand->scratchbuf.
Seespinand->scratchbuf:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418spi_mem_check_op():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199
--- drivers/mtd/nand/spi/winbond.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/nand/spi/winbond.c +2 -2
@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struc {struct nand_device *nand =spinand_to_nand (spinand);u8 mbf =0 ; -struct spi_mem_op op =SPINAND_GET_FEATURE_OP (0x30 , &mbf); +struct spi_mem_op op =SPINAND_GET_FEATURE_OP (0x30 , spinand->scratchbuf);switch (status &STATUS_ECC_MASK ) {case STATUS_ECC_NO_BITFLIPS :
@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(strucif (spi_mem_exec_op (spinand->spimem, &op))return nanddev_get_ecc_conf (nand)->strength; - mbf >>=4 ; + mbf = *(spinand->scratchbuf) >>4 ;if (WARN_ON (mbf >nanddev_get_ecc_conf (nand)->strength || !mbf))return nanddev_get_ecc_conf (nand)->strength;
Greg Kroah-Hartman
maintainerPATCH 109/165 mtd: rawnand: meson: fix OOB available bytes for ECC
In reply to Greg Kroah-HartmanFrom: Arseniy Krasnov <[email protected]>
commit 7e6b04f9238eab0f684fafd158c1f32ea65b9eaa upstream.
It is incorrect to calculate number of OOB bytes for ECC engine using some "already known" ECC step size (1024 bytes here). Number of such bytes for ECC engine must be whole OOB except 2 bytes for bad block marker, while proper ECC step size and strength will be selected by ECC logic.
--- drivers/mtd/nand/raw/meson_nand.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/mtd/nand/raw/meson_nand.c +1 -2
@@ -1184,7 +1184,6 @@ static int meson_nand_attach_chip(structstruct meson_nfc *nfc =nand_get_controller_data (nand);struct meson_nfc_nand_chip *meson_chip =to_meson_nand (nand);struct mtd_info *mtd =nand_to_mtd (nand); -int nsectors = mtd->writesize /1024 ;int ret;if (!mtd->name) {
@@ -1202,7 +1201,7 @@ static int meson_nand_attach_chip(struct nand->options |=NAND_NO_SUBPAGE_WRITE ; ret =nand_ecc_choose_conf (nand, nfc->data->ecc_caps, - mtd->oobsize -2 * nsectors); + mtd->oobsize -2 );if (ret) {dev_err (nfc->dev,"failed to ECC init\n" );return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 110/165 riscv: Export va_kernel_pa_offset in vmcoreinfo
In reply to Greg Kroah-HartmanFrom: Song Shuai <[email protected]>
commit fbe7d19d2b7fcbd38905ba9f691be8f245c6faa6 upstream.
Since RISC-V Linux v6.4, the commit 3335068f8721 ("riscv: Use PUD/P4D/PGD pages for the linear mapping") changes phys_ram_base from the physical start of the kernel to the actual start of the DRAM.
The Crash-utility's VTOP() still uses phys_ram_base and kernel_map.virt_addr to translate kernel virtual address, that failed the Crash with Linux v6.4 [1].
Export kernel_map.va_kernel_pa_offset in vmcoreinfo to help Crash translate the kernel virtual address correctly.
--- arch/riscv/kernel/crash_core.c | 2 ++ 1 file changed, 2 insertions(+)
arch/riscv/kernel/crash_core.c +2 -0
@@ -18,4 +18,6 @@ void arch_crash_save_vmcoreinfo(void)vmcoreinfo_append_str ("NUMBER(MODULES_END)=0x%lx\n" ,MODULES_END );#endif vmcoreinfo_append_str ("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n" ,KERNEL_LINK_ADDR ); +vmcoreinfo_append_str ("NUMBER(va_kernel_pa_offset)=0x%lx\n" , + kernel_map.va_kernel_pa_offset); }
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 111/165 bpf: Disable preemption in bpf_perf_event_output
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
commit f2c67a3e60d1071b65848efaa8c3b66c363dd025 upstream.
The nesting protection in bpf_perf_event_output relies on disabled preemption, which is guaranteed for kprobes and tracepoints.
However bpf_perf_event_output can be also called from uprobes context through bpf_prog_run_array_sleepable function which disables migration, but keeps preemption enabled.
This can cause task to be preempted by another one inside the nesting protection and lead eventually to two tasks using same perf_sample_data buffer and cause crashes like:
kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
BUG: unable to handle page fault for address: ffffffff82be3eea ... Call Trace: ? __die+0x1f/0x70 ? page_fault_oops+0x176/0x4d0 ? exc_page_fault+0x132/0x230 ? asm_exc_page_fault+0x22/0x30 ? perf_output_sample+0x12b/0x910 ? perf_event_output+0xd0/0x1d0 ? bpf_perf_event_output+0x162/0x1d0 ? bpf_prog_c6271286d9a4c938_krava1+0x76/0x87 ? __uprobe_perf_func+0x12b/0x540 ? uprobe_dispatcher+0x2c4/0x430 ? uprobe_notify_resume+0x2da/0xce0 ? atomic_notifier_call_chain+0x7b/0x110 ? exit_to_user_mode_prepare+0x13e/0x290 ? irqentry_exit_to_user_mode+0x5/0x30 ? asm_exc_int3+0x35/0x40
Fixing this by disabling preemption in bpf_perf_event_output.
--- kernel/trace/bpf_trace.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/trace/bpf_trace.c +7 -4
@@ -661,8 +661,7 @@ static DEFINE_PER_CPU(int, bpf_trace_nes BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, u64, flags, void *, data, u64, size) { -struct bpf_trace_sample_data *sds =this_cpu_ptr (&bpf_trace_sds); -int nest_level =this_cpu_inc_return (bpf_trace_nest_level); +struct bpf_trace_sample_data *sds;struct perf_raw_record raw = { .frag = { .size = size,
@@ -670,7 +669,11 @@ BPF_CALL_5(bpf_perf_event_output, struct }, };struct perf_sample_data *sd; -int err; +int nest_level, err; + +preempt_disable (); + sds =this_cpu_ptr (&bpf_trace_sds); + nest_level =this_cpu_inc_return (bpf_trace_nest_level);if (WARN_ON_ONCE (nest_level >ARRAY_SIZE (sds->sds))) { err = -EBUSY ;
@@ -688,9 +691,9 @@ BPF_CALL_5(bpf_perf_event_output, structperf_sample_save_raw_data (sd, &raw); err =__bpf_perf_event_output (regs, map, flags, sd); - out:this_cpu_dec (bpf_trace_nest_level); +preempt_enable ();return err; }
Greg Kroah-Hartman
maintainerPATCH 112/165 arm64: dts: stratix10: fix incorrect I2C property for SCL signal
In reply to Greg Kroah-HartmanFrom: Dinh Nguyen <[email protected]>
commit db66795f61354c373ecdadbdae1ed253a96c47cb upstream.
The correct dts property for the SCL falling time is "i2c-scl-falling-time-ns".
--- arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts | 2 +- arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +1 -1
@@ -145,7 +145,7 @@ status = "okay"; clock-frequency = <100000>; i2c-sda-falling-time-ns = <890>; /* hcnt */ - i2c-sdl-falling-time-ns = <890>; /* lcnt */ + i2c-scl-falling-time-ns = <890>; /* lcnt */ pinctrl-names = "default", "gpio"; pinctrl-0 = <&i2c1_pmx_func>;
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts +1 -1
@@ -141,7 +141,7 @@ status = "okay"; clock-frequency = <100000>; i2c-sda-falling-time-ns = <890>; /* hcnt */ - i2c-sdl-falling-time-ns = <890>; /* lcnt */ + i2c-scl-falling-time-ns = <890>; /* lcnt */ adc@14 { compatible = "lltc,ltc2497";
Greg Kroah-Hartman
maintainerPATCH 113/165 net: tun_chr_open(): set sk_uid from current_fsuid()
In reply to Greg Kroah-HartmanFrom: Laszlo Ersek <[email protected]>
commit 9bc3047374d5bec163e83e743709e23753376f0c upstream.
Commit a096ccca6e50 initializes the "sk_uid" field in the protocol socket (struct sock) from the "/dev/net/tun" device node's owner UID. Per original commit 86741ec25462 ("net: core: Add a UID field to struct sock.", 2016-11-04), that's wrong: the idea is to cache the UID of the userspace process that creates the socket. Commit 86741ec25462 mentions socket() and accept(); with "tun", the action that creates the socket is open("/dev/net/tun").
Therefore the device node's owner UID is irrelevant. In most cases, "/dev/net/tun" will be owned by root, so in practice, commit a096ccca6e50 has no observable effect:
- before, "sk_uid" would be zero, due to undefined behavior (CVE-2023-1076),
- after, "sk_uid" would be zero, due to "/dev/net/tun" being owned by root.
What matters is the (fs)UID of the process performing the open(), so cache that in "sk_uid".
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2173435
--- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/tun.c +1 -1
@@ -3469,7 +3469,7 @@ static int tun_chr_open(struct inode *in tfile->socket.file = file; tfile->socket.ops = &tun_socket_ops; -sock_init_data_uid (&tfile->socket, &tfile->sk, inode->i_uid); +sock_init_data_uid (&tfile->socket, &tfile->sk,current_fsuid ()); tfile->sk.sk_write_space = tun_sock_write_space; tfile->sk.sk_sndbuf =INT_MAX ;
Greg Kroah-Hartman
maintainerPATCH 114/165 net: tap_open(): set sk_uid from current_fsuid()
In reply to Greg Kroah-HartmanFrom: Laszlo Ersek <[email protected]>
commit 5c9241f3ceab3257abe2923a59950db0dc8bb737 upstream.
Commit 66b2c338adce initializes the "sk_uid" field in the protocol socket (struct sock) from the "/dev/tapX" device node's owner UID. Per original commit 86741ec25462 ("net: core: Add a UID field to struct sock.", 2016-11-04), that's wrong: the idea is to cache the UID of the userspace process that creates the socket. Commit 86741ec25462 mentions socket() and accept(); with "tap", the action that creates the socket is open("/dev/tapX").
Therefore the device node's owner UID is irrelevant. In most cases, "/dev/tapX" will be owned by root, so in practice, commit 66b2c338adce has no observable effect:
- before, "sk_uid" would be zero, due to undefined behavior (CVE-2023-1076),
- after, "sk_uid" would be zero, due to "/dev/tapX" being owned by root.
What matters is the (fs)UID of the process performing the open(), so cache that in "sk_uid".
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2173435
--- drivers/net/tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/tap.c +1 -1
@@ -534,7 +534,7 @@ static int tap_open(struct inode *inode, q->sock.state =SS_CONNECTED ; q->sock.file = file; q->sock.ops = &tap_socket_ops; -sock_init_data_uid (&q->sock, &q->sk, inode->i_uid); +sock_init_data_uid (&q->sock, &q->sk,current_fsuid ()); q->sk.sk_write_space = tap_sock_write_space; q->sk.sk_destruct = tap_sock_destruct; q->flags =IFF_VNET_HDR |IFF_NO_PI |IFF_TAP ;
Greg Kroah-Hartman
maintainerPATCH 115/165 wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)
In reply to Greg Kroah-HartmanFrom: Paul Fertser <[email protected]>
commit 421033deb91521aa6a9255e495cb106741a52275 upstream.
On DBDC devices the first (internal) phy is only capable of using 2.4 GHz band, and the 5 GHz band is exposed via a separate phy object, so avoid the false advertising.
--- drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +3 -3
@@ -128,12 +128,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mcase MT_EE_5GHZ : dev->mphy.cap.has_5ghz = true;break ; -case MT_EE_2GHZ : - dev->mphy.cap.has_2ghz = true; -break ;case MT_EE_DBDC : dev->dbdc_support = true; fallthrough; +case MT_EE_2GHZ : + dev->mphy.cap.has_2ghz = true; +break ;default : dev->mphy.cap.has_2ghz = true; dev->mphy.cap.has_5ghz = true;
Greg Kroah-Hartman
maintainerPATCH 116/165 x86/hyperv: Disable IBT when hypercall page lacks ENDBR instruction
In reply to Greg Kroah-HartmanFrom: Michael Kelley <[email protected]>
commit d5ace2a776442d80674eff9ed42e737f7dd95056 upstream.
On hardware that supports Indirect Branch Tracking (IBT), Hyper-V VMs with ConfigVersion 9.3 or later support IBT in the guest. However, current versions of Hyper-V have a bug in that there's not an ENDBR64 instruction at the beginning of the hypercall page. Since hypercalls are made with an indirect call to the hypercall page, all hypercall attempts fail with an exception and Linux panics.
A Hyper-V fix is in progress to add ENDBR64. But guard against the Linux panic by clearing X86_FEATURE_IBT if the hypercall page doesn't start with ENDBR. The VM will boot and run without IBT.
If future Linux 32-bit kernels were to support IBT, additional hypercall page hackery would be needed to make IBT work for such kernels in a Hyper-V VM.
--- arch/x86/hyperv/hv_init.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
arch/x86/hyperv/hv_init.c +21 -0
@@ -14,6 +14,7 @@#include <asm/apic.h> #include <asm/desc.h> #include <asm/sev.h> +#include <asm/ibt.h> #include <asm/hypervisor.h> #include <asm/hyperv-tlfs.h> #include <asm/mshyperv.h>
@@ -472,6 +473,26 @@ void __init hyperv_init(void) }/* +* Some versions of Hyper-V that provide IBT in guest VMs have a bug +* in that there's no ENDBR64 instruction at the entry to the +* hypercall page. Because hypercalls are invoked via an indirect call +* to the hypercall page, all hypercall attempts fail when IBT is +* enabled, and Linux panics. For such buggy versions, disable IBT. +* +* Fixed versions of Hyper-V always provide ENDBR64 on the hypercall +* page, so if future Linux kernel versions enable IBT for 32-bit +* builds, additional hypercall page hackery will be required here +* to provide an ENDBR32. +*/ +#ifdef CONFIG_X86_KERNEL_IBT +if (cpu_feature_enabled (X86_FEATURE_IBT ) && + *(u32 *)hv_hypercall_pg !=gen_endbr ()) { +setup_clear_cpu_cap (X86_FEATURE_IBT ); +pr_warn ("Hyper-V: Disabling IBT because of Hyper-V bug\n" ); + } +#endif + +/* * hyperv_init() is called before LAPIC is initialized: see * apic_intr_mode_init() -> x86_platform.apic_post_init() and * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER
Greg Kroah-Hartman
maintainerPATCH 117/165 rbd: prevent busy loop when requesting exclusive lock
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit 9d01e07fd1bfb4daae156ab528aa196f5ac2b2bc upstream.
Due to rbd_try_acquire_lock() effectively swallowing all but EBLOCKLISTED error from rbd_try_lock() ("request lock anyway") and rbd_request_lock() returning ETIMEDOUT error not only for an actual notify timeout but also when the lock owner doesn't respond, a busy loop inside of rbd_acquire_lock() between rbd_try_acquire_lock() and rbd_request_lock() is possible.
Requesting the lock on EBUSY error (returned by get_lock_owner_info() if an incompatible lock or invalid lock owner is detected) makes very little sense. The same goes for ETIMEDOUT error (might pop up pretty much anywhere if osd_request_timeout option is set) and many others.
Just fail I/O requests on rbd_dev->acquiring_list immediately on any error from rbd_try_lock().
--- drivers/block/rbd.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
drivers/block/rbd.c +15 -13
@@ -3675,7 +3675,7 @@ static int rbd_lock(struct rbd_device *r ret =ceph_cls_lock (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME ,CEPH_CLS_LOCK_EXCLUSIVE , cookie,RBD_LOCK_TAG ,"" ,0 ); -if (ret) +if (ret && ret != -EEXIST )return ret;__rbd_lock (rbd_dev, cookie);
@@ -3878,7 +3878,7 @@ static struct ceph_locker *get_lock_owne &rbd_dev->header_oloc,RBD_LOCK_NAME , &lock_type, &lock_tag, &lockers, &num_lockers);if (ret) { -rbd_warn (rbd_dev,"failed to retrieve lockers: %d" , ret); +rbd_warn (rbd_dev,"failed to get header lockers: %d" , ret);return ERR_PTR (ret); }
@@ -3940,8 +3940,10 @@ static int find_watcher(struct rbd_devic ret =ceph_osdc_list_watchers (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, &watchers, &num_watchers); -if (ret) +if (ret) { +rbd_warn (rbd_dev,"failed to get watchers: %d" , ret);return ret; + }sscanf (locker->id.cookie,RBD_LOCK_COOKIE_PREFIX " %llu" , &cookie);for (i =0 ; i < num_watchers; i++) {
@@ -3985,8 +3987,12 @@ static int rbd_try_lock(struct rbd_devic locker = refreshed_locker =NULL ; ret =rbd_lock (rbd_dev); -if (ret != -EBUSY ) +if (!ret) + goto out; +if (ret != -EBUSY ) { +rbd_warn (rbd_dev,"failed to lock header: %d" , ret); goto out; + }/* determine if the current lock holder is still alive */ locker =get_lock_owner_info (rbd_dev);
@@ -4089,11 +4095,8 @@ static int rbd_try_acquire_lock(struct r ret =rbd_try_lock (rbd_dev);if (ret <0 ) { -rbd_warn (rbd_dev,"failed to lock header: %d" , ret); -if (ret == -EBLOCKLISTED ) - goto out; - - ret =1 ;/* request lock anyway */ +rbd_warn (rbd_dev,"failed to acquire lock: %d" , ret); + goto out; }if (ret >0 ) {up_write (&rbd_dev->lock_rwsem);
@@ -6627,12 +6630,11 @@ static int rbd_add_acquire_lock(struct rcancel_delayed_work_sync (&rbd_dev->lock_dwork);if (!ret) ret = -ETIMEDOUT ; - } -if (ret) { -rbd_warn (rbd_dev,"failed to acquire exclusive lock: %ld" , ret); -return ret; +rbd_warn (rbd_dev,"failed to acquire lock: %ld" , ret); } +if (ret) +return ret;/* * The lock may have been released by now, unless automatic lock
Greg Kroah-Hartman
maintainerPATCH 118/165 bpf: Disable preemption in bpf_event_output
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
commit d62cc390c2e99ae267ffe4b8d7e2e08b6c758c32 upstream.
We received report [1] of kernel crash, which is caused by using nesting protection without disabled preemption.
The bpf_event_output can be called by programs executed by bpf_prog_run_array_cg function that disabled migration but keeps preemption enabled.
This can cause task to be preempted by another one inside the nesting protection and lead eventually to two tasks using same perf_sample_data buffer and cause crashes like:
BUG: kernel NULL pointer dereference, address: 0000000000000001 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page ... ? perf_output_sample+0x12a/0x9a0 ? finish_task_switch.isra.0+0x81/0x280 ? perf_event_output+0x66/0xa0 ? bpf_event_output+0x13a/0x190 ? bpf_event_output_data+0x22/0x40 ? bpf_prog_dfc84bbde731b257_cil_sock4_connect+0x40a/0xacb ? xa_load+0x87/0xe0 ? __cgroup_bpf_run_filter_sock_addr+0xc1/0x1a0 ? release_sock+0x3e/0x90 ? sk_setsockopt+0x1a1/0x12f0 ? udp_pre_connect+0x36/0x50 ? inet_dgram_connect+0x93/0xa0 ? __sys_connect+0xb4/0xe0 ? udp_setsockopt+0x27/0x40 ? __pfx_udp_push_pending_frames+0x10/0x10 ? __sys_setsockopt+0xdf/0x1a0 ? __x64_sys_connect+0xf/0x20 ? do_syscall_64+0x3a/0x90 ? entry_SYSCALL_64_after_hwframe+0x72/0xdc
Fixing this by disabling preemption in bpf_event_output.
[1] https://github.com/cilium/cilium/issues/26756
--- kernel/trace/bpf_trace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/trace/bpf_trace.c +5 -1
@@ -718,7 +718,6 @@ static DEFINE_PER_CPU(struct bpf_trace_su64 bpf_event_output (struct bpf_map *map,u64 flags,void *meta,u64 meta_size,void *ctx,u64 ctx_size,bpf_ctx_copy_t ctx_copy) { -int nest_level =this_cpu_inc_return (bpf_event_output_nest_level);struct perf_raw_frag frag = { .copy = ctx_copy, .size = ctx_size,
@@ -735,8 +734,12 @@ u64 bpf_event_output(struct bpf_map *map };struct perf_sample_data *sd;struct pt_regs *regs; +int nest_level;u64 ret; +preempt_disable (); + nest_level =this_cpu_inc_return (bpf_event_output_nest_level); +if (WARN_ON_ONCE (nest_level >ARRAY_SIZE (bpf_misc_sds.sds))) { ret = -EBUSY ; goto out;
@@ -751,6 +754,7 @@ u64 bpf_event_output(struct bpf_map *map ret =__bpf_perf_event_output (regs, map, flags, sd); out:this_cpu_dec (bpf_event_output_nest_level); +preempt_enable ();return ret; }
Greg Kroah-Hartman
maintainerPATCH 119/165 smb: client: fix dfs link mount against w2k8
In reply to Greg Kroah-HartmanFrom: Paulo Alcantara <[email protected]>
commit 11260c3d608b59231f4c228147a795ab21a10b33 upstream.
Customer reported that they couldn't mount their DFS link that was seen by the client as a DFS interlink -- special form of DFS link where its single target may point to a different DFS namespace -- and it turned out that it was just a regular DFS link where its referral header flags missed the StorageServers bit thus making the client think it couldn't tree connect to target directly without requiring further referrals.
When the DFS link referral header flags misses the StoraServers bit and its target doesn't respond to any referrals, then tree connect to it.
--- fs/smb/client/dfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/smb/client/dfs.c +5 -1
@@ -178,8 +178,12 @@ static int __dfs_mount_share(struct cifsstruct dfs_cache_tgt_list tl =DFS_CACHE_TGT_LIST_INIT (tl); rc =dfs_get_referral (mnt_ctx, ref_path +1 ,NULL , &tl); -if (rc) +if (rc) { + rc =cifs_mount_get_tcon (mnt_ctx); +if (!rc) + rc =cifs_is_path_remote (mnt_ctx);break ; + } tit =dfs_cache_get_tgt_iterator (&tl);if (!tit) {
Greg Kroah-Hartman
maintainerPATCH 120/165 powerpc/ftrace: Create a dummy stackframe to fix stack unwind
In reply to Greg Kroah-HartmanFrom: Naveen N Rao <[email protected]>
commit 41a506ef71eb38d94fe133f565c87c3e06ccc072 upstream.
With ppc64 -mprofile-kernel and ppc32 -pg, profiling instructions to call into ftrace are emitted right at function entry. The instruction sequence used is minimal to reduce overhead. Crucially, a stackframe is not created for the function being traced. This breaks stack unwinding since the function being traced does not have a stackframe for itself. As such, it never shows up in the backtrace:
/sys/kernel/debug/tracing # echo 1 > /proc/sys/kernel/stack_tracer_enabled /sys/kernel/debug/tracing # cat stack_trace
Depth Size Location (17 entries)
----- ---- --------
0) 4144 32 ftrace_call+0x4/0x44
1) 4112 432 get_page_from_freelist+0x26c/0x1ad0
2) 3680 496 __alloc_pages+0x290/0x1280
3) 3184 336 __folio_alloc+0x34/0x90
4) 2848 176 vma_alloc_folio+0xd8/0x540
5) 2672 272 __handle_mm_fault+0x700/0x1cc0
6) 2400 208 handle_mm_fault+0xf0/0x3f0
7) 2192 80 ___do_page_fault+0x3e4/0xbe0
8) 2112 160 do_page_fault+0x30/0xc0
9) 1952 256 data_access_common_virt+0x210/0x220
10) 1696 400 0xc00000000f16b100
11) 1296 384 load_elf_binary+0x804/0x1b80
12) 912 208 bprm_execve+0x2d8/0x7e0
13) 704 64 do_execveat_common+0x1d0/0x2f0
14) 640 160 sys_execve+0x54/0x70
15) 480 64 system_call_exception+0x138/0x350
16) 416 416 system_call_common+0x160/0x2c4Fix this by having ftrace create a dummy stackframe for the function being traced. With this, backtraces now capture the function being traced:
/sys/kernel/debug/tracing # cat stack_trace
Depth Size Location (17 entries)
----- ---- --------
0) 3888 32 _raw_spin_trylock+0x8/0x70
1) 3856 576 get_page_from_freelist+0x26c/0x1ad0
2) 3280 64 __alloc_pages+0x290/0x1280
3) 3216 336 __folio_alloc+0x34/0x90
4) 2880 176 vma_alloc_folio+0xd8/0x540
5) 2704 416 __handle_mm_fault+0x700/0x1cc0
6) 2288 96 handle_mm_fault+0xf0/0x3f0
7) 2192 48 ___do_page_fault+0x3e4/0xbe0
8) 2144 192 do_page_fault+0x30/0xc0
9) 1952 608 data_access_common_virt+0x210/0x220
10) 1344 16 0xc0000000334bbb50
11) 1328 416 load_elf_binary+0x804/0x1b80
12) 912 64 bprm_execve+0x2d8/0x7e0
13) 848 176 do_execveat_common+0x1d0/0x2f0
14) 672 192 sys_execve+0x54/0x70
15) 480 64 system_call_exception+0x138/0x350
16) 416 416 system_call_common+0x160/0x2c4This results in two additional stores in the ftrace entry code, but produces reliable backtraces.
--- arch/powerpc/kernel/trace/ftrace_mprofile.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/kernel/trace/ftrace_mprofile.S +7 -2
@@ -33,6 +33,9 @@ * and then arrange for the ftrace function to be called. */ .macro ftrace_regs_entry allregs + /* Create a minimal stack frame for representing B */ + PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1) + /* Create our stack frame + pt_regs */ PPC_STLU r1,-SWITCH_FRAME_SIZE(r1)
@@ -42,7 +45,7 @@ #ifdef CONFIG_PPC64 /* Save the original return address in A's stack frame */ - std r0, LRSAVE+SWITCH_FRAME_SIZE(r1) + std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1) /* Ok to continue? */ lbz r3, PACA_FTRACE_ENABLED(r13) cmpdi r3, 0
@@ -77,6 +80,8 @@ mflr r7 /* Save it as pt_regs->nip */ PPC_STL r7, _NIP(r1) + /* Also save it in B's stackframe header for proper unwind */ + PPC_STL r7, LRSAVE+SWITCH_FRAME_SIZE(r1) /* Save the read LR in pt_regs->link */ PPC_STL r0, _LINK(r1)
@@ -142,7 +147,7 @@ #endif /* Pop our stack frame */ - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE #ifdef CONFIG_LIVEPATCH_64 /* Based on the cmpd above, if the NIP was altered handle livepatch */