Skip to contentSkip to conversation

6.5.12-rc1 review

PATCH In review Greg Kroah-Hartman 8 participants 559 messages Nov 15, 2023 – Nov 17, 2023 Page 1 of 5

Subsystems (7)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.5.12-rc1 review

This is the start of the stable review cycle for the 6.5.12 release. There are 550 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, 17 Nov 2023 19:14:03 +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.5.12-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.5.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 6.5.12-rc1

Qu Wenruo <[email protected]>
btrfs: make found_logical_ret parameter mandatory for function queue_scrub_stripe()

Filipe Manana <[email protected]>
btrfs: use u64 for buffer sizes in the tree search ioctls

Dominique Martinet <[email protected]>
Revert "mmc: core: Capture correct oemid-bits for eMMC cards"

Heiner Kallweit <[email protected]>
Revert "PCI/ASPM: Disable only ASPM_STATE_L1 when driver, disables L1"

Yazen Ghannam <[email protected]>
x86/amd_nb: Use Family 19h Models 60h-7Fh Function 4 IDs

Jens Axboe <[email protected]>
io_uring/net: ensure socket is marked connected on connect retry

Geliang Tang <[email protected]>
selftests: mptcp: fix wait_rm_addr/sf parameters

Sasha Levin <[email protected]>
Revert "drm/ast: report connection status on Display Port."

Yujie Liu <[email protected]>
tracing/kprobes: Fix the order of argument descriptions

Arnd Bergmann <[email protected]>
fbdev: fsl-diu-fb: mark wr_reg_wa() static

Kailang Yang <[email protected]>
ALSA: hda/realtek: Add support dual speaker for Dell

Dan Carpenter <[email protected]>
fbdev: imsttfb: fix a resource leak in probe

Dan Carpenter <[email protected]>
fbdev: imsttfb: fix double free in probe()

Ilkka Koskinen <[email protected]>
arm64/arm: arm_pmuv3: perf: Don't truncate 64-bit registers

Amit Kumar Mahapatra <[email protected]>
spi: spi-zynq-qspi: add spi-mem to driver kconfig dependencies

Jerome Brunet <[email protected]>
ASoC: dapm: fix clock get name

Jerome Brunet <[email protected]>
ASoC: hdmi-codec: register hpd callback on component probe

Eugen Hristev <[email protected]>

    ASoC: mediatek: mt8186_mt6366_rt1019_rt5682s: trivial: fix error messages

Erik Kurzinger <[email protected]>
drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE

Maxime Ripard <[email protected]>
drm/vc4: tests: Fix UAF in the mock helpers

Andrea Righi <[email protected]>
module/decompress: use kvmalloc() consistently

Anup Patel <[email protected]>
RISC-V: Don't fail in riscv_of_parent_hartid() for disabled HARTs

Vlad Buslov <[email protected]>
net/sched: act_ct: Always fill offloading tuple iifidx

Florian Westphal <[email protected]>
netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses

Maciej Żenczykowski <[email protected]>
netfilter: xt_recent: fix (increase) ipv6 literal buffer length

Roman Bacik <[email protected]>
i2c: iproc: handle invalid slave state

Vladimir Oltean <[email protected]>
net: enetc: shorten enetc_setup_xdp_prog() error message to fit NETLINK_MAX_FMTMSG_LEN

Heiner Kallweit <[email protected]>
r8169: respect userspace disabling IFF_MULTICAST

Filippo Storniolo <[email protected]>
vsock/virtio: remove socket from connected/bound list on shutdown

Yu Kuai <[email protected]>
blk-core: use pr_warn_ratelimited() in bio_check_ro()

Li Lingfeng <[email protected]>
nbd: fix uaf in nbd_open

George Shuklin <[email protected]>
tg3: power down device only on SYSTEM_POWER_OFF

Geert Uytterhoeven <[email protected]>
riscv: boot: Fix creation of loader.bin

Anuj Gupta <[email protected]>
nvme: fix error-handling for io_uring nvme-passthrough

D. Wythe <[email protected]>
net/smc: put sk reference if close work was canceled

D. Wythe <[email protected]>
net/smc: allow cdc msg send rather than drop it with NULL sndbuf_desc

D. Wythe <[email protected]>
net/smc: fix dangling sock under state SMC_APPFINCLOSEWAIT

Geetha sowjanya <[email protected]>
octeontx2-pf: Free pending and dropped SQEs

Hangbin Liu <[email protected]>
selftests: pmtu.sh: fix result checking

Furong Xu <[email protected]>
net: stmmac: xgmac: Enable support for multiple Flexible PPS outputs

NeilBrown <[email protected]>
Fix termination state for idr_for_each_entry_ul()

Patrick Thompson <[email protected]>
net: r8169: Disable multicast filter for RTL8168H and RTL8107E

Kuniyuki Iwashima <[email protected]>
dccp/tcp: Call security_inet_conn_request() after setting IPv6 addresses.

Kuniyuki Iwashima <[email protected]>
dccp: Call security_inet_conn_request() after setting IPv4 addresses.

Jian Shen <[email protected]>
net: page_pool: add missing free_percpu when page_pool_init fail

Ratheesh Kannoth <[email protected]>
octeontx2-pf: Fix holes in error code

Ratheesh Kannoth <[email protected]>
octeontx2-pf: Fix error codes

Eric Dumazet <[email protected]>
inet: shrink struct flowi_common

Hou Tao <[email protected]>

    bpf: Check map->usercnt after timer->timer is assigned

David Howells <[email protected]>
rxrpc: Fix two connection reaping bugs

Shigeru Yoshida <[email protected]>
tipc: Change nla_policy for bearer-related names to NLA_NUL_STRING

Dan Carpenter <[email protected]>
hsr: Prevent use after free in prp_create_tagged_frame()

Willem de Bruijn <[email protected]>
llc: verify mac len before reading mac header

Linus Walleij <[email protected]>
watchdog: ixp4xx: Make sure restart always works

Dan Carpenter <[email protected]>
Input: synaptics-rmi4 - fix use after free in rmi_unregister_function()

Florian Fainelli <[email protected]>
pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume

Uwe Kleine-König <[email protected]>
pwm: sti: Reduce number of allocations and drop usage of chip_data

Alex Deucher <[email protected]>
drm/amdgpu: don't put MQDs in VRAM on ARM | ARM64

Alex Deucher <[email protected]>
drm/amdgpu/gfx10,11: use memcpy_to/fromio for MQDs

Ben Wolsieffer <[email protected]>
regmap: prevent noinc writes from clobbering cache

Vegard Nossum <[email protected]>
cpupower: fix reference to nonexistent document

Marek Szyprowski <[email protected]>
media: cec: meson: always include meson sub-directory in Makefile

Moudy Ho <[email protected]>
media: platform: mtk-mdp3: fix uninitialized variable in mdp_path_config()

Ming Qian <[email protected]>
media: imx-jpeg: notify source chagne event when the first picture parsed

Benjamin Gaignard <[email protected]>
media: verisilicon: Fixes clock list for rk3588 av1 decoder

Hans Verkuil <[email protected]>
media: dvb-usb-v2: af9035: fix missing unlock

Pratyush Yadav <[email protected]>
media: cadence: csi2rx: Unregister v4l2 async notifier

Jernej Skrabec <[email protected]>
media: cedrus: Fix clock/reset sequence

Jiasheng Jiang <[email protected]>
media: vidtv: mux: Add check and kfree for kstrdup

Jiasheng Jiang <[email protected]>
media: vidtv: psi: Add check for kstrdup

Katya Orlova <[email protected]>
media: s3c-camif: Avoid inappropriate kfree()

Fei Shao <[email protected]>
media: mtk-jpegenc: Fix bug in JPEG encode quality selection

Ming Qian <[email protected]>
media: amphion: handle firmware debug message

Zheng Wang <[email protected]>

    media: bttv: fix use after free error due to btv->timeout timer

Xiaolei Wang <[email protected]>
media: ov5640: Fix a memory leak when ov5640_probe fails

Christophe JAILLET <[email protected]>
media: i2c: max9286: Fix some redundant of_node_put() calls

Guoniu.zhou <[email protected]>
media: ov5640: fix vblank unchange issue when work at dvp mode

Marek Vasut <[email protected]>
media: verisilicon: Do not enable G2 postproc downscale if source is narrower than destination

Marek Vasut <[email protected]>
media: hantro: Check whether reset op is defined before use

Ming Qian <[email protected]>
media: imx-jpeg: initiate a drain of the capture queue in dynamic resolution change

Yang Yingliang <[email protected]>
pcmcia: ds: fix possible name leak in error path in pcmcia_device_add()

Yang Yingliang <[email protected]>
pcmcia: ds: fix refcount leak in pcmcia_device_add()

Yang Yingliang <[email protected]>
pcmcia: cs: fix possible hung task and memory leak pccardd()

Dan Williams <[email protected]>
cxl/hdm: Remove broken error path

Dan Williams <[email protected]>
cxl/port: Fix @host confusion in cxl_dport_setup_regs()

Robert Richter <[email protected]>
cxl/core/regs: Rename @dev to @host in struct cxl_register_map

Li Zhijian <[email protected]>
cxl/region: Fix cxl_region_rwsem lock held when returning to user space

Alison Schofield <[email protected]>
cxl/region: Use cxl_calc_interleave_pos() for auto-discovery

Alison Schofield <[email protected]>
cxl/region: Calculate a target position in a region interleave

Alison Schofield <[email protected]>
cxl/region: Prepare the decoder match range helper for reuse

Javier Carrasco <[email protected]>
rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits call

Mike Looijmans <[email protected]>
rtc: pcf85363: Allow to wake up system without IRQ

Dan Williams <[email protected]>
virt: sevguest: Fix passing a stack buffer as a scatterlist target

Dan Williams <[email protected]>
cxl/mem: Fix shutdown order

Dan Williams <[email protected]>
cxl/memdev: Fix sanitize vs decoder setup locking

Dan Williams <[email protected]>
cxl/pci: Fix sanitize notifier setup

Dan Williams <[email protected]>
cxl/pci: Clarify devm host for memdev relative setup

Dan Williams <[email protected]>
cxl/pci: Remove inconsistent usage of dev_err_probe()

Dan Williams <[email protected]>
cxl/pci: Cleanup 'sanitize' to always poll

Dan Williams <[email protected]>
cxl/pci: Remove unnecessary device reference management in sanitize work

Doug Berger <[email protected]>
rtc: brcmstb-waketimer: support level alarm_irq

Dinghao Liu <[email protected]>
i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs

Colin Ian King <[email protected]>
rtla: Fix uninitialized variable found

Hangyu Hua <[email protected]>
9p/net: fix possible memory leak in p9_check_errors()

Ian Rogers <[email protected]>
perf vendor events intel: Add broadwellde two metrics

Ian Rogers <[email protected]>
perf vendor events intel: Fix broadwellde tma_info_system_dram_bw_use metric

Ian Rogers <[email protected]>
perf hist: Add missing puts to hist__account_cycles

Ian Rogers <[email protected]>
libperf rc_check: Make implicit enabling work for GCC

Ian Rogers <[email protected]>
perf machine: Avoid out of bounds LBR memory read

Sergey Shtylyov <[email protected]>
usb: host: xhci-plat: fix possible kernel oops while resuming

Basavaraj Natikar <[email protected]>
xhci: Loosen RPM as default policy to cover for AMD xHC 1.1

Kajol Jain <[email protected]>
perf vendor events: Update PMC used in PM_RUN_INST_CMPL event for power10 platform

Wang Yufen <[email protected]>
powerpc/pseries: fix potential memory leak in init_cpu_associativity()

Sebastian Andrzej Siewior <[email protected]>
powerpc/imc-pmu: Use the correct spinlock initializer.

Haren Myneni <[email protected]>
powerpc/vas: Limit open window failure messages in log bufffer

Thomas Richter <[email protected]>
perf trace: Use the right bpf_probe_read(_str) variant for reading user data

Michael Ellerman <[email protected]>
powerpc: Hide empty pt_regs at base of the stack

Benjamin Gray <[email protected]>
powerpc/xive: Fix endian conversion size

Christophe Leroy <[email protected]>

    powerpc/40x: Remove stale PTE_ATOMIC_UPDATES macro

Namhyung Kim <[email protected]>
perf tools: Do not ignore the default vmlinux.h

Masahiro Yamada <[email protected]>
modpost: fix ishtp MODULE_DEVICE_TABLE built on big-endian host

Masahiro Yamada <[email protected]>
modpost: fix tee MODULE_DEVICE_TABLE built on big-endian host

Harald Freudenberger <[email protected]>
s390/ap: re-init AP queues on config on

Ian Rogers <[email protected]>
perf mem-events: Avoid uninitialized read

Ian Rogers <[email protected]>
perf pmu: Remove logic for PMU name being NULL

Ian Rogers <[email protected]>
perf parse-events: Fix for term values that are raw events

Arnaldo Carvalho de Melo <[email protected]>
perf build: Add missing comment about NO_LIBTRACEEVENT=1

Yang Yingliang <[email protected]>
interconnect: fix error handling in qnoc_probe()

Christophe Leroy <[email protected]>
powerpc: Only define __parse_fpscr() when required

Konrad Dybcio <[email protected]>
interconnect: qcom: sm8350: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sm8350: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>
interconnect: qcom: sm8150: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sm8150: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>
interconnect: qcom: sm6350: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sm6350: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>
interconnect: qcom: sdm845: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sdm845: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>
interconnect: qcom: sdm670: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sdm670: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>

    interconnect: qcom: sc8280xp: Set ACV enable_mask

Konrad Dybcio <[email protected]>

    interconnect: qcom: sc8180x: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sc7280: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sc7180: Set ACV enable_mask

Konrad Dybcio <[email protected]>
interconnect: qcom: sc7180: Retire DEFINE_QBCM

Konrad Dybcio <[email protected]>
interconnect: qcom: qdu1000: Set ACV enable_mask

Chao Yu <[email protected]>
f2fs: fix to initialize map.m_pblk in f2fs_precache_extents()

Christophe JAILLET <[email protected]>
dmaengine: pxa_dma: Remove an erroneous BUG_ON() in pxad_free_desc()

Jonas Blixt <[email protected]>
USB: usbip: fix stub_dev hub disconnect

Matti Vaittinen <[email protected]>
tools: iio: iio_generic_buffer ensure alignment

Jinjie Ruan <[email protected]>
misc: st_core: Do not call kfree_skb() under spin_lock_irqsave()

Kajol Jain <[email protected]>
tools/perf: Update call stack check in builtin-lock.c

Dan Carpenter <[email protected]>
dmaengine: ti: edma: handle irq_of_parse_and_map() errors

Michał Mirosław <[email protected]>
usb: chipidea: Simplify Tegra DMA alignment code

Michał Mirosław <[email protected]>
usb: chipidea: Fix DMA overwrite for Tegra

Jia-Ju Bai <[email protected]>
usb: dwc2: fix possible NULL pointer dereference caused by driver concurrency

Fenghua Yu <[email protected]>
dmaengine: idxd: Register dsa_bus_type before registering idxd sub-drivers

Namhyung Kim <[email protected]>
perf record: Fix BTF type checks in the off-cpu profiling

Biju Das <[email protected]>
pinctrl: renesas: rzg2l: Make reverse order of enable() for disable()

Zheng Yejian <[email protected]>
livepatch: Fix missing newline character in klp_resolve_symbols()

Ian Rogers <[email protected]>
perf parse-events: Fix tracepoint name memory leak

Ian Rogers <[email protected]>
perf tools: Revert enable indices setting syntax for BPF map

Ian Rogers <[email protected]>
perf parse-events: Remove ABORT_ON

Ian Rogers <[email protected]>
perf parse-events: Remove unused PE_KERNEL_PMU_EVENT token

Ian Rogers <[email protected]>
perf parse-events: Remove unused PE_PMU_EVENT_FAKE token

Yi Yang <[email protected]>
tty: tty_jobctrl: fix pid memleak in disassociate_ctty()

Chao Yu <[email protected]>
f2fs: fix to drop meta_inode's page cache in f2fs_put_super()

Chao Yu <[email protected]>
f2fs: compress: fix to avoid redundant compress extension

Chao Yu <[email protected]>
f2fs: compress: fix to avoid use-after-free on dic

Chao Yu <[email protected]>
f2fs: compress: fix deadloop in f2fs_write_cache_pages()

Yang Jihong <[email protected]>
perf kwork: Set ordered_events to true in 'struct perf_tool'

Yang Jihong <[email protected]>
perf kwork: Add the supported subcommands to the document

Yang Jihong <[email protected]>
perf kwork: Fix incorrect and missing free atom in work_push_atom()

Jinjie Ruan <[email protected]>
iio: frequency: adf4350: Use device managed functions and fix power down issue.

Ian Rogers <[email protected]>
perf stat: Fix aggr mode initialization

Georgia Garcia <[email protected]>

    apparmor: fix invalid reference on profile->disconnected

Clément Léger <[email protected]>
scripts/gdb: fix usage of MOD_TEXT not defined when CONFIG_MODULES=n

Christophe JAILLET <[email protected]>
leds: trigger: ledtrig-cpu:: Fix 'output may be truncated' issue for 'cpu'

Uwe Kleine-König <[email protected]>
leds: pwm: Don't disable the PWM when the LED should be off

Marek Behún <[email protected]>
leds: turris-omnia: Do not use SMBUS calls

Marek Behún <[email protected]>
leds: turris-omnia: Drop unnecessary mutex locking

Hans de Goede <[email protected]>
mfd: arizona-spi: Set pdata.hpdet_channel for ACPI enumerated devs

Chen-Yu Tsai <[email protected]>
dt-bindings: mfd: mt6397: Split out compatible for MediaTek MT6366 PMIC

Dinghao Liu <[email protected]>
mfd: dln2: Fix double put in dln2_probe

Herve Codina <[email protected]>
mfd: core: Ensure disabled devices are skipped without aborting

Michał Mirosław <[email protected]>
mfd: core: Un-constify mfd_cell.of_reg

George Kennedy <[email protected]>
IB/mlx5: Fix init stage error handling to avoid double free of same QP and UAF

Gao Xiang <[email protected]>
erofs: fix erofs_insert_workgroup() lockref usage

Kuninori Morimoto <[email protected]>
ASoC: ams-delta.c: use component after check

Giovanni Cabiddu <[email protected]>
crypto: qat - fix deadlock in backlog processing

Herbert Xu <[email protected]>
certs: Break circular dependency when selftest is modular

WangJinchao <[email protected]>
padata: Fix refcnt handling in padata_free_shell()

Dan Carpenter <[email protected]>
PCI: endpoint: Fix double free in __pci_epc_create()

Cezary Rojewski <[email protected]>
ASoC: Intel: Skylake: Fix mem leak when parsing UUIDs fails

Hans de Goede <[email protected]>
HID: logitech-hidpp: Move get_wireless_feature_index() check to hidpp_connect_event()

Hans de Goede <[email protected]>
HID: logitech-hidpp: Revert "Don't restart communication if not necessary"

Hans de Goede <[email protected]>
HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only

Geert Uytterhoeven <[email protected]>
sh: bios: Revive earlyprintk support

Jinjie Ruan <[email protected]>

    HID: uclogic: Fix a work->entry not empty bug in __queue_work()

Jinjie Ruan <[email protected]>
HID: uclogic: Fix user-memory-access bug in uclogic_params_ugee_v2_init_event_hooks()

Danny Kaehn <[email protected]>
hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip

Andy Shevchenko <[email protected]>
HID: cp2112: Make irq_chip immutable

Leon Romanovsky <[email protected]>
RDMA/hfi1: Workaround truncation compilation error

Daniel Mentz <[email protected]>
scsi: ufs: core: Leave space for '\0' in utf8 desc string

Zhang Shurong <[email protected]>
ASoC: fsl: Fix PM disable depth imbalance in fsl_easrc_probe

Maarten Lankhorst <[email protected]>
ASoC: SOF: core: Ensure sof_ops_free() is still called when probe never ran.

Luoyouming <[email protected]>
RDMA/hns: The UD mode can only be configured with DCQCN

Luoyouming <[email protected]>
RDMA/hns: Add check for SL

Chengchang Tang <[email protected]>
RDMA/hns: Fix signed-unsigned mixed comparisons

Chengchang Tang <[email protected]>
RDMA/hns: Fix uninitialized ucmd in hns_roce_create_qp_common()

Chengchang Tang <[email protected]>
RDMA/hns: Fix printing level of asynchronous events

Patrisious Haddad <[email protected]>
IB/mlx5: Fix rdma counter binding for RAW QP

Alexander Aring <[email protected]>
dlm: fix no ack after final message

Hui Wang <[email protected]>
ASoC: fsl-asoc-card: Add comment for mclk in the codec_priv

Bard Liao <[email protected]>
ASoC: Intel: sof_sdw_rt_sdca_jack_common: add rt713 support

Uwe Kleine-König <[email protected]>
backlight: pwm_bl: Disable PWM on shutdown, suspend and remove

Kuninori Morimoto <[email protected]>
ASoC: fsl: mpc5200_dma.c: Fix warning of Function parameter or member not described

Florent Revest <[email protected]>
kselftest: vm: fix mdwe's mmap_FIXED test case

Gou Hao <[email protected]>
ext4: move 'ix' sanity check to corrent position

wahrenst <[email protected]>
ARM: 9323/1: mm: Fix ARCH_LOW_ADDRESS_LIMIT when CONFIG_ZONE_DMA

Kursad Oney <[email protected]>
ARM: 9321/1: memset: cast the constant byte to unsigned char

Longfang Liu <[email protected]>
crypto: hisilicon/qm - fix PF queue parameter issue

Danny Kaehn <[email protected]>
hid: cp2112: Fix duplicate workqueue initialization

Ilpo Järvinen <[email protected]>
PCI: vmd: Correct PCI Header Type Register's multi-function check

Gustavo A. R. Silva <[email protected]>
ASoC: SOF: ipc4-topology: Use size_add() in call to struct_size()

Giovanni Cabiddu <[email protected]>
crypto: qat - increase size of buffers

Gaurav Jain <[email protected]>
crypto: caam/jr - fix Chacha20 + Poly1305 self test failure

Gaurav Jain <[email protected]>
crypto: caam/qi2 - fix Chacha20 + Poly1305 self test failure

Tomas Glozar <[email protected]>
nd_btt: Make BTT lanes preemptible

Chen Ni <[email protected]>
libnvdimm/of_pmem: Use devm_kstrdup instead of kstrdup and check its return value

Chancel Liu <[email protected]>
ASoC: soc-pcm.c: Make sure DAI parameters cleared if the DAI becomes inactive

Tyrel Datwyler <[email protected]>
scsi: ibmvfc: Fix erroneous use of rtas_busy_delay with hcall return code

Giovanni Cabiddu <[email protected]>
crypto: qat - fix unregistration of compression algorithms

Giovanni Cabiddu <[email protected]>
crypto: qat - fix unregistration of crypto algorithms

Giovanni Cabiddu <[email protected]>
crypto: qat - ignore subsequent state up commands

Giovanni Cabiddu <[email protected]>
crypto: qat - fix state machines cleanup paths

Gustavo A. R. Silva <[email protected]>
RDMA/core: Use size_{add,sub,mul}() in calls to struct_size()

Jonas Gorski <[email protected]>
hwrng: geode - fix accessing registers

Stefan Wahren <[email protected]>
hwrng: bcm2835 - Fix hwrng throughput regression

Christophe JAILLET <[email protected]>
crypto: hisilicon/hpre - Fix a erroneous check after snprintf()

Herbert Xu <[email protected]>
KEYS: Include linux/errno.h in linux/verification.h

Cristian Ciocaltea <[email protected]>
ALSA: hda: cs35l41: Undo runtime PM changes at driver exit time

Cristian Ciocaltea <[email protected]>
ALSA: hda: cs35l41: Fix unbalanced pm_runtime_get()

Cristian Ciocaltea <[email protected]>
ASoC: cs35l41: Undo runtime PM changes at driver exit time

Cristian Ciocaltea <[email protected]>
ASoC: cs35l41: Verify PM runtime resume errors in IRQ handler

Cristian Ciocaltea <[email protected]>
ASoC: cs35l41: Initialize completion object before requesting IRQ

Cristian Ciocaltea <[email protected]>
ASoC: cs35l41: Handle mdsync_down reg write errors

Andrea Righi <[email protected]>
module/decompress: use vmalloc() for gzip decompression workspace

Jason Gunthorpe <[email protected]>
iommufd: Add iopt_area_alloc()

Rafał Miłecki <[email protected]>
ARM: dts: BCM5301X: Explicitly disable unused switch CPU ports

Dmitry Baryshkov <[email protected]>
soc: qcom: pmic_glink: fix connector type to be DisplayPort

Ilpo Järvinen <[email protected]>
selftests/resctrl: Ensure the benchmark commands fits to its array

Maciej Wieczor-Retman <[email protected]>
selftests/pidfd: Fix ksft print formats

Thierry Reding <[email protected]>
arm64: tegra: Use correct interrupts for Tegra234 TKE

Thierry Reding <[email protected]>
memory: tegra: Set BPMP msg flags to reset IPC channels

Sumit Gupta <[email protected]>
firmware: tegra: Add suspend hook and reset BPMP IPC early on resume

Brad Griffis <[email protected]>
arm64: tegra: Fix P3767 QSPI speed

Brad Griffis <[email protected]>
arm64: tegra: Fix P3767 card detect polarity

Adam Ford <[email protected]>
arm64: dts: imx8mn: Add sound-dai-cells to micfil node

Adam Ford <[email protected]>
arm64: dts: imx8mm: Add sound-dai-cells to micfil node

Fabio Estevam <[email protected]>
arm64: dts: imx8mp-debix-model-a: Remove USB hub reset-gpios

Fabio Estevam <[email protected]>
arm64: dts: imx8qm-ss-img: Fix jpegenc compatible entry

Sudeep Holla <[email protected]>
clk: scmi: Free scmi_clk allocated when the clocks with invalid info are skipped

Adam Ford <[email protected]>

    ARM: dts: am3517-evm: Fix LED3/4 pinmux

Sudeep Holla <[email protected]>
firmware: arm_ffa: Allow the FF-A drivers to use 32bit mode of messaging

Sudeep Holla <[email protected]>
firmware: arm_ffa: Assign the missing IDR allocation ID to the FFA device

Jai Luthra <[email protected]>

    arm64: dts: ti: k3-am62a7-sk: Drop i2c-1 to 100Khz

Wadim Egorov <[email protected]>
arm64: dts: ti: k3-am625-beagleplay: Fix typo in ramoops reg

Dhruva Gole <[email protected]>
firmware: ti_sci: Mark driver as non removable

Jinjie Ruan <[email protected]>
kunit: test: Fix the possible memory leak in executor_test

Jinjie Ruan <[email protected]>
kunit: Fix missed memory release in kunit_free_suite_set()

Uwe Kleine-König <[email protected]>
soc: qcom: llcc: Handle a second device without data corruption

Krzysztof Kozlowski <[email protected]>
ARM: dts: qcom: mdm9615: populate vsdcc fixed regulator

Matti Lehtimäki <[email protected]>
ARM: dts: qcom: apq8026-samsung-matisse-wifi: Fix inverted hall sensor

Stephan Gerhold <[email protected]>
arm64: dts: qcom: apq8016-sbc: Add missing ADV7533 regulators

Conor Dooley <[email protected]>
riscv: dts: allwinner: remove address-cells from intc node

Gaurav Kohli <[email protected]>
arm64: dts: qcom: msm8939: Fix iommu local address range

Adam Skladowski <[email protected]>
arm64: dts: qcom: msm8976: Fix ipc bit shifts

Chris Packham <[email protected]>
ARM64: dts: marvell: cn9310: Use appropriate label for spi1 pins

Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sdm845-mtp: fix WiFi configuration

Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sm8350: fix pinctrl for UART18

Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: sm8150: add ref clock to PCIe PHYs

Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sc7280: drop incorrect EUD port on SoC side

Konrad Dybcio <[email protected]>

    arm64: dts: qcom: qrb2210-rb1: Swap UART index

Konrad Dybcio <[email protected]>
arm64: dts: qcom: sc7280: Add missing LMH interrupts

Marijn Suijten <[email protected]>
arm64: dts: qcom: sm6125: Pad APPS IOMMU address to 8 characters

Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: msm8992-libra: drop duplicated reserved memory

Gaurav Kohli <[email protected]>
arm64: dts: qcom: msm8916: Fix iommu local address range

Dmitry Baryshkov <[email protected]>

    arm64: dts: qcom: sc7280: link usb3_phy_wrapper_gcc_usb30_pipe_clk

David Heidelberg <[email protected]>
arm64: dts: qcom: sdm845: cheza doesn't support LMh node

David Heidelberg <[email protected]>
arm64: dts: qcom: sdm845: Fix PSCI power domain names

Geert Uytterhoeven <[email protected]>
ARM: dts: renesas: blanche: Fix typo in GP_11_2 pin name

Junhao He <[email protected]>
perf: hisi: Fix use-after-free when register pmu fails

Yicong Yang <[email protected]>
drivers/perf: hisi_pcie: Check the type first in pmu::event_init()

Robin Murphy <[email protected]>
perf/arm-cmn: Fix DTC domain detection

Kunwu.Chan <[email protected]>
drm/amd/pm: Fix a memory leak on an error path

Hao Chen <[email protected]>
drivers/perf: hisi: use cpuhp_state_remove_instance_nocalls() for hisi_hns3_pmu uninit process

AngeloGioacchino Del Regno <[email protected]>
drm: mediatek: mtk_dsi: Fix NO_EOT_PACKET settings/handling

Andre Przywara <[email protected]>
clocksource/drivers/arm_arch_timer: limit XGene-1 workaround

Dmitry Baryshkov <[email protected]>
drm/msm/dsi: free TX buffer in unbind

Dmitry Baryshkov <[email protected]>
drm/msm/dsi: use msm_gem_kernel_put to free TX buffer

Marek Marczykowski-Górecki <[email protected]>
xen-pciback: Consider INTx disabled when MSI/MSI-X is enabled

Juergen Gross <[email protected]>
xenbus: fix error exit in xenbus_init()

Dan Carpenter <[email protected]>
drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map()

Mark Rutland <[email protected]>
arm64/arm: xen: enlighten: Fix KPTI checks

Dmitry Baryshkov <[email protected]>
drm/bridge: lt9611uxc: fix the race in the error path

Johnny Liu <[email protected]>
gpu: host1x: Correct allocated size for contexts

Christophe JAILLET <[email protected]>
drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe()

Christophe JAILLET <[email protected]>
accel/habanalabs/gaudi2: Fix incorrect string length computation in gaudi2_psoc_razwi_get_engines()

Jason-JH.Lin <[email protected]>
drm/mediatek: Fix iommu fault during crtc enabling

Jason-JH.Lin <[email protected]>
drm/mediatek: Fix iommu fault by swapping FBs after updating plane state

Jason-JH.Lin <[email protected]>
drm/mediatek: Add mmsys_dev_num to mt8188 vdosys0 driver data

Gabriel Krisman Bertazi <[email protected]>
io_uring/kbuf: Allow the full buffer id space for provided buffers

Gabriel Krisman Bertazi <[email protected]>
io_uring/kbuf: Fix check of BID wrapping in provided buffers

Michel Dänzer <[email protected]>
drm/amd/display: Bail from dm_check_crtc_cursor if no relevant change

Michel Dänzer <[email protected]>
drm/amd/display: Refactor dm_get_plane_scale helper

Michel Dänzer <[email protected]>
drm/amd/display: Check all enabled planes in dm_check_crtc_cursor

Cong Liu <[email protected]>
drm/amd/display: Fix null pointer dereference in error message

Philip Yang <[email protected]>
drm/amdkfd: Handle errors from svm validate and map

Philip Yang <[email protected]>
drm/amdkfd: Remove svm range validated_once flag

Alex Sierra <[email protected]>
drm/amdkfd: retry after EBUSY is returned from hmm_ranges_get_pages

Xiaogang Chen <[email protected]>
drm/amdkfd: fix some race conditions in vram buffer alloc/free of svm code

Philip Yang <[email protected]>
drm/amdgpu: Increase IH soft ring size for GFX v9.4.3 dGPU

Douglas Anderson <[email protected]>
drm: Call drm_atomic_helper_shutdown() at shutdown/remove time for misc drivers

Uwe Kleine-König <[email protected]>
drm/tve200: Convert to platform remove callback returning void

Uwe Kleine-König <[email protected]>
drm/stm: Convert to platform remove callback returning void

Uwe Kleine-König <[email protected]>
drm/aspeed: Convert to platform remove callback returning void

Tomi Valkeinen <[email protected]>

    drm/bridge: tc358768: Fix tc358768_ns_to_cnt()

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Clean up clock period code

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Rename dsibclk to hsbyteclk

Tomi Valkeinen <[email protected]>

    drm/bridge: tc358768: Use dev for dbg prints, not priv->dev

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Print logical values, not raw register values

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Use struct videomode

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Fix bit updates

Tomi Valkeinen <[email protected]>
drm/bridge: tc358768: Fix use of uninitialized variable

Kai Huang <[email protected]>
x86/tdx: Zero out the missing RSI in TDX_HYPERCALL macro

Jason-JH.Lin <[email protected]>
drm/mediatek: Fix coverity issue with unintentional integer overflow

Tomi Valkeinen <[email protected]>
drm/bridge: lt8912b: Add missing drm_bridge_attach call

Tomi Valkeinen <[email protected]>
drm/bridge: lt8912b: Manually disable HPD only if it was enabled

Tomi Valkeinen <[email protected]>
drm/bridge: lt8912b: Fix crash on bridge detach

Tomi Valkeinen <[email protected]>
drm/bridge: lt8912b: Fix bridge_detach

Jai Luthra <[email protected]>
drm: bridge: it66121: Fix invalid connector dereference

Konstantin Meskhidze <[email protected]>
drm/radeon: possible buffer overflow

Jonas Karlman <[email protected]>
drm/rockchip: vop2: Add missing call to crtc reset helper

Jonas Karlman <[email protected]>
drm/rockchip: vop2: Don't crash for invalid duplicate_state

Jonas Karlman <[email protected]>
drm/rockchip: vop: Fix call to crtc reset helper

Jonas Karlman <[email protected]>
drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs

Marek Szyprowski <[email protected]>
drm: bridge: samsung-dsim: Fix waiting for empty cmd transfer FIFO on older Exynos

Randy Dunlap <[email protected]>
drm: bridge: for GENERIC_PHY_MIPI_DPHY also select GENERIC_PHY

Marek Vasut <[email protected]>
drm: bridge: samsung-dsim: Initialize ULPS EXIT for i.MX8M DSIM

Vaishnav Achath <[email protected]>
spi: omap2-mcspi: Fix hardcoded reference clock

Yang Yingliang <[email protected]>
spi: omap2-mcspi: switch to use modern name

Zhu Wang <[email protected]>
spi: omap2-mcspi: remove redundant dev_err_probe()

Lalith Rajendran <[email protected]>
platform/chrome: cros_ec_lpc: Separate host command and irq disable

Harshit Mogalapalli <[email protected]>
hte: tegra: Fix missing error code in tegra_hte_test_probe()

Armin Wolf <[email protected]>
hwmon: (sch5627) Disallow write access if virtual registers are locked

Armin Wolf <[email protected]>
hwmon: (sch5627) Use bit macros when accessing the control register

Guenter Roeck <[email protected]>
Revert "hwmon: (sch56xx-common) Add automatic module loading on supported devices"

Guenter Roeck <[email protected]>
Revert "hwmon: (sch56xx-common) Add DMI override table"

Zhang Rui <[email protected]>
hwmon: (coretemp) Fix potentially truncated sysfs attribute name

Dragos Bogdan <[email protected]>
hwmon: (axi-fan-control) Fix possible NULL pointer dereference

Abel Vesa <[email protected]>
regulator: qcom-rpmh: Fix smps4 regulator for pm8550ve

Armin Wolf <[email protected]>
platform/x86: wmi: Fix opening of char device

Armin Wolf <[email protected]>
platform/x86: wmi: Fix probe failure when failing to register WMI devices

Dan Carpenter <[email protected]>
clk: mediatek: fix double free in mtk_clk_register_pllfh()

Kathiravan Thirumoorthy <[email protected]>
clk: qcom: ipq5332: drop the CLK_SET_RATE_PARENT flag from GPLL clocks

Kathiravan Thirumoorthy <[email protected]>
clk: qcom: ipq9574: drop the CLK_SET_RATE_PARENT flag from GPLL clocks

Varadarajan Narayanan <[email protected]>
clk: qcom: apss-ipq-pll: Fix 'l' value for ipq5332_pll_config

Varadarajan Narayanan <[email protected]>
clk: qcom: apss-ipq-pll: Use stromer plus ops for stromer plus pll

Varadarajan Narayanan <[email protected]>
clk: qcom: clk-alpha-pll: introduce stromer plus ops

Varadarajan Narayanan <[email protected]>
clk: qcom: config IPQ_APSS_6018 should depend on QCOM_SMEM

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data

Jiasheng Jiang <[email protected]>
clk: mediatek: clk-mt6765: Add check for mtk_alloc_clk_data

Jonathan Neuschäfer <[email protected]>
clk: npcm7xx: Fix incorrect kfree

Dan Carpenter <[email protected]>
clk: ti: fix double free in of_ti_divider_clk_setup()

Dan Carpenter <[email protected]>
clk: keystone: pll: fix a couple NULL vs IS_ERR() checks

Sergio Paracuellos <[email protected]>
clk: ralink: mtmips: quiet unused variable warning

Han Xu <[email protected]>
spi: nxp-fspi: use the correct ioremap function

Randy Dunlap <[email protected]>
clk: linux/clk-provider.h: fix kernel-doc warnings and typos

Claudiu Beznea <[email protected]>
clk: renesas: rzg2l: Fix computation formula

Claudiu Beznea <[email protected]>
clk: renesas: rzg2l: Use FIELD_GET() for PLL register fields

Claudiu Beznea <[email protected]>
clk: renesas: rzg2l: Trust value returned by hardware

Claudiu Beznea <[email protected]>
clk: renesas: rzg2l: Lock around writes to mux register

Claudiu Beznea <[email protected]>
clk: renesas: rzg2l: Wait for status bit of SD mux before continuing

Dirk Behme <[email protected]>
clk: renesas: rcar-gen3: Extend SDnH divider table

Robert Chiras <[email protected]>
clk: imx: imx8qxp: Fix elcdif_pll clock

Peng Fan <[email protected]>
clk: imx: imx8mq: correct error handling path

Abel Vesa <[email protected]>
clk: imx: Select MXC_CLK for CLK_IMX8QXP

Chen-Yu Tsai <[email protected]>
regulator: mt6358: Fail probe on unknown chip ID

Danila Tikhonov <[email protected]>

    clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src

Konrad Dybcio <[email protected]>
clk: qcom: mmcc-msm8998: Fix the SMMU GDSC

Konrad Dybcio <[email protected]>
clk: qcom: mmcc-msm8998: Don't check halt bit on some branch clks

Devi Priya <[email protected]>
clk: qcom: clk-rcg2: Fix clock rate overflow for high parent frequencies

Konrad Dybcio <[email protected]>
clk: qcom: gcc-msm8996: Remove RPM bus clocks

Varadarajan Narayanan <[email protected]>
clk: qcom: ipq5332: Drop set rate parent from gpll0 dependent clocks

Zhang Shurong <[email protected]>
spi: tegra: Fix missing IRQ check in tegra_slink_probe()

Christophe JAILLET <[email protected]>
regmap: debugfs: Fix a erroneous check after snprintf()

Eric Dumazet <[email protected]>
ipvlan: properly track tx_errors

Eric Dumazet <[email protected]>
net: add DEV_STATS_READ() helper

Eric Dumazet <[email protected]>
virtio_net: use u64_stats_t infra to avoid data-races

Yan Zhai <[email protected]>
ipv6: avoid atomic fragment on GSO packets

Paolo Abeni <[email protected]>
mptcp: properly account fastopen data

Christophe JAILLET <[email protected]>
ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias()

Song Liu <[email protected]>
bpf: Fix unnecessary -EBUSY from htab_lock_bucket

Marcel Ziswiler <[email protected]>
Bluetooth: hci_sync: Fix Opcode prints in bt_dev_dbg/err

Ziyang Xuan <[email protected]>
Bluetooth: Make handle of hci_conn be unique

Iulia Tanasescu <[email protected]>
Bluetooth: ISO: Pass BIG encryption info through QoS

Iulia Tanasescu <[email protected]>
Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync

Miri Korenblit <[email protected]>
wifi: iwlwifi: empty overflow queue during flush

Yedidya Benshimol <[email protected]>
wifi: iwlwifi: mvm: update IGTK in mvmvif upon D3 resume

Johannes Berg <[email protected]>
wifi: iwlwifi: pcie: synchronize IRQs before NAPI

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: fix netif csum flags

Johannes Berg <[email protected]>
wifi: iwlwifi: increase number of RX buffers for EHT devices

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: remove TDLS stations from FW

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: change iwl_mvm_flush_sta() API

Ilan Peer <[email protected]>
wifi: iwlwifi: mvm: Don't always bind/link the P2P Device interface

Ilan Peer <[email protected]>
wifi: iwlwifi: mvm: Fix key flags for IGTK on AP interface

Ilan Peer <[email protected]>
wifi: iwlwifi: mvm: Correctly set link configuration

Rotem Saado <[email protected]>
wifi: iwlwifi: yoyo: swap cdb and jacket bits values

Ilan Peer <[email protected]>
wifi: mac80211: Fix setting vif links

Johannes Berg <[email protected]>
wifi: mac80211: don't recreate driver link debugfs in reconfig

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: use correct sta ID for IGTK/BIGTK

Avraham Stern <[email protected]>
wifi: iwlwifi: mvm: fix removing pasn station for responder

Avraham Stern <[email protected]>
wifi: iwlwifi: mvm: update station's MFP flag after association

Eric Dumazet <[email protected]>
tcp: fix cookie_init_timestamp() overflows

Eric Dumazet <[email protected]>

    chtls: fix tp->rcv_tstamp initialization

Nícolas F. R. A. Prado <[email protected]>
thermal: core: Don't update trip points inside the hysteresis range

Phil Sutter <[email protected]>
net: skb_find_text: Ignore patterns extending past 'to'

Xin Long <[email protected]>
selftests: netfilter: test for sctp collision processing in nf_conntrack

Yafang Shao <[email protected]>
bpf: Fix missed rcu read lock in bpf_task_under_cgroup()

Markus Schneider-Pargmann <[email protected]>
thermal/drivers/mediatek: Fix probe for THERMAL_V2

Heiner Kallweit <[email protected]>
r8169: fix rare issue with broken rx after link-down on RTL8125

Dan Carpenter <[email protected]>
thermal: core: prevent potential string overflow

Jinjie Ruan <[email protected]>
wifi: rtw88: Remove duplicate NULL check before calling usb_kill/free_urb()

Phil Sutter <[email protected]>
netfilter: nf_tables: Drop pointless memset when dumping rules

Felipe Negrelli Wolter <[email protected]>
wifi: wfx: fix case where rates are out of order

Sascha Hauer <[email protected]>
PM / devfreq: rockchip-dfi: Make pmu regmap mandatory

Marc Kleine-Budde <[email protected]>
can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds

Marc Kleine-Budde <[email protected]>
can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on()

Marc Kleine-Budde <[email protected]>
can: dev: can_restart(): don't crash kernel if carrier is OK

Aditya Kumar Singh <[email protected]>
wifi: ath11k: fix Tx power value during active CAC

Vincent Mailhol <[email protected]>
can: etas_es58x: add missing a blank line after declaration

Vincent Mailhol <[email protected]>
can: etas_es58x: rework the version check logic to silence -Wformat-truncation

Ondrej Zary <[email protected]>
ACPI: video: Add acpi_backlight=vendor quirk for Toshiba Portégé R100

Andy Shevchenko <[email protected]>
ACPI: property: Allow _DSD buffer data only for byte accessors

Dmitry Antipov <[email protected]>
wifi: rtlwifi: fix EDCA limit set by BT coexistence

Eric Dumazet <[email protected]>
tcp_metrics: do not create an entry from tcp_init_metrics()

Eric Dumazet <[email protected]>

    tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics()

Eric Dumazet <[email protected]>
tcp_metrics: add missing barriers on delete

Christophe JAILLET <[email protected]>
wifi: ath: dfs_pattern_detector: Fix a memory initialization issue

MeiChia Chiu <[email protected]>
wifi: mt76: mt7915: fix beamforming availability check

Shayne Chen <[email protected]>
wifi: mt76: fix per-band IEEE80211_CONF_MONITOR flag comparison

StanleyYP Wang <[email protected]>
wifi: mt76: get rid of false alamrs of tx emission issues

Bo Jiao <[email protected]>
wifi: mt76: fix potential memory leak of beacon commands

MeiChia Chiu <[email protected]>
wifi: mt76: update beacon size limitation

Peter Chiu <[email protected]>
wifi: mt76: mt7996: fix TWT command format

Peter Chiu <[email protected]>

    wifi: mt76: mt7996: fix rx rate report for CBW320-2

Peter Chiu <[email protected]>
wifi: mt76: mt7996: fix wmm queue mapping

Howard Hsu <[email protected]>
wifi: mt76: mt7996: fix beamformee ss subfield in EHT PHY cap

Howard Hsu <[email protected]>
wifi: mt76: mt7996: fix beamform mcu cmd configuration

Peter Chiu <[email protected]>
wifi: mt76: mt7996: set correct wcid in txp

Felix Fietkau <[email protected]>
wifi: mt76: remove unused error path in mt76_connac_tx_complete_skb

Lorenzo Bianconi <[email protected]>
wifi: mt76: connac: move connac3 definitions in mt76_connac3_mac.h

Felix Fietkau <[email protected]>
wifi: mt76: mt7603: improve stuck beacon handling

Felix Fietkau <[email protected]>
wifi: mt76: mt7603: improve watchdog reset reliablity

Felix Fietkau <[email protected]>
wifi: mt76: mt7603: rework/fix rx pse hang check

Sumit Gupta <[email protected]>
cpufreq: tegra194: fix warning due to missing opp_put

Raag Jadav <[email protected]>
PM: sleep: Fix symbol export for _SIMPLE_ variants of _PM_OPS()

Johannes Berg <[email protected]>
wifi: mac80211: fix check for unusable RX result

Baochen Qiang <[email protected]>
wifi: ath11k: fix boot failure with one MSI vector

Baochen Qiang <[email protected]>
wifi: ath12k: fix DMA unmap warning on NULL DMA address

Jinjie Ruan <[email protected]>
wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for debugfs_create_file()

Lorenzo Bianconi <[email protected]>
net: ethernet: mtk_wed: fix EXT_INT_STATUS_RX_FBUF definitions for MT7986 SoC

Gustavo A. R. Silva <[email protected]>
net: spider_net: Use size_add() in call to struct_size()

Gustavo A. R. Silva <[email protected]>
tipc: Use size_add() in calls to struct_size()

Gustavo A. R. Silva <[email protected]>
tls: Use size_add() in call to struct_size()

Gustavo A. R. Silva <[email protected]>
mlxsw: Use size_mul() in call to struct_size()

Gustavo A. R. Silva <[email protected]>
gve: Use size_add() in call to struct_size()

Kumar Kartikeya Dwivedi <[email protected]>
bpf: Fix kfunc callback register type handling

Aananth V <[email protected]>
tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed

Artem Savkov <[email protected]>
selftests/bpf: Skip module_fentry_shadow test when bpf_testmod is not available

Eric Dumazet <[email protected]>
udplite: fix various data-races

Eric Dumazet <[email protected]>
udplite: remove UDPLITE_BIT

Eric Dumazet <[email protected]>

    udp: annotate data-races around udp->encap_type

Eric Dumazet <[email protected]>
udp: lockless UDP_ENCAP_L2TPINUDP / UDP_GRO

Eric Dumazet <[email protected]>

    udp: move udp->accept_udp_{l4|fraglist} to udp->udp_flags

Eric Dumazet <[email protected]>

    udp: add missing WRITE_ONCE() around up->encap_rcv

Eric Dumazet <[email protected]>

    udp: move udp->gro_enabled to udp->udp_flags

Eric Dumazet <[email protected]>

    udp: move udp->no_check6_rx to udp->udp_flags

Eric Dumazet <[email protected]>

    udp: move udp->no_check6_tx to udp->udp_flags

Eric Dumazet <[email protected]>

    udp: introduce udp->udp_flags

Miri Korenblit <[email protected]>
wifi: iwlwifi: Use FW rate for non-data frames

Johannes Berg <[email protected]>
wifi: cfg80211: fix kernel-doc for wiphy_delayed_work_flush()

Leon Hwang <[email protected]>
bpf, x64: Fix tailcall infinite loop

Menglong Dong <[email protected]>
bpf, x86: allow function arguments up to 12 for TRACING

Menglong Dong <[email protected]>
bpf, x86: save/restore regs with BPF_DW size

Leon Hwang <[email protected]>
selftests/bpf: Correct map_fd to data_fd in tailcalls

Brett Creeley <[email protected]>
iavf: Fix promiscuous mode configuration flow messages

Andrii Staikov <[email protected]>
i40e: fix potential memory leaks in i40e_remove()

Miri Korenblit <[email protected]>
wifi: iwlwifi: don't use an uninitialized variable

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: honor the enable_ini value

Johannes Berg <[email protected]>
wifi: mac80211: fix # of MSDU in A-MSDU calculation

Johannes Berg <[email protected]>
wifi: cfg80211: fix off-by-one in element defrag

Johannes Berg <[email protected]>
wifi: mac80211: fix RCU usage warning in mesh fast-xmit

Johannes Berg <[email protected]>
wifi: mac80211: move sched-scan stop work to wiphy work

Johannes Berg <[email protected]>
wifi: mac80211: move offchannel works to wiphy work

Johannes Berg <[email protected]>
wifi: mac80211: move scan work to wiphy work

Johannes Berg <[email protected]>
wifi: mac80211: move radar detect work to wiphy work

Johannes Berg <[email protected]>
wifi: cfg80211: add flush functions for wiphy work

Harshitha Prem <[email protected]>
wifi: ath12k: fix undefined behavior with __fls in dp

Anup Patel <[email protected]>
irqchip/sifive-plic: Fix syscore registration for multi-socket systems

Chen Yu <[email protected]>
genirq/matrix: Exclude managed interrupts in irq_matrix_allocated()

Kees Cook <[email protected]>
string: Adjust strtomem() logic to allow for smaller sources

Reinette Chatre <[email protected]>
PCI/MSI: Provide stubs for IMS functions

Binbin Wu <[email protected]>
selftests/x86/lam: Zero out buffer for readlink()

Peter Zijlstra <[email protected]>
perf: Optimize perf_cgroup_switch()

Jiasheng Jiang <[email protected]>
pstore/platform: Add check for kstrdup

Paul E. McKenney <[email protected]>
x86/nmi: Fix out-of-order NMI nesting checks & false positive warning

Ivaylo Dimitrov <[email protected]>
drivers/clocksource/timer-ti-dm: Don't call clk_get_rate() in stop function

Frederic Weisbecker <[email protected]>
srcu: Fix callbacks acceleration mishandling

Thomas Gleixner <[email protected]>
x86/apic: Fake primary thread mask for XEN/PV

Thomas Gleixner <[email protected]>
cpu/SMT: Make SMT control more robust against enumeration failures

Michael Ellerman <[email protected]>
cpu/SMT: Create topology_smt_thread_allowed()

Laurent Dufour <[email protected]>
cpu/hotplug: Remove dependancy against cpu_primary_thread_mask

Yuntao Wang <[email protected]>
x86/boot: Fix incorrect startup_gdt_descr.size

Adam Dunlap <[email protected]>
x86/sev-es: Allow copy_from_kernel_nofault() in earlier boot

Alison Schofield <[email protected]>
ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window

Alison Schofield <[email protected]>
x86/numa: Introduce numa_fill_memblks()

Ben Wolsieffer <[email protected]>
futex: Don't include process MM in futex key on no-MMU

Josh Poimboeuf <[email protected]>
x86/srso: Fix unret validation dependencies

Josh Poimboeuf <[email protected]>
x86/srso: Fix vulnerability reporting for missing microcode

Josh Poimboeuf <[email protected]>
x86/srso: Print mitigation for retbleed IBPB case

Josh Poimboeuf <[email protected]>
x86/srso: Fix SBPB enablement for (possible) future fixed HW

Jingbo Xu <[email protected]>
writeback, cgroup: switch inodes with dirty timestamps to release dying cgwbs

Reuben Hawkins <[email protected]>
vfs: fix readahead(2) on block devices

Trond Myklebust <[email protected]>
nfsd: Handle EOPENSTALE correctly in the filecache

Peter Zijlstra <[email protected]>
sched: Fix stop_one_cpu_nowait() vs hotplug

Aaron Plattner <[email protected]>
objtool: Propagate early errors

Qais Yousef <[email protected]>

    sched/uclamp: Ignore (util == 0) optimization in feec() when p_util_max = 0

Qais Yousef <[email protected]>
sched/uclamp: Set max_spare_cap_cpu even if max_spare_cap is 0

David Howells <[email protected]>
iov_iter, x86: Be consistent about the __user tag on copy_mc_to_user()

Chengming Zhou <[email protected]>
sched/fair: Fix cfs_rq_is_decayed() on !SMP

Yury Norov <[email protected]>
sched/topology: Fix sched_numa_find_nth_cpu() in non-NUMA case

Yury Norov <[email protected]>
sched/topology: Fix sched_numa_find_nth_cpu() in CPU-less case

Yury Norov <[email protected]>
numa: Generalize numa_map_to_online_node()

Zev Weiss <[email protected]>
hwmon: (nct6775) Fix incorrect variable reuse in fan_div calculation

-------------

Diffstat:

 Documentation/admin-guide/hw-vuln/srso.rst         |  24 +-
 Documentation/devicetree/bindings/mfd/mt6397.txt   |   4 +-
 Makefile                                           |   4 +-
 arch/Kconfig                                       |   3 +
 .../bcm4708-buffalo-wzr-1166dhp-common.dtsi        |   8 +
 .../boot/dts/broadcom/bcm4708-luxul-xap-1510.dts   |   8 +
 .../boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts   |   8 +
 .../boot/dts/broadcom/bcm4708-netgear-r6250.dts    |   8 +
 .../boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts  |   8 +
 .../dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts  |   8 +
 .../boot/dts/broadcom/bcm47081-luxul-xap-1410.dts  |   8 +
 .../boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts  |   8 +
 .../boot/dts/broadcom/bcm4709-netgear-r8000.dts    |   8 +
 .../boot/dts/broadcom/bcm47094-dlink-dir-885l.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-dlink-dir-890l.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-luxul-abr-4500.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-luxul-xap-1610.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts  |   8 +
 .../boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts  |   8 +
 .../dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts    |   8 +
 .../arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts |   8 +
 .../arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts |   8 +
 arch/arm/boot/dts/broadcom/bcm953012er.dts         |   8 +
 .../dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts |   4 +-
 arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi           |  14 +-
 arch/arm/boot/dts/renesas/r8a7792-blanche.dts      |   2 +-
 arch/arm/boot/dts/ti/omap/am3517-evm.dts           |  16 +-
 arch/arm/include/asm/arm_pmuv3.h                   |  48 ++-
 arch/arm/include/asm/dma.h                         |   3 +
 arch/arm/lib/memset.S                              |   1 +
 arch/arm/xen/enlighten.c                           |  25 +-
 arch/arm64/boot/dts/freescale/imx8mm.dtsi          |   1 +
 arch/arm64/boot/dts/freescale/imx8mn.dtsi          |   1 +
 .../boot/dts/freescale/imx8mp-debix-model-a.dts    |   3 -
 arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi   |   2 +-
 arch/arm64/boot/dts/marvell/cn9130-crb.dtsi        |   4 +-
 arch/arm64/boot/dts/marvell/cn9130-db.dtsi         |   4 +-
 arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi     |   4 +-
 arch/arm64/boot/dts/nvidia/tegra234.dtsi           |  12 +-
 arch/arm64/boot/dts/qcom/apq8016-sbc.dts           |   3 +
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |   2 +-
 arch/arm64/boot/dts/qcom/msm8939.dtsi              |   2 +-
 arch/arm64/boot/dts/qcom/msm8976.dtsi              |   8 +-
 arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts  |   5 -
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts           |   4 +-
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |  32 +-
 arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi         |  32 +-
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts            |   2 +
 arch/arm64/boot/dts/qcom/sm6125.dtsi               |   2 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |  12 +-
 arch/arm64/boot/dts/qcom/sm8350.dtsi               |   2 +-
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts     |   2 +-
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts            |   2 +-
 arch/arm64/include/asm/arm_pmuv3.h                 |  25 +-
 arch/arm64/include/asm/cputype.h                   |   3 +-
 arch/arm64/kvm/guest.c                             |   2 +-
 arch/powerpc/include/asm/nohash/32/pte-40x.h       |   3 -
 arch/powerpc/kernel/process.c                      |  26 +-
 arch/powerpc/kernel/traps.c                        |   2 +
 arch/powerpc/perf/imc-pmu.c                        |   2 +-
 arch/powerpc/platforms/book3s/vas-api.c            |  34 +--
 arch/powerpc/platforms/pseries/lpar.c              |   4 +-
 arch/powerpc/platforms/pseries/vas.c               |   4 +-
 arch/powerpc/sysdev/xive/native.c                  |   2 +-
 arch/riscv/boot/Makefile                           |   1 +
 arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi      |   1 -
 arch/riscv/kernel/cpu.c                            |  11 +-
 arch/sh/Kconfig.debug                              |  11 +
 arch/x86/coco/tdx/tdcall.S                         |   1 +
 arch/x86/include/asm/nospec-branch.h               |   4 +-
 arch/x86/include/asm/sparsemem.h                   |   2 +
 arch/x86/include/asm/uaccess.h                     |   2 +-
 arch/x86/kernel/amd_nb.c                           |   3 +
 arch/x86/kernel/apic/apic.c                        |  11 +
 arch/x86/kernel/cpu/bugs.c                         |  42 +--
 arch/x86/kernel/head64.c                           |   2 +-
 arch/x86/kernel/nmi.c                              |  13 +-
 arch/x86/lib/copy_mc.c                             |   8 +-
 arch/x86/mm/maccess.c                              |  19 +-
 arch/x86/mm/numa.c                                 |  80 +++++
 arch/x86/net/bpf_jit_comp.c                        | 274 ++++++++++++++---
 block/blk-core.c                                   |   4 +-
 crypto/asymmetric_keys/Kconfig                     |   3 +-
 crypto/asymmetric_keys/Makefile                    |   3 +-
 crypto/asymmetric_keys/selftest.c                  |  13 +-
 crypto/asymmetric_keys/x509_parser.h               |   9 -
 crypto/asymmetric_keys/x509_public_key.c           |   8 +-
 drivers/accel/habanalabs/gaudi2/gaudi2.c           |   4 +-
 drivers/acpi/device_sysfs.c                        |  10 +-
 drivers/acpi/numa/srat.c                           |  11 +-
 drivers/acpi/property.c                            |  19 +-
 drivers/acpi/video_detect.c                        |  26 ++
 drivers/base/regmap/regmap-debugfs.c               |   2 +-
 drivers/base/regmap/regmap.c                       |  16 +-
 drivers/block/nbd.c                                |  11 +-
 drivers/char/hw_random/bcm2835-rng.c               |   2 +-
 drivers/char/hw_random/core.c                      |   6 +
 drivers/char/hw_random/geode-rng.c                 |   6 +-
 drivers/clk/clk-npcm7xx.c                          |   2 +-
 drivers/clk/clk-scmi.c                             |   1 +
 drivers/clk/imx/Kconfig                            |   1 +
 drivers/clk/imx/clk-imx8mq.c                       |  17 +-
 drivers/clk/imx/clk-imx8qxp.c                      |   2 +-
 drivers/clk/keystone/pll.c                         |  15 +-
 drivers/clk/mediatek/clk-mt2701.c                  |   8 +
 drivers/clk/mediatek/clk-mt6765.c                  |   6 +
 drivers/clk/mediatek/clk-mt6779.c                  |   4 +
 drivers/clk/mediatek/clk-mt6797.c                  |   6 +
 drivers/clk/mediatek/clk-mt7629-eth.c              |   4 +
 drivers/clk/mediatek/clk-mt7629.c                  |   6 +
 drivers/clk/mediatek/clk-pll.c                     |   6 +-
 drivers/clk/qcom/Kconfig                           |   1 +
 drivers/clk/qcom/apss-ipq-pll.c                    |   4 +-
 drivers/clk/qcom/clk-alpha-pll.c                   |  63 ++++
 drivers/clk/qcom/clk-alpha-pll.h                   |   1 +
 drivers/clk/qcom/clk-rcg2.c                        |  14 +-
 drivers/clk/qcom/gcc-ipq5332.c                     |   4 -
 drivers/clk/qcom/gcc-ipq9574.c                     |   4 -
 drivers/clk/qcom/gcc-msm8996.c                     | 237 +--------------
 drivers/clk/qcom/gcc-sm8150.c                      |   2 +-
 drivers/clk/qcom/mmcc-msm8998.c                    |   7 +-
 drivers/clk/ralink/clk-mtmips.c                    |  20 +-
 drivers/clk/renesas/rcar-cpg-lib.c                 |  15 +-
 drivers/clk/renesas/rzg2l-cpg.c                    |  62 ++--
 drivers/clk/renesas/rzg2l-cpg.h                    |   2 +-
 drivers/clk/ti/divider.c                           |   8 +-
 drivers/clocksource/arm_arch_timer.c               |   5 +-
 drivers/clocksource/timer-ti-dm.c                  |  36 ++-
 drivers/cpufreq/tegra194-cpufreq.c                 |   2 +
 drivers/crypto/caam/caamalg.c                      |   3 +-
 drivers/crypto/caam/caamalg_qi2.c                  |   3 +-
 drivers/crypto/hisilicon/hpre/hpre_main.c          |   7 +-
 drivers/crypto/hisilicon/qm.c                      |  18 +-
 drivers/crypto/hisilicon/qm_common.h               |   1 -
 drivers/crypto/hisilicon/sec2/sec_main.c           |   5 +
 drivers/crypto/hisilicon/zip/zip_main.c            |   5 +
 .../intel/qat/qat_common/adf_accel_devices.h       |   2 +-
 .../crypto/intel/qat/qat_common/adf_common_drv.h   |   2 +
 drivers/crypto/intel/qat/qat_common/adf_init.c     |  17 +-
 drivers/crypto/intel/qat/qat_common/adf_sysfs.c    |  11 +-
 .../intel/qat/qat_common/adf_transport_debug.c     |   4 +-
 .../crypto/intel/qat/qat_common/qat_algs_send.c    |  46 +--
 drivers/cxl/core/core.h                            |   1 +
 drivers/cxl/core/hdm.c                             |  40 +--
 drivers/cxl/core/mbox.c                            |  55 +++-
 drivers/cxl/core/memdev.c                          | 157 +++++-----
 drivers/cxl/core/port.c                            |  53 +++-
 drivers/cxl/core/region.c                          | 241 ++++++++-------
 drivers/cxl/core/regs.c                            |  28 +-
 drivers/cxl/cxl.h                                  |   4 +-
 drivers/cxl/cxlmem.h                               |  13 +-
 drivers/cxl/pci.c                                  |  80 +++--
 drivers/devfreq/event/rockchip-dfi.c               |  15 +-
 drivers/dma/idxd/Makefile                          |   6 +-
 drivers/dma/pxa_dma.c                              |   1 -
 drivers/dma/ti/edma.c                              |   4 +-
 drivers/firmware/arm_ffa/bus.c                     |   1 +
 drivers/firmware/arm_ffa/driver.c                  |  12 +-
 drivers/firmware/tegra/bpmp.c                      |  30 ++
 drivers/firmware/ti_sci.c                          |  46 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c            |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h             |   2 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c             |  12 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c             |  12 +-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c               |  90 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.h               |   2 -
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  73 ++++-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c   |   4 +-
 drivers/gpu/drm/aspeed/aspeed_gfx_drv.c            |  11 +-
 drivers/gpu/drm/ast/ast_dp.c                       |  11 -
 drivers/gpu/drm/ast/ast_dp501.c                    |  37 +--
 drivers/gpu/drm/ast/ast_drv.h                      |   2 -
 drivers/gpu/drm/ast/ast_mode.c                     |  30 +-
 drivers/gpu/drm/bridge/Kconfig                     |   2 +
 drivers/gpu/drm/bridge/cadence/Kconfig             |   1 +
 drivers/gpu/drm/bridge/ite-it66121.c               |  12 +-
 drivers/gpu/drm/bridge/lontium-lt8912b.c           |  22 +-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c         |  10 +-
 drivers/gpu/drm/bridge/samsung-dsim.c              |  20 +-
 drivers/gpu/drm/bridge/tc358768.c                  | 166 ++++++-----
 drivers/gpu/drm/drm_syncobj.c                      |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c            |   3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c             |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_gem.c             |   9 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c           |  41 ++-
 drivers/gpu/drm/mediatek/mtk_dsi.c                 |   4 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c              |   8 +
 drivers/gpu/drm/msm/dsi/dsi.c                      |   1 +
 drivers/gpu/drm/msm/dsi/dsi.h                      |   1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c                 |  16 +-
 drivers/gpu/drm/pl111/pl111_drv.c                  |   7 +
 drivers/gpu/drm/radeon/evergreen.c                 |   7 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |  15 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c        |   2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c        |   8 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c       |  39 ++-
 drivers/gpu/drm/stm/drv.c                          |  11 +-
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c              |   6 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                |  11 +-
 drivers/gpu/drm/tve200/tve200_drv.c                |  11 +-
 drivers/gpu/drm/vboxvideo/vbox_drv.c               |  10 +
 drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c          |   2 +-
 drivers/gpu/drm/vc4/tests/vc4_mock_output.c        |   2 +-
 drivers/gpu/host1x/context.c                       |   4 +-
 drivers/hid/hid-cp2112.c                           |  43 ++-
 drivers/hid/hid-logitech-hidpp.c                   |  60 ++--
 drivers/hid/hid-uclogic-core-test.c                |   7 +
 drivers/hid/hid-uclogic-params-test.c              |  16 +-
 drivers/hte/hte-tegra194-test.c                    |   4 +-
 drivers/hwmon/axi-fan-control.c                    |  29 +-
 drivers/hwmon/coretemp.c                           |   2 +-
 drivers/hwmon/nct6775-core.c                       |  12 +-
 drivers/hwmon/sch5627.c                            |  21 +-
 drivers/hwmon/sch56xx-common.c                     |  64 +---
 drivers/i2c/busses/i2c-bcm-iproc.c                 | 133 +++++----
 drivers/i3c/master.c                               |   4 +-
 drivers/iio/frequency/adf4350.c                    |  75 ++---
 drivers/infiniband/core/device.c                   |   2 +-
 drivers/infiniband/core/sa_query.c                 |   4 +-
 drivers/infiniband/core/sysfs.c                    |  10 +-
 drivers/infiniband/core/user_mad.c                 |   4 +-
 drivers/infiniband/hw/hfi1/efivar.c                |   2 +-
 drivers/infiniband/hw/hns/hns_roce_ah.c            |  13 +-
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c         |  34 ++-
 drivers/infiniband/hw/hns/hns_roce_qp.c            |   2 +-
 drivers/infiniband/hw/mlx5/main.c                  |   4 +-
 drivers/infiniband/hw/mlx5/qp.c                    |  27 ++
 drivers/input/rmi4/rmi_bus.c                       |   2 +-
 drivers/interconnect/qcom/icc-rpm.c                |  14 +-
 drivers/interconnect/qcom/qdu1000.c                |   1 +
 drivers/interconnect/qcom/sc7180.c                 | 256 ++++++++++++++--
 drivers/interconnect/qcom/sc7280.c                 |   1 +
 drivers/interconnect/qcom/sc8180x.c                |   1 +
 drivers/interconnect/qcom/sc8280xp.c               |   1 +
 drivers/interconnect/qcom/sdm670.c                 | 240 +++++++++++++--
 drivers/interconnect/qcom/sdm845.c                 | 278 ++++++++++++++++--
 drivers/interconnect/qcom/sm6350.c                 | 252 ++++++++++++++--
 drivers/interconnect/qcom/sm8150.c                 | 284 ++++++++++++++++--
 drivers/interconnect/qcom/sm8350.c                 | 309 +++++++++++++++++--
 drivers/iommu/iommufd/io_pagetable.c               |  18 +-
 drivers/iommu/iommufd/pages.c                      |   2 +
 drivers/irqchip/irq-sifive-plic.c                  |   7 +-
 drivers/leds/leds-pwm.c                            |   2 +-
 drivers/leds/leds-turris-omnia.c                   |  65 ++--
 drivers/leds/trigger/ledtrig-cpu.c                 |   4 +-
 drivers/media/cec/platform/Makefile                |   2 +-
 drivers/media/i2c/max9286.c                        |   2 -
 drivers/media/i2c/ov5640.c                         |  24 +-
 drivers/media/pci/bt8xx/bttv-driver.c              |   1 +
 drivers/media/platform/amphion/vpu_defs.h          |   1 +
 drivers/media/platform/amphion/vpu_helpers.c       |   1 +
 drivers/media/platform/amphion/vpu_malone.c        |   1 +
 drivers/media/platform/amphion/vpu_msgs.c          |  31 +-
 drivers/media/platform/cadence/cdns-csi2rx.c       |   7 +-
 .../media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c |   5 +-
 .../media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c   |   2 +-
 drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c     |  34 ++-
 drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h     |   1 +
 .../platform/samsung/s3c-camif/camif-capture.c     |   6 +-
 drivers/media/platform/verisilicon/hantro_drv.c    |   3 +-
 .../media/platform/verisilicon/hantro_postproc.c   |   2 +-
 .../media/platform/verisilicon/rockchip_vpu_hw.c   |   2 +-
 drivers/media/test-drivers/vidtv/vidtv_mux.c       |   7 +-
 drivers/media/test-drivers/vidtv/vidtv_psi.c       |  45 ++-
 drivers/media/usb/dvb-usb-v2/af9035.c              |  13 +-
 drivers/memory/tegra/tegra234.c                    |   4 +
 drivers/mfd/arizona-spi.c                          |   3 +
 drivers/mfd/dln2.c                                 |   1 -
 drivers/mfd/mfd-core.c                             |  17 +-
 drivers/misc/ti-st/st_core.c                       |   7 +-
 drivers/mmc/core/mmc.c                             |   2 +-
 drivers/net/can/dev/dev.c                          |  10 +-
 drivers/net/can/dev/skb.c                          |   6 +-
 drivers/net/can/usb/etas_es58x/es58x_core.c        |   1 +
 drivers/net/can/usb/etas_es58x/es58x_core.h        |   6 +-
 drivers/net/can/usb/etas_es58x/es58x_devlink.c     |  57 ++--
 drivers/net/ethernet/broadcom/tg3.c                |   3 +-
 .../chelsio/inline_crypto/chtls/chtls_cm.c         |   2 +-
 drivers/net/ethernet/freescale/enetc/enetc.c       |   2 +-
 drivers/net/ethernet/google/gve/gve_main.c         |   2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c        |  10 +-
 drivers/net/ethernet/intel/iavf/iavf.h             |  16 +-
 drivers/net/ethernet/intel/iavf/iavf_main.c        |  43 ++-
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c    |  75 +++--
 .../ethernet/marvell/octeontx2/nic/otx2_common.c   |  15 +-
 .../ethernet/marvell/octeontx2/nic/otx2_common.h   |   1 +
 .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c   |  81 ++---
 .../ethernet/marvell/octeontx2/nic/otx2_struct.h   |  34 +--
 .../net/ethernet/marvell/octeontx2/nic/otx2_txrx.c |  42 +++
 drivers/net/ethernet/mediatek/mtk_wed_regs.h       |   4 +-
 .../mellanox/mlxsw/spectrum_acl_bloom_filter.c     |   2 +-
 drivers/net/ethernet/realtek/r8169_main.c          |  10 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     |   2 +-
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    |  14 +-
 drivers/net/ethernet/toshiba/spider_net.c          |   2 +-
 drivers/net/gtp.c                                  |   4 +-
 drivers/net/ipvlan/ipvlan_core.c                   |   8 +-
 drivers/net/ipvlan/ipvlan_main.c                   |   1 +
 drivers/net/macsec.c                               |   6 +-
 drivers/net/virtio_net.c                           | 124 ++++----
 drivers/net/wireless/ath/ath11k/mac.c              |   8 +
 drivers/net/wireless/ath/ath11k/pci.c              |  24 +-
 drivers/net/wireless/ath/ath12k/dp_rx.c            |   2 +-
 drivers/net/wireless/ath/ath12k/dp_tx.c            |   7 +-
 drivers/net/wireless/ath/dfs_pattern_detector.c    |   2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/bz.c        |  14 +-
 drivers/net/wireless/intel/iwlwifi/cfg/sc.c        |  10 +-
 drivers/net/wireless/intel/iwlwifi/dvm/tx.c        |   5 +-
 .../net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h    |   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-config.h    |   5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h   |   5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c       |  51 ++--
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h      |   4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h     |  11 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c        |  10 +
 .../net/wireless/intel/iwlwifi/mvm/ftm-responder.c |   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/link.c      |  22 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c  |   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  | 182 +++++-------
 drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c   |  16 +-
 .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c  | 105 +++----
 drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c   |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h       |   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c       |  12 +-
 .../net/wireless/intel/iwlwifi/mvm/time-event.c    |  31 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c        |  36 +--
 .../net/wireless/intel/iwlwifi/pcie/trans-gen2.c   |   1 +
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c    |   1 +
 drivers/net/wireless/intel/iwlwifi/queue/tx.c      |   9 +-
 drivers/net/wireless/intel/iwlwifi/queue/tx.h      |   2 +-
 drivers/net/wireless/mediatek/mt76/dma.c           |   3 -
 drivers/net/wireless/mediatek/mt76/mt7603/beacon.c |  76 +++--
 drivers/net/wireless/mediatek/mt76/mt7603/core.c   |   2 +
 drivers/net/wireless/mediatek/mt76/mt7603/mac.c    |  52 ++--
 drivers/net/wireless/mediatek/mt76/mt7603/regs.h   |   5 +
 drivers/net/wireless/mediatek/mt76/mt7615/mcu.c    |   2 +-
 .../net/wireless/mediatek/mt76/mt7615/pci_mac.c    |   2 +-
 .../net/wireless/mediatek/mt76/mt76_connac3_mac.h  | 327 +++++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt76_connac_mac.c   |  17 --
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c    |   2 +-
 drivers/net/wireless/mediatek/mt76/mt7915/main.c   |   8 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c    |  69 +++--
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.h    |  18 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h |   2 +
 .../net/wireless/mediatek/mt76/mt7921/pci_mac.c    |   2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/init.c   |   9 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c    |  12 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mac.h    | 315 +-------------------
 drivers/net/wireless/mediatek/mt76/mt7996/main.c   |  16 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c    |  67 +++--
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.h    |  11 +-
 .../net/wireless/realtek/rtlwifi/rtl8188ee/dm.c    |   2 +-
 .../wireless/realtek/rtlwifi/rtl8192c/dm_common.c  |   2 +-
 .../net/wireless/realtek/rtlwifi/rtl8723ae/dm.c    |   2 +-
 drivers/net/wireless/realtek/rtw88/debug.c         |   4 +-
 drivers/net/wireless/realtek/rtw88/usb.c           |   9 +-
 drivers/net/wireless/silabs/wfx/data_tx.c          |  71 ++---
 drivers/nvdimm/of_pmem.c                           |   8 +-
 drivers/nvdimm/region_devs.c                       |   8 +-
 drivers/nvme/host/ioctl.c                          |   7 +-
 drivers/pci/controller/vmd.c                       |   3 +-
 drivers/pci/endpoint/pci-epc-core.c                |   1 -
 drivers/pci/pcie/aspm.c                            |   3 +-
 drivers/pcmcia/cs.c                                |   1 +
 drivers/pcmcia/ds.c                                |  14 +-
 drivers/perf/arm-cmn.c                             |  16 +-
 drivers/perf/arm_pmuv3.c                           |   6 +-
 drivers/perf/hisilicon/hisi_pcie_pmu.c             |   7 +-
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c        |   4 +-
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c      |   4 +-
 drivers/perf/hisilicon/hns3_pmu.c                  |   8 +-
 drivers/pinctrl/renesas/pinctrl-rzg2l.c            |   3 +-
 drivers/platform/chrome/cros_ec.c                  | 116 ++++++--
 drivers/platform/chrome/cros_ec.h                  |   4 +
 drivers/platform/chrome/cros_ec_lpc.c              |  22 +-
 drivers/platform/x86/wmi.c                         |  36 +--
 drivers/pwm/pwm-brcmstb.c                          |   4 +-
 drivers/pwm/pwm-sti.c                              |  29 +-
 drivers/regulator/mt6358-regulator.c               |  14 +-
 drivers/regulator/qcom-rpmh-regulator.c            |   2 +-
 drivers/rtc/rtc-brcmstb-waketimer.c                |  47 ++-
 drivers/rtc/rtc-pcf85363.c                         |  30 +-
 drivers/s390/crypto/ap_bus.c                       |  21 +-
 drivers/s390/crypto/ap_bus.h                       |   1 +
 drivers/s390/crypto/ap_queue.c                     |   9 +-
 drivers/scsi/ibmvscsi/ibmvfc.c                     |   3 +-
 drivers/soc/qcom/llcc-qcom.c                       |   3 +
 drivers/soc/qcom/pmic_glink_altmode.c              |   2 +-
 drivers/spi/Kconfig                                |   1 +
 drivers/spi/spi-nxp-fspi.c                         |   2 +-
 drivers/spi/spi-omap2-mcspi.c                      | 267 +++++++++--------
 drivers/spi/spi-tegra20-slink.c                    |   2 +
 drivers/staging/media/sunxi/cedrus/cedrus_hw.c     |  24 +-
 drivers/thermal/mediatek/auxadc_thermal.c          |   2 +-
 drivers/thermal/thermal_core.c                     |   6 +-
 drivers/thermal/thermal_trip.c                     |  19 +-
 drivers/tty/tty_jobctrl.c                          |  17 +-
 drivers/ufs/core/ufshcd.c                          |   2 +-
 drivers/usb/chipidea/host.c                        |  48 ++-
 drivers/usb/dwc2/hcd.c                             |   2 +-
 drivers/usb/host/xhci-pci.c                        |   2 +
 drivers/usb/host/xhci-plat.c                       |  23 +-
 drivers/usb/usbip/stub_dev.c                       |   9 +-
 drivers/video/backlight/pwm_bl.c                   |  22 ++
 drivers/video/fbdev/fsl-diu-fb.c                   |   2 +-
 drivers/video/fbdev/imsttfb.c                      |  35 ++-
 drivers/virt/coco/sev-guest/sev-guest.c            |  45 +--
 drivers/watchdog/ixp4xx_wdt.c                      |  28 +-
 drivers/xen/xen-pciback/conf_space.c               |  19 +-
 drivers/xen/xen-pciback/conf_space_capability.c    |   8 +-
 drivers/xen/xen-pciback/conf_space_header.c        |  21 +-
 drivers/xen/xenbus/xenbus_probe.c                  |   2 +-
 fs/btrfs/ioctl.c                                   |  10 +-
 fs/btrfs/scrub.c                                   |  10 +-
 fs/dlm/midcomms.c                                  |   6 +-
 fs/erofs/utils.c                                   |   8 +-
 fs/erofs/zdata.c                                   |   1 +
 fs/ext4/extents.c                                  |  10 +-
 fs/f2fs/data.c                                     |  24 +-
 fs/f2fs/file.c                                     |   1 +
 fs/f2fs/super.c                                    |  35 ++-
 fs/fs-writeback.c                                  |  41 ++-
 fs/nfsd/filecache.c                                |  27 +-
 fs/nfsd/vfs.c                                      |  28 +-
 fs/nfsd/vfs.h                                      |   4 +-
 fs/pstore/platform.c                               |   9 +-
 include/drm/bridge/samsung-dsim.h                  |   1 +
 include/linux/bpf.h                                |   5 +
 include/linux/clk-provider.h                       |  15 +-
 include/linux/cpuhotplug.h                         |   1 +
 include/linux/hisi_acc_qm.h                        |   7 +
 include/linux/hw_random.h                          |   1 +
 include/linux/idr.h                                |   6 +-
 include/linux/mfd/core.h                           |   2 +-
 include/linux/netdevice.h                          |   1 +
 include/linux/numa.h                               |  14 +-
 include/linux/objtool.h                            |   3 +-
 include/linux/pci.h                                |  34 ++-
 include/linux/perf_event.h                         |   1 +
 include/linux/pm.h                                 |  43 ++-
 include/linux/string.h                             |   7 +-
 include/linux/topology.h                           |   2 +-
 include/linux/udp.h                                |  66 +++--
 include/linux/verification.h                       |   1 +
 include/net/bluetooth/hci.h                        |   3 +
 include/net/bluetooth/hci_core.h                   |  59 +++-
 include/net/cfg80211.h                             |  21 ++
 include/net/flow.h                                 |   2 +-
 include/net/netfilter/nf_conntrack_act_ct.h        |  30 +-
 include/net/tcp.h                                  |   2 +-
 include/net/udp_tunnel.h                           |   9 +-
 include/net/udplite.h                              |  14 +-
 include/soc/tegra/bpmp.h                           |   6 +
 io_uring/kbuf.c                                    |  11 +-
 io_uring/net.c                                     |  24 +-
 kernel/bpf/hashtab.c                               |   7 +-
 kernel/bpf/helpers.c                               |  32 +-
 kernel/bpf/trampoline.c                            |   4 +-
 kernel/bpf/verifier.c                              |   7 +
 kernel/cpu.c                                       |  66 +++--
 kernel/events/core.c                               | 115 ++++----
 kernel/futex/core.c                                |  12 +-
 kernel/irq/matrix.c                                |   6 +-
 kernel/livepatch/core.c                            |   2 +-
 kernel/module/decompress.c                         |   8 +-
 kernel/padata.c                                    |   6 +-
 kernel/rcu/srcutree.c                              |  31 +-
 kernel/sched/core.c                                |  10 +-
 kernel/sched/deadline.c                            |   2 +
 kernel/sched/fair.c                                |  35 +--
 kernel/sched/rt.c                                  |   4 +
 kernel/sched/topology.c                            |   6 +-
 kernel/trace/trace_kprobe.c                        |   2 +-
 lib/kunit/executor.c                               |   4 +-
 lib/kunit/executor_test.c                          |  30 +-
 mm/mempolicy.c                                     |  18 +-
 mm/readahead.c                                     |   3 +-
 net/9p/client.c                                    |   6 +-
 net/bluetooth/amp.c                                |   3 +-
 net/bluetooth/hci_conn.c                           |  71 +++--
 net/bluetooth/hci_core.c                           |   3 +
 net/bluetooth/hci_event.c                          |  99 +++++--
 net/bluetooth/hci_sync.c                           |  19 +-
 net/bluetooth/iso.c                                | 169 ++++++++---
 net/core/page_pool.c                               |   6 +-
 net/core/skbuff.c                                  |   3 +-
 net/dccp/ipv4.c                                    |   6 +-
 net/dccp/ipv6.c                                    |   6 +-
 net/hsr/hsr_forward.c                              |   4 +-
 net/ipv4/syncookies.c                              |  20 +-
 net/ipv4/tcp_input.c                               |   9 +-
 net/ipv4/tcp_metrics.c                             |  15 +-
 net/ipv4/udp.c                                     |  74 ++---
 net/ipv4/udp_offload.c                             |   4 +-
 net/ipv4/udp_tunnel_core.c                         |   2 +-
 net/ipv4/udplite.c                                 |   1 -
 net/ipv4/xfrm4_input.c                             |   4 +-
 net/ipv6/ip6_output.c                              |   8 +-
 net/ipv6/syncookies.c                              |   7 +-
 net/ipv6/udp.c                                     |  34 ++-
 net/ipv6/udplite.c                                 |   1 -
 net/ipv6/xfrm6_input.c                             |   4 +-
 net/l2tp/l2tp_core.c                               |   6 +-
 net/llc/llc_input.c                                |  10 +-
 net/llc/llc_s_ac.c                                 |   3 +
 net/llc/llc_station.c                              |   3 +
 net/mac80211/driver-ops.c                          |   9 +-
 net/mac80211/drop.h                                |   3 +
 net/mac80211/ieee80211_i.h                         |  18 +-
 net/mac80211/iface.c                               |   2 +-
 net/mac80211/link.c                                |   2 +-
 net/mac80211/main.c                                |  25 +-
 net/mac80211/mesh_pathtbl.c                        |   2 +-
 net/mac80211/offchannel.c                          |  36 +--
 net/mac80211/rx.c                                  |   2 +-
 net/mac80211/scan.c                                |  36 +--
 net/mac80211/sta_info.c                            |   2 +-
 net/mac80211/util.c                                |  11 +-
 net/mptcp/fastopen.c                               |   1 +
 net/netfilter/nf_nat_redirect.c                    |  27 +-
 net/netfilter/nf_tables_api.c                      |   4 -
 net/netfilter/xt_recent.c                          |   2 +-
 net/openvswitch/conntrack.c                        |   2 +-
 net/rxrpc/conn_object.c                            |   2 +-
 net/rxrpc/local_object.c                           |   2 +-
 net/sched/act_ct.c                                 |  15 +-
 net/smc/af_smc.c                                   |   4 +-
 net/smc/smc.h                                      |   5 +
 net/smc/smc_cdc.c                                  |  11 +-
 net/smc/smc_close.c                                |   5 +-
 net/tipc/link.c                                    |   4 +-
 net/tipc/netlink.c                                 |   4 +-
 net/tls/tls_sw.c                                   |   2 +-
 net/vmw_vsock/virtio_transport_common.c            |  16 +-
 net/wireless/core.c                                |  34 ++-
 net/wireless/core.h                                |   3 +-
 net/wireless/scan.c                                |   4 +-
 net/wireless/sysfs.c                               |   4 +-
 scripts/Makefile.vmlinux_o                         |   3 +-
 scripts/gdb/linux/constants.py.in                  |   9 +-
 scripts/mod/file2alias.c                           |  14 +-
 security/apparmor/policy.c                         |   1 +
 security/apparmor/policy_unpack.c                  |   5 +-
 sound/pci/hda/cs35l41_hda.c                        |   5 +-
 sound/pci/hda/patch_realtek.c                      |  40 ++-
 sound/soc/codecs/cs35l41-lib.c                     |   2 +-
 sound/soc/codecs/cs35l41.c                         |  18 +-
 sound/soc/codecs/hdmi-codec.c                      |  27 +-
 sound/soc/fsl/fsl-asoc-card.c                      |   1 +
 sound/soc/fsl/fsl_easrc.c                          |   8 +-
 sound/soc/fsl/mpc5200_dma.c                        |   3 +
 .../soc/intel/boards/sof_sdw_rt_sdca_jack_common.c |   8 +
 sound/soc/intel/skylake/skl-sst-utils.c            |   1 +
 .../mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c |   4 +-
 sound/soc/soc-dapm.c                               |   2 +-
 sound/soc/soc-pcm.c                                |  21 +-
 sound/soc/sof/core.c                               |   6 +-
 sound/soc/sof/ipc4-topology.c                      |   3 +-
 sound/soc/ti/ams-delta.c                           |   4 +-
 tools/iio/iio_generic_buffer.c                     |  13 +-
 tools/lib/perf/include/internal/rc_check.h         |   6 +-
 tools/objtool/objtool.c                            |   4 +-
 tools/perf/Documentation/perf-kwork.txt            |   2 +-
 tools/perf/Makefile.perf                           |   4 +
 tools/perf/arch/arm64/util/mem-events.c            |   2 +-
 tools/perf/arch/powerpc/util/mem-events.c          |   6 +-
 tools/perf/arch/x86/util/mem-events.c              |   8 +-
 tools/perf/arch/x86/util/pmu.c                     |  10 +-
 tools/perf/builtin-kwork.c                         |  13 +-
 tools/perf/builtin-list.c                          |   2 +-
 tools/perf/builtin-lock.c                          |  17 +-
 tools/perf/builtin-stat.c                          |   2 +-
 tools/perf/examples/bpf/augmented_raw_syscalls.c   |  16 +-
 .../perf/pmu-events/arch/powerpc/power10/pmc.json  |   2 +-
 .../arch/x86/broadwellde/bdwde-metrics.json        |  14 +-
 tools/perf/tests/pmu-events.c                      |  16 +-
 tools/perf/util/bpf_off_cpu.c                      |   5 +-
 tools/perf/util/bpf_skel/vmlinux/.gitignore        |   1 +
 tools/perf/util/env.c                              |   8 +-
 tools/perf/util/header.c                           |   8 +-
 tools/perf/util/hist.c                             |  10 +-
 tools/perf/util/machine.c                          |  22 +-
 tools/perf/util/mem-events.c                       |  19 +-
 tools/perf/util/mem-events.h                       |   2 +-
 tools/perf/util/parse-events.c                     |  15 +-
 tools/perf/util/parse-events.h                     |   2 +-
 tools/perf/util/parse-events.l                     |  11 -
 tools/perf/util/parse-events.y                     | 196 +-----------
 tools/perf/util/pmu.c                              |  16 +-
 tools/perf/util/pmu.h                              |   8 +-
 tools/power/cpupower/man/cpupower-powercap-info.1  |   2 +-
 tools/testing/cxl/test/mem.c                       |   4 +-
 .../bpf/prog_tests/module_fentry_shadow.c          |   5 +
 tools/testing/selftests/bpf/prog_tests/tailcalls.c |  32 +-
 tools/testing/selftests/mm/mdwe_test.c             |   9 +-
 tools/testing/selftests/net/mptcp/mptcp_join.sh    |  14 +-
 tools/testing/selftests/net/pmtu.sh                |   2 +-
 tools/testing/selftests/netfilter/Makefile         |   5 +-
 .../netfilter/conntrack_sctp_collision.sh          |  89 ++++++
 tools/testing/selftests/netfilter/sctp_collision.c |  99 +++++++
 tools/testing/selftests/netfilter/xt_string.sh     | 128 ++++++++
 tools/testing/selftests/pidfd/pidfd_fdinfo_test.c  |   2 +-
 tools/testing/selftests/pidfd/pidfd_test.c         |  12 +-
 tools/testing/selftests/resctrl/resctrl_tests.c    |   5 +
 tools/testing/selftests/x86/lam.c                  |   6 +-
 tools/tracing/rtla/src/utils.c                     |   2 +-
 607 files changed, 7847 insertions(+), 4412 deletions(-)
author maintainer
#1 lore raw

PATCH 1/550 hwmon: (nct6775) Fix incorrect variable reuse in fan_div calculation

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zev Weiss <[email protected]>

commit 920057ad521dc8669e534736c2a12c14ec9fb2d7 upstream.

In the regmap conversion in commit 4ef2774511dc ("hwmon: (nct6775) Convert register access to regmap API") I reused the 'reg' variable for all three register reads in the fan speed calculation loop in nct6775_update_device(), but failed to notice that the value from the first one (data->REG_FAN[i]) is actually used in the call to nct6775_select_fan_div() at the end of the loop body. Since that patch the register value passed to nct6775_select_fan_div() has been (conditionally) incorrectly clobbered with the value of a different register than intended, which has in at least some cases resulted in fan speeds being adjusted down to zero.

Fix this by using dedicated temporaries for the two intermediate register reads instead of 'reg'.

---
 drivers/hwmon/nct6775-core.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/hwmon/nct6775-core.c +8 -4
@@ -1581,17 +1581,21 @@ struct nct6775_data *nct6775_update_devi
 							  data->fan_div[i]);
 
 			if (data->has_fan_min & BIT(i)) {
-				err = nct6775_read_value(data, data->REG_FAN_MIN[i], &reg);
+				u16 tmp;
+
+				err = nct6775_read_value(data, data->REG_FAN_MIN[i], &tmp);
 				if (err)
 					goto out;
-				data->fan_min[i] = reg;
+				data->fan_min[i] = tmp;
 			}
 
 			if (data->REG_FAN_PULSES[i]) {
-				err = nct6775_read_value(data, data->REG_FAN_PULSES[i], &reg);
+				u16 tmp;
+
+				err = nct6775_read_value(data, data->REG_FAN_PULSES[i], &tmp);
 				if (err)
 					goto out;
-				data->fan_pulses[i] = (reg >> data->FAN_PULSE_SHIFT[i]) & 0x03;
+				data->fan_pulses[i] = (tmp >> data->FAN_PULSE_SHIFT[i]) & 0x03;
 			}
 
 			err = nct6775_select_fan_div(dev, data, i, reg);
author maintainer
#2 lore raw

PATCH 2/550 numa: Generalize numa_map_to_online_node()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yury Norov <[email protected]>

[ Upstream commit b1f099b1cf51d553c510c6c8141c27d9ba7ea1fe ]

The function in fact searches the nearest node for a given one, based on a N_ONLINE state. This is a common pattern to search for a nearest node.

This patch converts numa_map_to_online_node() to numa_nearest_node() so that others won't need to opencode the logic.

Stable-dep-of: 617f2c38cb5c ("sched/topology: Fix sched_numa_find_nth_cpu() in CPU-less case")

---
 include/linux/numa.h |  7 +++++--
 mm/mempolicy.c       | 18 +++++++++++-------
 2 files changed, 16 insertions(+), 9 deletions(-)
include/linux/numa.h +5 -2
index 59df211d051fa..fb30a42f0700d 100644
@@ -25,7 +25,7 @@
 #include <asm/sparsemem.h>
 
 /* Generic implementation available */
-int numa_map_to_online_node(int node);
+int numa_nearest_node(int node, unsigned int state);
 
 #ifndef memory_add_physaddr_to_nid
 static inline int memory_add_physaddr_to_nid(u64 start)
@@ -44,10 +44,11 @@ static inline int phys_to_target_node(u64 start)
 }
 #endif
 #else /* !CONFIG_NUMA */
-static inline int numa_map_to_online_node(int node)
+static inline int numa_nearest_node(int node, unsigned int state)
 {
 	return NUMA_NO_NODE;
 }
+
 static inline int memory_add_physaddr_to_nid(u64 start)
 {
 	return 0;
@@ -58,6 +59,8 @@ static inline int phys_to_target_node(u64 start)
 }
 #endif
 
+#define numa_map_to_online_node(node) numa_nearest_node(node, N_ONLINE)
+
 #ifdef CONFIG_HAVE_ARCH_NODE_DEV_GROUP
 extern const struct attribute_group arch_node_dev_group;
 #endif
mm/mempolicy.c +11 -7
index 7d82355ad0b3b..03172a2fd5b3f 100644
@@ -131,22 +131,26 @@ static struct mempolicy default_policy = {
 static struct mempolicy preferred_node_policy[MAX_NUMNODES];
 
 /**
- * numa_map_to_online_node - Find closest online node
+ * numa_nearest_node - Find nearest node by state
  * @node: Node id to start the search
+ * @state: State to filter the search
  *
- * Lookup the next closest node by distance if @nid is not online.
+ * Lookup the closest node by distance if @nid is not in state.
  *
- * Return: this @node if it is online, otherwise the closest node by distance
+ * Return: this @node if it is in state, otherwise the closest node by distance
  */
-int numa_map_to_online_node(int node)
+int numa_nearest_node(int node, unsigned int state)
 {
 	int min_dist = INT_MAX, dist, n, min_node;
 
-	if (node == NUMA_NO_NODE || node_online(node))
+	if (state >= NR_NODE_STATES)
+		return -EINVAL;
+
+	if (node == NUMA_NO_NODE || node_state(node, state))
 		return node;
 
 	min_node = node;
-	for_each_online_node(n) {
+	for_each_node_state(n, state) {
 		dist = node_distance(node, n);
 		if (dist < min_dist) {
 			min_dist = dist;
@@ -156,7 +160,7 @@ int numa_map_to_online_node(int node)
 
 	return min_node;
 }
-EXPORT_SYMBOL_GPL(numa_map_to_online_node);
+EXPORT_SYMBOL_GPL(numa_nearest_node);
 
 struct mempolicy *get_task_policy(struct task_struct *p)
 {
Signature · 1 line
2.42.0
author maintainer
#3 lore raw

PATCH 3/550 sched/topology: Fix sched_numa_find_nth_cpu() in CPU-less case

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yury Norov <[email protected]>

[ Upstream commit 617f2c38cb5ce60226042081c09e2ee3a90d03f8 ]

When the node provided by user is CPU-less, corresponding record in sched_domains_numa_masks is not set. Trying to dereference it in the following code leads to kernel crash.

To avoid it, start searching from the nearest node with CPUs.

---
 kernel/sched/topology.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/sched/topology.c +5 -1
index d3a3b2646ec4f..c6e89afa0d65c 100644
@@ -2113,12 +2113,16 @@ static int hop_cmp(const void *a, const void *b)
  */
 int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node)
 {
-	struct __cmp_key k = { .cpus = cpus, .node = node, .cpu = cpu };
+	struct __cmp_key k = { .cpus = cpus, .cpu = cpu };
 	struct cpumask ***hop_masks;
 	int hop, ret = nr_cpu_ids;
 
 	rcu_read_lock();
 
+	/* CPU-less node entries are uninitialized in sched_domains_numa_masks */
+	node = numa_nearest_node(node, N_CPU);
+	k.node = node;
+
 	k.masks = rcu_dereference(sched_domains_numa_masks);
 	if (!k.masks)
 		goto unlock;
Signature · 1 line
2.42.0
author maintainer
#4 lore raw

PATCH 4/550 sched/topology: Fix sched_numa_find_nth_cpu() in non-NUMA case

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yury Norov <[email protected]>

[ Upstream commit 8ab63d418d4339d996f80d02a00dbce0aa3ff972 ]

When CONFIG_NUMA is enabled, sched_numa_find_nth_cpu() searches for a CPU in sched_domains_numa_masks. The masks includes only online CPUs, so effectively offline CPUs are skipped.

When CONFIG_NUMA is disabled, the fallback function should be consistent.

Fixes cd7f55359c90 ("sched: add sched_numa_find_nth_cpu()")
Cc Mel Gorman <[email protected]>
---
 include/linux/topology.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/topology.h +1 -1
index fea32377f7c77..52f5850730b3e 100644
@@ -251,7 +251,7 @@ extern const struct cpumask *sched_numa_hop_mask(unsigned int node, unsigned int
 #else
 static __always_inline int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node)
 {
-	return cpumask_nth(cpu, cpus);
+	return cpumask_nth_and(cpu, cpus, cpu_online_mask);
 }
 
 static inline const struct cpumask *
Signature · 1 line
2.42.0
author maintainer
#5 lore raw

PATCH 5/550 sched/fair: Fix cfs_rq_is_decayed() on !SMP

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chengming Zhou <[email protected]>

[ Upstream commit c0490bc9bb62d9376f3dd4ec28e03ca0fef97152 ]

We don't need to maintain per-queue leaf_cfs_rq_list on !SMP, since it's used for cfs_rq load tracking & balancing on SMP.

But sched debug interface uses it to print per-cfs_rq stats.

This patch fixes the !SMP version of cfs_rq_is_decayed(), so the per-queue leaf_cfs_rq_list is also maintained correctly on !SMP, to fix the warning in assert_list_leaf_cfs_rq().

---
 kernel/sched/fair.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/fair.c +1 -1
index 1d9c2482c5a35..7e3ed4f447fdf 100644
@@ -4654,7 +4654,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
 
 static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq)
 {
-	return true;
+	return !cfs_rq->nr_running;
 }
 
 #define UPDATE_TG	0x0
Signature · 1 line
2.42.0
author maintainer
#6 lore raw

PATCH 6/550 iov_iter, x86: Be consistent about the __user tag on copy_mc_to_user()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Howells <[email protected]>

[ Upstream commit 066baf92bed934c9fb4bcee97a193f47aa63431c ]

copy_mc_to_user() has the destination marked __user on powerpc, but not on x86; the latter results in a sparse warning in lib/iov_iter.c.

Fix this by applying the tag on x86 too.

Fixes ec6347bb4339 ("x86, powerpc: Rename memcpy_mcsafe() to copy_mc_to_{user, kernel}()")
cc Dan Williams <[email protected]>
cc Thomas Gleixner <[email protected]>
cc Ingo Molnar <[email protected]>
cc Borislav Petkov <[email protected]>
cc Dave Hansen <[email protected]>
cc "H. Peter Anvin" <[email protected]>
cc Alexander Viro <[email protected]>
cc Jens Axboe <[email protected]>
cc Christoph Hellwig <[email protected]>
cc Christian Brauner <[email protected]>
cc Matthew Wilcox <[email protected]>
cc Linus Torvalds <[email protected]>
cc David Laight <[email protected]>
---
 arch/x86/include/asm/uaccess.h | 2 +-
 arch/x86/lib/copy_mc.c         | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/x86/include/asm/uaccess.h +1 -1
index 8bae40a662827..5c367c1290c35 100644
@@ -496,7 +496,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len);
 #define copy_mc_to_kernel copy_mc_to_kernel
 
 unsigned long __must_check
-copy_mc_to_user(void *to, const void *from, unsigned len);
+copy_mc_to_user(void __user *to, const void *from, unsigned len);
 #endif
 
 /*
arch/x86/lib/copy_mc.c +4 -4
index 80efd45a77617..6e8b7e600def5 100644
@@ -70,23 +70,23 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne
 }
 EXPORT_SYMBOL_GPL(copy_mc_to_kernel);
 
-unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len)
+unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, unsigned len)
 {
 	unsigned long ret;
 
 	if (copy_mc_fragile_enabled) {
 		__uaccess_begin();
-		ret = copy_mc_fragile(dst, src, len);
+		ret = copy_mc_fragile((__force void *)dst, src, len);
 		__uaccess_end();
 		return ret;
 	}
 
 	if (static_cpu_has(X86_FEATURE_ERMS)) {
 		__uaccess_begin();
-		ret = copy_mc_enhanced_fast_string(dst, src, len);
+		ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len);
 		__uaccess_end();
 		return ret;
 	}
 
-	return copy_user_generic(dst, src, len);
+	return copy_user_generic((__force void *)dst, src, len);
 }
Signature · 1 line
2.42.0
author maintainer
#7 lore raw

PATCH 7/550 sched/uclamp: Set max_spare_cap_cpu even if max_spare_cap is 0

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Qais Yousef <[email protected]>

[ Upstream commit 6b00a40147653c8ea748e8f4396510f252763364 ]

When uclamp_max is being used, the util of the task could be higher than the spare capacity of the CPU, but due to uclamp_max value we force-fit it there.

The way the condition for checking for max_spare_cap in find_energy_efficient_cpu() was constructed; it ignored any CPU that has its spare_cap less than or _equal_ to max_spare_cap. Since we initialize max_spare_cap to 0; this lead to never setting max_spare_cap_cpu and hence ending up never performing compute_energy() for this cluster and missing an opportunity for a better energy efficient placement to honour uclamp_max setting.

	max_spare_cap = 0;
	cpu_cap = capacity_of(cpu) - cpu_util(p);  // 0 if cpu_util(p) is high

	...

	util_fits_cpu(...);		// will return true if uclamp_max forces it to fit

	...

	// this logic will fail to update max_spare_cap_cpu if cpu_cap is 0
	if (cpu_cap > max_spare_cap) {
		max_spare_cap = cpu_cap;
		max_spare_cap_cpu = cpu;
	}

prev_spare_cap suffers from a similar problem.

Fix the logic by converting the variables into long and treating -1 value as 'not populated' instead of 0 which is a viable and correct spare capacity value. We need to be careful signed comparison is used when comparing with cpu_cap in one of the conditions.

---
 kernel/sched/fair.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
kernel/sched/fair.c +5 -6
index 7e3ed4f447fdf..4ee95125d17a0 100644
@@ -7562,11 +7562,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 	for (; pd; pd = pd->next) {
 		unsigned long util_min = p_util_min, util_max = p_util_max;
 		unsigned long cpu_cap, cpu_thermal_cap, util;
-		unsigned long cur_delta, max_spare_cap = 0;
+		long prev_spare_cap = -1, max_spare_cap = -1;
 		unsigned long rq_util_min, rq_util_max;
-		unsigned long prev_spare_cap = 0;
+		unsigned long cur_delta, base_energy;
 		int max_spare_cap_cpu = -1;
-		unsigned long base_energy;
 		int fits, max_fits = -1;
 
 		cpumask_and(cpus, perf_domain_span(pd), cpu_online_mask);
@@ -7629,7 +7628,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 				prev_spare_cap = cpu_cap;
 				prev_fits = fits;
 			} else if ((fits > max_fits) ||
-				   ((fits == max_fits) && (cpu_cap > max_spare_cap))) {
+				   ((fits == max_fits) && ((long)cpu_cap > max_spare_cap))) {
 				/*
 				 * Find the CPU with the maximum spare capacity
 				 * among the remaining CPUs in the performance
@@ -7641,7 +7640,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 			}
 		}
 
-		if (max_spare_cap_cpu < 0 && prev_spare_cap == 0)
+		if (max_spare_cap_cpu < 0 && prev_spare_cap < 0)
 			continue;
 
 		eenv_pd_busy_time(&eenv, cpus, p);
@@ -7649,7 +7648,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 		base_energy = compute_energy(&eenv, pd, cpus, p, -1);
 
 		/* Evaluate the energy impact of using prev_cpu. */
-		if (prev_spare_cap > 0) {
+		if (prev_spare_cap > -1) {
 			prev_delta = compute_energy(&eenv, pd, cpus, p,
 						    prev_cpu);
 			/* CPU utilization has changed */
Signature · 1 line
2.42.0
author maintainer
#8 lore raw

PATCH 8/550 sched/uclamp: Ignore (util == 0) optimization in feec() when p_util_max = 0

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Qais Yousef <[email protected]>

[ Upstream commit 23c9519def98ee0fa97ea5871535e9b136f522fc ]

find_energy_efficient_cpu() bails out early if effective util of the task is 0 as the delta at this point will be zero and there's nothing for EAS to do. When uclamp is being used, this could lead to wrong decisions when uclamp_max is set to 0. In this case the task is capped to performance point 0, but it is actually running and consuming energy and we can benefit from EAS energy calculations.

Rework the condition so that it bails out when both util and uclamp_min are 0.

We can do that without needing to use uclamp_task_util(); remove it.

Fixes d81304bc6193 ("sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()'s early exit condition")
---
 kernel/sched/fair.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)
kernel/sched/fair.c +1 -17
index 4ee95125d17a0..a87ef35d5424a 100644
@@ -4348,22 +4348,6 @@ static inline unsigned long task_util_est(struct task_struct *p)
 	return max(task_util(p), _task_util_est(p));
 }
 
-#ifdef CONFIG_UCLAMP_TASK
-static inline unsigned long uclamp_task_util(struct task_struct *p,
-					     unsigned long uclamp_min,
-					     unsigned long uclamp_max)
-{
-	return clamp(task_util_est(p), uclamp_min, uclamp_max);
-}
-#else
-static inline unsigned long uclamp_task_util(struct task_struct *p,
-					     unsigned long uclamp_min,
-					     unsigned long uclamp_max)
-{
-	return task_util_est(p);
-}
-#endif
-
 static inline void util_est_enqueue(struct cfs_rq *cfs_rq,
 				    struct task_struct *p)
 {
@@ -7554,7 +7538,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 	target = prev_cpu;
 
 	sync_entity_load_avg(&p->se);
-	if (!uclamp_task_util(p, p_util_min, p_util_max))
+	if (!task_util_est(p) && p_util_min == 0)
 		goto unlock;
 
 	eenv_task_busy_time(&eenv, p, prev_cpu);
Signature · 1 line
2.42.0
author maintainer
#9 lore raw

PATCH 9/550 objtool: Propagate early errors

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaron Plattner <[email protected]>

[ Upstream commit e959c279d391c10b35ce300fb4b0fe3b98e86bd2 ]

If objtool runs into a problem that causes it to exit early, the overall tool still returns a status code of 0, which causes the build to continue as if nothing went wrong.

Note this only affects early errors, as later errors are still ignored by check().

---
 tools/objtool/objtool.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
tools/objtool/objtool.c +1 -3
index c54f7235c5d94..f40febdd6e36a 100644
@@ -146,7 +146,5 @@ int main(int argc, const char **argv)
 	exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED);
 	pager_init(UNUSED);
 
-	objtool_run(argc, argv);
-
-	return 0;
+	return objtool_run(argc, argv);
 }
Signature · 1 line
2.42.0
author maintainer
#10 lore raw

PATCH 10/550 sched: Fix stop_one_cpu_nowait() vs hotplug

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

[ Upstream commit f0498d2a54e7966ce23cd7c7ff42c64fa0059b07 ]

Kuyo reported sporadic failures on a sched_setaffinity() vs CPU hotplug stress-test -- notably affine_move_task() remains stuck in wait_for_completion(), leading to a hung-task detector warning.

Specifically, it was reported that stop_one_cpu_nowait(.fn = migration_cpu_stop) returns false -- this stopper is responsible for the matching complete().

The race scenario is:

	CPU0					CPU1

					// doing _cpu_down()

__set_cpus_allowed_ptr()

    task_rq_lock();
					takedown_cpu()
					  stop_machine_cpuslocked(take_cpu_down..)

					<PREEMPT: cpu_stopper_thread()
					  MULTI_STOP_PREPARE
					  ...
    __set_cpus_allowed_ptr_locked()
      affine_move_task()
        task_rq_unlock();

<PREEMPT: cpu_stopper_thread()\>

    ack_state()
					  MULTI_STOP_RUN
					    take_cpu_down()
					      __cpu_disable();
					      stop_machine_park();
						stopper->enabled = false;
					 />
   />
	stop_one_cpu_nowait(.fn = migration_cpu_stop);
          if (stopper->enabled) // false!!!

That is, by doing stop_one_cpu_nowait() after dropping rq-lock, the stopper thread gets a chance to preempt and allows the cpu-down for the target CPU to complete.

OTOH, since stop_one_cpu_nowait() / cpu_stop_queue_work() needs to issue a wakeup, it must not be ran under the scheduler locks.

Solve this apparent contradiction by keeping preemption disabled over the unlock + queue_stopper combination:

	preempt_disable();
	task_rq_unlock(...);
	if (!stop_pending)
	  stop_one_cpu_nowait(...)
	preempt_enable();

This respects the lock ordering contraints while still avoiding the above race. That is, if we find the CPU is online under rq-lock, the targeted stop_one_cpu_nowait() must succeed.

Apply this pattern to all similar stop_one_cpu_nowait() invocations.

---
 kernel/sched/core.c     | 10 ++++++++--
 kernel/sched/deadline.c |  2 ++
 kernel/sched/fair.c     |  4 +++-
 kernel/sched/rt.c       |  4 ++++
 4 files changed, 17 insertions(+), 3 deletions(-)
kernel/sched/core.c +8 -2
index e8f73ff12126c..149fdb212e20f 100644
@@ -2644,9 +2644,11 @@ static int migration_cpu_stop(void *data)
 		 * it.
 		 */
 		WARN_ON_ONCE(!pending->stop_pending);
+		preempt_disable();
 		task_rq_unlock(rq, p, &rf);
 		stop_one_cpu_nowait(task_cpu(p), migration_cpu_stop,
 				    &pending->arg, &pending->stop_work);
+		preempt_enable();
 		return 0;
 	}
 out:
@@ -2966,12 +2968,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
 			complete = true;
 		}
 
+		preempt_disable();
 		task_rq_unlock(rq, p, rf);
-
 		if (push_task) {
 			stop_one_cpu_nowait(rq->cpu, push_cpu_stop,
 					    p, &rq->push_work);
 		}
+		preempt_enable();
 
 		if (complete)
 			complete_all(&pending->done);
@@ -3037,12 +3040,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
 		if (flags & SCA_MIGRATE_ENABLE)
 			p->migration_flags &= ~MDF_PUSH;
 
+		preempt_disable();
 		task_rq_unlock(rq, p, rf);
-
 		if (!stop_pending) {
 			stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop,
 					    &pending->arg, &pending->stop_work);
 		}
+		preempt_enable();
 
 		if (flags & SCA_MIGRATE_ENABLE)
 			return 0;
@@ -9507,9 +9511,11 @@ static void balance_push(struct rq *rq)
 	 * Temporarily drop rq->lock such that we can wake-up the stop task.
 	 * Both preemption and IRQs are still disabled.
 	 */
+	preempt_disable();
 	raw_spin_rq_unlock(rq);
 	stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task,
 			    this_cpu_ptr(&push_work));
+	preempt_enable();
 	/*
 	 * At this point need_resched() is true and we'll take the loop in
 	 * schedule(). The next pick is obviously going to be the stop task
kernel/sched/deadline.c +2 -0
index 58b542bf28934..d78f2e8769fb4 100644
@@ -2449,9 +2449,11 @@ static void pull_dl_task(struct rq *this_rq)
 		double_unlock_balance(this_rq, src_rq);
 
 		if (push_task) {
+			preempt_disable();
 			raw_spin_rq_unlock(this_rq);
 			stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop,
 					    push_task, &src_rq->push_work);
+			preempt_enable();
 			raw_spin_rq_lock(this_rq);
 		}
 	}
kernel/sched/fair.c +3 -1
index a87ef35d5424a..8e1b54dc2a214 100644
@@ -10986,13 +10986,15 @@ static int load_balance(int this_cpu, struct rq *this_rq,
 				busiest->push_cpu = this_cpu;
 				active_balance = 1;
 			}
-			raw_spin_rq_unlock_irqrestore(busiest, flags);
 
+			preempt_disable();
+			raw_spin_rq_unlock_irqrestore(busiest, flags);
 			if (active_balance) {
 				stop_one_cpu_nowait(cpu_of(busiest),
 					active_load_balance_cpu_stop, busiest,
 					&busiest->active_balance_work);
 			}
+			preempt_enable();
 		}
 	} else {
 		sd->nr_balance_failed = 0;
kernel/sched/rt.c +4 -0
index 185d3d749f6b6..590abc1a013d2 100644
@@ -2109,9 +2109,11 @@ static int push_rt_task(struct rq *rq, bool pull)
 		 */
 		push_task = get_push_task(rq);
 		if (push_task) {
+			preempt_disable();
 			raw_spin_rq_unlock(rq);
 			stop_one_cpu_nowait(rq->cpu, push_cpu_stop,
 					    push_task, &rq->push_work);
+			preempt_enable();
 			raw_spin_rq_lock(rq);
 		}
 
@@ -2448,9 +2450,11 @@ static void pull_rt_task(struct rq *this_rq)
 		double_unlock_balance(this_rq, src_rq);
 
 		if (push_task) {
+			preempt_disable();
 			raw_spin_rq_unlock(this_rq);
 			stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop,
 					    push_task, &src_rq->push_work);
+			preempt_enable();
 			raw_spin_rq_lock(this_rq);
 		}
 	}
Signature · 1 line
2.42.0
author maintainer
#11 lore raw

PATCH 11/550 nfsd: Handle EOPENSTALE correctly in the filecache

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

[ Upstream commit d59b3515ab021e010fdc58a8f445ea62dd2f7f4c ]

The nfsd_open code handles EOPENSTALE correctly, by retrying the call to fh_verify() and __nfsd_open(). However the filecache just drops the error on the floor, and immediately returns nfserr_stale to the caller.

This patch ensures that we propagate the EOPENSTALE code back to nfsd_file_do_acquire, and that we handle it correctly.

Fixes 65294c1f2c5e ("nfsd: add a new struct file caching facility to nfsd")

Message-Id: <[email protected]>

---
 fs/nfsd/filecache.c | 27 +++++++++++++++++++--------
 fs/nfsd/vfs.c       | 28 +++++++++++++---------------
 fs/nfsd/vfs.h       |  4 ++--
 3 files changed, 34 insertions(+), 25 deletions(-)
fs/nfsd/filecache.c +19 -8
index ee9c923192e08..07bf219f9ae48 100644
@@ -989,22 +989,21 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
 	struct net *net = SVC_NET(rqstp);
 	struct nfsd_file *new, *nf;
-	const struct cred *cred;
+	bool stale_retry = true;
 	bool open_retry = true;
 	struct inode *inode;
 	__be32 status;
 	int ret;
 
+retry:
 	status = fh_verify(rqstp, fhp, S_IFREG,
 				may_flags|NFSD_MAY_OWNER_OVERRIDE);
 	if (status != nfs_ok)
 		return status;
 	inode = d_inode(fhp->fh_dentry);
-	cred = get_current_cred();
 
-retry:
 	rcu_read_lock();
-	nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc);
+	nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc);
 	rcu_read_unlock();
 
 	if (nf) {
@@ -1026,7 +1025,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
 	rcu_read_lock();
 	spin_lock(&inode->i_lock);
-	nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc);
+	nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc);
 	if (unlikely(nf)) {
 		spin_unlock(&inode->i_lock);
 		rcu_read_unlock();
@@ -1058,6 +1057,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 			goto construction_err;
 		}
 		open_retry = false;
+		fh_put(fhp);
 		goto retry;
 	}
 	this_cpu_inc(nfsd_file_cache_hits);
@@ -1074,7 +1074,6 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		nfsd_file_check_write_error(nf);
 		*pnf = nf;
 	}
-	put_cred(cred);
 	trace_nfsd_file_acquire(rqstp, inode, may_flags, nf, status);
 	return status;
 
@@ -1088,8 +1087,20 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 			status = nfs_ok;
 			trace_nfsd_file_opened(nf, status);
 		} else {
-			status = nfsd_open_verified(rqstp, fhp, may_flags,
-						    &nf->nf_file);
+			ret = nfsd_open_verified(rqstp, fhp, may_flags,
+						 &nf->nf_file);
+			if (ret == -EOPENSTALE && stale_retry) {
+				stale_retry = false;
+				nfsd_file_unhash(nf);
+				clear_and_wake_up_bit(NFSD_FILE_PENDING,
+						      &nf->nf_flags);
+				if (refcount_dec_and_test(&nf->nf_ref))
+					nfsd_file_free(nf);
+				nf = NULL;
+				fh_put(fhp);
+				goto retry;
+			}
+			status = nfserrno(ret);
 			trace_nfsd_file_open(nf, status);
 		}
 	} else
fs/nfsd/vfs.c +13 -15
index c7fdc19b0d5f7..4aa421d1efbfd 100644
@@ -823,7 +823,7 @@ int nfsd_open_break_lease(struct inode *inode, int access)
  * and additional flags.
  * N.B. After this call fhp needs an fh_put
  */
-static __be32
+static int
 __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 			int may_flags, struct file **filp)
 {
@@ -831,14 +831,12 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 	struct inode	*inode;
 	struct file	*file;
 	int		flags = O_RDONLY|O_LARGEFILE;
-	__be32		err;
-	int		host_err = 0;
+	int		host_err = -EPERM;
 
 	path.mnt = fhp->fh_export->ex_path.mnt;
 	path.dentry = fhp->fh_dentry;
 	inode = d_inode(path.dentry);
 
-	err = nfserr_perm;
 	if (IS_APPEND(inode) && (may_flags & NFSD_MAY_WRITE))
 		goto out;
 
@@ -847,7 +845,7 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 
 	host_err = nfsd_open_break_lease(inode, may_flags);
 	if (host_err) /* NOMEM or WOULDBLOCK */
-		goto out_nfserr;
+		goto out;
 
 	if (may_flags & NFSD_MAY_WRITE) {
 		if (may_flags & NFSD_MAY_READ)
@@ -859,13 +857,13 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 	file = dentry_open(&path, flags, current_cred());
 	if (IS_ERR(file)) {
 		host_err = PTR_ERR(file);
-		goto out_nfserr;
+		goto out;
 	}
 
 	host_err = ima_file_check(file, may_flags);
 	if (host_err) {
 		fput(file);
-		goto out_nfserr;
+		goto out;
 	}
 
 	if (may_flags & NFSD_MAY_64BIT_COOKIE)
@@ -874,10 +872,8 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 		file->f_mode |= FMODE_32BITHASH;
 
 	*filp = file;
-out_nfserr:
-	err = nfserrno(host_err);
 out:
-	return err;
+	return host_err;
 }
 
 __be32
@@ -885,6 +881,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 		int may_flags, struct file **filp)
 {
 	__be32 err;
+	int host_err;
 	bool retried = false;
 
 	validate_process_creds();
@@ -904,12 +901,13 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 retry:
 	err = fh_verify(rqstp, fhp, type, may_flags);
 	if (!err) {
-		err = __nfsd_open(rqstp, fhp, type, may_flags, filp);
-		if (err == nfserr_stale && !retried) {
+		host_err = __nfsd_open(rqstp, fhp, type, may_flags, filp);
+		if (host_err == -EOPENSTALE && !retried) {
 			retried = true;
 			fh_put(fhp);
 			goto retry;
 		}
+		err = nfserrno(host_err);
 	}
 	validate_process_creds();
 	return err;
@@ -922,13 +920,13 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
  * @may_flags: internal permission flags
  * @filp: OUT: open "struct file *"
  *
- * Returns an nfsstat value in network byte order.
+ * Returns zero on success, or a negative errno value.
  */
-__be32
+int
 nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags,
 		   struct file **filp)
 {
-	__be32 err;
+	int err;
 
 	validate_process_creds();
 	err = __nfsd_open(rqstp, fhp, S_IFREG, may_flags, filp);
fs/nfsd/vfs.h +2 -2
index a6890ea7b765b..e3c29596f4df1 100644
@@ -104,8 +104,8 @@ __be32		nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
 int 		nfsd_open_break_lease(struct inode *, int);
 __be32		nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
 				int, struct file **);
-__be32		nfsd_open_verified(struct svc_rqst *, struct svc_fh *,
-				int, struct file **);
+int		nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp,
+				   int may_flags, struct file **filp);
 __be32		nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
 				struct file *file, loff_t offset,
 				unsigned long *count,
Signature · 1 line
2.42.0
author maintainer
#12 lore raw

PATCH 12/550 vfs: fix readahead(2) on block devices

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Reuben Hawkins <[email protected]>

[ Upstream commit 7116c0af4b8414b2f19fdb366eea213cbd9d91c2 ]

Readahead was factored to call generic_fadvise. That refactor added an S_ISREG restriction which broke readahead on block devices.

In addition to S_ISREG, this change checks S_ISBLK to fix block device readahead. There is no change in behavior with any file type besides block devices in this change.

Fixes 3d8f7615319b ("vfs: implement readahead(2) using POSIX_FADV_WILLNEED")
---
 mm/readahead.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
mm/readahead.c +2 -1
index a9c999aa19af6..1f4701f1b8682 100644
@@ -748,7 +748,8 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
 	 */
 	ret = -EINVAL;
 	if (!f.file->f_mapping || !f.file->f_mapping->a_ops ||
-	    !S_ISREG(file_inode(f.file)->i_mode))
+	    (!S_ISREG(file_inode(f.file)->i_mode) &&
+	    !S_ISBLK(file_inode(f.file)->i_mode)))
 		goto out;
 
 	ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED);
Signature · 1 line
2.42.0
author maintainer
#13 lore raw

PATCH 13/550 writeback, cgroup: switch inodes with dirty timestamps to release dying cgwbs

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jingbo Xu <[email protected]>

[ Upstream commit 6654408a33e6297d8e1d2773409431d487399b95 ]

The cgwb cleanup routine will try to release the dying cgwb by switching the attached inodes. It fetches the attached inodes from wb->b_attached list, omitting the fact that inodes only with dirty timestamps reside in wb->b_dirty_time list, which is the case when lazytime is enabled. This causes enormous zombie memory cgroup when lazytime is enabled, as inodes with dirty timestamps can not be switched to a live cgwb for a long time.

It is reasonable not to switch cgwb for inodes with dirty data, as otherwise it may break the bandwidth restrictions. However since the writeback of inode metadata is not accounted for, let's also switch inodes with dirty timestamps to avoid zombie memory and block cgroups when laztytime is enabled.

Fixes c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
---
 fs/fs-writeback.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)
fs/fs-writeback.c +29 -12
index d532a93e980d7..e19edd179dfc0 100644
@@ -613,6 +613,24 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
 	kfree(isw);
 }
 
+static bool isw_prepare_wbs_switch(struct inode_switch_wbs_context *isw,
+				   struct list_head *list, int *nr)
+{
+	struct inode *inode;
+
+	list_for_each_entry(inode, list, i_io_list) {
+		if (!inode_prepare_wbs_switch(inode, isw->new_wb))
+			continue;
+
+		isw->inodes[*nr] = inode;
+		(*nr)++;
+
+		if (*nr >= WB_MAX_INODES_PER_ISW - 1)
+			return true;
+	}
+	return false;
+}
+
 /**
  * cleanup_offline_cgwb - detach associated inodes
  * @wb: target wb
@@ -625,7 +643,6 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
 {
 	struct cgroup_subsys_state *memcg_css;
 	struct inode_switch_wbs_context *isw;
-	struct inode *inode;
 	int nr;
 	bool restart = false;
 
@@ -647,17 +664,17 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
 
 	nr = 0;
 	spin_lock(&wb->list_lock);
-	list_for_each_entry(inode, &wb->b_attached, i_io_list) {
-		if (!inode_prepare_wbs_switch(inode, isw->new_wb))
-			continue;
-
-		isw->inodes[nr++] = inode;
-
-		if (nr >= WB_MAX_INODES_PER_ISW - 1) {
-			restart = true;
-			break;
-		}
-	}
+	/*
+	 * In addition to the inodes that have completed writeback, also switch
+	 * cgwbs for those inodes only with dirty timestamps. Otherwise, those
+	 * inodes won't be written back for a long time when lazytime is
+	 * enabled, and thus pinning the dying cgwbs. It won't break the
+	 * bandwidth restrictions, as writeback of inode metadata is not
+	 * accounted for.
+	 */
+	restart = isw_prepare_wbs_switch(isw, &wb->b_attached, &nr);
+	if (!restart)
+		restart = isw_prepare_wbs_switch(isw, &wb->b_dirty_time, &nr);
 	spin_unlock(&wb->list_lock);
 
 	/* no attached inodes? bail out */
Signature · 1 line
2.42.0
author maintainer
#14 lore raw

PATCH 14/550 x86/srso: Fix SBPB enablement for (possible) future fixed HW

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Poimboeuf <[email protected]>

[ Upstream commit 1d1142ac51307145dbb256ac3535a1d43a1c9800 ]

Make the SBPB check more robust against the (possible) case where future HW has SRSO fixed but doesn't have the SRSO_NO bit set.

---
 arch/x86/kernel/cpu/bugs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/bugs.c +1 -1
index 10499bcd4e396..2859a54660a28 100644
@@ -2496,7 +2496,7 @@ static void __init srso_select_mitigation(void)
 	pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
 
 pred_cmd:
-	if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) &&
+	if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) &&
 	     boot_cpu_has(X86_FEATURE_SBPB))
 		x86_pred_cmd = PRED_CMD_SBPB;
 }
Signature · 1 line
2.42.0
author maintainer
#15 lore raw

PATCH 15/550 x86/srso: Print mitigation for retbleed IBPB case

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Poimboeuf <[email protected]>

[ Upstream commit de9f5f7b06a5b7adbfdd8016f011120a4e928add ]

When overriding the requested mitigation with IBPB due to retbleed=ibpb, print the mitigation in the usual format instead of a custom error message.

Stable-dep-of: dc6306ad5b0d ("x86/srso: Fix vulnerability reporting for missing microcode")

---
 arch/x86/kernel/cpu/bugs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/bugs.c +3 -3
index 2859a54660a28..d5db0baca2f14 100644
@@ -2425,9 +2425,8 @@ static void __init srso_select_mitigation(void)
 
 	if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
 		if (has_microcode) {
-			pr_err("Retbleed IBPB mitigation enabled, using same for SRSO\n");
 			srso_mitigation = SRSO_MITIGATION_IBPB;
-			goto pred_cmd;
+			goto out;
 		}
 	}
 
@@ -2493,7 +2492,8 @@ static void __init srso_select_mitigation(void)
 		break;
 	}
 
-	pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
+out:
+	pr_info("%s%s\n", srso_strings[srso_mitigation], has_microcode ? "" : ", no microcode");
 
 pred_cmd:
 	if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) &&
Signature · 1 line
2.42.0
author maintainer
#16 lore raw

PATCH 16/550 x86/srso: Fix vulnerability reporting for missing microcode

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Poimboeuf <[email protected]>

[ Upstream commit dc6306ad5b0dda040baf1fde3cfd458e6abfc4da ]

The SRSO default safe-ret mitigation is reported as "mitigated" even if microcode hasn't been updated. That's wrong because userspace may still be vulnerable to SRSO attacks due to IBPB not flushing branch type predictions.

Report the safe-ret + !microcode case as vulnerable.

Also report the microcode-only case as vulnerable as it leaves the kernel open to attacks.

---
 Documentation/admin-guide/hw-vuln/srso.rst | 24 ++++++++++-----
 arch/x86/kernel/cpu/bugs.c                 | 36 +++++++++++++---------
 2 files changed, 39 insertions(+), 21 deletions(-)
Documentation/admin-guide/hw-vuln/srso.rst +17 -7
index b6cfb51cb0b46..e715bfc09879a 100644
@@ -46,12 +46,22 @@ The possible values in this file are:
 
    The processor is not vulnerable
 
- * 'Vulnerable: no microcode':
+* 'Vulnerable':
+
+   The processor is vulnerable and no mitigations have been applied.
+
+ * 'Vulnerable: No microcode':
 
    The processor is vulnerable, no microcode extending IBPB
    functionality to address the vulnerability has been applied.
 
- * 'Mitigation: microcode':
+ * 'Vulnerable: Safe RET, no microcode':
+
+   The "Safe RET" mitigation (see below) has been applied to protect the
+   kernel, but the IBPB-extending microcode has not been applied.  User
+   space tasks may still be vulnerable.
+
+ * 'Vulnerable: Microcode, no safe RET':
 
    Extended IBPB functionality microcode patch has been applied. It does
    not address User->Kernel and Guest->Host transitions protection but it
@@ -72,11 +82,11 @@ The possible values in this file are:
 
    (spec_rstack_overflow=microcode)
 
- * 'Mitigation: safe RET':
+ * 'Mitigation: Safe RET':
 
-   Software-only mitigation. It complements the extended IBPB microcode
-   patch functionality by addressing User->Kernel and Guest->Host
-   transitions protection.
+   Combined microcode/software mitigation. It complements the
+   extended IBPB microcode patch functionality by addressing
+   User->Kernel and Guest->Host transitions protection.
 
    Selected by default or by spec_rstack_overflow=safe-ret
 
@@ -129,7 +139,7 @@ an indrect branch prediction barrier after having applied the required
 microcode patch for one's system. This mitigation comes also at
 a performance cost.
 
-Mitigation: safe RET
+Mitigation: Safe RET
 --------------------
 
 The mitigation works by ensuring all RET instructions speculate to
arch/x86/kernel/cpu/bugs.c +22 -14
index d5db0baca2f14..a55a3864df1c9 100644
@@ -2353,6 +2353,8 @@ early_param("l1tf", l1tf_cmdline);
 
 enum srso_mitigation {
 	SRSO_MITIGATION_NONE,
+	SRSO_MITIGATION_UCODE_NEEDED,
+	SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED,
 	SRSO_MITIGATION_MICROCODE,
 	SRSO_MITIGATION_SAFE_RET,
 	SRSO_MITIGATION_IBPB,
@@ -2368,11 +2370,13 @@ enum srso_mitigation_cmd {
 };
 
 static const char * const srso_strings[] = {
-	[SRSO_MITIGATION_NONE]           = "Vulnerable",
-	[SRSO_MITIGATION_MICROCODE]      = "Mitigation: microcode",
-	[SRSO_MITIGATION_SAFE_RET]	 = "Mitigation: safe RET",
-	[SRSO_MITIGATION_IBPB]		 = "Mitigation: IBPB",
-	[SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only"
+	[SRSO_MITIGATION_NONE]			= "Vulnerable",
+	[SRSO_MITIGATION_UCODE_NEEDED]		= "Vulnerable: No microcode",
+	[SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED]	= "Vulnerable: Safe RET, no microcode",
+	[SRSO_MITIGATION_MICROCODE]		= "Vulnerable: Microcode, no safe RET",
+	[SRSO_MITIGATION_SAFE_RET]		= "Mitigation: Safe RET",
+	[SRSO_MITIGATION_IBPB]			= "Mitigation: IBPB",
+	[SRSO_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT only"
 };
 
 static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
@@ -2409,10 +2413,7 @@ static void __init srso_select_mitigation(void)
 	if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())
 		goto pred_cmd;
 
-	if (!has_microcode) {
-		pr_warn("IBPB-extending microcode not applied!\n");
-		pr_warn(SRSO_NOTICE);
-	} else {
+	if (has_microcode) {
 		/*
 		 * Zen1/2 with SMT off aren't vulnerable after the right
 		 * IBPB microcode has been applied.
@@ -2428,6 +2429,12 @@ static void __init srso_select_mitigation(void)
 			srso_mitigation = SRSO_MITIGATION_IBPB;
 			goto out;
 		}
+	} else {
+		pr_warn("IBPB-extending microcode not applied!\n");
+		pr_warn(SRSO_NOTICE);
+
+		/* may be overwritten by SRSO_CMD_SAFE_RET below */
+		srso_mitigation = SRSO_MITIGATION_UCODE_NEEDED;
 	}
 
 	switch (srso_cmd) {
@@ -2457,7 +2464,10 @@ static void __init srso_select_mitigation(void)
 				setup_force_cpu_cap(X86_FEATURE_SRSO);
 				x86_return_thunk = srso_return_thunk;
 			}
-			srso_mitigation = SRSO_MITIGATION_SAFE_RET;
+			if (has_microcode)
+				srso_mitigation = SRSO_MITIGATION_SAFE_RET;
+			else
+				srso_mitigation = SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED;
 		} else {
 			pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
 			goto pred_cmd;
@@ -2493,7 +2503,7 @@ static void __init srso_select_mitigation(void)
 	}
 
 out:
-	pr_info("%s%s\n", srso_strings[srso_mitigation], has_microcode ? "" : ", no microcode");
+	pr_info("%s\n", srso_strings[srso_mitigation]);
 
 pred_cmd:
 	if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) &&
@@ -2704,9 +2714,7 @@ static ssize_t srso_show_state(char *buf)
 	if (boot_cpu_has(X86_FEATURE_SRSO_NO))
 		return sysfs_emit(buf, "Mitigation: SMT disabled\n");
 
-	return sysfs_emit(buf, "%s%s\n",
-			  srso_strings[srso_mitigation],
-			  boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
+	return sysfs_emit(buf, "%s\n", srso_strings[srso_mitigation]);
 }
 
 static ssize_t gds_show_state(char *buf)
Signature · 1 line
2.42.0
author maintainer
#17 lore raw

PATCH 17/550 x86/srso: Fix unret validation dependencies

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Poimboeuf <[email protected]>

[ Upstream commit eeb9f34df065f42f0c9195b322ba6df420c9fc92 ]

CONFIG_CPU_SRSO isn't dependent on CONFIG_CPU_UNRET_ENTRY (AMD Retbleed), so the two features are independently configurable. Fix several issues for the (presumably rare) case where CONFIG_CPU_SRSO is enabled but CONFIG_CPU_UNRET_ENTRY isn't.

---
 arch/x86/include/asm/nospec-branch.h | 4 ++--
 include/linux/objtool.h              | 3 ++-
 scripts/Makefile.vmlinux_o           | 3 ++-
 3 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/include/asm/nospec-branch.h +2 -2
index c55cc243592e9..197ff4f4d1ceb 100644
@@ -271,7 +271,7 @@
 .Lskip_rsb_\@:
 .endm
 
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)
 #define CALL_UNTRAIN_RET	"call entry_untrain_ret"
 #else
 #define CALL_UNTRAIN_RET	""
@@ -312,7 +312,7 @@
 
 .macro UNTRAIN_RET_FROM_CALL
 #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \
-	defined(CONFIG_CALL_DEPTH_TRACKING)
+	defined(CONFIG_CALL_DEPTH_TRACKING) || defined(CONFIG_CPU_SRSO)
 	VALIDATE_UNRET_END
 	ALTERNATIVE_3 "",						\
 		      CALL_UNTRAIN_RET, X86_FEATURE_UNRET,		\
include/linux/objtool.h +2 -1
index 03f82c2c2ebf6..b5440e7da55bf 100644
@@ -130,7 +130,8 @@
  * it will be ignored.
  */
 .macro VALIDATE_UNRET_BEGIN
-#if defined(CONFIG_NOINSTR_VALIDATION) && defined(CONFIG_CPU_UNRET_ENTRY)
+#if defined(CONFIG_NOINSTR_VALIDATION) && \
+	(defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO))
 .Lhere_\@:
 	.pushsection .discard.validate_unret
 	.long	.Lhere_\@ - .
scripts/Makefile.vmlinux_o +2 -1
index 0edfdb40364b8..25b3b587d37c0 100644
@@ -37,7 +37,8 @@ objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
 
 vmlinux-objtool-args-$(delay-objtool)			+= $(objtool-args-y)
 vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL)		+= --no-unreachable
-vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret)
+vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
+							   $(if $(or $(CONFIG_CPU_UNRET_ENTRY),$(CONFIG_CPU_SRSO)), --unret)
 
 objtool-args = $(vmlinux-objtool-args-y) --link
 
Signature · 1 line
2.42.0
author maintainer
#18 lore raw

PATCH 18/550 futex: Dont include process MM in futex key on no-MMU

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ben Wolsieffer <[email protected]>

[ Upstream commit c73801ae4f22b390228ebf471d55668e824198b6 ]

On no-MMU, all futexes are treated as private because there is no need to map a virtual address to physical to match the futex across processes. This doesn't quite work though, because private futexes include the current process's mm_struct as part of their key. This makes it impossible for one process to wake up a shared futex being waited on in another process.

Fix this bug by excluding the mm_struct from the key. With a single address space, the futex address is already a unique key.

Fixes 784bdf3bb694 ("futex: Assume all mappings are private on !MMU systems")
Cc Thomas Gleixner <[email protected]>
Cc Darren Hart <[email protected]>
Cc Davidlohr Bueso <[email protected]>
Cc André Almeida <[email protected]>
---
 kernel/futex/core.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
kernel/futex/core.c +11 -1
index 514e4582b8634..d4141b0547187 100644
@@ -248,7 +248,17 @@ int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key,
 	 *        but access_ok() should be faster than find_vma()
 	 */
 	if (!fshared) {
-		key->private.mm = mm;
+		/*
+		 * On no-MMU, shared futexes are treated as private, therefore
+		 * we must not include the current process in the key. Since
+		 * there is only one address space, the address is a unique key
+		 * on its own.
+		 */
+		if (IS_ENABLED(CONFIG_MMU))
+			key->private.mm = mm;
+		else
+			key->private.mm = NULL;
+
 		key->private.address = address;
 		return 0;
 	}
Signature · 1 line
2.42.0
author maintainer
#19 lore raw

PATCH 19/550 x86/numa: Introduce numa_fill_memblks()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alison Schofield <[email protected]>

[ Upstream commit 8f012db27c9516be1a7aca93ea4a6ca9c75056c9 ]

numa_fill_memblks() fills in the gaps in numa_meminfo memblks over an physical address range.

The ACPI driver will use numa_fill_memblks() to implement a new Linux policy that prescribes extending proximity domains in a portion of a CFMWS window to the entire window.

Dan Williams offered this explanation of the policy:
A CFWMS is an ACPI data structure that indicates *potential* locations where CXL memory can be placed. It is the playground where the CXL driver has free reign to establish regions. That space can be populated by BIOS created regions, or driver created regions, after hotplug or other reconfiguration.

When BIOS creates a region in a CXL Window it additionally describes that subset of the Window range in the other typical ACPI tables SRAT, SLIT, and HMAT. The rationale for BIOS not pre-describing the entire CXL Window in SRAT, SLIT, and HMAT is that it can not predict the future. I.e. there is nothing stopping higher or lower performance devices being placed in the same Window. Compare that to ACPI memory hotplug that just onlines additional capacity in the proximity domain with little freedom for dynamic performance differentiation.

That leaves the OS with a choice, should unpopulated window capacity match the proximity domain of an existing region, or should it allocate a new one? This patch takes the simple position of minimizing proximity domain proliferation by reusing any proximity domain intersection for the entire Window. If the Window has no intersections then allocate a new proximity domain. Note that SRAT, SLIT and HMAT information can be enumerated dynamically in a standard way from device provided data. Think of CXL as the end of ACPI needing to describe memory attributes, CXL offers a standard discovery model for performance attributes, but Linux still needs to interoperate with the old regime.

Stable-dep-of: 8f1004679987 ("ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window")

---
 arch/x86/include/asm/sparsemem.h |  2 +
 arch/x86/mm/numa.c               | 80 ++++++++++++++++++++++++++++++++
 include/linux/numa.h             |  7 +++
 3 files changed, 89 insertions(+)
arch/x86/include/asm/sparsemem.h +2 -0
index 64df897c0ee30..1be13b2dfe8bf 100644
@@ -37,6 +37,8 @@ extern int phys_to_target_node(phys_addr_t start);
 #define phys_to_target_node phys_to_target_node
 extern int memory_add_physaddr_to_nid(u64 start);
 #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
+extern int numa_fill_memblks(u64 start, u64 end);
+#define numa_fill_memblks numa_fill_memblks
 #endif
 #endif /* __ASSEMBLY__ */
 
arch/x86/mm/numa.c +80 -0

90 lines not on this page · raw message

include/linux/numa.h +7 -0
index fb30a42f0700d..a904861de8000 100644
@@ -12,6 +12,7 @@
 #define MAX_NUMNODES    (1 << NODES_SHIFT)
 
 #define	NUMA_NO_NODE	(-1)
+#define	NUMA_NO_MEMBLK	(-1)
 
 /* optionally keep NUMA memory info available post init */
 #ifdef CONFIG_NUMA_KEEP_MEMINFO
@@ -43,6 +44,12 @@ static inline int phys_to_target_node(u64 start)
 	return 0;
 }
 #endif
+#ifndef numa_fill_memblks
+static inline int __init numa_fill_memblks(u64 start, u64 end)
+{
+	return NUMA_NO_MEMBLK;
+}
+#endif
 #else /* !CONFIG_NUMA */
 static inline int numa_nearest_node(int node, unsigned int state)
 {
Signature · 1 line
2.42.0
author maintainer
#20 lore raw

PATCH 20/550 ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alison Schofield <[email protected]>

[ Upstream commit 8f1004679987302b155f14b966ca6d4335814fcb ]

Commit fd49f99c1809 ("ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT") did not account for the case where the BIOS only partially describes a CFMWS Window in the SRAT. That means the omitted address ranges, of a partially described CFMWS Window, do not get assigned to a NUMA node.

Replace the call to phys_to_target_node() with numa_add_memblks(). Numa_add_memblks() searches an HPA range for existing memblk(s) and extends those memblk(s) to fill the entire CFMWS Window.

Extending the existing memblks is a simple strategy that reuses SRAT defined proximity domains from part of a window to fill out the entire window, based on the knowledge* that all of a CFMWS window is of a similar performance class.

*Note that this heuristic will evolve when CFMWS Windows present a wider range of characteristics. The extension of the proximity domain, implemented here, is likely a step in developing a more sophisticated performance profile in the future.

There is no change in behavior when the SRAT does not describe the CFMWS Window at all. In that case, a new NUMA node with a single memblk covering the entire CFMWS Window is created.

---
 drivers/acpi/numa/srat.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/acpi/numa/srat.c +8 -3
index 1f4fc5f8a819d..12f330b0eac01 100644
@@ -310,11 +310,16 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
 	start = cfmws->base_hpa;
 	end = cfmws->base_hpa + cfmws->window_size;
 
-	/* Skip if the SRAT already described the NUMA details for this HPA */
-	node = phys_to_target_node(start);
-	if (node != NUMA_NO_NODE)
+	/*
+	 * The SRAT may have already described NUMA details for all,
+	 * or a portion of, this CFMWS HPA range. Extend the memblks
+	 * found for any portion of the window to cover the entire
+	 * window.
+	 */
+	if (!numa_fill_memblks(start, end))
 		return 0;
 
+	/* No SRAT description. Create a new node. */
 	node = acpi_map_pxm_to_node(*fake_pxm);
 
 	if (node == NUMA_NO_NODE) {
Signature · 1 line
2.42.0
author maintainer
#21 lore raw

PATCH 21/550 x86/sev-es: Allow copy_from_kernel_nofault() in earlier boot

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Adam Dunlap <[email protected]>

[ Upstream commit f79936545fb122856bd78b189d3c7ee59928c751 ]

Previously, if copy_from_kernel_nofault() was called before boot_cpu_data.x86_virt_bits was set up, then it would trigger undefined behavior due to a shift by 64.

This ended up causing boot failures in the latest version of ubuntu2204 in the gcp project when using SEV-SNP.

Specifically, this function is called during an early #VC handler which is triggered by a CPUID to check if NX is implemented.

---
 arch/x86/mm/maccess.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
arch/x86/mm/maccess.c +14 -5
index 5a53c2cc169cc..6993f026adec9 100644
@@ -9,12 +9,21 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
 	unsigned long vaddr = (unsigned long)unsafe_src;
 
 	/*
-	 * Range covering the highest possible canonical userspace address
-	 * as well as non-canonical address range. For the canonical range
-	 * we also need to include the userspace guard page.
+	 * Do not allow userspace addresses.  This disallows
+	 * normal userspace and the userspace guard page:
 	 */
-	return vaddr >= TASK_SIZE_MAX + PAGE_SIZE &&
-	       __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
+	if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
+		return false;
+
+	/*
+	 * Allow everything during early boot before 'x86_virt_bits'
+	 * is initialized.  Needed for instruction decoding in early
+	 * exception handlers.
+	 */
+	if (!boot_cpu_data.x86_virt_bits)
+		return true;
+
+	return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
 }
 #else
 bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
Signature · 1 line
2.42.0
author maintainer
#22 lore raw

PATCH 22/550 x86/boot: Fix incorrect startup_gdt_descr.size

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yuntao Wang <[email protected]>

[ Upstream commit 001470fed5959d01faecbd57fcf2f60294da0de1 ]

Since the size value is added to the base address to yield the last valid byte address of the GDT, the current size value of startup_gdt_descr is incorrect (too large by one), fix it.

[ mingo: This probably never mattered, because startup_gdt[] is only used
in a very controlled fashion - but make it consistent nevertheless. ]

Fixes 866b556efa12 ("x86/head/64: Install startup GDT")
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/kernel/head64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/head64.c +1 -1
index 49f7629b17f73..bbc21798df10e 100644
@@ -80,7 +80,7 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] = {
  * while the kernel still uses a direct mapping.
  */
 static struct desc_ptr startup_gdt_descr = {
-	.size = sizeof(startup_gdt),
+	.size = sizeof(startup_gdt)-1,
 	.address = 0,
 };
 
Signature · 1 line
2.42.0
author maintainer
#23 lore raw

PATCH 23/550 cpu/hotplug: Remove dependancy against cpu_primary_thread_mask

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Laurent Dufour <[email protected]>

[ Upstream commit 7a4dcb4a5de1214c4a59448a759e2e264c2c4473 ]

The commit 18415f33e2ac ("cpu/hotplug: Allow "parallel" bringup up to CPUHP_BP_KICK_AP_STATE") introduce a dependancy against a global variable cpu_primary_thread_mask exported by the X86 code. This variable is only used when CONFIG_HOTPLUG_PARALLEL is set.

Since cpuhp_get_primary_thread_mask() and cpuhp_smt_aware() are only used when CONFIG_HOTPLUG_PARALLEL is set, don't define them when it is not set.

No functional change.

Stable-dep-of: d91bdd96b55c ("cpu/SMT: Make SMT control more robust against enumeration failures")

---
 kernel/cpu.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)
kernel/cpu.c +10 -14
index 9628ae3c2825b..dd59ffeacff2e 100644
@@ -650,22 +650,8 @@ bool cpu_smt_possible(void)
 }
 EXPORT_SYMBOL_GPL(cpu_smt_possible);
 
-static inline bool cpuhp_smt_aware(void)
-{
-	return topology_smt_supported();
-}
-
-static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
-{
-	return cpu_primary_thread_mask;
-}
 #else
 static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
-static inline bool cpuhp_smt_aware(void) { return false; }
-static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
-{
-	return cpu_present_mask;
-}
 #endif
 
 static inline enum cpuhp_state
@@ -1815,6 +1801,16 @@ static int __init parallel_bringup_parse_param(char *arg)
 }
 early_param("cpuhp.parallel", parallel_bringup_parse_param);
 
+static inline bool cpuhp_smt_aware(void)
+{
+	return topology_smt_supported();
+}
+
+static inline const struct cpumask *cpuhp_get_primary_thread_mask(void)
+{
+	return cpu_primary_thread_mask;
+}
+
 /*
  * On architectures which have enabled parallel bringup this invokes all BP
  * prepare states for each of the to be onlined APs first. The last state
Signature · 1 line
2.42.0
author maintainer
#24 lore raw

PATCH 24/550 cpu/SMT: Create topology_smt_thread_allowed()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Ellerman <[email protected]>

[ Upstream commit 38253464bc821d6de6bba81bb1412ebb36f6cbd1 ]

Some architectures allows partial SMT states, i.e. when not all SMT threads are brought online.

To support that, add an architecture helper which checks whether a given CPU is allowed to be brought online depending on how many SMT threads are currently enabled. Since this is only applicable to architecture supporting partial SMT, only these architectures should select the new configuration variable CONFIG_SMT_NUM_THREADS_DYNAMIC. For the other architectures, not supporting the partial SMT states, there is no need to define topology_cpu_smt_allowed(), the generic code assumed that all the threads are allowed or only the primary ones.

Call the helper from cpu_smt_enable(), and cpu_smt_allowed() when SMT is enabled, to check if the particular thread should be onlined. Notably, also call it from cpu_smt_disable() if CPU_SMT_ENABLED, to allow offlining some threads to move from a higher to lower number of threads online.

[ ldufour: Slightly reword the commit's description ] [ ldufour: Introduce CONFIG_SMT_NUM_THREADS_DYNAMIC ]

Stable-dep-of: d91bdd96b55c ("cpu/SMT: Make SMT control more robust against enumeration failures")

---
 arch/Kconfig |  3 +++
 kernel/cpu.c | 24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)
arch/Kconfig +3 -0
index aff2746c8af28..63c5d6a2022bc 100644
@@ -34,6 +34,9 @@ config ARCH_HAS_SUBPAGE_FAULTS
 config HOTPLUG_SMT
 	bool
 
+config SMT_NUM_THREADS_DYNAMIC
+	bool
+
 # Selected by HOTPLUG_CORE_SYNC_DEAD or HOTPLUG_CORE_SYNC_FULL
 config HOTPLUG_CORE_SYNC
 	bool
kernel/cpu.c +23 -1
index dd59ffeacff2e..21864899c770a 100644
@@ -625,9 +625,23 @@ static int __init smt_cmdline_disable(char *str)
 }
 early_param("nosmt", smt_cmdline_disable);
 
+/*
+ * For Archicture supporting partial SMT states check if the thread is allowed.
+ * Otherwise this has already been checked through cpu_smt_max_threads when
+ * setting the SMT level.
+ */
+static inline bool cpu_smt_thread_allowed(unsigned int cpu)
+{
+#ifdef CONFIG_SMT_NUM_THREADS_DYNAMIC
+	return topology_smt_thread_allowed(cpu);
+#else
+	return true;
+#endif
+}
+
 static inline bool cpu_smt_allowed(unsigned int cpu)
 {
-	if (cpu_smt_control == CPU_SMT_ENABLED)
+	if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu))
 		return true;
 
 	if (topology_is_primary_thread(cpu))
@@ -2644,6 +2658,12 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
 	for_each_online_cpu(cpu) {
 		if (topology_is_primary_thread(cpu))
 			continue;
+		/*
+		 * Disable can be called with CPU_SMT_ENABLED when changing
+		 * from a higher to lower number of SMT threads per core.
+		 */
+		if (ctrlval == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu))
+			continue;
 		ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
 		if (ret)
 			break;
@@ -2678,6 +2698,8 @@ int cpuhp_smt_enable(void)
 		/* Skip online CPUs and CPUs on offline nodes */
 		if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
 			continue;
+		if (!cpu_smt_thread_allowed(cpu))
+			continue;
 		ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
 		if (ret)
 			break;
Signature · 1 line
2.42.0
author maintainer
#25 lore raw

PATCH 25/550 cpu/SMT: Make SMT control more robust against enumeration failures

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

[ Upstream commit d91bdd96b55cc3ce98d883a60f133713821b80a6 ]

The SMT control mechanism got added as speculation attack vector mitigation. The implemented logic relies on the primary thread mask to be set up properly.

This turns out to be an issue with XEN/PV guests because their CPU hotplug mechanics do not enumerate APICs and therefore the mask is never correctly populated.

This went unnoticed so far because by chance XEN/PV ends up with smp_num_siblings == 2. So smt_hotplug_control stays at its default value CPU_SMT_ENABLED and the primary thread mask is never evaluated in the context of CPU hotplug.

This stopped "working" with the upcoming overhaul of the topology evaluation which legitimately provides a fake topology for XEN/PV. That sets smp_num_siblings to 1, which causes the core CPU hot-plug core to refuse to bring up the APs.

This happens because smt_hotplug_control is set to CPU_SMT_NOT_SUPPORTED which causes cpu_smt_allowed() to evaluate the unpopulated primary thread mask with the conclusion that all non-boot CPUs are not valid to be plugged.

Make cpu_smt_allowed() more robust and take CPU_SMT_NOT_SUPPORTED and CPU_SMT_NOT_IMPLEMENTED into account. Rename it to cpu_bootable() while at it as that makes it more clear what the function is about.

The primary mask issue on x86 XEN/PV needs to be addressed separately as there are users outside of the CPU hotplug code too.

---
 kernel/cpu.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
kernel/cpu.c +13 -5
index 21864899c770a..26119d2154102 100644
@@ -639,11 +639,19 @@ static inline bool cpu_smt_thread_allowed(unsigned int cpu)
 #endif
 }
 
-static inline bool cpu_smt_allowed(unsigned int cpu)
+static inline bool cpu_bootable(unsigned int cpu)
 {
 	if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu))
 		return true;
 
+	/* All CPUs are bootable if controls are not configured */
+	if (cpu_smt_control == CPU_SMT_NOT_IMPLEMENTED)
+		return true;
+
+	/* All CPUs are bootable if CPU is not SMT capable */
+	if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
+		return true;
+
 	if (topology_is_primary_thread(cpu))
 		return true;
 
@@ -665,7 +673,7 @@ bool cpu_smt_possible(void)
 EXPORT_SYMBOL_GPL(cpu_smt_possible);
 
 #else
-static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
+static inline bool cpu_bootable(unsigned int cpu) { return true; }
 #endif
 
 static inline enum cpuhp_state
@@ -768,10 +776,10 @@ static int bringup_wait_for_ap_online(unsigned int cpu)
 	 * SMT soft disabling on X86 requires to bring the CPU out of the
 	 * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit.  The
 	 * CPU marked itself as booted_once in notify_cpu_starting() so the
-	 * cpu_smt_allowed() check will now return false if this is not the
+	 * cpu_bootable() check will now return false if this is not the
 	 * primary sibling.
 	 */
-	if (!cpu_smt_allowed(cpu))
+	if (!cpu_bootable(cpu))
 		return -ECANCELED;
 	return 0;
 }
@@ -1721,7 +1729,7 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target)
 		err = -EBUSY;
 		goto out;
 	}
-	if (!cpu_smt_allowed(cpu)) {
+	if (!cpu_bootable(cpu)) {
 		err = -EPERM;
 		goto out;
 	}
Signature · 1 line
2.42.0
author maintainer
#26 lore raw

PATCH 26/550 x86/apic: Fake primary thread mask for XEN/PV

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

[ Upstream commit 965e05ff8af98c44f9937366715c512000373164 ]

The SMT control mechanism got added as speculation attack vector mitigation. The implemented logic relies on the primary thread mask to be set up properly.

This turns out to be an issue with XEN/PV guests because their CPU hotplug mechanics do not enumerate APICs and therefore the mask is never correctly populated.

This went unnoticed so far because by chance XEN/PV ends up with smp_num_siblings == 2. So cpu_smt_control stays at its default value CPU_SMT_ENABLED and the primary thread mask is never evaluated in the context of CPU hotplug.

This stopped "working" with the upcoming overhaul of the topology evaluation which legitimately provides a fake topology for XEN/PV. That sets smp_num_siblings to 1, which causes the core CPU hot-plug core to refuse to bring up the APs.

This happens because cpu_smt_control is set to CPU_SMT_NOT_SUPPORTED which causes cpu_bootable() to evaluate the unpopulated primary thread mask with the conclusion that all non-boot CPUs are not valid to be plugged.

The core code has already been made more robust against this kind of fail, but the primary thread mask really wants to be populated to avoid other issues all over the place.

Just fake the mask by pretending that all XEN/PV vCPUs are primary threads, which is consistent because all of XEN/PVs topology is fake or non-existent.

---
 arch/x86/kernel/apic/apic.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/x86/kernel/apic/apic.c +11 -0
index af49e24b46a43..7e0c7fbdc7d08 100644
@@ -36,6 +36,8 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 
+#include <xen/xen.h>
+
 #include <asm/trace/irq_vectors.h>
 #include <asm/irq_remapping.h>
 #include <asm/pc-conf-reg.h>
@@ -2408,6 +2410,15 @@ static int __init smp_init_primary_thread_mask(void)
 {
 	unsigned int cpu;
 
+	/*
+	 * XEN/PV provides either none or useless topology information.
+	 * Pretend that all vCPUs are primary threads.
+	 */
+	if (xen_pv_domain()) {
+		cpumask_copy(&__cpu_primary_thread_mask, cpu_possible_mask);
+		return 0;
+	}
+
 	for (cpu = 0; cpu < nr_logical_cpuids; cpu++)
 		cpu_mark_primary_thread(cpu, cpuid_to_apicid[cpu]);
 	return 0;
Signature · 1 line
2.42.0
author maintainer
#27 lore raw

PATCH 27/550 srcu: Fix callbacks acceleration mishandling

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Frederic Weisbecker <[email protected]>

[ Upstream commit 4a8e65b0c348e42107c64381e692e282900be361 ]

SRCU callbacks acceleration might fail if the preceding callbacks advance also fails. This can happen when the following steps are met:

1) The RCU_WAIT_TAIL segment has callbacks (say for gp_num 8) and the RCU_NEXT_READY_TAIL also has callbacks (say for gp_num 12).

2) The grace period for RCU_WAIT_TAIL is observed as started but not yet completed so rcu_seq_current() returns 4 + SRCU_STATE_SCAN1 = 5.

3) This value is passed to rcu_segcblist_advance() which can't move any segment forward and fails.

4) srcu_gp_start_if_needed() still proceeds with callback acceleration. But then the call to rcu_seq_snap() observes the grace period for the RCU_WAIT_TAIL segment (gp_num 8) as completed and the subsequent one for the RCU_NEXT_READY_TAIL segment as started
(ie: 8 + SRCU_STATE_SCAN1 = 9) so it returns a snapshot of the next grace period, which is 16.

5) The value of 16 is passed to rcu_segcblist_accelerate() but the freshly enqueued callback in RCU_NEXT_TAIL can't move to RCU_NEXT_READY_TAIL which already has callbacks for a previous grace period (gp_num = 12). So acceleration fails.

6) Note in all these steps, srcu_invoke_callbacks() hadn't had a chance to run srcu_invoke_callbacks().

Then some very bad outcome may happen if the following happens:

7) Some other CPU races and starts the grace period number 16 before the CPU handling previous steps had a chance. Therefore srcu_gp_start() isn't called on the latter sdp to fix the acceleration leak from previous steps with a new pair of call to advance/accelerate.

8) The grace period 16 completes and srcu_invoke_callbacks() is finally called. All the callbacks from previous grace periods (8 and 12) are correctly advanced and executed but callbacks in RCU_NEXT_READY_TAIL still remain. Then rcu_segcblist_accelerate() is called with a snaphot of 20.

9) Since nothing started the grace period number 20, callbacks stay unhandled.

This has been reported in real load:

	[3144162.608392] INFO: task kworker/136:12:252684 blocked for more
	than 122 seconds.
	[3144162.615986]       Tainted: G           O  K   5.4.203-1-tlinux4-0011.1 #1
	[3144162.623053] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
	disables this message.
	[3144162.631162] kworker/136:12  D    0 252684      2 0x90004000
	[3144162.631189] Workqueue: kvm-irqfd-cleanup irqfd_shutdown [kvm]
	[3144162.631192] Call Trace:
	[3144162.631202]  __schedule+0x2ee/0x660
	[3144162.631206]  schedule+0x33/0xa0
	[3144162.631209]  schedule_timeout+0x1c4/0x340
	[3144162.631214]  ? update_load_avg+0x82/0x660
	[3144162.631217]  ? raw_spin_rq_lock_nested+0x1f/0x30
	[3144162.631218]  wait_for_completion+0x119/0x180
	[3144162.631220]  ? wake_up_q+0x80/0x80
	[3144162.631224]  __synchronize_srcu.part.19+0x81/0xb0
	[3144162.631226]  ? __bpf_trace_rcu_utilization+0x10/0x10
	[3144162.631227]  synchronize_srcu+0x5f/0xc0
	[3144162.631236]  irqfd_shutdown+0x3c/0xb0 [kvm]
	[3144162.631239]  ? __schedule+0x2f6/0x660
	[3144162.631243]  process_one_work+0x19a/0x3a0
	[3144162.631244]  worker_thread+0x37/0x3a0
	[3144162.631247]  kthread+0x117/0x140
	[3144162.631247]  ? process_one_work+0x3a0/0x3a0
	[3144162.631248]  ? __kthread_cancel_work+0x40/0x40
	[3144162.631250]  ret_from_fork+0x1f/0x30

Fix this with taking the snapshot for acceleration _before_ the read of the current grace period number.

The only side effect of this solution is that callbacks advancing happen then _after_ the full barrier in rcu_seq_snap(). This is not a problem because that barrier only cares about:

1) Ordering accesses of the update side before call_srcu() so they don't bleed.
2) See all the accesses prior to the grace period of the current gp_num

The only things callbacks advancing need to be ordered against are carried by snp locking.

---
 kernel/rcu/srcutree.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
kernel/rcu/srcutree.c +29 -2
index 20d7a238d675a..253ed509b6abb 100644
@@ -1242,10 +1242,37 @@ static unsigned long srcu_gp_start_if_needed(struct srcu_struct *ssp,
 	spin_lock_irqsave_sdp_contention(sdp, &flags);
 	if (rhp)
 		rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp);
+	/*
+	 * The snapshot for acceleration must be taken _before_ the read of the
+	 * current gp sequence used for advancing, otherwise advancing may fail
+	 * and acceleration may then fail too.
+	 *
+	 * This could happen if:
+	 *
+	 *  1) The RCU_WAIT_TAIL segment has callbacks (gp_num = X + 4) and the
+	 *     RCU_NEXT_READY_TAIL also has callbacks (gp_num = X + 8).
+	 *
+	 *  2) The grace period for RCU_WAIT_TAIL is seen as started but not
+	 *     completed so rcu_seq_current() returns X + SRCU_STATE_SCAN1.
+	 *
+	 *  3) This value is passed to rcu_segcblist_advance() which can't move
+	 *     any segment forward and fails.
+	 *
+	 *  4) srcu_gp_start_if_needed() still proceeds with callback acceleration.
+	 *     But then the call to rcu_seq_snap() observes the grace period for the
+	 *     RCU_WAIT_TAIL segment as completed and the subsequent one for the
+	 *     RCU_NEXT_READY_TAIL segment as started (ie: X + 4 + SRCU_STATE_SCAN1)
+	 *     so it returns a snapshot of the next grace period, which is X + 12.
+	 *
+	 *  5) The value of X + 12 is passed to rcu_segcblist_accelerate() but the
+	 *     freshly enqueued callback in RCU_NEXT_TAIL can't move to
+	 *     RCU_NEXT_READY_TAIL which already has callbacks for a previous grace
+	 *     period (gp_num = X + 8). So acceleration fails.
+	 */
+	s = rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq);
 	rcu_segcblist_advance(&sdp->srcu_cblist,
 			      rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
-	s = rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq);
-	(void)rcu_segcblist_accelerate(&sdp->srcu_cblist, s);
+	WARN_ON_ONCE(!rcu_segcblist_accelerate(&sdp->srcu_cblist, s) && rhp);
 	if (ULONG_CMP_LT(sdp->srcu_gp_seq_needed, s)) {
 		sdp->srcu_gp_seq_needed = s;
 		needgp = true;
Signature · 1 line
2.42.0
author maintainer
#28 lore raw

PATCH 28/550 drivers/clocksource/timer-ti-dm: Dont call clk_get_rate() in stop function

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ivaylo Dimitrov <[email protected]>

[ Upstream commit 12590d4d0e331d3cb9e6b3494515cd61c8a6624e ]

clk_get_rate() might sleep, and that prevents dm-timer based PWM from being used from atomic context.

Fix that by getting fclk rate in probe() and using a notifier in case rate changes.

Fixes af04aa856e93 ("ARM: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource")
---
 drivers/clocksource/timer-ti-dm.c | 36 ++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 8 deletions(-)
drivers/clocksource/timer-ti-dm.c +28 -8
index 349236a7ba5ff..2d0bed0877e03 100644
@@ -141,6 +141,8 @@ struct dmtimer {
 	struct platform_device *pdev;
 	struct list_head node;
 	struct notifier_block nb;
+	struct notifier_block fclk_nb;
+	unsigned long fclk_rate;
 };
 
 static u32 omap_reserved_systimers;
@@ -254,8 +256,7 @@ static inline void __omap_dm_timer_enable_posted(struct dmtimer *timer)
 	timer->posted = OMAP_TIMER_POSTED;
 }
 
-static inline void __omap_dm_timer_stop(struct dmtimer *timer,
-					unsigned long rate)
+static inline void __omap_dm_timer_stop(struct dmtimer *timer)
 {
 	u32 l;
 
@@ -270,7 +271,7 @@ static inline void __omap_dm_timer_stop(struct dmtimer *timer,
 		 * Wait for functional clock period x 3.5 to make sure that
 		 * timer is stopped
 		 */
-		udelay(3500000 / rate + 1);
+		udelay(3500000 / timer->fclk_rate + 1);
 #endif
 	}
 
@@ -349,6 +350,21 @@ static int omap_timer_context_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
+static int omap_timer_fclk_notifier(struct notifier_block *nb,
+				    unsigned long event, void *data)
+{
+	struct clk_notifier_data *clk_data = data;
+	struct dmtimer *timer = container_of(nb, struct dmtimer, fclk_nb);
+
+	switch (event) {
+	case POST_RATE_CHANGE:
+		timer->fclk_rate = clk_data->new_rate;
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
 static int omap_dm_timer_reset(struct dmtimer *timer)
 {
 	u32 l, timeout = 100000;
@@ -755,7 +771,6 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie)
 {
 	struct dmtimer *timer;
 	struct device *dev;
-	unsigned long rate = 0;
 
 	timer = to_dmtimer(cookie);
 	if (unlikely(!timer))
@@ -763,10 +778,7 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie)
 
 	dev = &timer->pdev->dev;
 
-	if (!timer->omap1)
-		rate = clk_get_rate(timer->fclk);
-
-	__omap_dm_timer_stop(timer, rate);
+	__omap_dm_timer_stop(timer);
 
 	pm_runtime_put_sync(dev);
 
@@ -1125,6 +1137,14 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
 		timer->fclk = devm_clk_get(dev, "fck");
 		if (IS_ERR(timer->fclk))
 			return PTR_ERR(timer->fclk);
+
+		timer->fclk_nb.notifier_call = omap_timer_fclk_notifier;
+		ret = devm_clk_notifier_register(dev, timer->fclk,
+						 &timer->fclk_nb);
+		if (ret)
+			return ret;
+
+		timer->fclk_rate = clk_get_rate(timer->fclk);
 	} else {
 		timer->fclk = ERR_PTR(-ENODEV);
 	}
Signature · 1 line
2.42.0
author maintainer
#29 lore raw

PATCH 29/550 x86/nmi: Fix out-of-order NMI nesting checks & false positive warning

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul E. McKenney <[email protected]>

[ Upstream commit f44075ecafb726830e63d33fbca29413149eeeb8 ]

The ->idt_seq and ->recv_jiffies variables added by:

1a3ea611fc10 ("x86/nmi: Accumulate NMI-progress evidence in exc_nmi()")

... place the exit-time check of the bottom bit of ->idt_seq after the this_cpu_dec_return() that re-enables NMI nesting. This can result in the following sequence of events on a given CPU in kernels built with CONFIG_NMI_CHECK_CPU=y:

o An NMI arrives, and ->idt_seq is incremented to an odd number.

      In addition, nmi_state is set to NMI_EXECUTING==1.

o The NMI is processed.

o The this_cpu_dec_return(nmi_state) zeroes nmi_state and returns

      NMI_EXECUTING==1, thus opting out of the "goto nmi_restart".

o Another NMI arrives and ->idt_seq is incremented to an even
number, triggering the warning. But all is just fine, at least assuming we don't get so many closely spaced NMIs that the stack overflows or some such.

Experience on the fleet indicates that the MTBF of this false positive is about 70 years. Or, for those who are not quite that patient, the MTBF appears to be about one per week per 4,000 systems.

Fix this false-positive warning by moving the "nmi_restart" label before the initial ->idt_seq increment/check and moving the this_cpu_dec_return() to follow the final ->idt_seq increment/check. This way, all nested NMIs that get past the NMI_NOT_RUNNING check get a clean ->idt_seq slate. And if they don't get past that check, they will set nmi_state to NMI_LATCHED, which will cause the this_cpu_dec_return(nmi_state) to restart.

Fixes 1a3ea611fc10 ("x86/nmi: Accumulate NMI-progress evidence in exc_nmi()")
Cc Linus Torvalds <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/kernel/nmi.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
arch/x86/kernel/nmi.c +7 -6
index a0c551846b35f..4766b6bed4439 100644
@@ -507,12 +507,13 @@ DEFINE_IDTENTRY_RAW(exc_nmi)
 	}
 	this_cpu_write(nmi_state, NMI_EXECUTING);
 	this_cpu_write(nmi_cr2, read_cr2());
+
+nmi_restart:
 	if (IS_ENABLED(CONFIG_NMI_CHECK_CPU)) {
 		WRITE_ONCE(nsp->idt_seq, nsp->idt_seq + 1);
 		WARN_ON_ONCE(!(nsp->idt_seq & 0x1));
 		WRITE_ONCE(nsp->recv_jiffies, jiffies);
 	}
-nmi_restart:
 
 	/*
 	 * Needs to happen before DR7 is accessed, because the hypervisor can
@@ -548,16 +549,16 @@ DEFINE_IDTENTRY_RAW(exc_nmi)
 
 	if (unlikely(this_cpu_read(nmi_cr2) != read_cr2()))
 		write_cr2(this_cpu_read(nmi_cr2));
-	if (this_cpu_dec_return(nmi_state))
-		goto nmi_restart;
-
-	if (user_mode(regs))
-		mds_user_clear_cpu_buffers();
 	if (IS_ENABLED(CONFIG_NMI_CHECK_CPU)) {
 		WRITE_ONCE(nsp->idt_seq, nsp->idt_seq + 1);
 		WARN_ON_ONCE(nsp->idt_seq & 0x1);
 		WRITE_ONCE(nsp->recv_jiffies, jiffies);
 	}
+	if (this_cpu_dec_return(nmi_state))
+		goto nmi_restart;
+
+	if (user_mode(regs))
+		mds_user_clear_cpu_buffers();
 }
 
 #if IS_ENABLED(CONFIG_KVM_INTEL)
Signature · 1 line
2.42.0
author maintainer
#30 lore raw

PATCH 30/550 pstore/platform: Add check for kstrdup

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiasheng Jiang <[email protected]>

[ Upstream commit a19d48f7c5d57c0f0405a7d4334d1d38fe9d3c1c ]

Add check for the return value of kstrdup() and return the error if it fails in order to avoid NULL pointer dereference.

Fixes 563ca40ddf40 ("pstore/platform: Switch pstore_info::name to const")
---
 fs/pstore/platform.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
fs/pstore/platform.c +8 -1
index cbc0b468c1ab6..15cefe268ffd8 100644
@@ -573,6 +573,8 @@ static int pstore_write_user_compat(struct pstore_record *record,
  */
 int pstore_register(struct pstore_info *psi)
 {
+	char *new_backend;
+
 	if (backend && strcmp(backend, psi->name)) {
 		pr_warn("backend '%s' already in use: ignoring '%s'\n",
 			backend, psi->name);
@@ -593,11 +595,16 @@ int pstore_register(struct pstore_info *psi)
 		return -EINVAL;
 	}
 
+	new_backend = kstrdup(psi->name, GFP_KERNEL);
+	if (!new_backend)
+		return -ENOMEM;
+
 	mutex_lock(&psinfo_lock);
 	if (psinfo) {
 		pr_warn("backend '%s' already loaded: ignoring '%s'\n",
 			psinfo->name, psi->name);
 		mutex_unlock(&psinfo_lock);
+		kfree(new_backend);
 		return -EBUSY;
 	}
 
@@ -630,7 +637,7 @@ int pstore_register(struct pstore_info *psi)
 	 * Update the module parameter backend, so it is visible
 	 * through /sys/module/pstore/parameters/backend
 	 */
-	backend = kstrdup(psi->name, GFP_KERNEL);
+	backend = new_backend;
 
 	pr_info("Registered %s as persistent store backend\n", psi->name);
 
Signature · 1 line
2.42.0
author maintainer
#31 lore raw

PATCH 31/550 perf: Optimize perf_cgroup_switch()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

[ Upstream commit f06cc667f79909e9175460b167c277b7c64d3df0 ]

Namhyung reported that bd2756811766 ("perf: Rewrite core context handling") regresses context switch overhead when perf-cgroup is in use together with 'slow' PMUs like uncore.

Specifically, perf_cgroup_switch()'s perf_ctx_disable() / ctx_sched_out() etc.. all iterate the full list of active PMUs for that CPU, even if they don't have cgroup events.

Previously there was cgrp_cpuctx_list which linked the relevant PMUs together, but that got lost in the rework. Instead of re-instruducing a similar list, let the perf_event_pmu_context iteration skip those that do not have cgroup events. This avoids growing multiple versions of the perf_event_pmu_context iteration.

Measured performance (on a slightly different patch):

Before)

  $ taskset -c 0 ./perf bench sched pipe -l 10000 -G AAA,BBB
  # Running 'sched/pipe' benchmark:
  # Executed 10000 pipe operations between two processes
       Total time: 0.901 [sec]

        90.128700 usecs/op
            11095 ops/sec

After)

  $ taskset -c 0 ./perf bench sched pipe -l 10000 -G AAA,BBB
  # Running 'sched/pipe' benchmark:
  # Executed 10000 pipe operations between two processes
       Total time: 0.065 [sec]

         6.560100 usecs/op
           152436 ops/sec
---
 include/linux/perf_event.h |   1 +
 kernel/events/core.c       | 115 +++++++++++++++++++------------------
 2 files changed, 61 insertions(+), 55 deletions(-)
include/linux/perf_event.h +1 -0
index 227e9d45f61b6..e7afd0dd8a3d1 100644
@@ -879,6 +879,7 @@ struct perf_event_pmu_context {
 	unsigned int			embedded : 1;
 
 	unsigned int			nr_events;
+	unsigned int			nr_cgroups;
 
 	atomic_t			refcount; /* event <-> epc */
 	struct rcu_head			rcu_head;
kernel/events/core.c +60 -55

273 lines not on this page · raw message

Signature · 1 line
2.42.0
author maintainer
#32 lore raw

PATCH 32/550 selftests/x86/lam: Zero out buffer for readlink()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Binbin Wu <[email protected]>

[ Upstream commit 29060633411a02f6f2dd9d5245919385d69d81f0 ]

Zero out the buffer for readlink() since readlink() does not append a terminating null byte to the buffer. Also change the buffer length passed to readlink() to 'PATH_MAX - 1' to ensure the resulting string is always null terminated.

Fixes 833c12ce0f430 ("selftests/x86/lam: Add inherit test cases for linear-address masking")
---
 tools/testing/selftests/x86/lam.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/x86/lam.c +3 -3
index eb0e46905bf9d..8f9b06d9ce039 100644
@@ -573,7 +573,7 @@ int do_uring(unsigned long lam)
 	char path[PATH_MAX] = {0};
 
 	/* get current process path */
-	if (readlink("/proc/self/exe", path, PATH_MAX) <= 0)
+	if (readlink("/proc/self/exe", path, PATH_MAX - 1) <= 0)
 		return 1;
 
 	int file_fd = open(path, O_RDONLY);
@@ -680,14 +680,14 @@ static int handle_execve(struct testcases *test)
 		perror("Fork failed.");
 		ret = 1;
 	} else if (pid == 0) {
-		char path[PATH_MAX];
+		char path[PATH_MAX] = {0};
 
 		/* Set LAM mode in parent process */
 		if (set_lam(lam) != 0)
 			return 1;
 
 		/* Get current binary's path and the binary was run by execve */
-		if (readlink("/proc/self/exe", path, PATH_MAX) <= 0)
+		if (readlink("/proc/self/exe", path, PATH_MAX - 1) <= 0)
 			exit(-1);
 
 		/* run binary to get LAM mode and return to parent process */
Signature · 1 line
2.42.0
author maintainer
#33 lore raw

PATCH 33/550 PCI/MSI: Provide stubs for IMS functions

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Reinette Chatre <[email protected]>

[ Upstream commit 41efa431244f6498833ff8ee8dde28c4924c5479 ]

The IMS related functions (pci_create_ims_domain(), pci_ims_alloc_irq(), and pci_ims_free_irq()) are not declared when CONFIG_PCI_MSI is disabled.

Provide definitions of these functions for use when callers are compiled with CONFIG_PCI_MSI disabled.

Fixes 0194425af0c8 ("PCI/MSI: Provide IMS (Interrupt Message Store) support")
Fixes c9e5bea27383 ("PCI/MSI: Provide pci_ims_alloc/free_irq()")
---
 include/linux/pci.h | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)
include/linux/pci.h +26 -8
index 7ee498cd1f374..c8688d13cc224 100644
@@ -1625,6 +1625,8 @@ struct msix_entry {
 	u16	entry;	/* Driver uses to specify entry, OS writes */
 };
 
+struct msi_domain_template;
+
 #ifdef CONFIG_PCI_MSI
 int pci_msi_vec_count(struct pci_dev *dev);
 void pci_disable_msi(struct pci_dev *dev);
@@ -1657,6 +1659,11 @@ void pci_msix_free_irq(struct pci_dev *pdev, struct msi_map map);
 void pci_free_irq_vectors(struct pci_dev *dev);
 int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
 const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec);
+bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template,
+			   unsigned int hwsize, void *data);
+struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie,
+				 const struct irq_affinity_desc *affdesc);
+void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);
 
 #else
 static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; }
@@ -1720,6 +1727,25 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev,
 {
 	return cpu_possible_mask;
 }
+
+static inline bool pci_create_ims_domain(struct pci_dev *pdev,
+					 const struct msi_domain_template *template,
+					 unsigned int hwsize, void *data)
+{ return false; }
+
+static inline struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev,
+					       union msi_instance_cookie *icookie,
+					       const struct irq_affinity_desc *affdesc)
+{
+	struct msi_map map = { .index = -ENOSYS, };
+
+	return map;
+}
+
+static inline void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map)
+{
+}
+
 #endif
 
 /**
@@ -2612,14 +2638,6 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
 void pci_uevent_ers(struct pci_dev *pdev, enum  pci_ers_result err_type);
 #endif
 
-struct msi_domain_template;
-
-bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template,
-			   unsigned int hwsize, void *data);
-struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie,
-				 const struct irq_affinity_desc *affdesc);
-void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);
-
 #include <linux/dma-mapping.h>
 
 #define pci_printk(level, pdev, fmt, arg...) \
Signature · 1 line
2.42.0
author maintainer
#34 lore raw

PATCH 34/550 string: Adjust strtomem() logic to allow for smaller sources

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kees Cook <[email protected]>

[ Upstream commit 0e108725f6cc5b3be9e607f89c9fbcbb236367b7 ]

Arnd noticed we have a case where a shorter source string is being copied into a destination byte array, but this results in a strnlen() call that exceeds the size of the source. This is seen with -Wstringop-overread:

In file included from ../include/linux/uuid.h:11,

                 from ../include/linux/mod_devicetable.h:14,
                 from ../include/linux/cpufeature.h:12,
                 from ../arch/x86/coco/tdx/tdx.c:7:
../arch/x86/coco/tdx/tdx.c: In function 'tdx_panic.constprop':
../include/linux/string.h:284:9: error: 'strnlen' specified bound 64 exceeds source size 60 [-Werror=stringop-overread]
  284 |         memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../arch/x86/coco/tdx/tdx.c:124:9: note: in expansion of macro 'strtomem_pad'
  124 |         strtomem_pad(message.str, msg, '\0');
      |         ^~~~~~~~~~~~

Use the smaller of the two buffer sizes when calling strnlen(). When src length is unknown (SIZE_MAX), it is adjusted to use dest length, which is what the original code did.

Fixes dfbafa70bde2 ("string: Introduce strtomem() and strtomem_pad()")
Cc Andy Shevchenko <[email protected]>
---
 include/linux/string.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
include/linux/string.h +5 -2
index dbfc66400050f..9e3cb6923b0ef 100644
@@ -277,10 +277,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
  */
 #define strtomem_pad(dest, src, pad)	do {				\
 	const size_t _dest_len = __builtin_object_size(dest, 1);	\
+	const size_t _src_len = __builtin_object_size(src, 1);		\
 									\
 	BUILD_BUG_ON(!__builtin_constant_p(_dest_len) ||		\
 		     _dest_len == (size_t)-1);				\
-	memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \
+	memcpy_and_pad(dest, _dest_len, src,				\
+		       strnlen(src, min(_src_len, _dest_len)), pad);	\
 } while (0)
 
 /**
@@ -298,10 +300,11 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
  */
 #define strtomem(dest, src)	do {					\
 	const size_t _dest_len = __builtin_object_size(dest, 1);	\
+	const size_t _src_len = __builtin_object_size(src, 1);		\
 									\
 	BUILD_BUG_ON(!__builtin_constant_p(_dest_len) ||		\
 		     _dest_len == (size_t)-1);				\
-	memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len)));	\
+	memcpy(dest, src, strnlen(src, min(_src_len, _dest_len)));	\
 } while (0)
 
 /**
Signature · 1 line
2.42.0
author maintainer
#35 lore raw

PATCH 35/550 genirq/matrix: Exclude managed interrupts in irq_matrix_allocated()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chen Yu <[email protected]>

[ Upstream commit a0b0bad10587ae2948a7c36ca4ffc206007fbcf3 ]

When a CPU is about to be offlined, x86 validates that all active interrupts which are targeted to this CPU can be migrated to the remaining online CPUs. If not, the offline operation is aborted.

The validation uses irq_matrix_allocated() to retrieve the number of vectors which are allocated on the outgoing CPU. The returned number of allocated vectors includes also vectors which are associated to managed interrupts.

That's overaccounting because managed interrupts are:

- not migrated when the affinity mask of the interrupt targets only the outgoing CPU

- migrated to another CPU, but in that case the vector is already pre-allocated on the potential target CPUs and must not be taken into account.

As a consequence the check whether the remaining online CPUs have enough capacity for migrating the allocated vectors from the outgoing CPU might fail incorrectly.

Let irq_matrix_allocated() return only the number of allocated non-managed interrupts to make this validation check correct.

[ tglx: Amend changelog and fixup kernel-doc comment ]

Fixes 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator")
---
 kernel/irq/matrix.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/irq/matrix.c +3 -3
index 1698e77645acf..75d0ae490e29c 100644
@@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m)
 }
 
 /**
- * irq_matrix_allocated - Get the number of allocated irqs on the local cpu
+ * irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU
  * @m:		Pointer to the matrix to search
  *
- * This returns number of allocated irqs
+ * This returns number of allocated non-managed interrupts.
  */
 unsigned int irq_matrix_allocated(struct irq_matrix *m)
 {
 	struct cpumap *cm = this_cpu_ptr(m->maps);
 
-	return cm->allocated;
+	return cm->allocated - cm->managed_allocated;
 }
 
 #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
Signature · 1 line
2.42.0
author maintainer
#36 lore raw

PATCH 36/550 irqchip/sifive-plic: Fix syscore registration for multi-socket systems

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Anup Patel <[email protected]>

[ Upstream commit f99b926f6543faeadba1b4524d8dc9c102489135 ]

Multi-socket systems have a separate PLIC in each socket, so __plic_init() is invoked for each PLIC. __plic_init() registers syscore operations, which obviously fails on the second invocation.

Move it into the already existing condition for installing the CPU hotplug state so it is only invoked once when the first PLIC is initialized.

[ tglx: Massaged changelog ]

Fixes e80f0b6a2cf3 ("irqchip/irq-sifive-plic: Add syscore callbacks for hibernation")
---
 drivers/irqchip/irq-sifive-plic.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/irqchip/irq-sifive-plic.c +4 -3
index e1484905b7bdb..5b7bc4fd9517c 100644
@@ -532,17 +532,18 @@ static int __init __plic_init(struct device_node *node,
 	}
 
 	/*
-	 * We can have multiple PLIC instances so setup cpuhp state only
-	 * when context handler for current/boot CPU is present.
+	 * We can have multiple PLIC instances so setup cpuhp state
+	 * and register syscore operations only when context handler
+	 * for current/boot CPU is present.
 	 */
 	handler = this_cpu_ptr(&plic_handlers);
 	if (handler->present && !plic_cpuhp_setup_done) {
 		cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
 				  "irqchip/sifive/plic:starting",
 				  plic_starting_cpu, plic_dying_cpu);
+		register_syscore_ops(&plic_irq_syscore_ops);
 		plic_cpuhp_setup_done = true;
 	}
-	register_syscore_ops(&plic_irq_syscore_ops);
 
 	pr_info("%pOFP: mapped %d interrupts with %d handlers for"
 		" %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
Signature · 1 line
2.42.0
author maintainer
#37 lore raw

PATCH 37/550 wifi: ath12k: fix undefined behavior with __fls in dp

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Harshitha Prem <[email protected]>

[ Upstream commit d48f55e773dcce8fcf9e587073452a4944011b11 ]

When max virtual ap interfaces are configured in all the bands with ACS and hostapd restart is done every 60s,
a crash is observed at random times because of handling the uninitialized peer fragments with fragment id of packet as 0.

"__fls" would have an undefined behavior if the argument is passed as "0". Hence, added changes to handle the same.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Fixes d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
---
 drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/dp_rx.c +1 -1
index ffd9a2018610f..fcb91b8ef00e3 100644
@@ -3228,7 +3228,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
 		goto out_unlock;
 	}
 
-	if (frag_no > __fls(rx_tid->rx_frag_bitmap))
+	if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap)))
 		__skb_queue_tail(&rx_tid->rx_frags, msdu);
 	else
 		ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu);
Signature · 1 line
2.42.0
author maintainer
#38 lore raw

PATCH 38/550 wifi: cfg80211: add flush functions for wiphy work

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 56cfb8ce1f7f6c4e5ca571a2ec0880e131cd0311 ]

There may be sometimes reasons to actually run the work if it's pending, add flush functions for both regular and delayed wiphy work that will do this.

Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work")

---
 include/net/cfg80211.h | 21 +++++++++++++++++++++
 net/wireless/core.c    | 34 ++++++++++++++++++++++++++++++++--
 net/wireless/core.h    |  3 ++-
 net/wireless/sysfs.c   |  4 ++--
 4 files changed, 57 insertions(+), 5 deletions(-)
include/net/cfg80211.h +21 -0
index 641c6edc9b81d..0f0bf26adb15d 100644
@@ -5827,6 +5827,16 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work);
  */
 void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work);
 
+/**
+ * wiphy_work_flush - flush previously queued work
+ * @wiphy: the wiphy, for debug purposes
+ * @work: the work to flush, this can be %NULL to flush all work
+ *
+ * Flush the work (i.e. run it if pending). This must be called
+ * under the wiphy mutex acquired by wiphy_lock().
+ */
+void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work);
+
 struct wiphy_delayed_work {
 	struct wiphy_work work;
 	struct wiphy *wiphy;
@@ -5870,6 +5880,17 @@ void wiphy_delayed_work_queue(struct wiphy *wiphy,
 void wiphy_delayed_work_cancel(struct wiphy *wiphy,
 			       struct wiphy_delayed_work *dwork);
 
+/**
+ * wiphy_delayed work_flush - flush previously queued delayed work
+ * @wiphy: the wiphy, for debug purposes
+ * @work: the work to flush
+ *
+ * Flush the work (i.e. run it if pending). This must be called
+ * under the wiphy mutex acquired by wiphy_lock().
+ */
+void wiphy_delayed_work_flush(struct wiphy *wiphy,
+			      struct wiphy_delayed_work *dwork);
+
 /**
  * struct wireless_dev - wireless device state
  *
net/wireless/core.c +32 -2
index acec41c1809a8..563cfbe3237c9 100644
@@ -1049,7 +1049,8 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy)
 }
 EXPORT_SYMBOL(wiphy_rfkill_start_polling);
 
-void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev)
+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev,
+				  struct wiphy_work *end)
 {
 	unsigned int runaway_limit = 100;
 	unsigned long flags;
@@ -1068,6 +1069,10 @@ void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev)
 		wk->func(&rdev->wiphy, wk);
 
 		spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
+
+		if (wk == end)
+			break;
+
 		if (WARN_ON(--runaway_limit == 0))
 			INIT_LIST_HEAD(&rdev->wiphy_work_list);
 	}
@@ -1118,7 +1123,7 @@ void wiphy_unregister(struct wiphy *wiphy)
 #endif
 
 	/* surely nothing is reachable now, clean up work */
-	cfg80211_process_wiphy_works(rdev);
+	cfg80211_process_wiphy_works(rdev, NULL);
 	wiphy_unlock(&rdev->wiphy);
 	rtnl_unlock();
 
@@ -1640,6 +1645,21 @@ void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work)
 }
 EXPORT_SYMBOL_GPL(wiphy_work_cancel);
 
+void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	unsigned long flags;
+	bool run;
+
+	spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
+	run = !work || !list_empty(&work->entry);
+	spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
+
+	if (run)
+		cfg80211_process_wiphy_works(rdev, work);
+}
+EXPORT_SYMBOL_GPL(wiphy_work_flush);
+
 void wiphy_delayed_work_timer(struct timer_list *t)
 {
 	struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer);
@@ -1672,6 +1692,16 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel);
 
+void wiphy_delayed_work_flush(struct wiphy *wiphy,
+			      struct wiphy_delayed_work *dwork)
+{
+	lockdep_assert_held(&wiphy->mtx);
+
+	del_timer_sync(&dwork->timer);
+	wiphy_work_flush(wiphy, &dwork->work);
+}
+EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
+
 static int __init cfg80211_init(void)
 {
 	int err;
net/wireless/core.h +2 -1
index 86f209abc06ab..ba1f2ce5f4ff3 100644
@@ -464,7 +464,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev, enum nl80211_iftype ntype,
 			  struct vif_params *params);
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
-void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev);
+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev,
+				  struct wiphy_work *end);
 void cfg80211_process_wdev_events(struct wireless_dev *wdev);
 
 bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
net/wireless/sysfs.c +2 -2
index c629bac3f2983..565511a3f461e 100644
@@ -105,14 +105,14 @@ static int wiphy_suspend(struct device *dev)
 			cfg80211_leave_all(rdev);
 			cfg80211_process_rdev_events(rdev);
 		}
-		cfg80211_process_wiphy_works(rdev);
+		cfg80211_process_wiphy_works(rdev, NULL);
 		if (rdev->ops->suspend)
 			ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
 		if (ret == 1) {
 			/* Driver refuse to configure wowlan */
 			cfg80211_leave_all(rdev);
 			cfg80211_process_rdev_events(rdev);
-			cfg80211_process_wiphy_works(rdev);
+			cfg80211_process_wiphy_works(rdev, NULL);
 			ret = rdev_suspend(rdev, NULL);
 		}
 		if (ret == 0)
Signature · 1 line
2.42.0
author maintainer
#39 lore raw

PATCH 39/550 wifi: mac80211: move radar detect work to wiphy work

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 228e4f931b0e630dacca8dd867ddd863aea53913 ]

Move the radar detect work to wiphy work in order to lock the wiphy for it without doing it manually.

Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work")

---
 net/mac80211/ieee80211_i.h | 5 +++--
 net/mac80211/main.c        | 9 +++++----
 net/mac80211/util.c        | 7 +++----
 3 files changed, 11 insertions(+), 10 deletions(-)
net/mac80211/ieee80211_i.h +3 -2
index 2cce9eba6a120..90eda427e9ab8 100644
@@ -1406,7 +1406,7 @@ struct ieee80211_local {
 	/* wowlan is enabled -- don't reconfig on resume */
 	bool wowlan;
 
-	struct work_struct radar_detected_work;
+	struct wiphy_work radar_detected_work;
 
 	/* number of RX chains the hardware has */
 	u8 rx_chains;
@@ -2568,7 +2568,8 @@ bool ieee80211_is_radar_required(struct ieee80211_local *local);
 void ieee80211_dfs_cac_timer(unsigned long data);
 void ieee80211_dfs_cac_timer_work(struct work_struct *work);
 void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);
-void ieee80211_dfs_radar_detected_work(struct work_struct *work);
+void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
+				       struct wiphy_work *work);
 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
 			      struct cfg80211_csa_settings *csa_settings);
 
net/mac80211/main.c +5 -4
index 24315d7b31263..3bbd66e5a0df0 100644
@@ -338,7 +338,6 @@ static void ieee80211_restart_work(struct work_struct *work)
 	/* wait for scan work complete */
 	flush_workqueue(local->workqueue);
 	flush_work(&local->sched_scan_stopped_work);
-	flush_work(&local->radar_detected_work);
 
 	rtnl_lock();
 	/* we might do interface manipulations, so need both */
@@ -813,8 +812,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 
 	INIT_WORK(&local->restart_work, ieee80211_restart_work);
 
-	INIT_WORK(&local->radar_detected_work,
-		  ieee80211_dfs_radar_detected_work);
+	wiphy_work_init(&local->radar_detected_work,
+			ieee80211_dfs_radar_detected_work);
 
 	INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
 	local->smps_mode = IEEE80211_SMPS_OFF;
@@ -1482,13 +1481,15 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	 */
 	ieee80211_remove_interfaces(local);
 
+	wiphy_lock(local->hw.wiphy);
+	wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work);
+	wiphy_unlock(local->hw.wiphy);
 	rtnl_unlock();
 
 	cancel_delayed_work_sync(&local->roc_work);
 	cancel_work_sync(&local->restart_work);
 	cancel_work_sync(&local->reconfig_filter);
 	flush_work(&local->sched_scan_stopped_work);
-	flush_work(&local->radar_detected_work);
 
 	ieee80211_clear_tx_pending(local);
 	rate_control_deinitialize(local);
net/mac80211/util.c +3 -4
index 8a6917cf63cf9..e878b6a27651a 100644
@@ -4356,7 +4356,8 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
 	mutex_unlock(&local->mtx);
 }
 
-void ieee80211_dfs_radar_detected_work(struct work_struct *work)
+void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
+				       struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, radar_detected_work);
@@ -4374,9 +4375,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
 	}
 	mutex_unlock(&local->chanctx_mtx);
 
-	wiphy_lock(local->hw.wiphy);
 	ieee80211_dfs_cac_cancel(local);
-	wiphy_unlock(local->hw.wiphy);
 
 	if (num_chanctx > 1)
 		/* XXX: multi-channel is not supported yet */
@@ -4391,7 +4390,7 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw)
 
 	trace_api_radar_detected(local);
 
-	schedule_work(&local->radar_detected_work);
+	wiphy_work_queue(hw->wiphy, &local->radar_detected_work);
 }
 EXPORT_SYMBOL(ieee80211_radar_detected);
 
Signature · 1 line
2.42.0
author maintainer
#40 lore raw

PATCH 40/550 wifi: mac80211: move scan work to wiphy work

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 201712512cbbda360f62c222a4bab260350462a0 ]

Move the scan work to wiphy work, which also simplifies the way we handle the work vs. the scan configuration.

Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work")

---
 net/mac80211/ieee80211_i.h |  4 ++--
 net/mac80211/iface.c       |  2 +-
 net/mac80211/main.c        |  4 +---
 net/mac80211/scan.c        | 29 ++++++++++++-----------------
 net/mac80211/util.c        |  4 ++--
 5 files changed, 18 insertions(+), 25 deletions(-)
net/mac80211/ieee80211_i.h +2 -2
index 90eda427e9ab8..fef9aea9ba958 100644
@@ -1490,7 +1490,7 @@ struct ieee80211_local {
 
 	unsigned long leave_oper_channel_time;
 	enum mac80211_scan_state next_scan_state;
-	struct delayed_work scan_work;
+	struct wiphy_delayed_work scan_work;
 	struct ieee80211_sub_if_data __rcu *scan_sdata;
 	/* For backward compatibility only -- do not use */
 	struct cfg80211_chan_def _oper_chandef;
@@ -1930,7 +1930,7 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata,
 			      u64 *changed);
 
 /* scan/BSS handling */
-void ieee80211_scan_work(struct work_struct *work);
+void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work);
 int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 				const u8 *ssid, u8 ssid_len,
 				struct ieee80211_channel **channels,
net/mac80211/iface.c +1 -1
index be586bc0b5b7d..6e3bfb46af44d 100644
@@ -691,7 +691,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 	ieee80211_recalc_ps(local);
 
 	if (cancel_scan)
-		flush_delayed_work(&local->scan_work);
+		wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work);
 
 	if (local->open_count == 0) {
 		ieee80211_stop_device(local);
net/mac80211/main.c +1 -3
index 3bbd66e5a0df0..adb8637a37445 100644
@@ -335,9 +335,7 @@ static void ieee80211_restart_work(struct work_struct *work)
 	struct ieee80211_sub_if_data *sdata;
 	int ret;
 
-	/* wait for scan work complete */
 	flush_workqueue(local->workqueue);
-	flush_work(&local->sched_scan_stopped_work);
 
 	rtnl_lock();
 	/* we might do interface manipulations, so need both */
@@ -808,7 +806,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 	INIT_LIST_HEAD(&local->chanctx_list);
 	mutex_init(&local->chanctx_mtx);
 
-	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
+	wiphy_delayed_work_init(&local->scan_work, ieee80211_scan_work);
 
 	INIT_WORK(&local->restart_work, ieee80211_restart_work);
 
net/mac80211/scan.c +12 -17
index 0805aa8603c61..2117cb2a916ac 100644
@@ -274,8 +274,8 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
 		 * the beacon/proberesp rx gives us an opportunity to upgrade
 		 * to active scan
 		 */
-		 set_bit(SCAN_BEACON_DONE, &local->scanning);
-		 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+		set_bit(SCAN_BEACON_DONE, &local->scanning);
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
 	}
 
 	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
@@ -505,7 +505,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw,
 
 	memcpy(&local->scan_info, info, sizeof(*info));
 
-	ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+	wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
 }
 EXPORT_SYMBOL(ieee80211_scan_completed);
 
@@ -545,8 +545,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
 	/* We need to set power level at maximum rate for scanning. */
 	ieee80211_hw_config(local, 0);
 
-	ieee80211_queue_delayed_work(&local->hw,
-				     &local->scan_work, 0);
+	wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
 
 	return 0;
 }
@@ -603,8 +602,8 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local)
 					lockdep_is_held(&local->mtx))))
 		return;
 
-	ieee80211_queue_delayed_work(&local->hw, &local->scan_work,
-				     round_jiffies_relative(0));
+	wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work,
+				 round_jiffies_relative(0));
 }
 
 static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -795,8 +794,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 		}
 
 		/* Now, just wait a bit and we are all done! */
-		ieee80211_queue_delayed_work(&local->hw, &local->scan_work,
-					     next_delay);
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work,
+					 next_delay);
 		return 0;
 	} else {
 		/* Do normal software scan */
@@ -1043,7 +1042,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local,
 	local->next_scan_state = SCAN_SET_CHANNEL;
 }
 
-void ieee80211_scan_work(struct work_struct *work)
+void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, scan_work.work);
@@ -1137,7 +1136,8 @@ void ieee80211_scan_work(struct work_struct *work)
 		}
 	} while (next_delay == 0);
 
-	ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
+	wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work,
+				 next_delay);
 	goto out;
 
 out_complete:
@@ -1280,12 +1280,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
 		goto out;
 	}
 
-	/*
-	 * If the work is currently running, it must be blocked on
-	 * the mutex, but we'll set scan_sdata = NULL and it'll
-	 * simply exit once it acquires the mutex.
-	 */
-	cancel_delayed_work(&local->scan_work);
+	wiphy_delayed_work_cancel(local->hw.wiphy, &local->scan_work);
 	/* and clean up */
 	memset(&local->scan_info, 0, sizeof(local->scan_info));
 	__ieee80211_scan_completed(&local->hw, true);
net/mac80211/util.c +2 -2
index e878b6a27651a..172173b2a9eb8 100644
@@ -2340,8 +2340,8 @@ static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
 		 */
 		if (aborted)
 			set_bit(SCAN_ABORTED, &local->scanning);
-		ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
-		flush_delayed_work(&local->scan_work);
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
+		wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work);
 	}
 }
 
Signature · 1 line
2.42.0
author maintainer
#41 lore raw

PATCH 41/550 wifi: mac80211: move offchannel works to wiphy work

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 97c19e42b264e6b71a9ff9deea04c19f621805b9 ]

Make the offchannel works wiphy works to have the
wiphy locked for executing them.

Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work")

---
 net/mac80211/ieee80211_i.h |  4 ++--
 net/mac80211/main.c        |  6 +++---
 net/mac80211/offchannel.c  | 36 ++++++++++++++++++------------------
 3 files changed, 23 insertions(+), 23 deletions(-)
net/mac80211/ieee80211_i.h +2 -2
index fef9aea9ba958..10ad1d8f9ba83 100644
@@ -1583,9 +1583,9 @@ struct ieee80211_local {
 	/*
 	 * Remain-on-channel support
 	 */
-	struct delayed_work roc_work;
+	struct wiphy_delayed_work roc_work;
 	struct list_head roc_list;
-	struct work_struct hw_roc_start, hw_roc_done;
+	struct wiphy_work hw_roc_start, hw_roc_done;
 	unsigned long hw_roc_start_time;
 	u64 roc_cookie_counter;
 
net/mac80211/main.c +3 -3
index adb8637a37445..f1cbb7c5d4ac3 100644
@@ -376,8 +376,8 @@ static void ieee80211_restart_work(struct work_struct *work)
 	ieee80211_scan_cancel(local);
 
 	/* make sure any new ROC will consider local->in_reconfig */
-	flush_delayed_work(&local->roc_work);
-	flush_work(&local->hw_roc_done);
+	wiphy_delayed_work_flush(local->hw.wiphy, &local->roc_work);
+	wiphy_work_flush(local->hw.wiphy, &local->hw_roc_done);
 
 	/* wait for all packet processing to be done */
 	synchronize_net();
@@ -1480,11 +1480,11 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	ieee80211_remove_interfaces(local);
 
 	wiphy_lock(local->hw.wiphy);
+	wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work);
 	wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work);
 	wiphy_unlock(local->hw.wiphy);
 	rtnl_unlock();
 
-	cancel_delayed_work_sync(&local->roc_work);
 	cancel_work_sync(&local->restart_work);
 	cancel_work_sync(&local->reconfig_filter);
 	flush_work(&local->sched_scan_stopped_work);
net/mac80211/offchannel.c +18 -18
index cdf991e74ab99..5bedd9cef414d 100644
@@ -230,7 +230,7 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local,
 	if (dur == LONG_MAX)
 		return false;
 
-	mod_delayed_work(local->workqueue, &local->roc_work, dur);
+	wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, dur);
 	return true;
 }
 
@@ -258,7 +258,7 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
 	roc->notified = true;
 }
 
-static void ieee80211_hw_roc_start(struct work_struct *work)
+static void ieee80211_hw_roc_start(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, hw_roc_start);
@@ -285,7 +285,7 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw)
 
 	trace_api_ready_on_channel(local);
 
-	ieee80211_queue_work(hw, &local->hw_roc_start);
+	wiphy_work_queue(hw->wiphy, &local->hw_roc_start);
 }
 EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel);
 
@@ -338,7 +338,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local)
 				tmp->started = true;
 				tmp->abort = true;
 			}
-			ieee80211_queue_work(&local->hw, &local->hw_roc_done);
+			wiphy_work_queue(local->hw.wiphy, &local->hw_roc_done);
 			return;
 		}
 
@@ -368,8 +368,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local)
 			ieee80211_hw_config(local, 0);
 		}
 
-		ieee80211_queue_delayed_work(&local->hw, &local->roc_work,
-					     msecs_to_jiffies(min_dur));
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
+					 msecs_to_jiffies(min_dur));
 
 		/* tell userspace or send frame(s) */
 		list_for_each_entry(tmp, &local->roc_list, list) {
@@ -407,8 +407,8 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
 		_ieee80211_start_next_roc(local);
 	} else {
 		/* delay it a bit */
-		ieee80211_queue_delayed_work(&local->hw, &local->roc_work,
-					     round_jiffies_relative(HZ/2));
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
+					 round_jiffies_relative(HZ / 2));
 	}
 }
 
@@ -451,7 +451,7 @@ static void __ieee80211_roc_work(struct ieee80211_local *local)
 	}
 }
 
-static void ieee80211_roc_work(struct work_struct *work)
+static void ieee80211_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, roc_work.work);
@@ -461,7 +461,7 @@ static void ieee80211_roc_work(struct work_struct *work)
 	mutex_unlock(&local->mtx);
 }
 
-static void ieee80211_hw_roc_done(struct work_struct *work)
+static void ieee80211_hw_roc_done(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, hw_roc_done);
@@ -482,7 +482,7 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw)
 
 	trace_api_remain_on_channel_expired(local);
 
-	ieee80211_queue_work(hw, &local->hw_roc_done);
+	wiphy_work_queue(hw->wiphy, &local->hw_roc_done);
 }
 EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired);
 
@@ -586,8 +586,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
 		/* if not HW assist, just queue & schedule work */
 		if (!local->ops->remain_on_channel) {
 			list_add_tail(&roc->list, &local->roc_list);
-			ieee80211_queue_delayed_work(&local->hw,
-						     &local->roc_work, 0);
+			wiphy_delayed_work_queue(local->hw.wiphy,
+						 &local->roc_work, 0);
 		} else {
 			/* otherwise actually kick it off here
 			 * (for error handling)
@@ -695,7 +695,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
 	if (!cookie)
 		return -ENOENT;
 
-	flush_work(&local->hw_roc_start);
+	wiphy_work_flush(local->hw.wiphy, &local->hw_roc_start);
 
 	mutex_lock(&local->mtx);
 	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
@@ -745,7 +745,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
 	} else {
 		/* go through work struct to return to the operating channel */
 		found->abort = true;
-		mod_delayed_work(local->workqueue, &local->roc_work, 0);
+		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, 0);
 	}
 
  out_unlock:
@@ -994,9 +994,9 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 
 void ieee80211_roc_setup(struct ieee80211_local *local)
 {
-	INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start);
-	INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done);
-	INIT_DELAYED_WORK(&local->roc_work, ieee80211_roc_work);
+	wiphy_work_init(&local->hw_roc_start, ieee80211_hw_roc_start);
+	wiphy_work_init(&local->hw_roc_done, ieee80211_hw_roc_done);
+	wiphy_delayed_work_init(&local->roc_work, ieee80211_roc_work);
 	INIT_LIST_HEAD(&local->roc_list);
 }
 
Signature · 1 line
2.42.0
author maintainer
#42 lore raw

PATCH 42/550 wifi: mac80211: move sched-scan stop work to wiphy work

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit eadfb54756aea5610d8d0a467f66305f777c85dd ]

This also has the wiphy locked here then. We need to use the _locked version of cfg80211_sched_scan_stopped() now, which also fixes an old deadlock there.

Fixes a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
---
 net/mac80211/ieee80211_i.h | 5 +++--
 net/mac80211/main.c        | 6 +++---
 net/mac80211/scan.c        | 7 ++++---
 3 files changed, 10 insertions(+), 8 deletions(-)
net/mac80211/ieee80211_i.h +3 -2
index 10ad1d8f9ba83..8032167e15332 100644
@@ -1483,7 +1483,7 @@ struct ieee80211_local {
 	int hw_scan_ies_bufsize;
 	struct cfg80211_scan_info scan_info;
 
-	struct work_struct sched_scan_stopped_work;
+	struct wiphy_work sched_scan_stopped_work;
 	struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
 	struct cfg80211_sched_scan_request __rcu *sched_scan_req;
 	u8 scan_addr[ETH_ALEN];
@@ -1963,7 +1963,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
 				       struct cfg80211_sched_scan_request *req);
 int ieee80211_request_sched_scan_stop(struct ieee80211_local *local);
 void ieee80211_sched_scan_end(struct ieee80211_local *local);
-void ieee80211_sched_scan_stopped_work(struct work_struct *work);
+void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy,
+				       struct wiphy_work *work);
 
 /* off-channel/mgmt-tx */
 void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
net/mac80211/main.c +3 -3
index f1cbb7c5d4ac3..4548f84451095 100644
@@ -822,8 +822,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 		  ieee80211_dynamic_ps_disable_work);
 	timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0);
 
-	INIT_WORK(&local->sched_scan_stopped_work,
-		  ieee80211_sched_scan_stopped_work);
+	wiphy_work_init(&local->sched_scan_stopped_work,
+			ieee80211_sched_scan_stopped_work);
 
 	spin_lock_init(&local->ack_status_lock);
 	idr_init(&local->ack_status_frames);
@@ -1481,13 +1481,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
 	wiphy_lock(local->hw.wiphy);
 	wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work);
+	wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work);
 	wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work);
 	wiphy_unlock(local->hw.wiphy);
 	rtnl_unlock();
 
 	cancel_work_sync(&local->restart_work);
 	cancel_work_sync(&local->reconfig_filter);
-	flush_work(&local->sched_scan_stopped_work);
 
 	ieee80211_clear_tx_pending(local);
 	rate_control_deinitialize(local);
net/mac80211/scan.c +4 -3
index 2117cb2a916ac..68ec2124c3db5 100644
@@ -1422,10 +1422,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local)
 
 	mutex_unlock(&local->mtx);
 
-	cfg80211_sched_scan_stopped(local->hw.wiphy, 0);
+	cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);
 }
 
-void ieee80211_sched_scan_stopped_work(struct work_struct *work)
+void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy,
+				       struct wiphy_work *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local,
@@ -1448,6 +1449,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 	if (local->in_reconfig)
 		return;
 
-	schedule_work(&local->sched_scan_stopped_work);
+	wiphy_work_queue(hw->wiphy, &local->sched_scan_stopped_work);
 }
 EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
Signature · 1 line
2.42.0
author maintainer
#43 lore raw

PATCH 43/550 wifi: mac80211: fix RCU usage warning in mesh fast-xmit

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 5ea82df1f50e42416d0a8a7c42d37cc1df1545fe ]

In mesh_fast_tx_flush_addr() we already hold the lock, so don't need additional hashtable RCU protection. Use the rhashtable_lookup_fast() variant to avoid RCU protection warnings.

Fixes d5edb9ae8d56 ("wifi: mac80211: mesh fast xmit support")
---
 net/mac80211/mesh_pathtbl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/mesh_pathtbl.c +1 -1
index d32e304eeb4ba..3e52aaa57b1fc 100644
@@ -648,7 +648,7 @@ void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata,
 
 	cache = &sdata->u.mesh.tx_cache;
 	spin_lock_bh(&cache->walk_lock);
-	entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
+	entry = rhashtable_lookup_fast(&cache->rht, addr, fast_tx_rht_params);
 	if (entry)
 		mesh_fast_tx_entry_free(cache, entry);
 	spin_unlock_bh(&cache->walk_lock);
Signature · 1 line
2.42.0
author maintainer
#44 lore raw

PATCH 44/550 wifi: cfg80211: fix off-by-one in element defrag

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 43125539fc69c6aa63d34b516939431391bddeac ]

If a fragment is the last element, it's erroneously not accepted. Fix that.

---
 net/wireless/scan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/wireless/scan.c +2 -2
index 8210a6090ac16..e4cc6209c7b9b 100644
@@ -2358,8 +2358,8 @@ ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
 
 	/* elem might be invalid after the memmove */
 	next = (void *)(elem->data + elem->datalen);
-
 	elem_datalen = elem->datalen;
+
 	if (elem->id == WLAN_EID_EXTENSION) {
 		copied = elem->datalen - 1;
 		if (copied > data_len)
@@ -2380,7 +2380,7 @@ ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
 
 	for (elem = next;
 	     elem->data < ies + ieslen &&
-		elem->data + elem->datalen < ies + ieslen;
+		elem->data + elem->datalen <= ies + ieslen;
 	     elem = next) {
 		/* elem might be invalid after the memmove */
 		next = (void *)(elem->data + elem->datalen);
Signature · 1 line
2.42.0
author maintainer
#45 lore raw

PATCH 45/550 wifi: mac80211: fix # of MSDU in A-MSDU calculation

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 428e8976a15f849ad92b1c1e38dda2a684350ff7 ]

During my refactoring I wanted to get rid of the switch, but replaced it with the wrong calculation. Fix that.

---
 net/mac80211/sta_info.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/sta_info.c +1 -1
index 7751f8ba960ee..0c5cc75857e4f 100644
@@ -2990,7 +2990,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
 				   WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB) << 1;
 
 	if (val)
-		sta->sta.max_amsdu_subframes = 4 << val;
+		sta->sta.max_amsdu_subframes = 4 << (4 - val);
 }
 
 #ifdef CONFIG_LOCKDEP
Signature · 1 line
2.42.0
author maintainer
#46 lore raw

PATCH 46/550 wifi: iwlwifi: honor the enable_ini value

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Emmanuel Grumbach <[email protected]>

[ Upstream commit e0c1ca236e28e4263fba76d47a108ed95dcae33e ]

In case the user sets the enable_ini to some preset, we want to honor the value.

Remove the ops to set the value of the module parameter is runtime, we don't want to allow to modify the value in runtime since we configure the firmware once at the beginning on its life.

---
 .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h   |  1 +
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |  5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  | 51 +++++++------------
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |  4 ++
 4 files changed, 25 insertions(+), 36 deletions(-)
drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +1 -0
index ba538d70985f4..39bee9c00e071 100644
@@ -13,6 +13,7 @@
 #define IWL_FW_INI_DOMAIN_ALWAYS_ON		0
 #define IWL_FW_INI_REGION_ID_MASK		GENMASK(15, 0)
 #define IWL_FW_INI_REGION_DUMP_POLICY_MASK	GENMASK(31, 16)
+#define IWL_FW_INI_PRESET_DISABLE		0xff
 
 /**
  * struct iwl_fw_ini_hcmd
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +3 -2
index 128059ca77e60..06fb7d6653905 100644
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
  */
 #ifndef __iwl_dbg_tlv_h__
 #define __iwl_dbg_tlv_h__
@@ -10,7 +10,8 @@
 #include <fw/file.h>
 #include <fw/api/dbg-tlv.h>
 
-#define IWL_DBG_TLV_MAX_PRESET 15
+#define IWL_DBG_TLV_MAX_PRESET	15
+#define ENABLE_INI		(IWL_DBG_TLV_MAX_PRESET + 1)
 
 /**
  * struct iwl_dbg_tlv_node - debug TLV node
drivers/net/wireless/intel/iwlwifi/iwl-drv.c +17 -34

69 lines not on this page · raw message

drivers/net/wireless/intel/iwlwifi/iwl-trans.h +4 -0
index d02943d0ea625..b248944e11df9 100644
@@ -56,6 +56,10 @@
  *	6) Eventually, the free function will be called.
  */
 
+/* default preset 0 (start from bit 16)*/
+#define IWL_FW_DBG_DOMAIN_POS	16
+#define IWL_FW_DBG_DOMAIN	BIT(IWL_FW_DBG_DOMAIN_POS)
+
 #define IWL_TRANS_FW_DBG_DOMAIN(trans)	IWL_FW_INI_DOMAIN_ALWAYS_ON
 
 #define FH_RSCSR_FRAME_SIZE_MSK		0x00003FFF	/* bits 0-13 */
Signature · 1 line
2.42.0
author maintainer
#47 lore raw

PATCH 47/550 wifi: iwlwifi: dont use an uninitialized variable

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miri Korenblit <[email protected]>

[ Upstream commit c46fcc6e43d617252945e706f04e5f82a59f2b8e ]

Don't use variable err uninitialized.
The reason for removing the check instead of initializing it in the beginning of the function is because that way static checkers will be able to catch issues if we do something wrong in the future.

---
 drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 3 ---
 1 file changed, 3 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +0 -3
index b719843e94576..778a311b500bc 100644
@@ -1089,9 +1089,6 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
 		}
 	}
 
-	if (err)
-		goto out_err;
-
 	err = 0;
 	if (new_links == 0) {
 		mvmvif->link[0] = &mvmvif->deflink;
Signature · 1 line
2.42.0
author maintainer
#48 lore raw

PATCH 48/550 i40e: fix potential memory leaks in i40e_remove()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andrii Staikov <[email protected]>

[ Upstream commit 5ca636d927a106780451d957734f02589b972e2b ]

Instead of freeing memory of a single VSI, make sure the memory for all VSIs is cleared before releasing VSIs. Add releasing of their resources in a loop with the iteration number equal to the number of allocated VSIs.

---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +7 -3
index a86bfa3bba74a..fc9ebef70bd9d 100644
@@ -16324,11 +16324,15 @@ static void i40e_remove(struct pci_dev *pdev)
 			i40e_switch_branch_release(pf->veb[i]);
 	}
 
-	/* Now we can shutdown the PF's VSI, just before we kill
+	/* Now we can shutdown the PF's VSIs, just before we kill
 	 * adminq and hmc.
 	 */
-	if (pf->vsi[pf->lan_vsi])
-		i40e_vsi_release(pf->vsi[pf->lan_vsi]);
+	for (i = pf->num_alloc_vsi; i--;)
+		if (pf->vsi[i]) {
+			i40e_vsi_close(pf->vsi[i]);
+			i40e_vsi_release(pf->vsi[i]);
+			pf->vsi[i] = NULL;
+		}
 
 	i40e_cloud_filter_exit(pf);
 
Signature · 1 line
2.42.0
author maintainer
#49 lore raw

PATCH 49/550 iavf: Fix promiscuous mode configuration flow messages

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brett Creeley <[email protected]>

[ Upstream commit 221465de6bd8090ab61267f019866e8d2dd4ea3d ]

Currently when configuring promiscuous mode on the AVF we detect a change in the netdev->flags. We use IFF_PROMISC and IFF_ALLMULTI to determine whether or not we need to request/release promiscuous mode and/or multicast promiscuous mode. The problem is that the AQ calls for setting/clearing promiscuous/multicast mode are treated separately. This leads to a case where we can trigger two promiscuous mode AQ calls in a row with the incorrect state. To fix this make a few changes.

Use IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE instead of the previous IAVF_FLAG_AQ_[REQUEST|RELEASE]_[PROMISC|ALLMULTI] flags.

In iavf_set_rx_mode() detect if there is a change in the netdev->flags in comparison with adapter->flags and set the IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE aq_required bit. Then in iavf_process_aq_command() only check for IAVF_FLAG_CONFIGURE_PROMISC_MODE and call iavf_set_promiscuous() if it's set.

In iavf_set_promiscuous() check again to see which (if any) promiscuous mode bits have changed when comparing the netdev->flags with the adapter->flags. Use this to set the flags which get sent to the PF driver.

Add a spinlock that is used for updating current_netdev_promisc_flags and only allows one promiscuous mode AQ at a time.

[1] Fixes the fact that we will only have one AQ call in the aq_required queue at any one time.

[2] Streamlines the change in promiscuous mode to only set one AQ required bit.

[3] This allows us to keep track of the current state of the flags and also makes it so we can take the most recent netdev->flags promiscuous mode state.

[4] This fixes the problem where a change in the netdev->flags can cause IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE to be set in iavf_set_rx_mode(), but cleared in iavf_set_promiscuous() before the change is ever made via AQ call.

Fixes 47d3483988f6 ("i40evf: Add driver support for promiscuous mode")
---
 drivers/net/ethernet/intel/iavf/iavf.h        | 16 ++--
 drivers/net/ethernet/intel/iavf/iavf_main.c   | 43 +++++------
 .../net/ethernet/intel/iavf/iavf_virtchnl.c   | 75 ++++++++++++-------
 3 files changed, 74 insertions(+), 60 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +9 -7
index 4d4508e04b1d2..7f6f1677199b9 100644
@@ -298,8 +298,6 @@ struct iavf_adapter {
 #define IAVF_FLAG_CLIENT_NEEDS_OPEN		BIT(10)
 #define IAVF_FLAG_CLIENT_NEEDS_CLOSE		BIT(11)
 #define IAVF_FLAG_CLIENT_NEEDS_L2_PARAMS	BIT(12)
-#define IAVF_FLAG_PROMISC_ON			BIT(13)
-#define IAVF_FLAG_ALLMULTI_ON			BIT(14)
 #define IAVF_FLAG_LEGACY_RX			BIT(15)
 #define IAVF_FLAG_REINIT_ITR_NEEDED		BIT(16)
 #define IAVF_FLAG_QUEUES_DISABLED		BIT(17)
@@ -325,10 +323,7 @@ struct iavf_adapter {
 #define IAVF_FLAG_AQ_SET_HENA			BIT_ULL(12)
 #define IAVF_FLAG_AQ_SET_RSS_KEY		BIT_ULL(13)
 #define IAVF_FLAG_AQ_SET_RSS_LUT		BIT_ULL(14)
-#define IAVF_FLAG_AQ_REQUEST_PROMISC		BIT_ULL(15)
-#define IAVF_FLAG_AQ_RELEASE_PROMISC		BIT_ULL(16)
-#define IAVF_FLAG_AQ_REQUEST_ALLMULTI		BIT_ULL(17)
-#define IAVF_FLAG_AQ_RELEASE_ALLMULTI		BIT_ULL(18)
+#define IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE	BIT_ULL(15)
 #define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING	BIT_ULL(19)
 #define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING	BIT_ULL(20)
 #define IAVF_FLAG_AQ_ENABLE_CHANNELS		BIT_ULL(21)
@@ -365,6 +360,12 @@ struct iavf_adapter {
 	(IAVF_EXTENDED_CAP_SEND_VLAN_V2 |		\
 	 IAVF_EXTENDED_CAP_RECV_VLAN_V2)
 
+	/* Lock to prevent possible clobbering of
+	 * current_netdev_promisc_flags
+	 */
+	spinlock_t current_netdev_promisc_flags_lock;
+	netdev_features_t current_netdev_promisc_flags;
+
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
@@ -551,7 +552,8 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter);
 void iavf_del_ether_addrs(struct iavf_adapter *adapter);
 void iavf_add_vlans(struct iavf_adapter *adapter);
 void iavf_del_vlans(struct iavf_adapter *adapter);
-void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags);
+void iavf_set_promiscuous(struct iavf_adapter *adapter);
+bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter);
 void iavf_request_stats(struct iavf_adapter *adapter);
 int iavf_request_reset(struct iavf_adapter *adapter);
 void iavf_get_hena(struct iavf_adapter *adapter);
drivers/net/ethernet/intel/iavf/iavf_main.c +17 -26

67 lines not on this page · raw message

drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +48 -27

98 lines not on this page · raw message

Signature · 1 line
2.42.0
author maintainer
#50 lore raw

PATCH 50/550 selftests/bpf: Correct map_fd to data_fd in tailcalls

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Leon Hwang <[email protected]>

[ Upstream commit 96daa9874211d5497aa70fa409b67afc29f0cb86 ]

Get and check data_fd. It should not check map_fd again.

Meanwhile, correct some 'return' to 'goto out'.

Thank the suggestion from Maciej in "bpf, x64: Fix tailcall infinite loop"[0] discussions.

[0] https://lore.kernel.org/bpf/[email protected]/T/#m7d3b601066ba66400d436b7e7579b2df4a101033

Fixes 79d49ba048ec ("bpf, testing: Add various tail call test cases")
Fixes 3b0379111197 ("selftests/bpf: Add tailcall_bpf2bpf tests")
Fixes 5e0b0a4c52d3 ("selftests/bpf: Test tail call counting with bpf2bpf and data on stack")
---
 .../selftests/bpf/prog_tests/tailcalls.c      | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)
tools/testing/selftests/bpf/prog_tests/tailcalls.c +16 -16
index 58fe2c586ed76..09c189761926c 100644
@@ -271,11 +271,11 @@ static void test_tailcall_count(const char *which)
 
 	data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
 	if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
-		return;
+		goto out;
 
 	data_fd = bpf_map__fd(data_map);
-	if (CHECK_FAIL(map_fd < 0))
-		return;
+	if (CHECK_FAIL(data_fd < 0))
+		goto out;
 
 	i = 0;
 	err = bpf_map_lookup_elem(data_fd, &i, &val);
@@ -352,11 +352,11 @@ static void test_tailcall_4(void)
 
 	data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
 	if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
-		return;
+		goto out;
 
 	data_fd = bpf_map__fd(data_map);
-	if (CHECK_FAIL(map_fd < 0))
-		return;
+	if (CHECK_FAIL(data_fd < 0))
+		goto out;
 
 	for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
 		snprintf(prog_name, sizeof(prog_name), "classifier_%d", i);
@@ -442,11 +442,11 @@ static void test_tailcall_5(void)
 
 	data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
 	if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
-		return;
+		goto out;
 
 	data_fd = bpf_map__fd(data_map);
-	if (CHECK_FAIL(map_fd < 0))
-		return;
+	if (CHECK_FAIL(data_fd < 0))
+		goto out;
 
 	for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
 		snprintf(prog_name, sizeof(prog_name), "classifier_%d", i);
@@ -631,11 +631,11 @@ static void test_tailcall_bpf2bpf_2(void)
 
 	data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
 	if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
-		return;
+		goto out;
 
 	data_fd = bpf_map__fd(data_map);
-	if (CHECK_FAIL(map_fd < 0))
-		return;
+	if (CHECK_FAIL(data_fd < 0))
+		goto out;
 
 	i = 0;
 	err = bpf_map_lookup_elem(data_fd, &i, &val);
@@ -805,11 +805,11 @@ static void test_tailcall_bpf2bpf_4(bool noise)
 
 	data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
 	if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
-		return;
+		goto out;
 
 	data_fd = bpf_map__fd(data_map);
-	if (CHECK_FAIL(map_fd < 0))
-		return;
+	if (CHECK_FAIL(data_fd < 0))
+		goto out;
 
 	i = 0;
 	val.noise = noise;
@@ -872,7 +872,7 @@ static void test_tailcall_bpf2bpf_6(void)
 	ASSERT_EQ(topts.retval, 0, "tailcall retval");
 
 	data_fd = bpf_map__fd(obj->maps.bss);
-	if (!ASSERT_GE(map_fd, 0, "bss map fd"))
+	if (!ASSERT_GE(data_fd, 0, "bss map fd"))
 		goto out;
 
 	i = 0;
Signature · 1 line
2.42.0
author maintainer
#51 lore raw

PATCH 51/550 bpf, x86: save/restore regs with BPF_DW size

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Menglong Dong <[email protected]>

[ Upstream commit 02a6dfa8ff43efb1c989f87a4d862aedf436088a ]

As we already reserve 8 byte in the stack for each reg, it is ok to store/restore the regs in BPF_DW size. This will make the code in save_regs()/restore_regs() simpler.

Stable-dep-of: 2b5dcb31a19a ("bpf, x64: Fix tailcall infinite loop")

---
 arch/x86/net/bpf_jit_comp.c | 35 ++++++-----------------------------
 1 file changed, 6 insertions(+), 29 deletions(-)
arch/x86/net/bpf_jit_comp.c +6 -29
index 438adb695daab..fcbd3b7123a47 100644
@@ -1860,57 +1860,34 @@ st:			if (is_imm8(insn->off))
 static void save_regs(const struct btf_func_model *m, u8 **prog, int nr_regs,
 		      int stack_size)
 {
-	int i, j, arg_size;
-	bool next_same_struct = false;
+	int i;
 
 	/* Store function arguments to stack.
 	 * For a function that accepts two pointers the sequence will be:
 	 * mov QWORD PTR [rbp-0x10],rdi
 	 * mov QWORD PTR [rbp-0x8],rsi
 	 */
-	for (i = 0, j = 0; i < min(nr_regs, 6); i++) {
-		/* The arg_size is at most 16 bytes, enforced by the verifier. */
-		arg_size = m->arg_size[j];
-		if (arg_size > 8) {
-			arg_size = 8;
-			next_same_struct = !next_same_struct;
-		}
-
-		emit_stx(prog, bytes_to_bpf_size(arg_size),
-			 BPF_REG_FP,
+	for (i = 0; i < min(nr_regs, 6); i++)
+		emit_stx(prog, BPF_DW, BPF_REG_FP,
 			 i == 5 ? X86_REG_R9 : BPF_REG_1 + i,
 			 -(stack_size - i * 8));
-
-		j = next_same_struct ? j : j + 1;
-	}
 }
 
 static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_regs,
 			 int stack_size)
 {
-	int i, j, arg_size;
-	bool next_same_struct = false;
+	int i;
 
 	/* Restore function arguments from stack.
 	 * For a function that accepts two pointers the sequence will be:
 	 * EMIT4(0x48, 0x8B, 0x7D, 0xF0); mov rdi,QWORD PTR [rbp-0x10]
 	 * EMIT4(0x48, 0x8B, 0x75, 0xF8); mov rsi,QWORD PTR [rbp-0x8]
 	 */
-	for (i = 0, j = 0; i < min(nr_regs, 6); i++) {
-		/* The arg_size is at most 16 bytes, enforced by the verifier. */
-		arg_size = m->arg_size[j];
-		if (arg_size > 8) {
-			arg_size = 8;
-			next_same_struct = !next_same_struct;
-		}
-
-		emit_ldx(prog, bytes_to_bpf_size(arg_size),
+	for (i = 0; i < min(nr_regs, 6); i++)
+		emit_ldx(prog, BPF_DW,
 			 i == 5 ? X86_REG_R9 : BPF_REG_1 + i,
 			 BPF_REG_FP,
 			 -(stack_size - i * 8));
-
-		j = next_same_struct ? j : j + 1;
-	}
 }
 
 static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
Signature · 1 line
2.42.0
author maintainer
#52 lore raw

PATCH 52/550 bpf, x86: allow function arguments up to 12 for TRACING

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Menglong Dong <[email protected]>

[ Upstream commit 473e3150e30a2db4199e6bad68c0be11279d1c34 ]

For now, the BPF program of type BPF_PROG_TYPE_TRACING can only be used on the kernel functions whose arguments count less than or equal to 6, if not considering '> 8 bytes' struct argument. This is not friendly at all, as too many functions have arguments count more than 6.

According to the current kernel version, below is a statistics of the function arguments count:

argument count | function count
7              | 704
8              | 270
9              | 84
10             | 47
11             | 47
12             | 27
13             | 22
14             | 5
15             | 0
16             | 1

Therefore, let's enhance it by increasing the function arguments count allowed in arch_prepare_bpf_trampoline(), for now, only x86_64.

For the case that we don't need to call origin function, which means without BPF_TRAMP_F_CALL_ORIG, we need only copy the function arguments that stored in the frame of the caller to current frame. The 7th and later arguments are stored in "$rbp + 0x18", and they will be copied to the stack area following where register values are saved.

For the case with BPF_TRAMP_F_CALL_ORIG, we need prepare the arguments in stack before call origin function, which means we need alloc extra "8 * (arg_count - 6)" memory in the top of the stack. Note, there should not be any data be pushed to the stack before calling the origin function. So 'rbx' value will be stored on a stack position higher than where stack arguments are stored for BPF_TRAMP_F_CALL_ORIG.

According to the research of Yonghong, struct members should be all in register or all on the stack. Meanwhile, the compiler will pass the argument on regs if the remaining regs can hold the argument. Therefore, we need save the arguments in order. Otherwise, disorder of the args can happen. For example:

  struct foo_struct {
      long a;
      int b;
  };
  int foo(char, char, char, char, char, struct foo_struct,
          char);

the arg1-5,arg7 will be passed by regs, and arg6 will by stack. Therefore, we should save/restore the arguments in the same order with the declaration of foo(). And the args used as ctx in stack will be like this:

reg_arg6 -- copy from regs
stack_arg2 -- copy from stack
stack_arg1
reg_arg5 -- copy from regs
reg_arg4
reg_arg3
reg_arg2
reg_arg1

We use EMIT3_off32() or EMIT4() for "lea" and "sub". The range of the imm in "lea" and "sub" is [-128, 127] if EMIT4() is used. Therefore, we use EMIT3_off32() instead if the imm out of the range.

It works well for the FENTRY/FEXIT/MODIFY_RETURN.

Stable-dep-of: 2b5dcb31a19a ("bpf, x64: Fix tailcall infinite loop")

---
 arch/x86/net/bpf_jit_comp.c | 235 ++++++++++++++++++++++++++++++++----
 1 file changed, 209 insertions(+), 26 deletions(-)
arch/x86/net/bpf_jit_comp.c +209 -26
index fcbd3b7123a47..5ab531be56acf 100644
@@ -1857,37 +1857,178 @@ st:			if (is_imm8(insn->off))
 	return proglen;
 }
 
-static void save_regs(const struct btf_func_model *m, u8 **prog, int nr_regs,
-		      int stack_size)
+static void clean_stack_garbage(const struct btf_func_model *m,
+				u8 **pprog, int nr_stack_slots,
+				int stack_size)
 {
-	int i;
+	int arg_size, off;
+	u8 *prog;
+
+	/* Generally speaking, the compiler will pass the arguments
+	 * on-stack with "push" instruction, which will take 8-byte
+	 * on the stack. In this case, there won't be garbage values
+	 * while we copy the arguments from origin stack frame to current
+	 * in BPF_DW.
+	 *
+	 * However, sometimes the compiler will only allocate 4-byte on
+	 * the stack for the arguments. For now, this case will only
+	 * happen if there is only one argument on-stack and its size
+	 * not more than 4 byte. In this case, there will be garbage
+	 * values on the upper 4-byte where we store the argument on
+	 * current stack frame.
+	 *
+	 * arguments on origin stack:
+	 *
+	 * stack_arg_1(4-byte) xxx(4-byte)
+	 *
+	 * what we copy:
+	 *
+	 * stack_arg_1(8-byte): stack_arg_1(origin) xxx
+	 *
+	 * and the xxx is the garbage values which we should clean here.
+	 */
+	if (nr_stack_slots != 1)
+		return;
+
+	/* the size of the last argument */
+	arg_size = m->arg_size[m->nr_args - 1];
+	if (arg_size <= 4) {
+		off = -(stack_size - 4);
+		prog = *pprog;
+		/* mov DWORD PTR [rbp + off], 0 */
+		if (!is_imm8(off))
+			EMIT2_off32(0xC7, 0x85, off);
+		else
+			EMIT3(0xC7, 0x45, off);
+		EMIT(0, 4);
+		*pprog = prog;
+	}
+}
+
+/* get the count of the regs that are used to pass arguments */
+static int get_nr_used_regs(const struct btf_func_model *m)
+{
+	int i, arg_regs, nr_used_regs = 0;
+
+	for (i = 0; i < min_t(int, m->nr_args, MAX_BPF_FUNC_ARGS); i++) {
+		arg_regs = (m->arg_size[i] + 7) / 8;
+		if (nr_used_regs + arg_regs <= 6)
+			nr_used_regs += arg_regs;
+
+		if (nr_used_regs >= 6)
+			break;
+	}
+
+	return nr_used_regs;
+}
+
+static void save_args(const struct btf_func_model *m, u8 **prog,
+		      int stack_size, bool for_call_origin)
+{
+	int arg_regs, first_off, nr_regs = 0, nr_stack_slots = 0;
+	int i, j;
 
 	/* Store function arguments to stack.
 	 * For a function that accepts two pointers the sequence will be:
 	 * mov QWORD PTR [rbp-0x10],rdi
 	 * mov QWORD PTR [rbp-0x8],rsi
 	 */
-	for (i = 0; i < min(nr_regs, 6); i++)
-		emit_stx(prog, BPF_DW, BPF_REG_FP,
-			 i == 5 ? X86_REG_R9 : BPF_REG_1 + i,
-			 -(stack_size - i * 8));
+	for (i = 0; i < min_t(int, m->nr_args, MAX_BPF_FUNC_ARGS); i++) {
+		arg_regs = (m->arg_size[i] + 7) / 8;
+
+		/* According to the research of Yonghong, struct members
+		 * should be all in register or all on the stack.
+		 * Meanwhile, the compiler will pass the argument on regs
+		 * if the remaining regs can hold the argument.
+		 *
+		 * Disorder of the args can happen. For example:
+		 *
+		 * struct foo_struct {
+		 *     long a;
+		 *     int b;
+		 * };
+		 * int foo(char, char, char, char, char, struct foo_struct,
+		 *         char);
+		 *
+		 * the arg1-5,arg7 will be passed by regs, and arg6 will
+		 * by stack.
+		 */
+		if (nr_regs + arg_regs > 6) {
+			/* copy function arguments from origin stack frame
+			 * into current stack frame.
+			 *
+			 * The starting address of the arguments on-stack
+			 * is:
+			 *   rbp + 8(push rbp) +
+			 *   8(return addr of origin call) +
+			 *   8(return addr of the caller)
+			 * which means: rbp + 24
+			 */
+			for (j = 0; j < arg_regs; j++) {
+				emit_ldx(prog, BPF_DW, BPF_REG_0, BPF_REG_FP,
+					 nr_stack_slots * 8 + 0x18);
+				emit_stx(prog, BPF_DW, BPF_REG_FP, BPF_REG_0,
+					 -stack_size);
+
+				if (!nr_stack_slots)
+					first_off = stack_size;
+				stack_size -= 8;
+				nr_stack_slots++;
+			}
+		} else {
+			/* Only copy the arguments on-stack to current
+			 * 'stack_size' and ignore the regs, used to
+			 * prepare the arguments on-stack for orign call.
+			 */
+			if (for_call_origin) {
+				nr_regs += arg_regs;
+				continue;
+			}
+
+			/* copy the arguments from regs into stack */
+			for (j = 0; j < arg_regs; j++) {
+				emit_stx(prog, BPF_DW, BPF_REG_FP,
+					 nr_regs == 5 ? X86_REG_R9 : BPF_REG_1 + nr_regs,
+					 -stack_size);
+				stack_size -= 8;
+				nr_regs++;
+			}
+		}
+	}
+
+	clean_stack_garbage(m, prog, nr_stack_slots, first_off);
 }
 
-static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_regs,
+static void restore_regs(const struct btf_func_model *m, u8 **prog,
 			 int stack_size)
 {
-	int i;
+	int i, j, arg_regs, nr_regs = 0;
 
 	/* Restore function arguments from stack.
 	 * For a function that accepts two pointers the sequence will be:
 	 * EMIT4(0x48, 0x8B, 0x7D, 0xF0); mov rdi,QWORD PTR [rbp-0x10]
 	 * EMIT4(0x48, 0x8B, 0x75, 0xF8); mov rsi,QWORD PTR [rbp-0x8]
+	 *
+	 * The logic here is similar to what we do in save_args()
 	 */
-	for (i = 0; i < min(nr_regs, 6); i++)
-		emit_ldx(prog, BPF_DW,
-			 i == 5 ? X86_REG_R9 : BPF_REG_1 + i,
-			 BPF_REG_FP,
-			 -(stack_size - i * 8));
+	for (i = 0; i < min_t(int, m->nr_args, MAX_BPF_FUNC_ARGS); i++) {
+		arg_regs = (m->arg_size[i] + 7) / 8;
+		if (nr_regs + arg_regs <= 6) {
+			for (j = 0; j < arg_regs; j++) {
+				emit_ldx(prog, BPF_DW,
+					 nr_regs == 5 ? X86_REG_R9 : BPF_REG_1 + nr_regs,
+					 BPF_REG_FP,
+					 -stack_size);
+				stack_size -= 8;
+				nr_regs++;
+			}
+		} else {
+			stack_size -= 8 * arg_regs;
+		}
+
+		if (nr_regs >= 6)
+			break;
+	}
 }
 
 static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
@@ -1915,7 +2056,10 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
 	/* arg1: mov rdi, progs[i] */
 	emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
 	/* arg2: lea rsi, [rbp - ctx_cookie_off] */
-	EMIT4(0x48, 0x8D, 0x75, -run_ctx_off);
+	if (!is_imm8(-run_ctx_off))
+		EMIT3_off32(0x48, 0x8D, 0xB5, -run_ctx_off);
+	else
+		EMIT4(0x48, 0x8D, 0x75, -run_ctx_off);
 
 	if (emit_rsb_call(&prog, bpf_trampoline_enter(p), prog))
 		return -EINVAL;
@@ -1931,7 +2075,10 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
 	emit_nops(&prog, 2);
 
 	/* arg1: lea rdi, [rbp - stack_size] */
-	EMIT4(0x48, 0x8D, 0x7D, -stack_size);
+	if (!is_imm8(-stack_size))
+		EMIT3_off32(0x48, 0x8D, 0xBD, -stack_size);
+	else
+		EMIT4(0x48, 0x8D, 0x7D, -stack_size);
 	/* arg2: progs[i]->insnsi for interpreter */
 	if (!p->jited)
 		emit_mov_imm64(&prog, BPF_REG_2,
@@ -1961,7 +2108,10 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
 	/* arg2: mov rsi, rbx <- start time in nsec */
 	emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6);
 	/* arg3: lea rdx, [rbp - run_ctx_off] */
-	EMIT4(0x48, 0x8D, 0x55, -run_ctx_off);
+	if (!is_imm8(-run_ctx_off))
+		EMIT3_off32(0x48, 0x8D, 0x95, -run_ctx_off);
+	else
+		EMIT4(0x48, 0x8D, 0x55, -run_ctx_off);
 	if (emit_rsb_call(&prog, bpf_trampoline_exit(p), prog))
 		return -EINVAL;
 
@@ -2113,7 +2263,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 				void *func_addr)
 {
 	int i, ret, nr_regs = m->nr_args, stack_size = 0;
-	int regs_off, nregs_off, ip_off, run_ctx_off;
+	int regs_off, nregs_off, ip_off, run_ctx_off, arg_stack_off, rbx_off;
 	struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
 	struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
 	struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
@@ -2127,8 +2277,10 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 		if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
 			nr_regs += (m->arg_size[i] + 7) / 8 - 1;
 
-	/* x86-64 supports up to 6 arguments. 7+ can be added in the future */
-	if (nr_regs > 6)
+	/* x86-64 supports up to MAX_BPF_FUNC_ARGS arguments. 1-6
+	 * are passed through regs, the remains are through stack.
+	 */
+	if (nr_regs > MAX_BPF_FUNC_ARGS)
 		return -ENOTSUPP;
 
 	/* Generated trampoline stack layout:
@@ -2147,7 +2299,14 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	 *
 	 * RBP - ip_off    [ traced function ]  BPF_TRAMP_F_IP_ARG flag
 	 *
+	 * RBP - rbx_off   [ rbx value       ]  always
+	 *
 	 * RBP - run_ctx_off [ bpf_tramp_run_ctx ]
+	 *
+	 *                     [ stack_argN ]  BPF_TRAMP_F_CALL_ORIG
+	 *                     [ ...        ]
+	 *                     [ stack_arg2 ]
+	 * RBP - arg_stack_off [ stack_arg1 ]
 	 */
 
 	/* room for return value of orig_call or fentry prog */
@@ -2167,9 +2326,26 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 
 	ip_off = stack_size;
 
+	stack_size += 8;
+	rbx_off = stack_size;
+
 	stack_size += (sizeof(struct bpf_tramp_run_ctx) + 7) & ~0x7;
 	run_ctx_off = stack_size;
 
+	if (nr_regs > 6 && (flags & BPF_TRAMP_F_CALL_ORIG)) {
+		/* the space that used to pass arguments on-stack */
+		stack_size += (nr_regs - get_nr_used_regs(m)) * 8;
+		/* make sure the stack pointer is 16-byte aligned if we
+		 * need pass arguments on stack, which means
+		 *  [stack_size + 8(rbp) + 8(rip) + 8(origin rip)]
+		 * should be 16-byte aligned. Following code depend on
+		 * that stack_size is already 8-byte aligned.
+		 */
+		stack_size += (stack_size % 16) ? 0 : 8;
+	}
+
+	arg_stack_off = stack_size;
+
 	if (flags & BPF_TRAMP_F_SKIP_FRAME) {
 		/* skip patched call instruction and point orig_call to actual
 		 * body of the kernel function.
@@ -2189,8 +2365,14 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	x86_call_depth_emit_accounting(&prog, NULL);
 	EMIT1(0x55);		 /* push rbp */
 	EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
-	EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */
-	EMIT1(0x53);		 /* push rbx */
+	if (!is_imm8(stack_size))
+		/* sub rsp, stack_size */
+		EMIT3_off32(0x48, 0x81, 0xEC, stack_size);
+	else
+		/* sub rsp, stack_size */
+		EMIT4(0x48, 0x83, 0xEC, stack_size);
+	/* mov QWORD PTR [rbp - rbx_off], rbx */
+	emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_6, -rbx_off);
 
 	/* Store number of argument registers of the traced function:
 	 *   mov rax, nr_regs
@@ -2208,7 +2390,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 		emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off);
 	}
 
-	save_regs(m, &prog, nr_regs, regs_off);
+	save_args(m, &prog, regs_off, false);
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
 		/* arg1: mov rdi, im */
@@ -2238,7 +2420,8 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	}
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
-		restore_regs(m, &prog, nr_regs, regs_off);
+		restore_regs(m, &prog, regs_off);
+		save_args(m, &prog, arg_stack_off, true);
 
 		if (flags & BPF_TRAMP_F_ORIG_STACK) {
 			emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8);
@@ -2279,7 +2462,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 		}
 
 	if (flags & BPF_TRAMP_F_RESTORE_REGS)
-		restore_regs(m, &prog, nr_regs, regs_off);
+		restore_regs(m, &prog, regs_off);
 
 	/* This needs to be done regardless. If there were fmod_ret programs,
 	 * the return value is only updated on the stack and still needs to be
@@ -2298,7 +2481,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	if (save_ret)
 		emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8);
 
-	EMIT1(0x5B); /* pop rbx */
+	emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, -rbx_off);
 	EMIT1(0xC9); /* leave */
 	if (flags & BPF_TRAMP_F_SKIP_FRAME)
 		/* skip our return address and return to parent */
Signature · 1 line
2.42.0
author maintainer
#53 lore raw

PATCH 53/550 bpf, x64: Fix tailcall infinite loop

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Leon Hwang <[email protected]>

[ Upstream commit 2b5dcb31a19a2e0acd869b12c9db9b2d696ef544 ]

Quoted 1 line

From commit ebf7d1f508a73871 ("bpf, x64: rework pro/epilogue and tailcall

handling in JIT"), the tailcall on x64 works better than before.

Quoted 1 line

From commit e411901c0b775a3a ("bpf: allow for tailcalls in BPF subprograms

for x64 JIT"), tailcall is able to run in BPF subprograms on x64.

Quoted 1 line

From commit 5b92a28aae4dd0f8 ("bpf: Support attaching tracing BPF program

to other BPF programs"), BPF program is able to trace other BPF programs.

How about combining them all together?

1. FENTRY/FEXIT on a BPF subprogram.
2. A tailcall runs in the BPF subprogram.
3. The tailcall calls the subprogram's caller.

As a result, a tailcall infinite loop comes up. And the loop would halt the machine.

As we know, in tail call context, the tail_call_cnt propagates by stack and rax register between BPF subprograms. So do in trampolines.

Fixes ebf7d1f508a7 ("bpf, x64: rework pro/epilogue and tailcall handling in JIT")
Fixes e411901c0b77 ("bpf: allow for tailcalls in BPF subprograms for x64 JIT")
---
 arch/x86/net/bpf_jit_comp.c | 28 ++++++++++++++++++++++------
 include/linux/bpf.h         |  5 +++++
 kernel/bpf/trampoline.c     |  4 ++--
 kernel/bpf/verifier.c       |  3 +++
 4 files changed, 32 insertions(+), 8 deletions(-)
arch/x86/net/bpf_jit_comp.c +22 -6
index 5ab531be56acf..7ee72917f13cb 100644
@@ -963,6 +963,10 @@ static void emit_shiftx(u8 **pprog, u32 dst_reg, u8 src_reg, bool is64, u8 op)
 
 #define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
 
+/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */
+#define RESTORE_TAIL_CALL_CNT(stack)				\
+	EMIT3_off32(0x48, 0x8B, 0x85, -round_up(stack, 8) - 8)
+
 static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image,
 		  int oldproglen, struct jit_context *ctx, bool jmp_padding)
 {
@@ -1538,9 +1542,7 @@ st:			if (is_imm8(insn->off))
 
 			func = (u8 *) __bpf_call_base + imm32;
 			if (tail_call_reachable) {
-				/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */
-				EMIT3_off32(0x48, 0x8B, 0x85,
-					    -round_up(bpf_prog->aux->stack_depth, 8) - 8);
+				RESTORE_TAIL_CALL_CNT(bpf_prog->aux->stack_depth);
 				if (!imm32)
 					return -EINVAL;
 				offs = 7 + x86_call_depth_emit_accounting(&prog, func);
@@ -2307,6 +2309,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	 *                     [ ...        ]
 	 *                     [ stack_arg2 ]
 	 * RBP - arg_stack_off [ stack_arg1 ]
+	 * RSP                 [ tail_call_cnt ] BPF_TRAMP_F_TAIL_CALL_CTX
 	 */
 
 	/* room for return value of orig_call or fentry prog */
@@ -2371,6 +2374,8 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 	else
 		/* sub rsp, stack_size */
 		EMIT4(0x48, 0x83, 0xEC, stack_size);
+	if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
+		EMIT1(0x50);		/* push rax */
 	/* mov QWORD PTR [rbp - rbx_off], rbx */
 	emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_6, -rbx_off);
 
@@ -2423,9 +2428,15 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 		restore_regs(m, &prog, regs_off);
 		save_args(m, &prog, arg_stack_off, true);
 
+		if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
+			/* Before calling the original function, restore the
+			 * tail_call_cnt from stack to rax.
+			 */
+			RESTORE_TAIL_CALL_CNT(stack_size);
+
 		if (flags & BPF_TRAMP_F_ORIG_STACK) {
-			emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8);
-			EMIT2(0xff, 0xd0); /* call *rax */
+			emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, 8);
+			EMIT2(0xff, 0xd3); /* call *rbx */
 		} else {
 			/* call original function */
 			if (emit_rsb_call(&prog, orig_call, prog)) {
@@ -2476,7 +2487,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
 			ret = -EINVAL;
 			goto cleanup;
 		}
-	}
+	} else if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
+		/* Before running the original function, restore the
+		 * tail_call_cnt from stack to rax.
+		 */
+		RESTORE_TAIL_CALL_CNT(stack_size);
+
 	/* restore return value of orig_call or fentry prog back into RAX */
 	if (save_ret)
 		emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8);
include/linux/bpf.h +5 -0
index 6ba9d3ed8f0b0..98a7d6fd10360 100644
@@ -1016,6 +1016,11 @@ struct btf_func_model {
  */
 #define BPF_TRAMP_F_SHARE_IPMODIFY	BIT(6)
 
+/* Indicate that current trampoline is in a tail call context. Then, it has to
+ * cache and restore tail_call_cnt to avoid infinite tail call loop.
+ */
+#define BPF_TRAMP_F_TAIL_CALL_CTX	BIT(7)
+
 /* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50
  * bytes on x86.
  */
kernel/bpf/trampoline.c +2 -2
index 53ff50cac61ea..e97aeda3a86b5 100644
@@ -415,8 +415,8 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
 		goto out;
 	}
 
-	/* clear all bits except SHARE_IPMODIFY */
-	tr->flags &= BPF_TRAMP_F_SHARE_IPMODIFY;
+	/* clear all bits except SHARE_IPMODIFY and TAIL_CALL_CTX */
+	tr->flags &= (BPF_TRAMP_F_SHARE_IPMODIFY | BPF_TRAMP_F_TAIL_CALL_CTX);
 
 	if (tlinks[BPF_TRAMP_FEXIT].nr_links ||
 	    tlinks[BPF_TRAMP_MODIFY_RETURN].nr_links) {
kernel/bpf/verifier.c +3 -0
index 104681258d24f..6c52055916287 100644
@@ -19384,6 +19384,9 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
 	if (!tr)
 		return -ENOMEM;
 
+	if (tgt_prog && tgt_prog->aux->tail_call_reachable)
+		tr->flags = BPF_TRAMP_F_TAIL_CALL_CTX;
+
 	prog->aux->dst_trampoline = tr;
 	return 0;
 }
Signature · 1 line
2.42.0
author maintainer
#54 lore raw

PATCH 54/550 wifi: cfg80211: fix kernel-doc for wiphy_delayed_work_flush()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 8c73d5248dcf112611654bcd32352dc330b02397 ]

Clearly, there's no space in the function name, not sure how that could've happened. Put the underscore that it should be.

Fixes 56cfb8ce1f7f ("wifi: cfg80211: add flush functions for wiphy work")
---
 include/net/cfg80211.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/cfg80211.h +1 -1
index 0f0bf26adb15d..d58d6d37a4479 100644
@@ -5881,7 +5881,7 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
 			       struct wiphy_delayed_work *dwork);
 
 /**
- * wiphy_delayed work_flush - flush previously queued delayed work
+ * wiphy_delayed_work_flush - flush previously queued delayed work
  * @wiphy: the wiphy, for debug purposes
  * @work: the work to flush
  *
Signature · 1 line
2.42.0
author maintainer
#55 lore raw

PATCH 55/550 wifi: iwlwifi: Use FW rate for non-data frames

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miri Korenblit <[email protected]>

[ Upstream commit 499d02790495958506a64f37ceda7e97345a50a8 ]

Currently we are setting the rate in the tx cmd for mgmt frames (e.g. during connection establishment). This was problematic when sending mgmt frames in eSR mode, as we don't know what link this frame will be sent on (This is decided by the FW), so we don't know what is the lowest rate.
Fix this by not setting the rate in tx cmd and rely
on FW to choose the right one.
Set rate only for injected frames with fixed rate,
or when no sta is given.
Also set for important frames (EAPOL etc.) the High Priority flag.

---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +9 -5
index 898dca3936435..8158e6d9ef190 100644
@@ -536,16 +536,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
 			flags |= IWL_TX_FLAGS_ENCRYPT_DIS;
 
 		/*
-		 * For data packets rate info comes from the fw. Only
-		 * set rate/antenna during connection establishment or in case
-		 * no station is given.
+		 * For data and mgmt packets rate info comes from the fw. Only
+		 * set rate/antenna for injected frames with fixed rate, or
+		 * when no sta is given.
 		 */
-		if (!sta || !ieee80211_is_data(hdr->frame_control) ||
-		    mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) {
+		if (unlikely(!sta ||
+			     info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
 			flags |= IWL_TX_FLAGS_CMD_RATE;
 			rate_n_flags =
 				iwl_mvm_get_tx_rate_n_flags(mvm, info, sta,
 							    hdr->frame_control);
+		} else if (!ieee80211_is_data(hdr->frame_control) ||
+			   mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) {
+			/* These are important frames */
+			flags |= IWL_TX_FLAGS_HIGH_PRI;
 		}
 
 		if (mvm->trans->trans_cfg->device_family >=
Signature · 1 line
2.42.0
author maintainer
#56 lore raw

PATCH 56/550 udp: introduce udp->udp_flags

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 81b36803ac139827538ac5ce4028e750a3c53f53 ]

According to syzbot, it is time to use proper atomic flags for various UDP flags.

Add udp_flags field, and convert udp->corkflag to first bit in it.

Stable-dep-of: a0002127cd74 ("udp: move udp->no_check6_tx to udp->udp_flags")

---
 include/linux/udp.h | 28 +++++++++++++++++++++-------
 net/ipv4/udp.c      | 12 ++++++------
 net/ipv6/udp.c      |  6 +++---
 3 files changed, 30 insertions(+), 16 deletions(-)
include/linux/udp.h +21 -7
index 43c1fb2d2c21a..23f0693e0d9cc 100644
@@ -32,14 +32,20 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask)
 	return (num + net_hash_mix(net)) & mask;
 }
 
+enum {
+	UDP_FLAGS_CORK,		/* Cork is required */
+};
+
 struct udp_sock {
 	/* inet_sock has to be the first member */
 	struct inet_sock inet;
 #define udp_port_hash		inet.sk.__sk_common.skc_u16hashes[0]
 #define udp_portaddr_hash	inet.sk.__sk_common.skc_u16hashes[1]
 #define udp_portaddr_node	inet.sk.__sk_common.skc_portaddr_node
+
+	unsigned long	 udp_flags;
+
 	int		 pending;	/* Any pending frames ? */
-	unsigned int	 corkflag;	/* Cork is required */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
 	unsigned char	 no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
 			 no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
@@ -51,6 +57,11 @@ struct udp_sock {
 			 gro_enabled:1,	/* Request GRO aggregation */
 			 accept_udp_l4:1,
 			 accept_udp_fraglist:1;
+/* indicator bits used by pcflag: */
+#define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
+#define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
+#define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
+	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
 	/*
 	 * Following member retains the information to create a UDP header
 	 * when the socket is uncorked.
@@ -62,12 +73,6 @@ struct udp_sock {
 	 */
 	__u16		 pcslen;
 	__u16		 pcrlen;
-/* indicator bits used by pcflag: */
-#define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
-#define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
-#define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
-	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
-	__u8		 unused[3];
 	/*
 	 * For encapsulation sockets.
 	 */
@@ -95,6 +100,15 @@ struct udp_sock {
 	int		forward_threshold;
 };
 
+#define udp_test_bit(nr, sk)			\
+	test_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
+#define udp_set_bit(nr, sk)			\
+	set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
+#define udp_clear_bit(nr, sk)			\
+	clear_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
+#define udp_assign_bit(nr, sk, val)		\
+	assign_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags, val)
+
 #define UDP_MAX_SEGMENTS	(1 << 6UL)
 
 #define udp_sk(ptr) container_of_const(ptr, struct udp_sock, inet.sk)
net/ipv4/udp.c +6 -6
index 4c847baf52d1c..c7873bb4375d0 100644
@@ -1080,7 +1080,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	u8 tos, scope;
 	__be16 dport;
 	int err, is_udplite = IS_UDPLITE(sk);
-	int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE;
+	int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE;
 	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 	struct sk_buff *skb;
 	struct ip_options_data opt_copy;
@@ -1344,11 +1344,11 @@ void udp_splice_eof(struct socket *sock)
 	struct sock *sk = sock->sk;
 	struct udp_sock *up = udp_sk(sk);
 
-	if (!up->pending || READ_ONCE(up->corkflag))
+	if (!up->pending || udp_test_bit(CORK, sk))
 		return;
 
 	lock_sock(sk);
-	if (up->pending && !READ_ONCE(up->corkflag))
+	if (up->pending && !udp_test_bit(CORK, sk))
 		udp_push_pending_frames(sk);
 	release_sock(sk);
 }
@@ -2683,9 +2683,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 	switch (optname) {
 	case UDP_CORK:
 		if (val != 0) {
-			WRITE_ONCE(up->corkflag, 1);
+			udp_set_bit(CORK, sk);
 		} else {
-			WRITE_ONCE(up->corkflag, 0);
+			udp_clear_bit(CORK, sk);
 			lock_sock(sk);
 			push_pending_frames(sk);
 			release_sock(sk);
@@ -2808,7 +2808,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 
 	switch (optname) {
 	case UDP_CORK:
-		val = READ_ONCE(up->corkflag);
+		val = udp_test_bit(CORK, sk);
 		break;
 
 	case UDP_ENCAP:
net/ipv6/udp.c +3 -3
index 24d3c5c791218..816247afc2f89 100644
@@ -1361,7 +1361,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	int addr_len = msg->msg_namelen;
 	bool connected = false;
 	int ulen = len;
-	int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE;
+	int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
 	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
@@ -1673,11 +1673,11 @@ static void udpv6_splice_eof(struct socket *sock)
 	struct sock *sk = sock->sk;
 	struct udp_sock *up = udp_sk(sk);
 
-	if (!up->pending || READ_ONCE(up->corkflag))
+	if (!up->pending || udp_test_bit(CORK, sk))
 		return;
 
 	lock_sock(sk);
-	if (up->pending && !READ_ONCE(up->corkflag))
+	if (up->pending && !udp_test_bit(CORK, sk))
 		udp_v6_push_pending_frames(sk);
 	release_sock(sk);
 }
Signature · 1 line
2.42.0
author maintainer
#57 lore raw

PATCH 57/550 udp: move udp->no_check6_tx to udp->udp_flags

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit a0002127cd746fcaa182ad3386ef6931c37f3bda ]

syzbot reported that udp->no_check6_tx can be read locklessly. Use one atomic bit from udp->udp_flags

Fixes 1c19448c9ba6 ("net: Make enabling of zero UDP6 csums more restrictive")
---
 include/linux/udp.h | 10 +++++-----
 net/ipv4/udp.c      |  4 ++--
 net/ipv6/udp.c      |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)
include/linux/udp.h +5 -5
index 23f0693e0d9cc..e3f2a6c7ac1d1 100644
@@ -34,6 +34,7 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask)
 
 enum {
 	UDP_FLAGS_CORK,		/* Cork is required */
+	UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */
 };
 
 struct udp_sock {
@@ -47,8 +48,7 @@ struct udp_sock {
 
 	int		 pending;	/* Any pending frames ? */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
-	unsigned char	 no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
-			 no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
+	unsigned char	 no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
 			 encap_enabled:1, /* This socket enabled encap
 					   * processing; UDP tunnels and
 					   * different encapsulation layer set
@@ -115,7 +115,7 @@ struct udp_sock {
 
 static inline void udp_set_no_check6_tx(struct sock *sk, bool val)
 {
-	udp_sk(sk)->no_check6_tx = val;
+	udp_assign_bit(NO_CHECK6_TX, sk, val);
 }
 
 static inline void udp_set_no_check6_rx(struct sock *sk, bool val)
@@ -123,9 +123,9 @@ static inline void udp_set_no_check6_rx(struct sock *sk, bool val)
 	udp_sk(sk)->no_check6_rx = val;
 }
 
-static inline bool udp_get_no_check6_tx(struct sock *sk)
+static inline bool udp_get_no_check6_tx(const struct sock *sk)
 {
-	return udp_sk(sk)->no_check6_tx;
+	return udp_test_bit(NO_CHECK6_TX, sk);
 }
 
 static inline bool udp_get_no_check6_rx(struct sock *sk)
net/ipv4/udp.c +2 -2
index c7873bb4375d0..716eaddc7bdd0 100644
@@ -2719,7 +2719,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_NO_CHECK6_TX:
-		up->no_check6_tx = valbool;
+		udp_set_no_check6_tx(sk, valbool);
 		break;
 
 	case UDP_NO_CHECK6_RX:
@@ -2816,7 +2816,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_NO_CHECK6_TX:
-		val = up->no_check6_tx;
+		val = udp_get_no_check6_tx(sk);
 		break;
 
 	case UDP_NO_CHECK6_RX:
net/ipv6/udp.c +2 -2
index 816247afc2f89..c4f82dfa533fe 100644
@@ -1270,7 +1270,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 			kfree_skb(skb);
 			return -EINVAL;
 		}
-		if (udp_sk(sk)->no_check6_tx) {
+		if (udp_get_no_check6_tx(sk)) {
 			kfree_skb(skb);
 			return -EINVAL;
 		}
@@ -1291,7 +1291,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 
 	if (is_udplite)
 		csum = udplite_csum(skb);
-	else if (udp_sk(sk)->no_check6_tx) {   /* UDP csum disabled */
+	else if (udp_get_no_check6_tx(sk)) {   /* UDP csum disabled */
 		skb->ip_summed = CHECKSUM_NONE;
 		goto send;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
Signature · 1 line
2.42.0
author maintainer
#58 lore raw

PATCH 58/550 udp: move udp->no_check6_rx to udp->udp_flags

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit bcbc1b1de884647aa0318bf74eb7f293d72a1e40 ]

syzbot reported that udp->no_check6_rx can be read locklessly. Use one atomic bit from udp->udp_flags.

Fixes 1c19448c9ba6 ("net: Make enabling of zero UDP6 csums more restrictive")
---
 include/linux/udp.h | 10 +++++-----
 net/ipv4/udp.c      |  4 ++--
 net/ipv6/udp.c      |  6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)
include/linux/udp.h +5 -5
index e3f2a6c7ac1d1..8d4c3835b1b21 100644
@@ -35,6 +35,7 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask)
 enum {
 	UDP_FLAGS_CORK,		/* Cork is required */
 	UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */
+	UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */
 };
 
 struct udp_sock {
@@ -48,8 +49,7 @@ struct udp_sock {
 
 	int		 pending;	/* Any pending frames ? */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
-	unsigned char	 no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
-			 encap_enabled:1, /* This socket enabled encap
+	unsigned char	 encap_enabled:1, /* This socket enabled encap
 					   * processing; UDP tunnels and
 					   * different encapsulation layer set
 					   * this
@@ -120,7 +120,7 @@ static inline void udp_set_no_check6_tx(struct sock *sk, bool val)
 
 static inline void udp_set_no_check6_rx(struct sock *sk, bool val)
 {
-	udp_sk(sk)->no_check6_rx = val;
+	udp_assign_bit(NO_CHECK6_RX, sk, val);
 }
 
 static inline bool udp_get_no_check6_tx(const struct sock *sk)
@@ -128,9 +128,9 @@ static inline bool udp_get_no_check6_tx(const struct sock *sk)
 	return udp_test_bit(NO_CHECK6_TX, sk);
 }
 
-static inline bool udp_get_no_check6_rx(struct sock *sk)
+static inline bool udp_get_no_check6_rx(const struct sock *sk)
 {
-	return udp_sk(sk)->no_check6_rx;
+	return udp_test_bit(NO_CHECK6_RX, sk);
 }
 
 static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,
net/ipv4/udp.c +2 -2
index 716eaddc7bdd0..6b1754704acd1 100644
@@ -2723,7 +2723,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_NO_CHECK6_RX:
-		up->no_check6_rx = valbool;
+		udp_set_no_check6_rx(sk, valbool);
 		break;
 
 	case UDP_SEGMENT:
@@ -2820,7 +2820,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_NO_CHECK6_RX:
-		val = up->no_check6_rx;
+		val = udp_get_no_check6_rx(sk);
 		break;
 
 	case UDP_SEGMENT:
net/ipv6/udp.c +3 -3
index c4f82dfa533fe..1df116951f5eb 100644
@@ -891,7 +891,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 		/* If zero checksum and no_check is not on for
 		 * the socket then skip it.
 		 */
-		if (!uh->check && !udp_sk(sk)->no_check6_rx)
+		if (!uh->check && !udp_get_no_check6_rx(sk))
 			continue;
 		if (!first) {
 			first = sk;
@@ -1009,7 +1009,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst))
 			udp6_sk_rx_dst_set(sk, dst);
 
-		if (!uh->check && !udp_sk(sk)->no_check6_rx) {
+		if (!uh->check && !udp_get_no_check6_rx(sk)) {
 			if (refcounted)
 				sock_put(sk);
 			goto report_csum_error;
@@ -1031,7 +1031,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	/* Unicast */
 	sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
 	if (sk) {
-		if (!uh->check && !udp_sk(sk)->no_check6_rx)
+		if (!uh->check && !udp_get_no_check6_rx(sk))
 			goto report_csum_error;
 		return udp6_unicast_rcv_skb(sk, skb, uh);
 	}
Signature · 1 line
2.42.0
author maintainer
#59 lore raw

PATCH 59/550 udp: move udp->gro_enabled to udp->udp_flags

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit e1dc0615c6b08ef36414f08c011965b8fb56198b ]

syzbot reported that udp->gro_enabled can be read locklessly. Use one atomic bit from udp->udp_flags.

Fixes e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
---
 include/linux/udp.h    | 2 +-
 net/ipv4/udp.c         | 6 +++---
 net/ipv4/udp_offload.c | 4 ++--
 net/ipv6/udp.c         | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)
include/linux/udp.h +1 -1
index 8d4c3835b1b21..b344bd2e41fc9 100644
@@ -36,6 +36,7 @@ enum {
 	UDP_FLAGS_CORK,		/* Cork is required */
 	UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */
 	UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */
+	UDP_FLAGS_GRO_ENABLED,	/* Request GRO aggregation */
 };
 
 struct udp_sock {
@@ -54,7 +55,6 @@ struct udp_sock {
 					   * different encapsulation layer set
 					   * this
 					   */
-			 gro_enabled:1,	/* Request GRO aggregation */
 			 accept_udp_l4:1,
 			 accept_udp_fraglist:1;
 /* indicator bits used by pcflag: */
net/ipv4/udp.c +3 -3
index 6b1754704acd1..a160fce601acb 100644
@@ -1897,7 +1897,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 						      (struct sockaddr *)sin);
 	}
 
-	if (udp_sk(sk)->gro_enabled)
+	if (udp_test_bit(GRO_ENABLED, sk))
 		udp_cmsg_recv(msg, sk, skb);
 
 	if (inet->cmsg_flags)
@@ -2738,7 +2738,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		/* when enabling GRO, accept the related GSO packet type */
 		if (valbool)
 			udp_tunnel_encap_enable(sk->sk_socket);
-		up->gro_enabled = valbool;
+		udp_assign_bit(GRO_ENABLED, sk, valbool);
 		up->accept_udp_l4 = valbool;
 		release_sock(sk);
 		break;
@@ -2828,7 +2828,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_GRO:
-		val = up->gro_enabled;
+		val = udp_test_bit(GRO_ENABLED, sk);
 		break;
 
 	/* The following two cannot be changed on UDP sockets, the return is
net/ipv4/udp_offload.c +2 -2
index 0f46b3c2e4ac5..6c95d28d0c4a7 100644
@@ -557,10 +557,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
 	NAPI_GRO_CB(skb)->is_flist = 0;
 	if (!sk || !udp_sk(sk)->gro_receive) {
 		if (skb->dev->features & NETIF_F_GRO_FRAGLIST)
-			NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1;
+			NAPI_GRO_CB(skb)->is_flist = sk ? !udp_test_bit(GRO_ENABLED, sk) : 1;
 
 		if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) ||
-		    (sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist)
+		    (sk && udp_test_bit(GRO_ENABLED, sk)) || NAPI_GRO_CB(skb)->is_flist)
 			return call_gro_receive(udp_gro_receive_segment, head, skb);
 
 		/* no GRO, be sure flush the current packet */
net/ipv6/udp.c +1 -1
index 1df116951f5eb..3e9497418758f 100644
@@ -446,7 +446,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 						      (struct sockaddr *)sin6);
 	}
 
-	if (udp_sk(sk)->gro_enabled)
+	if (udp_test_bit(GRO_ENABLED, sk))
 		udp_cmsg_recv(msg, sk, skb);
 
 	if (np->rxopt.all)
Signature · 1 line
2.42.0
author maintainer
#60 lore raw

PATCH 60/550 udp: add missing WRITE_ONCE() around up->encap_rcv

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 6d5a12eb91224d707f8691dccb40a5719fe5466d ]

UDP_ENCAP_ESPINUDP_NON_IKE setsockopt() writes over up->encap_rcv while other cpus read it.

Fixes 067b207b281d ("[UDP]: Cleanup UDP encapsulation code")
---
 net/ipv4/udp.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/ipv4/udp.c +4 -2
index a160fce601acb..a018fb0965806 100644
@@ -2700,10 +2700,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		case UDP_ENCAP_ESPINUDP_NON_IKE:
 #if IS_ENABLED(CONFIG_IPV6)
 			if (sk->sk_family == AF_INET6)
-				up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv;
+				WRITE_ONCE(up->encap_rcv,
+					   ipv6_stub->xfrm6_udp_encap_rcv);
 			else
 #endif
-				up->encap_rcv = xfrm4_udp_encap_rcv;
+				WRITE_ONCE(up->encap_rcv,
+					   xfrm4_udp_encap_rcv);
 #endif
 			fallthrough;
 		case UDP_ENCAP_L2TPINUDP:
Signature · 1 line
2.42.0
author maintainer
#61 lore raw

PATCH 61/550 udp: move udp->accept_udp_{l4|fraglist} to udp->udp_flags

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit f5f52f0884a595ff99ab1a608643fe4025fca2d5 ]

These are read locklessly, move them to udp_flags to fix data-races.

Stable-dep-of: 70a36f571362 ("udp: annotate data-races around udp->encap_type")

---
 include/linux/udp.h | 16 +++++++++-------
 net/ipv4/udp.c      |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)
include/linux/udp.h +9 -7
index b344bd2e41fc9..bb2b87adfbea9 100644
@@ -37,6 +37,8 @@ enum {
 	UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */
 	UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */
 	UDP_FLAGS_GRO_ENABLED,	/* Request GRO aggregation */
+	UDP_FLAGS_ACCEPT_FRAGLIST,
+	UDP_FLAGS_ACCEPT_L4,
 };
 
 struct udp_sock {
@@ -50,13 +52,11 @@ struct udp_sock {
 
 	int		 pending;	/* Any pending frames ? */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
-	unsigned char	 encap_enabled:1, /* This socket enabled encap
+	unsigned char	 encap_enabled:1; /* This socket enabled encap
 					   * processing; UDP tunnels and
 					   * different encapsulation layer set
 					   * this
 					   */
-			 accept_udp_l4:1,
-			 accept_udp_fraglist:1;
 /* indicator bits used by pcflag: */
 #define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
 #define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
@@ -149,10 +149,12 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
 	if (!skb_is_gso(skb))
 		return false;
 
-	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4)
+	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 &&
+	    !udp_test_bit(ACCEPT_L4, sk))
 		return true;
 
-	if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist)
+	if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST &&
+	    !udp_test_bit(ACCEPT_FRAGLIST, sk))
 		return true;
 
 	return false;
@@ -160,8 +162,8 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
 
 static inline void udp_allow_gso(struct sock *sk)
 {
-	udp_sk(sk)->accept_udp_l4 = 1;
-	udp_sk(sk)->accept_udp_fraglist = 1;
+	udp_set_bit(ACCEPT_L4, sk);
+	udp_set_bit(ACCEPT_FRAGLIST, sk);
 }
 
 #define udp_portaddr_for_each_entry(__sk, list) \
net/ipv4/udp.c +1 -1
index a018fb0965806..a2eb4921d2440 100644
@@ -2741,7 +2741,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		if (valbool)
 			udp_tunnel_encap_enable(sk->sk_socket);
 		udp_assign_bit(GRO_ENABLED, sk, valbool);
-		up->accept_udp_l4 = valbool;
+		udp_assign_bit(ACCEPT_L4, sk, valbool);
 		release_sock(sk);
 		break;
 
Signature · 1 line
2.42.0
author maintainer
#62 lore raw

PATCH 62/550 udp: lockless UDP_ENCAP_L2TPINUDP / UDP_GRO

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit ac9a7f4ce5dda1472e8f44096f33066c6ec1a3b4 ]

Move udp->encap_enabled to udp->udp_flags.

Add udp_test_and_set_bit() helper to allow lockless udp_tunnel_encap_enable() implementation.

Stable-dep-of: 70a36f571362 ("udp: annotate data-races around udp->encap_type")

---
 include/linux/udp.h        |  9 ++++-----
 include/net/udp_tunnel.h   |  9 +++------
 net/ipv4/udp.c             | 10 +++-------
 net/ipv4/udp_tunnel_core.c |  2 +-
 net/ipv6/udp.c             |  2 +-
 5 files changed, 12 insertions(+), 20 deletions(-)
include/linux/udp.h +4 -5
index bb2b87adfbea9..0cf83270a4a28 100644
@@ -39,6 +39,7 @@ enum {
 	UDP_FLAGS_GRO_ENABLED,	/* Request GRO aggregation */
 	UDP_FLAGS_ACCEPT_FRAGLIST,
 	UDP_FLAGS_ACCEPT_L4,
+	UDP_FLAGS_ENCAP_ENABLED, /* This socket enabled encap */
 };
 
 struct udp_sock {
@@ -52,11 +53,7 @@ struct udp_sock {
 
 	int		 pending;	/* Any pending frames ? */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
-	unsigned char	 encap_enabled:1; /* This socket enabled encap
-					   * processing; UDP tunnels and
-					   * different encapsulation layer set
-					   * this
-					   */
+
 /* indicator bits used by pcflag: */
 #define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
 #define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
@@ -104,6 +101,8 @@ struct udp_sock {
 	test_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
 #define udp_set_bit(nr, sk)			\
 	set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
+#define udp_test_and_set_bit(nr, sk)		\
+	test_and_set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
 #define udp_clear_bit(nr, sk)			\
 	clear_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags)
 #define udp_assign_bit(nr, sk, val)		\
include/net/udp_tunnel.h +3 -6
index 0ca9b7a11baf5..29251c3519cf0 100644
@@ -174,16 +174,13 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
 }
 #endif
 
-static inline void udp_tunnel_encap_enable(struct socket *sock)
+static inline void udp_tunnel_encap_enable(struct sock *sk)
 {
-	struct udp_sock *up = udp_sk(sock->sk);
-
-	if (up->encap_enabled)
+	if (udp_test_and_set_bit(ENCAP_ENABLED, sk))
 		return;
 
-	up->encap_enabled = 1;
 #if IS_ENABLED(CONFIG_IPV6)
-	if (sock->sk->sk_family == PF_INET6)
+	if (READ_ONCE(sk->sk_family) == PF_INET6)
 		ipv6_stub->udpv6_encap_enable();
 #endif
 	udp_encap_enable();
net/ipv4/udp.c +3 -7
index a2eb4921d2440..4df99839e7a30 100644
@@ -2643,7 +2643,7 @@ void udp_destroy_sock(struct sock *sk)
 			if (encap_destroy)
 				encap_destroy(sk);
 		}
-		if (up->encap_enabled)
+		if (udp_test_bit(ENCAP_ENABLED, sk))
 			static_branch_dec(&udp_encap_needed_key);
 	}
 }
@@ -2710,9 +2710,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 			fallthrough;
 		case UDP_ENCAP_L2TPINUDP:
 			up->encap_type = val;
-			lock_sock(sk);
-			udp_tunnel_encap_enable(sk->sk_socket);
-			release_sock(sk);
+			udp_tunnel_encap_enable(sk);
 			break;
 		default:
 			err = -ENOPROTOOPT;
@@ -2735,14 +2733,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_GRO:
-		lock_sock(sk);
 
 		/* when enabling GRO, accept the related GSO packet type */
 		if (valbool)
-			udp_tunnel_encap_enable(sk->sk_socket);
+			udp_tunnel_encap_enable(sk);
 		udp_assign_bit(GRO_ENABLED, sk, valbool);
 		udp_assign_bit(ACCEPT_L4, sk, valbool);
-		release_sock(sk);
 		break;
 
 	/*
net/ipv4/udp_tunnel_core.c +1 -1
index 5f8104cf082d0..732e21b75ba28 100644
@@ -78,7 +78,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
 	udp_sk(sk)->gro_receive = cfg->gro_receive;
 	udp_sk(sk)->gro_complete = cfg->gro_complete;
 
-	udp_tunnel_encap_enable(sock);
+	udp_tunnel_encap_enable(sk);
 }
 EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
 
net/ipv6/udp.c +1 -1
index 3e9497418758f..4f39511bb0969 100644
@@ -1699,7 +1699,7 @@ void udpv6_destroy_sock(struct sock *sk)
 			if (encap_destroy)
 				encap_destroy(sk);
 		}
-		if (up->encap_enabled) {
+		if (udp_test_bit(ENCAP_ENABLED, sk)) {
 			static_branch_dec(&udpv6_encap_needed_key);
 			udp_encap_disable();
 		}
Signature · 1 line
2.42.0
author maintainer
#63 lore raw

PATCH 63/550 udp: annotate data-races around udp->encap_type

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 70a36f571362a8de8b8c02d21ae524fc776287f2 ]

syzbot/KCSAN complained about UDP_ENCAP_L2TPINUDP setsockopt() racing.

Add READ_ONCE()/WRITE_ONCE() to document races on this lockless field.

syzbot report was:

BUG: KCSAN: data-race in udp_lib_setsockopt / udp_lib_setsockopt

read-write to 0xffff8881083603fa of 1 bytes by task 16557 on cpu 0:

udp_lib_setsockopt+0x682/0x6c0
udp_setsockopt+0x73/0xa0 net/ipv4/udp.c:2779
sock_common_setsockopt+0x61/0x70 net/core/sock.c:3697
__sys_setsockopt+0x1c9/0x230 net/socket.c:2263
__do_sys_setsockopt net/socket.c:2274 [inline]
__se_sys_setsockopt net/socket.c:2271 [inline]
__x64_sys_setsockopt+0x66/0x80 net/socket.c:2271
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

read-write to 0xffff8881083603fa of 1 bytes by task 16554 on cpu 1:

udp_lib_setsockopt+0x682/0x6c0
udp_setsockopt+0x73/0xa0 net/ipv4/udp.c:2779
sock_common_setsockopt+0x61/0x70 net/core/sock.c:3697
__sys_setsockopt+0x1c9/0x230 net/socket.c:2263
__do_sys_setsockopt net/socket.c:2274 [inline]
__se_sys_setsockopt net/socket.c:2271 [inline]
__x64_sys_setsockopt+0x66/0x80 net/socket.c:2271
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

value changed: 0x01 -> 0x05

Reported by Kernel Concurrency Sanitizer on:

CPU: 1 PID: 16554 Comm: syz-executor.5 Not tainted 6.5.0-rc7-syzkaller-00004-gf7757129e3de #0
---
 drivers/net/gtp.c      | 4 ++--
 net/ipv4/udp.c         | 9 +++++----
 net/ipv4/xfrm4_input.c | 4 ++--
 net/ipv6/udp.c         | 5 +++--
 net/ipv6/xfrm6_input.c | 4 ++--
 net/l2tp/l2tp_core.c   | 6 +++---
 6 files changed, 17 insertions(+), 15 deletions(-)
drivers/net/gtp.c +2 -2
index 477b4d4f860bd..bace989591f75 100644
@@ -629,7 +629,7 @@ static void __gtp_encap_destroy(struct sock *sk)
 			gtp->sk0 = NULL;
 		else
 			gtp->sk1u = NULL;
-		udp_sk(sk)->encap_type = 0;
+		WRITE_ONCE(udp_sk(sk)->encap_type, 0);
 		rcu_assign_sk_user_data(sk, NULL);
 		release_sock(sk);
 		sock_put(sk);
@@ -681,7 +681,7 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
 	netdev_dbg(gtp->dev, "encap_recv sk=%p\n", sk);
 
-	switch (udp_sk(sk)->encap_type) {
+	switch (READ_ONCE(udp_sk(sk)->encap_type)) {
 	case UDP_ENCAP_GTP0:
 		netdev_dbg(gtp->dev, "received GTP0 packet\n");
 		ret = gtp0_udp_encap_recv(gtp, skb);
net/ipv4/udp.c +5 -4
index 4df99839e7a30..be0370a64cc15 100644
@@ -744,7 +744,7 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
 			       iph->saddr, uh->source, skb->dev->ifindex,
 			       inet_sdif(skb), udptable, NULL);
 
-	if (!sk || udp_sk(sk)->encap_type) {
+	if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) {
 		/* No socket for error: try tunnels before discarding */
 		if (static_branch_unlikely(&udp_encap_needed_key)) {
 			sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb,
@@ -2110,7 +2110,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 	}
 	nf_reset_ct(skb);
 
-	if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) {
+	if (static_branch_unlikely(&udp_encap_needed_key) &&
+	    READ_ONCE(up->encap_type)) {
 		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
 
 		/*
@@ -2709,7 +2710,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 #endif
 			fallthrough;
 		case UDP_ENCAP_L2TPINUDP:
-			up->encap_type = val;
+			WRITE_ONCE(up->encap_type, val);
 			udp_tunnel_encap_enable(sk);
 			break;
 		default:
@@ -2810,7 +2811,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case UDP_ENCAP:
-		val = up->encap_type;
+		val = READ_ONCE(up->encap_type);
 		break;
 
 	case UDP_NO_CHECK6_TX:
net/ipv4/xfrm4_input.c +2 -2
index eac206a290d05..183f6dc372429 100644
@@ -85,11 +85,11 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 	struct udphdr *uh;
 	struct iphdr *iph;
 	int iphlen, len;
-
 	__u8 *udpdata;
 	__be32 *udpdata32;
-	__u16 encap_type = up->encap_type;
+	u16 encap_type;
 
+	encap_type = READ_ONCE(up->encap_type);
 	/* if this is not encapsulated socket, then just return now */
 	if (!encap_type)
 		return 1;
net/ipv6/udp.c +3 -2
index 4f39511bb0969..9988160ca4a76 100644
@@ -604,7 +604,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source,
 			       inet6_iif(skb), inet6_sdif(skb), udptable, NULL);
 
-	if (!sk || udp_sk(sk)->encap_type) {
+	if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) {
 		/* No socket for error: try tunnels before discarding */
 		if (static_branch_unlikely(&udpv6_encap_needed_key)) {
 			sk = __udp6_lib_err_encap(net, hdr, offset, uh,
@@ -721,7 +721,8 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 	}
 	nf_reset_ct(skb);
 
-	if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
+	if (static_branch_unlikely(&udpv6_encap_needed_key) &&
+	    READ_ONCE(up->encap_type)) {
 		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
 
 		/*
net/ipv6/xfrm6_input.c +2 -2
index 4907ab241d6be..4156387248e40 100644
@@ -81,14 +81,14 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 	struct ipv6hdr *ip6h;
 	int len;
 	int ip6hlen = sizeof(struct ipv6hdr);
-
 	__u8 *udpdata;
 	__be32 *udpdata32;
-	__u16 encap_type = up->encap_type;
+	u16 encap_type;
 
 	if (skb->protocol == htons(ETH_P_IP))
 		return xfrm4_udp_encap_rcv(sk, skb);
 
+	encap_type = READ_ONCE(up->encap_type);
 	/* if this is not encapsulated socket, then just return now */
 	if (!encap_type)
 		return 1;
net/l2tp/l2tp_core.c +3 -3
index 03608d3ded4b8..8d21ff25f1602 100644
@@ -1139,9 +1139,9 @@ static void l2tp_tunnel_destruct(struct sock *sk)
 	switch (tunnel->encap) {
 	case L2TP_ENCAPTYPE_UDP:
 		/* No longer an encapsulation socket. See net/ipv4/udp.c */
-		(udp_sk(sk))->encap_type = 0;
-		(udp_sk(sk))->encap_rcv = NULL;
-		(udp_sk(sk))->encap_destroy = NULL;
+		WRITE_ONCE(udp_sk(sk)->encap_type, 0);
+		udp_sk(sk)->encap_rcv = NULL;
+		udp_sk(sk)->encap_destroy = NULL;
 		break;
 	case L2TP_ENCAPTYPE_IP:
 		break;
Signature · 1 line
2.42.0
author maintainer
#64 lore raw

PATCH 64/550 udplite: remove UDPLITE_BIT

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 729549aa350c56a777bb342941ed4d69b6585769 ]

This flag is set but never read, we can remove it.

Stable-dep-of: 882af43a0fc3 ("udplite: fix various data-races")

---
 include/linux/udp.h | 5 ++---
 net/ipv4/udplite.c  | 1 -
 net/ipv6/udplite.c  | 1 -
 3 files changed, 2 insertions(+), 5 deletions(-)
include/linux/udp.h +2 -3
index 0cf83270a4a28..58156edec0096 100644
@@ -55,9 +55,8 @@ struct udp_sock {
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
 
 /* indicator bits used by pcflag: */
-#define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
-#define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
-#define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
+#define UDPLITE_SEND_CC  0x1  		/* set via udplite setsockopt         */
+#define UDPLITE_RECV_CC  0x2		/* set via udplite setsocktopt        */
 	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
 	/*
 	 * Following member retains the information to create a UDP header
net/ipv4/udplite.c +0 -1
index 39ecdad1b50ce..af37af3ab727b 100644
@@ -21,7 +21,6 @@ EXPORT_SYMBOL(udplite_table);
 static int udplite_sk_init(struct sock *sk)
 {
 	udp_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
 	pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, "
 		     "please contact the netdev mailing list\n");
 	return 0;
net/ipv6/udplite.c +0 -1
index 267d491e97075..a60bec9b14f14 100644
@@ -17,7 +17,6 @@
 static int udplitev6_sk_init(struct sock *sk)
 {
 	udpv6_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
 	pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, "
 		     "please contact the netdev mailing list\n");
 	return 0;
Signature · 1 line
2.42.0
author maintainer
#65 lore raw

PATCH 65/550 udplite: fix various data-races

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 882af43a0fc37e26d85fb0df0c9edd3bed928de4 ]

udp->pcflag, udp->pcslen and udp->pcrlen reads/writes are racy.

Move udp->pcflag to udp->udp_flags for atomicity,
and add READ_ONCE()/WRITE_ONCE() annotations for pcslen and pcrlen.

Fixes ba4e58eca8aa ("[NET]: Supporting UDP-Lite (RFC 3828) in Linux")
---
 include/linux/udp.h   |  6 ++----
 include/net/udplite.h | 14 +++++++++-----
 net/ipv4/udp.c        | 21 +++++++++++----------
 net/ipv6/udp.c        |  9 +++++----
 4 files changed, 27 insertions(+), 23 deletions(-)
include/linux/udp.h +2 -4
index 58156edec0096..d04188714dca1 100644
@@ -40,6 +40,8 @@ enum {
 	UDP_FLAGS_ACCEPT_FRAGLIST,
 	UDP_FLAGS_ACCEPT_L4,
 	UDP_FLAGS_ENCAP_ENABLED, /* This socket enabled encap */
+	UDP_FLAGS_UDPLITE_SEND_CC, /* set via udplite setsockopt */
+	UDP_FLAGS_UDPLITE_RECV_CC, /* set via udplite setsockopt */
 };
 
 struct udp_sock {
@@ -54,10 +56,6 @@ struct udp_sock {
 	int		 pending;	/* Any pending frames ? */
 	__u8		 encap_type;	/* Is this an Encapsulation socket? */
 
-/* indicator bits used by pcflag: */
-#define UDPLITE_SEND_CC  0x1  		/* set via udplite setsockopt         */
-#define UDPLITE_RECV_CC  0x2		/* set via udplite setsocktopt        */
-	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
 	/*
 	 * Following member retains the information to create a UDP header
 	 * when the socket is uncorked.
include/net/udplite.h +9 -5
index 299c14ce2bb94..dd60b51364837 100644
@@ -66,14 +66,18 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
 /* Fast-path computation of checksum. Socket may not be locked. */
 static inline __wsum udplite_csum(struct sk_buff *skb)
 {
-	const struct udp_sock *up = udp_sk(skb->sk);
 	const int off = skb_transport_offset(skb);
+	const struct sock *sk = skb->sk;
 	int len = skb->len - off;
 
-	if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
-		if (0 < up->pcslen)
-			len = up->pcslen;
-		udp_hdr(skb)->len = htons(up->pcslen);
+	if (udp_test_bit(UDPLITE_SEND_CC, sk)) {
+		u16 pcslen = READ_ONCE(udp_sk(sk)->pcslen);
+
+		if (pcslen < len) {
+			if (pcslen > 0)
+				len = pcslen;
+			udp_hdr(skb)->len = htons(pcslen);
+		}
 	}
 	skb->ip_summed = CHECKSUM_NONE;     /* no HW support for checksumming */
 
net/ipv4/udp.c +11 -10
index be0370a64cc15..f712ff61beb8a 100644
@@ -2149,7 +2149,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 	/*
 	 * 	UDP-Lite specific tests, ignored on UDP sockets
 	 */
-	if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+	if (udp_test_bit(UDPLITE_RECV_CC, sk) && UDP_SKB_CB(skb)->partial_cov) {
+		u16 pcrlen = READ_ONCE(up->pcrlen);
 
 		/*
 		 * MIB statistics other than incrementing the error count are
@@ -2162,7 +2163,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 		 * delivery of packets with coverage values less than a value
 		 * provided by the application."
 		 */
-		if (up->pcrlen == 0) {          /* full coverage was set  */
+		if (pcrlen == 0) {          /* full coverage was set  */
 			net_dbg_ratelimited("UDPLite: partial coverage %d while full coverage %d requested\n",
 					    UDP_SKB_CB(skb)->cscov, skb->len);
 			goto drop;
@@ -2173,9 +2174,9 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 		 * that it wants x while sender emits packets of smaller size y.
 		 * Therefore the above ...()->partial_cov statement is essential.
 		 */
-		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
+		if (UDP_SKB_CB(skb)->cscov < pcrlen) {
 			net_dbg_ratelimited("UDPLite: coverage %d too small, need min %d\n",
-					    UDP_SKB_CB(skb)->cscov, up->pcrlen);
+					    UDP_SKB_CB(skb)->cscov, pcrlen);
 			goto drop;
 		}
 	}
@@ -2754,8 +2755,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 			val = 8;
 		else if (val > USHRT_MAX)
 			val = USHRT_MAX;
-		up->pcslen = val;
-		up->pcflag |= UDPLITE_SEND_CC;
+		WRITE_ONCE(up->pcslen, val);
+		udp_set_bit(UDPLITE_SEND_CC, sk);
 		break;
 
 	/* The receiver specifies a minimum checksum coverage value. To make
@@ -2768,8 +2769,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 			val = 8;
 		else if (val > USHRT_MAX)
 			val = USHRT_MAX;
-		up->pcrlen = val;
-		up->pcflag |= UDPLITE_RECV_CC;
+		WRITE_ONCE(up->pcrlen, val);
+		udp_set_bit(UDPLITE_RECV_CC, sk);
 		break;
 
 	default:
@@ -2833,11 +2834,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 	/* The following two cannot be changed on UDP sockets, the return is
 	 * always 0 (which corresponds to the full checksum coverage of UDP). */
 	case UDPLITE_SEND_CSCOV:
-		val = up->pcslen;
+		val = READ_ONCE(up->pcslen);
 		break;
 
 	case UDPLITE_RECV_CSCOV:
-		val = up->pcrlen;
+		val = READ_ONCE(up->pcrlen);
 		break;
 
 	default:
net/ipv6/udp.c +5 -4
index 9988160ca4a76..8d79642ae45dd 100644
@@ -760,16 +760,17 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 	/*
 	 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
 	 */
-	if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+	if (udp_test_bit(UDPLITE_RECV_CC, sk) && UDP_SKB_CB(skb)->partial_cov) {
+		u16 pcrlen = READ_ONCE(up->pcrlen);
 
-		if (up->pcrlen == 0) {          /* full coverage was set  */
+		if (pcrlen == 0) {          /* full coverage was set  */
 			net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n",
 					    UDP_SKB_CB(skb)->cscov, skb->len);
 			goto drop;
 		}
-		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
+		if (UDP_SKB_CB(skb)->cscov < pcrlen) {
 			net_dbg_ratelimited("UDPLITE6: coverage %d too small, need min %d\n",
-					    UDP_SKB_CB(skb)->cscov, up->pcrlen);
+					    UDP_SKB_CB(skb)->cscov, pcrlen);
 			goto drop;
 		}
 	}
Signature · 1 line
2.42.0
author maintainer
#66 lore raw

PATCH 66/550 selftests/bpf: Skip module_fentry_shadow test when bpf_testmod is not available

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Artem Savkov <[email protected]>

[ Upstream commit 971f7c32147f2d0953a815a109b22b8ed45949d4 ]

This test relies on bpf_testmod, so skip it if the module is not available.

Fixes aa3d65de4b900 ("bpf/selftests: Test fentry attachment to shadowed functions")
---
 .../testing/selftests/bpf/prog_tests/module_fentry_shadow.c  | 5 +++++
 1 file changed, 5 insertions(+)
tools/testing/selftests/bpf/prog_tests/module_fentry_shadow.c +5 -0
index c7636e18b1ebd..aa9f67eb1c95b 100644
@@ -61,6 +61,11 @@ void test_module_fentry_shadow(void)
 	int link_fd[2] = {};
 	__s32 btf_id[2] = {};
 
+	if (!env.has_testmod) {
+		test__skip();
+		return;
+	}
+
 	LIBBPF_OPTS(bpf_prog_load_opts, load_opts,
 		.expected_attach_type = BPF_TRACE_FENTRY,
 	);
Signature · 1 line
2.42.0
author maintainer
#67 lore raw

PATCH 67/550 tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aananth V <[email protected]>

[ Upstream commit e326578a21414738de45f77badd332fb00bd0f58 ]

For passive TCP Fast Open sockets that had SYN/ACK timeout and did not send more data in SYN_RECV, upon receiving the final ACK in 3WHS, the congestion state may awkwardly stay in CA_Loss mode unless the CA state was undone due to TCP timestamp checks. However, if tcp_rcv_synrecv_state_fastopen() decides not to undo, then we should enter CA_Open, because at that point we have received an ACK covering the retransmitted SYNACKs. Currently, the icsk_ca_state is only set to CA_Open after we receive an ACK for a data-packet. This is because tcp_ack does not call tcp_fastretrans_alert (and tcp_process_loss) if !prior_packets

Note that tcp_process_loss() calls tcp_try_undo_recovery(), so having tcp_rcv_synrecv_state_fastopen() decide that if we're in CA_Loss we should call tcp_try_undo_recovery() is consistent with that, and low risk.

Fixes dad8cea7add9 ("tcp: fix TFO SYNACK undo to avoid double-timestamp-undo")
---
 net/ipv4/tcp_input.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
net/ipv4/tcp_input.c +5 -4
index 7d544f965b264..908db91f7b4cd 100644
@@ -6434,22 +6434,23 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
 
 static void tcp_rcv_synrecv_state_fastopen(struct sock *sk)
 {
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct request_sock *req;
 
 	/* If we are still handling the SYNACK RTO, see if timestamp ECR allows
 	 * undo. If peer SACKs triggered fast recovery, we can't undo here.
 	 */
-	if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss)
-		tcp_try_undo_loss(sk, false);
+	if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out)
+		tcp_try_undo_recovery(sk);
 
 	/* Reset rtx states to prevent spurious retransmits_timed_out() */
-	tcp_sk(sk)->retrans_stamp = 0;
+	tp->retrans_stamp = 0;
 	inet_csk(sk)->icsk_retransmits = 0;
 
 	/* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1,
 	 * we no longer need req so release it.
 	 */
-	req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk,
+	req = rcu_dereference_protected(tp->fastopen_rsk,
 					lockdep_sock_is_held(sk));
 	reqsk_fastopen_remove(sk, req, false);
 
Signature · 1 line
2.42.0
author maintainer
#68 lore raw

PATCH 68/550 bpf: Fix kfunc callback register type handling

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kumar Kartikeya Dwivedi <[email protected]>

[ Upstream commit 06d686f771ddc27a8554cd8f5b22e071040dc90e ]

The kfunc code to handle KF_ARG_PTR_TO_CALLBACK does not check the reg type before using reg->subprogno. This can accidently permit invalid pointers from being passed into callback helpers (e.g. silently from different paths). Likewise, reg->subprogno from the per-register type union may not be meaningful either. We need to reject any other type except PTR_TO_FUNC.

---
 kernel/bpf/verifier.c | 4 ++++
 1 file changed, 4 insertions(+)
kernel/bpf/verifier.c +4 -0
index 6c52055916287..e7e2687c35884 100644
@@ -11029,6 +11029,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
 			break;
 		}
 		case KF_ARG_PTR_TO_CALLBACK:
+			if (reg->type != PTR_TO_FUNC) {
+				verbose(env, "arg%d expected pointer to func\n", i);
+				return -EINVAL;
+			}
 			meta->subprogno = reg->subprogno;
 			break;
 		case KF_ARG_PTR_TO_REFCOUNTED_KPTR:
Signature · 1 line
2.42.0
author maintainer
#69 lore raw

PATCH 69/550 gve: Use size_add() in call to struct_size()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gustavo A. R. Silva <[email protected]>

[ Upstream commit d692873cbe861a870cdc9cbfb120eefd113c3dfd ]

If, for any reason, tx_stats_num + rx_stats_num wraps around, the protection that struct_size() adds against potential integer overflows is defeated. Fix this by hardening call to struct_size() with size_add().

Fixes 691f4077d560 ("gve: Replace zero-length array with flexible-array member")
---
 drivers/net/ethernet/google/gve/gve_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/google/gve/gve_main.c +1 -1
index e6f1711d9be04..465a6db5a40a8 100644
@@ -191,7 +191,7 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
 	rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
 		       priv->rx_cfg.num_queues;
 	priv->stats_report_len = struct_size(priv->stats_report, stats,
-					     tx_stats_num + rx_stats_num);
+					     size_add(tx_stats_num, rx_stats_num));
 	priv->stats_report =
 		dma_alloc_coherent(&priv->pdev->dev, priv->stats_report_len,
 				   &priv->stats_report_bus, GFP_KERNEL);
Signature · 1 line
2.42.0
author maintainer
#70 lore raw

PATCH 70/550 mlxsw: Use size_mul() in call to struct_size()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gustavo A. R. Silva <[email protected]>

[ Upstream commit e22c6ea025013ae447fe269269753ffec763dde5 ]

If, for any reason, the open-coded arithmetic causes a wraparound, the protection that struct_size() adds against potential integer overflows is defeated. Fix this by hardening call to struct_size() with size_mul().

Fixes 2285ec872d9d ("mlxsw: spectrum_acl_bloom_filter: use struct_size() in kzalloc()")
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +1 -1
index e2aced7ab4547..95f63fcf4ba1f 100644
@@ -496,7 +496,7 @@ mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks)
 	 * is 2^ACL_MAX_BF_LOG
 	 */
 	bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG);
-	bf = kzalloc(struct_size(bf, refcnt, bf_bank_size * num_erp_banks),
+	bf = kzalloc(struct_size(bf, refcnt, size_mul(bf_bank_size, num_erp_banks)),
 		     GFP_KERNEL);
 	if (!bf)
 		return ERR_PTR(-ENOMEM);
Signature · 1 line
2.42.0
author maintainer
#71 lore raw

PATCH 71/550 tls: Use size_add() in call to struct_size()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gustavo A. R. Silva <[email protected]>

[ Upstream commit a2713257ee2be22827d7bc248302d408c91bfb95 ]

If, for any reason, the open-coded arithmetic causes a wraparound, the protection that struct_size() adds against potential integer overflows is defeated. Fix this by hardening call to struct_size() with size_add().

Fixes b89fec54fd61 ("tls: rx: wrap decrypt params in a struct")
---
 net/tls/tls_sw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/tls/tls_sw.c +1 -1
index ce925f3a52492..57e4601eaaf50 100644
@@ -1488,7 +1488,7 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov,
 	 */
 	aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv);
 	aead_size = ALIGN(aead_size, __alignof__(*dctx));
-	mem = kmalloc(aead_size + struct_size(dctx, sg, n_sgin + n_sgout),
+	mem = kmalloc(aead_size + struct_size(dctx, sg, size_add(n_sgin, n_sgout)),
 		      sk->sk_allocation);
 	if (!mem) {
 		err = -ENOMEM;
Signature · 1 line
2.42.0
author maintainer
#72 lore raw

PATCH 72/550 tipc: Use size_add() in calls to struct_size()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gustavo A. R. Silva <[email protected]>

[ Upstream commit 2506a91734754de690869824fb0d1ac592ec1266 ]

If, for any reason, the open-coded arithmetic causes a wraparound, the protection that struct_size() adds against potential integer overflows is defeated. Fix this by hardening call to struct_size() with size_add().

Fixes e034c6d23bc4 ("tipc: Use struct_size() helper")
---
 net/tipc/link.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/tipc/link.c +2 -2
index 2eff1c7949cbc..8715c9b05f90d 100644
@@ -1446,7 +1446,7 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l,
 		p = (struct tipc_gap_ack_blks *)msg_data(hdr);
 		sz = ntohs(p->len);
 		/* Sanity check */
-		if (sz == struct_size(p, gacks, p->ugack_cnt + p->bgack_cnt)) {
+		if (sz == struct_size(p, gacks, size_add(p->ugack_cnt, p->bgack_cnt))) {
 			/* Good, check if the desired type exists */
 			if ((uc && p->ugack_cnt) || (!uc && p->bgack_cnt))
 				goto ok;
@@ -1533,7 +1533,7 @@ static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr)
 			__tipc_build_gap_ack_blks(ga, l, ga->bgack_cnt) : 0;
 
 	/* Total len */
-	len = struct_size(ga, gacks, ga->bgack_cnt + ga->ugack_cnt);
+	len = struct_size(ga, gacks, size_add(ga->bgack_cnt, ga->ugack_cnt));
 	ga->len = htons(len);
 	return len;
 }
Signature · 1 line
2.42.0
author maintainer
#73 lore raw

PATCH 73/550 net: spider_net: Use size_add() in call to struct_size()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gustavo A. R. Silva <[email protected]>

[ Upstream commit 0201409079b975e46cc40e8bdff4bd61329ee10f ]

If, for any reason, the open-coded arithmetic causes a wraparound, the protection that struct_size() adds against potential integer overflows is defeated. Fix this by hardening call to struct_size() with size_add().

Fixes 3f1071ec39f7 ("net: spider_net: Use struct_size() helper")
---
 drivers/net/ethernet/toshiba/spider_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/toshiba/spider_net.c +1 -1
index 50d7eacfec582..87e67121477cb 100644
@@ -2332,7 +2332,7 @@ spider_net_alloc_card(void)
 	struct spider_net_card *card;
 
 	netdev = alloc_etherdev(struct_size(card, darray,
-					    tx_descriptors + rx_descriptors));
+					    size_add(tx_descriptors, rx_descriptors)));
 	if (!netdev)
 		return NULL;
 
Signature · 1 line
2.42.0
author maintainer
#74 lore raw

PATCH 74/550 net: ethernet: mtk_wed: fix EXT_INT_STATUS_RX_FBUF definitions for MT7986 SoC

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lorenzo Bianconi <[email protected]>

[ Upstream commit c80471ba74b7f332ac19b985ccb76d852d507acf ]

Fix MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH and MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH definitions for MT7986 (MT7986 is the only SoC to use them).

Fixes de84a090d99a ("net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset")
---
 drivers/net/ethernet/mediatek/mtk_wed_regs.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed_regs.h +2 -2
index 0a50bb98c5ea4..20652c4e739a8 100644
@@ -64,8 +64,8 @@ struct mtk_wdma_desc {
 #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID	BIT(4)
 #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH		BIT(8)
 #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH		BIT(9)
-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH		BIT(12)
-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH		BIT(13)
+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH		BIT(10) /* wed v2 */
+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH		BIT(11) /* wed v2 */
 #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR	BIT(16)
 #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR	BIT(17)
 #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT		BIT(18)
Signature · 1 line
2.42.0
author maintainer
#75 lore raw

PATCH 75/550 wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for debugfs_create_file()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jinjie Ruan <[email protected]>

[ Upstream commit 74f7957c9b1b95553faaf146a2553e023a9d1720 ]

Since debugfs_create_file() return ERR_PTR and never return NULL, so use IS_ERR() to check it instead of checking NULL.

---
 drivers/net/wireless/realtek/rtw88/debug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw88/debug.c +2 -2
index f8ba133baff06..35bc37a3c469d 100644
@@ -1233,9 +1233,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
 #define rtw_debugfs_add_core(name, mode, fopname, parent)		\
 	do {								\
 		rtw_debug_priv_ ##name.rtwdev = rtwdev;			\
-		if (!debugfs_create_file(#name, mode,			\
+		if (IS_ERR(debugfs_create_file(#name, mode,		\
 					 parent, &rtw_debug_priv_ ##name,\
-					 &file_ops_ ##fopname))		\
+					 &file_ops_ ##fopname)))	\
 			pr_debug("Unable to initialize debugfs:%s\n",	\
 			       #name);					\
 	} while (0)
Signature · 1 line
2.42.0
author maintainer
#76 lore raw

PATCH 76/550 wifi: ath12k: fix DMA unmap warning on NULL DMA address

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Baochen Qiang <[email protected]>

[ Upstream commit 9ae8c496d211155a3f220b63da364fba1a794292 ]

In ath12k_dp_tx(), if we reach fail_dma_unmap due to some errors, current code does DMA unmap unconditionally on skb_cb->paddr_ext_desc. However, skb_cb->paddr_ext_desc may be NULL and thus we get below warning:

kernel: [ 8887.076212] WARNING: CPU: 3 PID: 0 at drivers/iommu/dma-iommu.c:1077 iommu_dma_unmap_page+0x79/0x90

Fix it by checking skb_cb->paddr_ext_desc before unmap it.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4

Fixes d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
---
 drivers/net/wireless/ath/ath12k/dp_tx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath12k/dp_tx.c +5 -2
index d3c7c76d6b75e..5d1be6451d587 100644
@@ -330,8 +330,11 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
 
 fail_unmap_dma:
 	dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
-	dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
-			 sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);
+
+	if (skb_cb->paddr_ext_desc)
+		dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+				 sizeof(struct hal_tx_msdu_ext_desc),
+				 DMA_TO_DEVICE);
 
 fail_remove_tx_buf:
 	ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);
Signature · 1 line
2.42.0
author maintainer
#77 lore raw

PATCH 77/550 wifi: ath11k: fix boot failure with one MSI vector

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Baochen Qiang <[email protected]>

[ Upstream commit 39564b475ac5a589e6c22c43a08cbd283c295d2c ]

Commit 5b32b6dd96633 ("ath11k: Remove core PCI references from PCI common code") breaks with one MSI vector because it moves affinity setting after IRQ request, see below log:

[ 1417.278835] ath11k_pci 0000:02:00.0: failed to receive control response completion, polling..
[ 1418.302829] ath11k_pci 0000:02:00.0: Service connect timeout
[ 1418.302833] ath11k_pci 0000:02:00.0: failed to connect to HTT: -110
[ 1418.303669] ath11k_pci 0000:02:00.0: failed to start core: -110

The detail is, if do affinity request after IRQ activated, which is done in request_irq(), kernel caches that request and returns success directly. Later when a subsequent MHI interrupt is fired, kernel will do the real affinity setting work, as a result, changs the MSI vector. However at that time host has configured old vector to hardware, so host never receives CE or DP interrupts.

Fix it by setting affinity before registering MHI controller where host is, for the first time, doing IRQ request.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01160-QCAMSLSWPLZ-1

Fixes 5b32b6dd9663 ("ath11k: Remove core PCI references from PCI common code")
---
 drivers/net/wireless/ath/ath11k/pci.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/net/wireless/ath/ath11k/pci.c +12 -12
index a181563ec0851..c0f00343cee93 100644
@@ -853,10 +853,16 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto err_pci_disable_msi;
 
+	ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
+	if (ret) {
+		ath11k_err(ab, "failed to set irq affinity %d\n", ret);
+		goto err_pci_disable_msi;
+	}
+
 	ret = ath11k_mhi_register(ab_pci);
 	if (ret) {
 		ath11k_err(ab, "failed to register mhi: %d\n", ret);
-		goto err_pci_disable_msi;
+		goto err_irq_affinity_cleanup;
 	}
 
 	ret = ath11k_hal_srng_init(ab);
@@ -877,12 +883,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 		goto err_ce_free;
 	}
 
-	ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
-	if (ret) {
-		ath11k_err(ab, "failed to set irq affinity %d\n", ret);
-		goto err_free_irq;
-	}
-
 	/* kernel may allocate a dummy vector before request_irq and
 	 * then allocate a real vector when request_irq is called.
 	 * So get msi_data here again to avoid spurious interrupt
@@ -891,19 +891,16 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 	ret = ath11k_pci_config_msi_data(ab_pci);
 	if (ret) {
 		ath11k_err(ab, "failed to config msi_data: %d\n", ret);
-		goto err_irq_affinity_cleanup;
+		goto err_free_irq;
 	}
 
 	ret = ath11k_core_init(ab);
 	if (ret) {
 		ath11k_err(ab, "failed to init core: %d\n", ret);
-		goto err_irq_affinity_cleanup;
+		goto err_free_irq;
 	}
 	return 0;
 
-err_irq_affinity_cleanup:
-	ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
-
 err_free_irq:
 	ath11k_pcic_free_irq(ab);
 
@@ -916,6 +913,9 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
 err_mhi_unregister:
 	ath11k_mhi_unregister(ab_pci);
 
+err_irq_affinity_cleanup:
+	ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
 err_pci_disable_msi:
 	ath11k_pci_free_msi(ab_pci);
 
Signature · 1 line
2.42.0
author maintainer
#78 lore raw

PATCH 78/550 wifi: mac80211: fix check for unusable RX result

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

[ Upstream commit 583058542f46e3e2b0c536316fbd641f62d91dc6 ]

If we just check "result & RX_DROP_UNUSABLE", this really only works by accident, because SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE got to have the value 1, and SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR is 2.

Fix this to really check the entire subsys mask for the value, so it doesn't matter what the subsystem value is.

Fixes 7f4e09700bdc ("wifi: mac80211: report all unusable beacon frames")
---
 net/mac80211/drop.h | 3 +++
 net/mac80211/rx.c   | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)
net/mac80211/drop.h +3 -0
index 49dc809cab290..1570fac8411f4 100644
@@ -53,4 +53,7 @@ enum mac80211_drop_reason {
 #undef DEF
 };
 
+#define RX_RES_IS_UNUSABLE(result)	\
+	(((__force u32)(result) & SKB_DROP_REASON_SUBSYS_MASK) == ___RX_DROP_UNUSABLE)
+
 #endif /* MAC80211_DROP_H */
net/mac80211/rx.c +1 -1
index 8f6b6f56b65b4..26ca2f5dc52b2 100644
@@ -2112,7 +2112,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 	/* either the frame has been decrypted or will be dropped */
 	status->flag |= RX_FLAG_DECRYPTED;
 
-	if (unlikely(ieee80211_is_beacon(fc) && (result & RX_DROP_UNUSABLE) &&
+	if (unlikely(ieee80211_is_beacon(fc) && RX_RES_IS_UNUSABLE(result) &&
 		     rx->sdata->dev))
 		cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
 					     skb->data, skb->len);
Signature · 1 line
2.42.0
author maintainer
#79 lore raw

PATCH 79/550 PM: sleep: Fix symbol export for _SIMPLE_ variants of _PM_OPS()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Raag Jadav <[email protected]>

[ Upstream commit 8d74f1da776da9b0306630b13a3025214fa44618 ]

Currently EXPORT_*_SIMPLE_DEV_PM_OPS() use EXPORT_*_DEV_PM_OPS() set of macros to export dev_pm_ops symbol, which export the symbol in case CONFIG_PM=y but don't take CONFIG_PM_SLEEP into consideration.

Since _SIMPLE_ variants of _PM_OPS() do not include runtime PM handles and are only used in case CONFIG_PM_SLEEP=y, we should not be exporting dev_pm_ops symbol for them in case CONFIG_PM_SLEEP=n.

This can be fixed by having two distinct set of export macros for both _RUNTIME_ and _SIMPLE_ variants of _PM_OPS(), such that the export of dev_pm_ops symbol used in each variant depends on CONFIG_PM and CONFIG_PM_SLEEP respectively.

Introduce _DEV_SLEEP_PM_OPS() set of export macros for _SIMPLE_ variants of _PM_OPS(), which export dev_pm_ops symbol only in case CONFIG_PM_SLEEP=y and discard it otherwise.

Fixes 34e1ed189fab ("PM: Improve EXPORT_*_DEV_PM_OPS macros")
---
 include/linux/pm.h | 43 +++++++++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 14 deletions(-)
include/linux/pm.h +29 -14
index badad7d11f4fd..d305412556f35 100644
@@ -374,24 +374,39 @@ const struct dev_pm_ops name = { \
 	RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \
 }
 
-#ifdef CONFIG_PM
-#define _EXPORT_DEV_PM_OPS(name, license, ns)				\
+#define _EXPORT_PM_OPS(name, license, ns)				\
 	const struct dev_pm_ops name;					\
 	__EXPORT_SYMBOL(name, license, ns);				\
 	const struct dev_pm_ops name
-#define EXPORT_PM_FN_GPL(name)		EXPORT_SYMBOL_GPL(name)
-#define EXPORT_PM_FN_NS_GPL(name, ns)	EXPORT_SYMBOL_NS_GPL(name, ns)
-#else
-#define _EXPORT_DEV_PM_OPS(name, license, ns)				\
+
+#define _DISCARD_PM_OPS(name, license, ns)				\
 	static __maybe_unused const struct dev_pm_ops __static_##name
+
+#ifdef CONFIG_PM
+#define _EXPORT_DEV_PM_OPS(name, license, ns)		_EXPORT_PM_OPS(name, license, ns)
+#define EXPORT_PM_FN_GPL(name)				EXPORT_SYMBOL_GPL(name)
+#define EXPORT_PM_FN_NS_GPL(name, ns)			EXPORT_SYMBOL_NS_GPL(name, ns)
+#else
+#define _EXPORT_DEV_PM_OPS(name, license, ns)		_DISCARD_PM_OPS(name, license, ns)
 #define EXPORT_PM_FN_GPL(name)
 #define EXPORT_PM_FN_NS_GPL(name, ns)
 #endif
 
-#define EXPORT_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "", "")
-#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "GPL", "")
-#define EXPORT_NS_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "", #ns)
-#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "GPL", #ns)
+#ifdef CONFIG_PM_SLEEP
+#define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns)	_EXPORT_PM_OPS(name, license, ns)
+#else
+#define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns)	_DISCARD_PM_OPS(name, license, ns)
+#endif
+
+#define EXPORT_DEV_PM_OPS(name)				_EXPORT_DEV_PM_OPS(name, "", "")
+#define EXPORT_GPL_DEV_PM_OPS(name)			_EXPORT_DEV_PM_OPS(name, "GPL", "")
+#define EXPORT_NS_DEV_PM_OPS(name, ns)			_EXPORT_DEV_PM_OPS(name, "", #ns)
+#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns)		_EXPORT_DEV_PM_OPS(name, "GPL", #ns)
+
+#define EXPORT_DEV_SLEEP_PM_OPS(name)			_EXPORT_DEV_SLEEP_PM_OPS(name, "", "")
+#define EXPORT_GPL_DEV_SLEEP_PM_OPS(name)		_EXPORT_DEV_SLEEP_PM_OPS(name, "GPL", "")
+#define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)		_EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
+#define EXPORT_NS_GPL_DEV_SLEEP_PM_OPS(name, ns)	_EXPORT_DEV_SLEEP_PM_OPS(name, "GPL", #ns)
 
 /*
  * Use this if you want to use the same suspend and resume callbacks for suspend
@@ -404,19 +419,19 @@ const struct dev_pm_ops name = { \
 	_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)
 
 #define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
-	EXPORT_DEV_PM_OPS(name) = { \
+	EXPORT_DEV_SLEEP_PM_OPS(name) = { \
 		SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
 	}
 #define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
-	EXPORT_GPL_DEV_PM_OPS(name) = { \
+	EXPORT_GPL_DEV_SLEEP_PM_OPS(name) = { \
 		SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
 	}
 #define EXPORT_NS_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns)	\
-	EXPORT_NS_DEV_PM_OPS(name, ns) = { \
+	EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
 		SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
 	}
 #define EXPORT_NS_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns)	\
-	EXPORT_NS_GPL_DEV_PM_OPS(name, ns) = { \
+	EXPORT_NS_GPL_DEV_SLEEP_PM_OPS(name, ns) = { \
 		SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
 	}
 
Signature · 1 line
2.42.0
author maintainer
#80 lore raw

PATCH 80/550 cpufreq: tegra194: fix warning due to missing opp_put

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sumit Gupta <[email protected]>

[ Upstream commit bae8222a6c291dbe58c908dab5c2abd3a75d0d63 ]

Fix the warning due to missing dev_pm_opp_put() call and hence wrong refcount value. This causes below warning message when trying to remove the module.

 Call trace:
  dev_pm_opp_put_opp_table+0x154/0x15c
  dev_pm_opp_remove_table+0x34/0xa0
  _dev_pm_opp_cpumask_remove_table+0x7c/0xbc
  dev_pm_opp_of_cpumask_remove_table+0x10/0x18
  tegra194_cpufreq_exit+0x24/0x34 [tegra194_cpufreq]
  cpufreq_remove_dev+0xa8/0xf8
  subsys_interface_unregister+0x90/0xe8
  cpufreq_unregister_driver+0x54/0x9c
  tegra194_cpufreq_remove+0x18/0x2c [tegra194_cpufreq]
  platform_remove+0x24/0x74
  device_remove+0x48/0x78
  device_release_driver_internal+0xc8/0x160
  driver_detach+0x4c/0x90
  bus_remove_driver+0x68/0xb8
  driver_unregister+0x2c/0x58
  platform_driver_unregister+0x10/0x18
  tegra194_ccplex_driver_exit+0x14/0x1e0 [tegra194_cpufreq]
  __arm64_sys_delete_module+0x184/0x270
Fixes f41e1442ac5b ("cpufreq: tegra194: add OPP support and set bandwidth")
[ Viresh: Add a blank line ]
---
 drivers/cpufreq/tegra194-cpufreq.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/cpufreq/tegra194-cpufreq.c +2 -0
index 75f1e611d0aab..f7b193b195dc9 100644
@@ -450,6 +450,8 @@ static int tegra_cpufreq_init_cpufreq_table(struct cpufreq_policy *policy,
 		if (IS_ERR(opp))
 			continue;
 
+		dev_pm_opp_put(opp);
+
 		ret = dev_pm_opp_enable(cpu_dev, pos->frequency * KHZ);
 		if (ret < 0)
 			return ret;
Signature · 1 line
2.42.0
author maintainer
#81 lore raw

PATCH 81/550 wifi: mt76: mt7603: rework/fix rx pse hang check

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

[ Upstream commit baa19b2e4b7bbb509a7ca7939c8785477dcd40ee ]

It turns out that the code in mt7603_rx_pse_busy() does not detect actual hardware hangs, it only checks for busy conditions in PSE.
A reset should only be performed if these conditions are true and if there is no rx activity as well.
Reset the counter whenever a rx interrupt occurs. In order to also deal with a fully loaded CPU that leaves interrupts disabled with continuous NAPI polling, also check for pending rx interrupts in the function itself.

Fixes c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688")
---
 .../net/wireless/mediatek/mt76/mt7603/core.c  |  2 ++
 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 23 +++++++++++++------
 2 files changed, 18 insertions(+), 7 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/core.c +2 -0
index 60a996b63c0c0..915b8349146af 100644
@@ -42,11 +42,13 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance)
 	}
 
 	if (intr & MT_INT_RX_DONE(0)) {
+		dev->rx_pse_check = 0;
 		mt7603_irq_disable(dev, MT_INT_RX_DONE(0));
 		napi_schedule(&dev->mt76.napi[0]);
 	}
 
 	if (intr & MT_INT_RX_DONE(1)) {
+		dev->rx_pse_check = 0;
 		mt7603_irq_disable(dev, MT_INT_RX_DONE(1));
 		napi_schedule(&dev->mt76.napi[1]);
 	}
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +16 -7
index 12e0af52082a6..05cdb970b3d8b 100644
@@ -1559,20 +1559,29 @@ static bool mt7603_rx_pse_busy(struct mt7603_dev *dev)
 {
 	u32 addr, val;
 
-	if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES)
-		return true;
-
 	if (mt7603_rx_fifo_busy(dev))
-		return false;
+		goto out;
 
 	addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS);
 	mt76_wr(dev, addr, 3);
 	val = mt76_rr(dev, addr) >> 16;
 
-	if (is_mt7628(dev) && (val & 0x4001) == 0x4001)
-		return true;
+	if (!(val & BIT(0)))
+		return false;
+
+	if (is_mt7628(dev))
+		val &= 0xa000;
+	else
+		val &= 0x8000;
+	if (!val)
+		return false;
+
+out:
+	if (mt76_rr(dev, MT_INT_SOURCE_CSR) &
+	    (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1)))
+		return false;
 
-	return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001;
+	return true;
 }
 
 static bool
Signature · 1 line
2.42.0
author maintainer
#82 lore raw

PATCH 82/550 wifi: mt76: mt7603: improve watchdog reset reliablity

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

[ Upstream commit c677dda165231c3efffb9de4bace249d5d2a51b9 ]

Only trigger PSE reset if PSE was stuck, otherwise it can cause DMA issues. Trigger the PSE reset while DMA is fully stopped in order to improve reliabilty.

Fixes c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688")
---
 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 29 ++++++++-----------
 1 file changed, 12 insertions(+), 17 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +12 -17
index 05cdb970b3d8b..47aefb0efd8ee 100644
@@ -1430,15 +1430,6 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
 
 	mt7603_beacon_set_timer(dev, -1, 0);
 
-	if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] ||
-	    dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY ||
-	    dev->cur_reset_cause == RESET_CAUSE_BEACON_STUCK ||
-	    dev->cur_reset_cause == RESET_CAUSE_TX_HANG)
-		mt7603_pse_reset(dev);
-
-	if (dev->reset_cause[RESET_CAUSE_RESET_FAILED])
-		goto skip_dma_reset;
-
 	mt7603_mac_stop(dev);
 
 	mt76_clear(dev, MT_WPDMA_GLO_CFG,
@@ -1448,28 +1439,32 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
 
 	mt7603_irq_disable(dev, mask);
 
-	mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_FORCE_TX_EOF);
-
 	mt7603_pse_client_reset(dev);
 
 	mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true);
 	for (i = 0; i < __MT_TXQ_MAX; i++)
 		mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
 
+	mt7603_dma_sched_reset(dev);
+
+	mt76_tx_status_check(&dev->mt76, true);
+
 	mt76_for_each_q_rx(&dev->mt76, i) {
 		mt76_queue_rx_reset(dev, i);
 	}
 
-	mt76_tx_status_check(&dev->mt76, true);
+	if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] ||
+	    dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY)
+		mt7603_pse_reset(dev);
 
-	mt7603_dma_sched_reset(dev);
+	if (!dev->reset_cause[RESET_CAUSE_RESET_FAILED]) {
+		mt7603_mac_dma_start(dev);
 
-	mt7603_mac_dma_start(dev);
+		mt7603_irq_enable(dev, mask);
 
-	mt7603_irq_enable(dev, mask);
+		clear_bit(MT76_RESET, &dev->mphy.state);
+	}
 
-skip_dma_reset:
-	clear_bit(MT76_RESET, &dev->mphy.state);
 	mutex_unlock(&dev->mt76.mutex);
 
 	mt76_worker_enable(&dev->mt76.tx_worker);
Signature · 1 line
2.42.0
author maintainer
#83 lore raw

PATCH 83/550 wifi: mt76: mt7603: improve stuck beacon handling

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

[ Upstream commit 3176205933494bd184c6acd70e796c382bc729b5 ]

Before preparing the new beacon, check the queue status, flush out all previous beacons and buffered multicast packets, then (if necessary) try to recover more gracefully from a stuck beacon condition by making a less invasive attempt at getting the MAC un-stuck.

Fixes c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688")
---
 .../wireless/mediatek/mt76/mt7603/beacon.c    | 76 ++++++++++++++-----
 .../net/wireless/mediatek/mt76/mt7603/regs.h  |  5 ++
 2 files changed, 60 insertions(+), 21 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c +55 -21
index b65b0a88c1ded..808466b7de472 100644
@@ -9,6 +9,23 @@ struct beacon_bc_data {
 	int count[MT7603_MAX_INTERFACES];
 };
 
+static void
+mt7603_mac_stuck_beacon_recovery(struct mt7603_dev *dev)
+{
+	if (dev->beacon_check % 5 != 4)
+		return;
+
+	mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN);
+	mt76_set(dev, MT_SCH_4, MT_SCH_4_RESET);
+	mt76_clear(dev, MT_SCH_4, MT_SCH_4_RESET);
+	mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN);
+
+	mt76_set(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS);
+	mt76_set(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE);
+	mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE);
+	mt76_clear(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS);
+}
+
 static void
 mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 {
@@ -16,6 +33,8 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 	struct mt76_dev *mdev = &dev->mt76;
 	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
 	struct sk_buff *skb = NULL;
+	u32 om_idx = mvif->idx;
+	u32 val;
 
 	if (!(mdev->beacon_mask & BIT(mvif->idx)))
 		return;
@@ -24,20 +43,33 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 	if (!skb)
 		return;
 
-	mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON],
-			  MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
+	if (om_idx)
+		om_idx |= 0x10;
+	val = MT_DMA_FQCR0_BUSY | MT_DMA_FQCR0_MODE |
+		FIELD_PREP(MT_DMA_FQCR0_TARGET_BSS, om_idx) |
+		FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
+		FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8);
 
 	spin_lock_bh(&dev->ps_lock);
-	mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY |
-		FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) |
-		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID,
-			   dev->mphy.q_tx[MT_TXQ_CAB]->hw_idx) |
-		FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
-		FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8));
 
-	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000))
+	mt76_wr(dev, MT_DMA_FQCR0, val |
+		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN));
+	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
 		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		goto out;
+	}
+
+	mt76_wr(dev, MT_DMA_FQCR0, val |
+		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC));
+	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
+		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		goto out;
+	}
 
+	mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON],
+			  MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
+
+out:
 	spin_unlock_bh(&dev->ps_lock);
 }
 
@@ -81,6 +113,18 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
 	data.dev = dev;
 	__skb_queue_head_init(&data.q);
 
+	/* Flush all previous CAB queue packets and beacons */
+	mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
+
+	mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false);
+	mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false);
+
+	if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > 0)
+		dev->beacon_check++;
+	else
+		dev->beacon_check = 0;
+	mt7603_mac_stuck_beacon_recovery(dev);
+
 	q = dev->mphy.q_tx[MT_TXQ_BEACON];
 	spin_lock(&q->lock);
 	ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
@@ -89,14 +133,9 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
 	mt76_queue_kick(dev, q);
 	spin_unlock(&q->lock);
 
-	/* Flush all previous CAB queue packets */
-	mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
-
-	mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false);
-
 	mt76_csa_check(mdev);
 	if (mdev->csa_complete)
-		goto out;
+		return;
 
 	q = dev->mphy.q_tx[MT_TXQ_CAB];
 	do {
@@ -108,7 +147,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
 		 skb_queue_len(&data.q) < 8);
 
 	if (skb_queue_empty(&data.q))
-		goto out;
+		return;
 
 	for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
 		if (!data.tail[i])
@@ -136,11 +175,6 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
 		MT_WF_ARB_CAB_START_BSSn(0) |
 		(MT_WF_ARB_CAB_START_BSS0n(1) *
 		 ((1 << (MT7603_MAX_INTERFACES - 1)) - 1)));
-
-out:
-	mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false);
-	if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > hweight8(mdev->beacon_mask))
-		dev->beacon_check++;
 }
 
 void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval)
drivers/net/wireless/mediatek/mt76/mt7603/regs.h +5 -0
index 3b901090b29c6..9b84db233aceb 100644
@@ -462,6 +462,11 @@ enum {
 #define MT_WF_SEC_BASE			0x21a00
 #define MT_WF_SEC(ofs)			(MT_WF_SEC_BASE + (ofs))
 
+#define MT_WF_CFG_OFF_BASE		0x21e00
+#define MT_WF_CFG_OFF(ofs)		(MT_WF_CFG_OFF_BASE + (ofs))
+#define MT_WF_CFG_OFF_WOCCR		MT_WF_CFG_OFF(0x004)
+#define MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS	BIT(4)
+
 #define MT_SEC_SCR			MT_WF_SEC(0x004)
 #define MT_SEC_SCR_MASK_ORDER		GENMASK(1, 0)
 
Signature · 1 line
2.42.0
author maintainer
#84 lore raw

PATCH 84/550 wifi: mt76: connac: move connac3 definitions in mt76_connac3_mac.h

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lorenzo Bianconi <[email protected]>

[ Upstream commit 4e9011fcdfc4f325df1661e600a0dcd9064c2bd9 ]

Connac3 mac definitions are shared between WiFi7 chipsets so move them in mt76_connac3_mac.h

Stable-dep-of: bde2e77f7626 ("wifi: mt76: mt7996: set correct wcid in txp")

---
 .../wireless/mediatek/mt76/mt76_connac3_mac.h | 325 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7996/mac.h   | 315 +----------------
 2 files changed, 326 insertions(+), 314 deletions(-)
 create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h new file +325 -0
new file mode 100644
index 0000000000000..6663a0b46541a
@@ -0,0 +1,325 @@
+/* SPDX-License-Identifier: ISC */
+/* Copyright (C) 2023 MediaTek Inc. */
+
+#ifndef __MT76_CONNAC3_MAC_H
+#define __MT76_CONNAC3_MAC_H
+
+#define MT_CT_PARSE_LEN			72
+#define MT_CT_DMA_BUF_NUM		2
+
+#define MT_RXD0_LENGTH			GENMASK(15, 0)
+#define MT_RXD0_PKT_FLAG                GENMASK(19, 16)
+#define MT_RXD0_PKT_TYPE		GENMASK(31, 27)
+
+#define MT_RXD0_MESH			BIT(18)
+#define MT_RXD0_MHCP			BIT(19)
+#define MT_RXD0_NORMAL_ETH_TYPE_OFS	GENMASK(22, 16)
+#define MT_RXD0_NORMAL_IP_SUM		BIT(23)
+#define MT_RXD0_NORMAL_UDP_TCP_SUM	BIT(24)
+
+#define MT_RXD0_SW_PKT_TYPE_MASK	GENMASK(31, 16)
+#define MT_RXD0_SW_PKT_TYPE_MAP		0x380F
+#define MT_RXD0_SW_PKT_TYPE_FRAME	0x3801
+
+/* RXD DW1 */
+#define MT_RXD1_NORMAL_WLAN_IDX		GENMASK(11, 0)
+#define MT_RXD1_NORMAL_GROUP_1		BIT(16)
+#define MT_RXD1_NORMAL_GROUP_2		BIT(17)
+#define MT_RXD1_NORMAL_GROUP_3		BIT(18)
+#define MT_RXD1_NORMAL_GROUP_4		BIT(19)
+#define MT_RXD1_NORMAL_GROUP_5		BIT(20)
+#define MT_RXD1_NORMAL_KEY_ID		GENMASK(22, 21)
+#define MT_RXD1_NORMAL_CM		BIT(23)
+#define MT_RXD1_NORMAL_CLM		BIT(24)
+#define MT_RXD1_NORMAL_ICV_ERR		BIT(25)
+#define MT_RXD1_NORMAL_TKIP_MIC_ERR	BIT(26)
+#define MT_RXD1_NORMAL_BAND_IDX		GENMASK(28, 27)
+#define MT_RXD1_NORMAL_SPP_EN		BIT(29)
+#define MT_RXD1_NORMAL_ADD_OM		BIT(30)
+#define MT_RXD1_NORMAL_SEC_DONE		BIT(31)
+
+/* RXD DW2 */
+#define MT_RXD2_NORMAL_BSSID		GENMASK(5, 0)
+#define MT_RXD2_NORMAL_MAC_HDR_LEN	GENMASK(12, 8)
+#define MT_RXD2_NORMAL_HDR_TRANS	BIT(7)
+#define MT_RXD2_NORMAL_HDR_OFFSET	GENMASK(15, 13)
+#define MT_RXD2_NORMAL_SEC_MODE		GENMASK(20, 16)
+#define MT_RXD2_NORMAL_MU_BAR		BIT(21)
+#define MT_RXD2_NORMAL_SW_BIT		BIT(22)
+#define MT_RXD2_NORMAL_AMSDU_ERR	BIT(23)
+#define MT_RXD2_NORMAL_MAX_LEN_ERROR	BIT(24)
+#define MT_RXD2_NORMAL_HDR_TRANS_ERROR	BIT(25)
+#define MT_RXD2_NORMAL_INT_FRAME	BIT(26)
+#define MT_RXD2_NORMAL_FRAG		BIT(27)
+#define MT_RXD2_NORMAL_NULL_FRAME	BIT(28)
+#define MT_RXD2_NORMAL_NDATA		BIT(29)
+#define MT_RXD2_NORMAL_NON_AMPDU	BIT(30)
+#define MT_RXD2_NORMAL_BF_REPORT	BIT(31)
+
+/* RXD DW3 */
+#define MT_RXD3_NORMAL_RXV_SEQ		GENMASK(7, 0)
+#define MT_RXD3_NORMAL_CH_FREQ		GENMASK(15, 8)
+#define MT_RXD3_NORMAL_ADDR_TYPE	GENMASK(17, 16)
+#define MT_RXD3_NORMAL_U2M		BIT(0)
+#define MT_RXD3_NORMAL_HTC_VLD		BIT(18)
+#define MT_RXD3_NORMAL_BEACON_MC	BIT(20)
+#define MT_RXD3_NORMAL_BEACON_UC	BIT(21)
+#define MT_RXD3_NORMAL_CO_ANT		BIT(22)
+#define MT_RXD3_NORMAL_FCS_ERR		BIT(24)
+#define MT_RXD3_NORMAL_VLAN2ETH		BIT(31)
+
+/* RXD DW4 */
+#define MT_RXD4_NORMAL_PAYLOAD_FORMAT	GENMASK(1, 0)
+#define MT_RXD4_FIRST_AMSDU_FRAME	GENMASK(1, 0)
+#define MT_RXD4_MID_AMSDU_FRAME		BIT(1)
+#define MT_RXD4_LAST_AMSDU_FRAME	BIT(0)
+
+#define MT_RXV_HDR_BAND_IDX		BIT(24)
+
+/* RXD GROUP4 */
+#define MT_RXD8_FRAME_CONTROL		GENMASK(15, 0)
+
+#define MT_RXD10_SEQ_CTRL		GENMASK(15, 0)
+#define MT_RXD10_QOS_CTL		GENMASK(31, 16)
+
+#define MT_RXD11_HT_CONTROL		GENMASK(31, 0)
+
+/* P-RXV */
+#define MT_PRXV_TX_RATE			GENMASK(6, 0)
+#define MT_PRXV_TX_DCM			BIT(4)
+#define MT_PRXV_TX_ER_SU_106T		BIT(5)
+#define MT_PRXV_NSTS			GENMASK(10, 7)
+#define MT_PRXV_TXBF			BIT(11)
+#define MT_PRXV_HT_AD_CODE		BIT(12)
+#define MT_PRXV_HE_RU_ALLOC		GENMASK(30, 22)
+#define MT_PRXV_RCPI3			GENMASK(31, 24)
+#define MT_PRXV_RCPI2			GENMASK(23, 16)
+#define MT_PRXV_RCPI1			GENMASK(15, 8)
+#define MT_PRXV_RCPI0			GENMASK(7, 0)
+#define MT_PRXV_HT_SHORT_GI		GENMASK(4, 3)
+#define MT_PRXV_HT_STBC			GENMASK(10, 9)
+#define MT_PRXV_TX_MODE			GENMASK(14, 11)
+#define MT_PRXV_FRAME_MODE		GENMASK(2, 0)
+#define MT_PRXV_DCM			BIT(5)
+
+/* C-RXV */
+#define MT_CRXV_HE_NUM_USER		GENMASK(26, 20)
+#define MT_CRXV_HE_LTF_SIZE		GENMASK(28, 27)
+#define MT_CRXV_HE_LDPC_EXT_SYM		BIT(30)
+
+#define MT_CRXV_HE_PE_DISAMBIG		BIT(1)
+#define MT_CRXV_HE_UPLINK		BIT(2)
+
+#define MT_CRXV_HE_MU_AID		GENMASK(27, 17)
+#define MT_CRXV_HE_BEAM_CHNG		BIT(29)
+
+#define MT_CRXV_HE_DOPPLER		BIT(0)
+#define MT_CRXV_HE_BSS_COLOR		GENMASK(15, 10)
+#define MT_CRXV_HE_TXOP_DUR		GENMASK(19, 17)
+
+#define MT_CRXV_HE_SR_MASK		GENMASK(11, 8)
+#define MT_CRXV_HE_SR1_MASK		GENMASK(16, 12)
+#define MT_CRXV_HE_SR2_MASK             GENMASK(20, 17)
+#define MT_CRXV_HE_SR3_MASK             GENMASK(24, 21)
+
+#define MT_CRXV_HE_RU0			GENMASK(8, 0)
+#define MT_CRXV_HE_RU1			GENMASK(17, 9)
+#define MT_CRXV_HE_RU2			GENMASK(26, 18)
+#define MT_CRXV_HE_RU3_L		GENMASK(31, 27)
+#define MT_CRXV_HE_RU3_H		GENMASK(3, 0)
+
+enum tx_header_format {
+	MT_HDR_FORMAT_802_3,
+	MT_HDR_FORMAT_CMD,
+	MT_HDR_FORMAT_802_11,
+	MT_HDR_FORMAT_802_11_EXT,
+};
+
+enum tx_pkt_type {
+	MT_TX_TYPE_CT,
+	MT_TX_TYPE_SF,
+	MT_TX_TYPE_CMD,
+	MT_TX_TYPE_FW,
+};
+
+enum tx_port_idx {
+	MT_TX_PORT_IDX_LMAC,
+	MT_TX_PORT_IDX_MCU
+};
+
+enum tx_mcu_port_q_idx {
+	MT_TX_MCU_PORT_RX_Q0 = 0x20,
+	MT_TX_MCU_PORT_RX_Q1,
+	MT_TX_MCU_PORT_RX_Q2,
+	MT_TX_MCU_PORT_RX_Q3,
+	MT_TX_MCU_PORT_RX_FWDL = 0x3e
+};
+
+enum tx_mgnt_type {
+	MT_TX_NORMAL,
+	MT_TX_TIMING,
+	MT_TX_ADDBA,
+};
+
+#define MT_CT_INFO_APPLY_TXD		BIT(0)
+#define MT_CT_INFO_COPY_HOST_TXD_ALL	BIT(1)
+#define MT_CT_INFO_MGMT_FRAME		BIT(2)
+#define MT_CT_INFO_NONE_CIPHER_FRAME	BIT(3)
+#define MT_CT_INFO_HSR2_TX		BIT(4)
+#define MT_CT_INFO_FROM_HOST		BIT(7)
+
+#define MT_TXD_SIZE			(8 * 4)
+
+#define MT_TXD0_Q_IDX			GENMASK(31, 25)
+#define MT_TXD0_PKT_FMT			GENMASK(24, 23)
+#define MT_TXD0_ETH_TYPE_OFFSET		GENMASK(22, 16)
+#define MT_TXD0_TX_BYTES		GENMASK(15, 0)
+
+#define MT_TXD1_FIXED_RATE		BIT(31)
+#define MT_TXD1_OWN_MAC			GENMASK(30, 25)
+#define MT_TXD1_TID			GENMASK(24, 21)
+#define MT_TXD1_BIP			BIT(24)
+#define MT_TXD1_ETH_802_3		BIT(20)
+#define MT_TXD1_HDR_INFO		GENMASK(20, 16)
+#define MT_TXD1_HDR_FORMAT		GENMASK(15, 14)
+#define MT_TXD1_TGID			GENMASK(13, 12)
+#define MT_TXD1_WLAN_IDX		GENMASK(11, 0)
+
+#define MT_TXD2_POWER_OFFSET		GENMASK(31, 26)
+#define MT_TXD2_MAX_TX_TIME		GENMASK(25, 16)
+#define MT_TXD2_FRAG			GENMASK(15, 14)
+#define MT_TXD2_HTC_VLD			BIT(13)
+#define MT_TXD2_DURATION		BIT(12)
+#define MT_TXD2_HDR_PAD			GENMASK(11, 10)
+#define MT_TXD2_RTS			BIT(9)
+#define MT_TXD2_OWN_MAC_MAP		BIT(8)
+#define MT_TXD2_BF_TYPE			GENMASK(6, 7)
+#define MT_TXD2_FRAME_TYPE		GENMASK(5, 4)
+#define MT_TXD2_SUB_TYPE		GENMASK(3, 0)
+
+#define MT_TXD3_SN_VALID		BIT(31)
+#define MT_TXD3_PN_VALID		BIT(30)
+#define MT_TXD3_SW_POWER_MGMT		BIT(29)
+#define MT_TXD3_BA_DISABLE		BIT(28)
+#define MT_TXD3_SEQ			GENMASK(27, 16)
+#define MT_TXD3_REM_TX_COUNT		GENMASK(15, 11)
+#define MT_TXD3_TX_COUNT		GENMASK(10, 6)
+#define MT_TXD3_HW_AMSDU		BIT(5)
+#define MT_TXD3_BCM			BIT(4)
+#define MT_TXD3_EEOSP			BIT(3)
+#define MT_TXD3_EMRD			BIT(2)
+#define MT_TXD3_PROTECT_FRAME		BIT(1)
+#define MT_TXD3_NO_ACK			BIT(0)
+
+#define MT_TXD4_PN_LOW			GENMASK(31, 0)
+
+#define MT_TXD5_PN_HIGH			GENMASK(31, 16)
+#define MT_TXD5_FL			BIT(15)
+#define MT_TXD5_BYPASS_TBB		BIT(14)
+#define MT_TXD5_BYPASS_RBB		BIT(13)
+#define MT_TXD5_BSS_COLOR_ZERO		BIT(12)
+#define MT_TXD5_TX_STATUS_HOST		BIT(10)
+#define MT_TXD5_TX_STATUS_MCU		BIT(9)
+#define MT_TXD5_TX_STATUS_FMT		BIT(8)
+#define MT_TXD5_PID			GENMASK(7, 0)
+
+#define MT_TXD6_TX_SRC			GENMASK(31, 30)
+#define MT_TXD6_VTA			BIT(28)
+#define MT_TXD6_BW			GENMASK(25, 22)
+#define MT_TXD6_TX_RATE			GENMASK(21, 16)
+#define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
+#define MT_TXD6_TIMESTAMP_OFS_IDX	GENMASK(14, 10)
+#define MT_TXD6_MSDU_CNT		GENMASK(9, 4)
+#define MT_TXD6_DIS_MAT			BIT(3)
+#define MT_TXD6_DAS			BIT(2)
+#define MT_TXD6_AMSDU_CAP		BIT(1)
+
+#define MT_TXD7_TXD_LEN			GENMASK(31, 30)
+#define MT_TXD7_IP_SUM			BIT(29)
+#define MT_TXD7_DROP_BY_SDO		BIT(28)
+#define MT_TXD7_MAC_TXD			BIT(27)
+#define MT_TXD7_CTXD			BIT(26)
+#define MT_TXD7_CTXD_CNT		GENMASK(25, 22)
+#define MT_TXD7_UDP_TCP_SUM		BIT(15)
+#define MT_TXD7_TX_TIME			GENMASK(9, 0)
+
+#define MT_TX_RATE_STBC			BIT(14)
+#define MT_TX_RATE_NSS			GENMASK(13, 10)
+#define MT_TX_RATE_MODE			GENMASK(9, 6)
+#define MT_TX_RATE_SU_EXT_TONE		BIT(5)
+#define MT_TX_RATE_DCM			BIT(4)
+/* VHT/HE only use bits 0-3 */
+#define MT_TX_RATE_IDX			GENMASK(5, 0)
+
+#define MT_TXFREE0_PKT_TYPE		GENMASK(31, 27)
+#define MT_TXFREE0_MSDU_CNT		GENMASK(25, 16)
+#define MT_TXFREE0_RX_BYTE		GENMASK(15, 0)
+
+#define MT_TXFREE1_VER			GENMASK(18, 16)
+
+#define MT_TXFREE_INFO_PAIR		BIT(31)
+#define MT_TXFREE_INFO_HEADER		BIT(30)
+#define MT_TXFREE_INFO_WLAN_ID		GENMASK(23, 12)
+#define MT_TXFREE_INFO_MSDU_ID		GENMASK(14, 0)
+#define MT_TXFREE_INFO_COUNT		GENMASK(27, 24)
+#define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
+
+#define MT_TXS0_BW			GENMASK(31, 29)
+#define MT_TXS0_TID			GENMASK(28, 26)
+#define MT_TXS0_AMPDU			BIT(25)
+#define MT_TXS0_TXS_FORMAT		GENMASK(24, 23)
+#define MT_TXS0_BA_ERROR		BIT(22)
+#define MT_TXS0_PS_FLAG			BIT(21)
+#define MT_TXS0_TXOP_TIMEOUT		BIT(20)
+#define MT_TXS0_BIP_ERROR		BIT(19)
+
+#define MT_TXS0_QUEUE_TIMEOUT		BIT(18)
+#define MT_TXS0_RTS_TIMEOUT		BIT(17)
+#define MT_TXS0_ACK_TIMEOUT		BIT(16)
+#define MT_TXS0_ACK_ERROR_MASK		GENMASK(18, 16)
+
+#define MT_TXS0_TX_STATUS_HOST		BIT(15)
+#define MT_TXS0_TX_STATUS_MCU		BIT(14)
+#define MT_TXS0_TX_RATE			GENMASK(13, 0)
+
+#define MT_TXS1_SEQNO			GENMASK(31, 20)
+#define MT_TXS1_RESP_RATE		GENMASK(19, 16)
+#define MT_TXS1_RXV_SEQNO		GENMASK(15, 8)
+#define MT_TXS1_TX_POWER_DBM		GENMASK(7, 0)
+
+#define MT_TXS2_BF_STATUS		GENMASK(31, 30)
+#define MT_TXS2_BAND			GENMASK(29, 28)
+#define MT_TXS2_WCID			GENMASK(27, 16)
+#define MT_TXS2_TX_DELAY		GENMASK(15, 0)
+
+#define MT_TXS3_PID			GENMASK(31, 24)
+#define MT_TXS3_RATE_STBC		BIT(7)
+#define MT_TXS3_FIXED_RATE		BIT(6)
+#define MT_TXS3_SRC			GENMASK(5, 4)
+#define MT_TXS3_SHARED_ANTENNA		BIT(3)
+#define MT_TXS3_LAST_TX_RATE		GENMASK(2, 0)
+
+#define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
+
+#define MT_TXS5_F0_FINAL_MPDU		BIT(31)
+#define MT_TXS5_F0_QOS			BIT(30)
+#define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
+#define MT_TXS5_F0_FRONT_TIME		GENMASK(24, 0)
+#define MT_TXS5_F1_MPDU_TX_COUNT	GENMASK(31, 24)
+#define MT_TXS5_F1_MPDU_TX_BYTES	GENMASK(23, 0)
+
+#define MT_TXS6_F0_NOISE_3		GENMASK(31, 24)
+#define MT_TXS6_F0_NOISE_2		GENMASK(23, 16)
+#define MT_TXS6_F0_NOISE_1		GENMASK(15, 8)
+#define MT_TXS6_F0_NOISE_0		GENMASK(7, 0)
+#define MT_TXS6_F1_MPDU_FAIL_COUNT	GENMASK(31, 24)
+#define MT_TXS6_F1_MPDU_FAIL_BYTES	GENMASK(23, 0)
+
+#define MT_TXS7_F0_RCPI_3		GENMASK(31, 24)
+#define MT_TXS7_F0_RCPI_2		GENMASK(23, 16)
+#define MT_TXS7_F0_RCPI_1		GENMASK(15, 8)
+#define MT_TXS7_F0_RCPI_0		GENMASK(7, 0)
+#define MT_TXS7_F1_MPDU_RETRY_COUNT	GENMASK(31, 24)
+#define MT_TXS7_F1_MPDU_RETRY_BYTES	GENMASK(23, 0)
+
+#endif /* __MT76_CONNAC3_MAC_H */
drivers/net/wireless/mediatek/mt76/mt7996/mac.h +1 -314

321 lines not on this page · raw message

Signature · 1 line
2.42.0
author maintainer
#85 lore raw

PATCH 85/550 wifi: mt76: remove unused error path in mt76_connac_tx_complete_skb

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

[ Upstream commit 832f42699791e7a90e81c15da0ce886b4f8300b8 ]

The error handling code was added in order to allow tx enqueue to fail after calling .tx_prepare_skb. Since this can no longer happen, the error handling code is unused.

Stable-dep-of: bde2e77f7626 ("wifi: mt76: mt7996: set correct wcid in txp")

---
 drivers/net/wireless/mediatek/mt76/dma.c        |  3 ---
 .../net/wireless/mediatek/mt76/mt7615/pci_mac.c |  2 +-
 .../wireless/mediatek/mt76/mt76_connac_mac.c    | 17 -----------------
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c |  2 +-
 .../net/wireless/mediatek/mt76/mt7921/pci_mac.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c |  2 +-
 6 files changed, 4 insertions(+), 24 deletions(-)
drivers/net/wireless/mediatek/mt76/dma.c +0 -3
index f539913aadf86..e57ce25f3d816 100644
@@ -330,9 +330,6 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
 	if (e->txwi == DMA_DUMMY_DATA)
 		e->txwi = NULL;
 
-	if (e->skb == DMA_DUMMY_DATA)
-		e->skb = NULL;
-
 	*prev_e = *e;
 	memset(e, 0, sizeof(*e));
 }
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +1 -1
index 0019890fdb784..fbb1181c58ff3 100644
@@ -106,7 +106,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	else
 		mt76_connac_write_hw_txp(mdev, tx_info, txp, id);
 
-	tx_info->skb = DMA_DUMMY_DATA;
+	tx_info->skb = NULL;
 
 	return 0;
 }
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +0 -17
index e415ac5e321f1..a800c071537f8 100644
@@ -151,23 +151,6 @@ void mt76_connac_tx_complete_skb(struct mt76_dev *mdev,
 		return;
 	}
 
-	/* error path */
-	if (e->skb == DMA_DUMMY_DATA) {
-		struct mt76_connac_txp_common *txp;
-		struct mt76_txwi_cache *t;
-		u16 token;
-
-		txp = mt76_connac_txwi_to_txp(mdev, e->txwi);
-		if (is_mt76_fw_txp(mdev))
-			token = le16_to_cpu(txp->fw.token);
-		else
-			token = le16_to_cpu(txp->hw.msdu_id[0]) &
-				~MT_MSDU_ID_VALID;
-
-		t = mt76_token_put(mdev, token);
-		e->skb = t ? t->skb : NULL;
-	}
-
 	if (e->skb)
 		mt76_tx_complete_skb(mdev, e->wcid, e->skb);
 }
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
index 7df8d95fc3fbc..13071df3f6c21 100644
@@ -808,7 +808,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 		txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
 	else
 		txp->rept_wds_wcid = cpu_to_le16(0x3ff);
-	tx_info->skb = DMA_DUMMY_DATA;
+	tx_info->skb = NULL;
 
 	/* pass partial skb header to fw */
 	tx_info->buf[1].len = MT_CT_PARSE_LEN;
drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +1 -1
index 6053a2556c20c..46f1360fbc59a 100644
@@ -48,7 +48,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	memset(txp, 0, sizeof(struct mt76_connac_hw_txp));
 	mt76_connac_write_hw_txp(mdev, tx_info, txp, id);
 
-	tx_info->skb = DMA_DUMMY_DATA;
+	tx_info->skb = NULL;
 
 	return 0;
 }
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +1 -1
index 25c5deb15d213..b18fa4153aeb2 100644
@@ -1172,7 +1172,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 		txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
 	else
 		txp->fw.rept_wds_wcid = cpu_to_le16(0xfff);
-	tx_info->skb = DMA_DUMMY_DATA;
+	tx_info->skb = NULL;
 
 	/* pass partial skb header to fw */
 	tx_info->buf[1].len = MT_CT_PARSE_LEN;
Signature · 1 line
2.42.0
author maintainer
#86 lore raw

PATCH 86/550 wifi: mt76: mt7996: set correct wcid in txp

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Chiu <[email protected]>

[ Upstream commit bde2e77f76266fbd81ff74cb12b3d87f9460b1e0 ]

Set correct wcid in txp to let the SDO hw module look into the correct wtbl, otherwise the tx descriptor may be wrongly fiiled. This patch also fixed the issue that driver could not correctly report sta statistics, especially in WDS mode, which misled AQL.

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h | 2 ++
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c       | 8 +++-----
 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2 -0
index 6663a0b46541a..a6d8e59a2b60e 100644
@@ -243,6 +243,8 @@ enum tx_mgnt_type {
 #define MT_TXD7_UDP_TCP_SUM		BIT(15)
 #define MT_TXD7_TX_TIME			GENMASK(9, 0)
 
+#define MT_TXD9_WLAN_IDX		GENMASK(23, 8)
+
 #define MT_TX_RATE_STBC			BIT(14)
 #define MT_TX_RATE_NSS			GENMASK(13, 10)
 #define MT_TX_RATE_MODE			GENMASK(9, 6)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +3 -5
index b18fa4153aeb2..7da3baecc6de2 100644
@@ -1168,10 +1168,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	}
 
 	txp->fw.token = cpu_to_le16(id);
-	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
-		txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
-	else
-		txp->fw.rept_wds_wcid = cpu_to_le16(0xfff);
+	txp->fw.rept_wds_wcid = cpu_to_le16(sta ? wcid->idx : 0xfff);
+
 	tx_info->skb = NULL;
 
 	/* pass partial skb header to fw */
@@ -1228,7 +1226,7 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
 		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
 			mt7996_tx_check_aggr(sta, txwi);
 	} else {
-		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+		wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX);
 	}
 
 	__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
Signature · 1 line
2.42.0
author maintainer
#87 lore raw

PATCH 87/550 wifi: mt76: mt7996: fix beamform mcu cmd configuration

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Howard Hsu <[email protected]>

[ Upstream commit d40fd59b7267d2e7722d3edf3935a9a9f03c0115 ]

The bf_num field represents how many bands can support beamform, so set the value to 3, and bf_bitmap represents the bitmap of bf_num.

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +2 -2
index 62a02b03d83ba..8244bb3561028 100644
@@ -3208,8 +3208,8 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)
 
 		tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en));
 		req_mod_en = (struct bf_mod_en_ctrl *)tlv;
-		req_mod_en->bf_num = 2;
-		req_mod_en->bf_bitmap = GENMASK(0, 0);
+		req_mod_en->bf_num = 3;
+		req_mod_en->bf_bitmap = GENMASK(2, 0);
 		break;
 	}
 	default:
Signature · 1 line
2.42.0
author maintainer
#88 lore raw

PATCH 88/550 wifi: mt76: mt7996: fix beamformee ss subfield in EHT PHY cap

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Howard Hsu <[email protected]>

[ Upstream commit e19028104b2de5510b43282f632c4b6453568c41 ]

According to P802.11be_D3.2 Table 9-404m, the minimum value of Beamformee SS field shall be 3. Fix the values to follow the spec.

Fixes 348533eb968d ("wifi: mt76: mt7996: add EHT capability init")
---
 drivers/net/wireless/mediatek/mt76/mt7996/init.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/init.c +5 -4
index f1b48cdda58f3..f7344d4c7383a 100644
@@ -729,16 +729,17 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
 
+	val = max_t(u8, sts - 1, 3);
 	eht_cap_elem->phy_cap_info[0] |=
-		u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
+		u8_encode_bits(u8_get_bits(val, BIT(0)),
 			       IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
 
 	eht_cap_elem->phy_cap_info[1] =
-		u8_encode_bits(u8_get_bits(sts - 1, GENMASK(2, 1)),
+		u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)),
 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) |
-		u8_encode_bits(sts - 1,
+		u8_encode_bits(val,
 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK) |
-		u8_encode_bits(sts - 1,
+		u8_encode_bits(val,
 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
 
 	eht_cap_elem->phy_cap_info[2] =
Signature · 1 line
2.42.0
author maintainer
#89 lore raw

PATCH 89/550 wifi: mt76: mt7996: fix wmm queue mapping

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Chiu <[email protected]>

[ Upstream commit 9b11696e5c5bf6030a32571f3f88845226d8b662 ]

Firmware uses access class index (ACI) for wmm parameters update, so convert mac80211 queue to ACI in mt7996_conf_tx().

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7996/main.c | 12 +++++++++---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c  |  2 +-
 2 files changed, 10 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +9 -3
index f306e9c50ea3b..16db03e86d7a2 100644
@@ -184,7 +184,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
 	mvif->mt76.omac_idx = idx;
 	mvif->phy = phy;
 	mvif->mt76.band_idx = band_idx;
-	mvif->mt76.wmm_idx = band_idx;
+	mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
 
 	ret = mt7996_mcu_add_dev_info(phy, vif, true);
 	if (ret)
@@ -414,10 +414,16 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	       const struct ieee80211_tx_queue_params *params)
 {
 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+	const u8 mq_to_aci[] = {
+		[IEEE80211_AC_VO] = 3,
+		[IEEE80211_AC_VI] = 2,
+		[IEEE80211_AC_BE] = 0,
+		[IEEE80211_AC_BK] = 1,
+	};
 
+	/* firmware uses access class index */
+	mvif->queue_params[mq_to_aci[queue]] = *params;
 	/* no need to update right away, we'll get BSS_CHANGED_QOS */
-	queue = mt76_connac_lmac_mapping(queue);
-	mvif->queue_params[queue] = *params;
 
 	return 0;
 }
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +1 -1
index 8244bb3561028..6520761d9fe13 100644
@@ -2580,7 +2580,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif)
 
 		e = (struct edca *)tlv;
 		e->set = WMM_PARAM_SET;
-		e->queue = ac + mvif->mt76.wmm_idx * MT7996_MAX_WMM_SETS;
+		e->queue = ac;
 		e->aifs = q->aifs;
 		e->txop = cpu_to_le16(q->txop);
 
Signature · 1 line
2.42.0
author maintainer
#90 lore raw

PATCH 90/550 wifi: mt76: mt7996: fix rx rate report for CBW320-2

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Chiu <[email protected]>

[ Upstream commit 0197923ecf5eb4dbd785f5576040d49611f591a4 ]

RX vector reports channel bandwidth 320-1 and 320-2 with different values. Fix it to correctly report rx rate when using CBW320-2.

Fixes 80f5a31d2856 ("wifi: mt76: mt7996: add support for EHT rate report")
---
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +2 -0
index 7da3baecc6de2..37104e84db886 100644
@@ -611,7 +611,9 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
 	case IEEE80211_STA_RX_BW_160:
 		status->bw = RATE_INFO_BW_160;
 		break;
+	/* rxv reports bw 320-1 and 320-2 separately */
 	case IEEE80211_STA_RX_BW_320:
+	case IEEE80211_STA_RX_BW_320 + 1:
 		status->bw = RATE_INFO_BW_320;
 		break;
 	default:
Signature · 1 line
2.42.0
author maintainer
#91 lore raw

PATCH 91/550 wifi: mt76: mt7996: fix TWT command format

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Chiu <[email protected]>

[ Upstream commit 84f313b7392f6501f05d8981105d79859b1252cb ]

Align the command format of UNI_CMD_TWT_ARGT_UPDATE to firmware.

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +5 -2
index 6520761d9fe13..fbf9a5c3b98ee 100644
@@ -3449,7 +3449,9 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
 			       int cmd)
 {
 	struct {
-		u8 _rsv[4];
+		/* fixed field */
+		u8 bss;
+		u8 _rsv[3];
 
 		__le16 tag;
 		__le16 len;
@@ -3467,7 +3469,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
 		u8 exponent;
 		u8 is_ap;
 		u8 agrt_params;
-		u8 __rsv2[135];
+		u8 __rsv2[23];
 	} __packed req = {
 		.tag = cpu_to_le16(UNI_CMD_TWT_ARGT_UPDATE),
 		.len = cpu_to_le16(sizeof(req) - 4),
@@ -3477,6 +3479,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
 		.flowid = flow->id,
 		.peer_id = cpu_to_le16(flow->wcid),
 		.duration = flow->duration,
+		.bss = mvif->mt76.idx,
 		.bss_idx = mvif->mt76.idx,
 		.start_tsf = cpu_to_le64(flow->tsf),
 		.mantissa = flow->mantissa,
Signature · 1 line
2.42.0
author maintainer
#92 lore raw

PATCH 92/550 wifi: mt76: update beacon size limitation

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: MeiChia Chiu <[email protected]>

[ Upstream commit de869f81f994c4a4dea0d70921ac5ab78858b224 ]

To accommodate 11v MBSSID IE and support maximum 16 MBSSIDs, expand the beacon size limitation for beacon and inband discovery commands.

Stable-dep-of: d6a2f91741d9 ("wifi: mt76: fix potential memory leak of beacon commands")

---
 .../net/wireless/mediatek/mt76/mt7915/main.c  |  8 +--
 .../net/wireless/mediatek/mt76/mt7915/mcu.c   | 49 +++++++++++--------
 .../net/wireless/mediatek/mt76/mt7915/mcu.h   | 18 +++----
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |  2 +
 .../net/wireless/mediatek/mt76/mt7996/main.c  |  4 +-
 .../net/wireless/mediatek/mt76/mt7996/mcu.c   | 38 ++++++++------
 .../net/wireless/mediatek/mt76/mt7996/mcu.h   | 11 ++---
 7 files changed, 72 insertions(+), 58 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/main.c +5 -3
index 42a983e40ade9..b39ccfc641579 100644
@@ -646,11 +646,13 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
 		mt7915_update_bss_color(hw, vif, &info->he_bss_color);
 
 	if (changed & (BSS_CHANGED_BEACON |
-		       BSS_CHANGED_BEACON_ENABLED |
-		       BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
-		       BSS_CHANGED_FILS_DISCOVERY))
+		       BSS_CHANGED_BEACON_ENABLED))
 		mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
 
+	if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
+		       BSS_CHANGED_FILS_DISCOVERY))
+		mt7915_mcu_add_inband_discov(dev, vif, changed);
+
 	if (set_bss_info == 0)
 		mt7915_mcu_add_bss_info(phy, vif, false);
 	if (set_sta == 0)
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +29 -20

110 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +8 -10
index b9ea297f382c3..1592b5d6751a0 100644
@@ -495,10 +495,14 @@ enum {
 	SER_RECOVER
 };
 
-#define MT7915_MAX_BEACON_SIZE		512
-#define MT7915_MAX_INBAND_FRAME_SIZE	256
-#define MT7915_MAX_BSS_OFFLOAD_SIZE	(MT7915_MAX_BEACON_SIZE +	  \
-					 MT7915_MAX_INBAND_FRAME_SIZE +	  \
+#define MT7915_MAX_BEACON_SIZE		1308
+#define MT7915_BEACON_UPDATE_SIZE	(sizeof(struct sta_req_hdr) +	\
+					 sizeof(struct bss_info_bcn) +	\
+					 sizeof(struct bss_info_bcn_cntdwn) +	\
+					 sizeof(struct bss_info_bcn_mbss) +	\
+					 MT_TXD_SIZE +	\
+					 sizeof(struct bss_info_bcn_cont))
+#define MT7915_MAX_BSS_OFFLOAD_SIZE	(MT7915_MAX_BEACON_SIZE +	\
 					 MT7915_BEACON_UPDATE_SIZE)
 
 #define MT7915_BSS_UPDATE_MAX_SIZE	(sizeof(struct sta_req_hdr) +	\
@@ -511,12 +515,6 @@ enum {
 					 sizeof(struct bss_info_bmc_rate) +\
 					 sizeof(struct bss_info_ext_bss))
 
-#define MT7915_BEACON_UPDATE_SIZE	(sizeof(struct sta_req_hdr) +	\
-					 sizeof(struct bss_info_bcn_cntdwn) + \
-					 sizeof(struct bss_info_bcn_mbss) + \
-					 sizeof(struct bss_info_bcn_cont) + \
-					 sizeof(struct bss_info_inband_discovery))
-
 static inline s8
 mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
 {
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +2 -0
index 0f76733c9c1ac..ed92605059b0c 100644
@@ -505,6 +505,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
 			 bool add);
 int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
 				struct cfg80211_he_bss_color *he_bss_color);
+int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+				 u32 changed);
 int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			  int enable, u32 changed);
 int mt7915_mcu_add_obss_spr(struct mt7915_phy *phy, struct ieee80211_vif *vif,
drivers/net/wireless/mediatek/mt76/mt7996/main.c +2 -2
index 16db03e86d7a2..623a240938dff 100644
@@ -604,8 +604,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
 		mt7996_mcu_add_beacon(hw, vif, info->enable_beacon);
 	}
 
-	if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
-	    changed & BSS_CHANGED_FILS_DISCOVERY)
+	if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
+		       BSS_CHANGED_FILS_DISCOVERY))
 		mt7996_mcu_beacon_inband_discov(dev, vif, changed);
 
 	mutex_unlock(&dev->mt76.mutex);
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +22 -16
index fbf9a5c3b98ee..ac06450a79512 100644
@@ -1916,7 +1916,7 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 			bcn->bcc_ie_pos = cpu_to_le16(offset - 3);
 	}
 
-	buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE;
+	buf = (u8 *)bcn + sizeof(*bcn);
 	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
 			      BSS_CHANGED_BEACON);
 
@@ -1934,25 +1934,18 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
 	struct sk_buff *skb, *rskb;
 	struct tlv *tlv;
 	struct bss_bcn_content_tlv *bcn;
+	int len;
 
 	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
-					  MT7996_BEACON_UPDATE_SIZE);
+					  MT7996_MAX_BSS_OFFLOAD_SIZE);
 	if (IS_ERR(rskb))
 		return PTR_ERR(rskb);
 
-	tlv = mt7996_mcu_add_uni_tlv(rskb,
-				     UNI_BSS_INFO_BCN_CONTENT, sizeof(*bcn));
-	bcn = (struct bss_bcn_content_tlv *)tlv;
-	bcn->enable = en;
-
-	if (!en)
-		goto out;
-
 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
 	if (!skb)
 		return -EINVAL;
 
-	if (skb->len > MAX_BEACON_SIZE - MT_TXD_SIZE) {
+	if (skb->len > MT7996_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
 		dev_kfree_skb(skb);
 		return -EINVAL;
@@ -1961,11 +1954,18 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
 	info = IEEE80211_SKB_CB(skb);
 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
 
+	len = sizeof(*bcn) + MT_TXD_SIZE + skb->len;
+	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);
+	bcn = (struct bss_bcn_content_tlv *)tlv;
+	bcn->enable = en;
+	if (!en)
+		goto out;
+
 	mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
 	/* TODO: subtag - 11v MBSSID */
 	mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
-	dev_kfree_skb(skb);
 out:
+	dev_kfree_skb(skb);
 	return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
 				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
 }
@@ -1986,9 +1986,13 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
 	struct sk_buff *rskb, *skb = NULL;
 	struct tlv *tlv;
 	u8 *buf, interval;
+	int len;
+
+	if (vif->bss_conf.nontransmitted)
+		return 0;
 
 	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
-					  MT7996_INBAND_FRAME_SIZE);
+					  MT7996_MAX_BSS_OFFLOAD_SIZE);
 	if (IS_ERR(rskb))
 		return PTR_ERR(rskb);
 
@@ -2005,7 +2009,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
 	if (!skb)
 		return -EINVAL;
 
-	if (skb->len > MAX_INBAND_FRAME_SIZE - MT_TXD_SIZE) {
+	if (skb->len > MT7996_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
 		dev_kfree_skb(skb);
 		return -EINVAL;
@@ -2016,7 +2020,9 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
 	info->band = band;
 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
 
-	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, sizeof(*discov));
+	len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
+
+	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);
 
 	discov = (struct bss_inband_discovery_tlv *)tlv;
 	discov->tx_mode = OFFLOAD_TX_MODE_SU;
@@ -2027,7 +2033,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
 	discov->enable = true;
 	discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED);
 
-	buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE;
+	buf = (u8 *)tlv + sizeof(*discov);
 
 	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);
 
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +4 -7
index d7075a4d0667c..2620eaeaece04 100644
@@ -270,8 +270,6 @@ struct bss_inband_discovery_tlv {
 	u8 enable;
 	__le16 wcid;
 	__le16 prob_rsp_len;
-#define MAX_INBAND_FRAME_SIZE 512
-	u8 pkt[MAX_INBAND_FRAME_SIZE];
 } __packed;
 
 struct bss_bcn_content_tlv {
@@ -283,8 +281,6 @@ struct bss_bcn_content_tlv {
 	u8 enable;
 	u8 type;
 	__le16 pkt_len;
-#define MAX_BEACON_SIZE 512
-	u8 pkt[MAX_BEACON_SIZE];
 } __packed;
 
 struct bss_bcn_cntdwn_tlv {
@@ -574,13 +570,14 @@ enum {
 					 sizeof(struct sta_rec_hdr_trans) +	\
 					 sizeof(struct tlv))
 
+#define MT7996_MAX_BEACON_SIZE		1342
 #define MT7996_BEACON_UPDATE_SIZE	(sizeof(struct bss_req_hdr) +		\
 					 sizeof(struct bss_bcn_content_tlv) +	\
+					 MT_TXD_SIZE +				\
 					 sizeof(struct bss_bcn_cntdwn_tlv) +	\
 					 sizeof(struct bss_bcn_mbss_tlv))
-
-#define MT7996_INBAND_FRAME_SIZE	(sizeof(struct bss_req_hdr) +		\
-					 sizeof(struct bss_inband_discovery_tlv))
+#define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
+					 MT7996_BEACON_UPDATE_SIZE)
 
 enum {
 	UNI_BAND_CONFIG_RADIO_ENABLE,
Signature · 1 line
2.42.0
author maintainer
#93 lore raw

PATCH 93/550 wifi: mt76: fix potential memory leak of beacon commands

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bo Jiao <[email protected]>

[ Upstream commit d6a2f91741d9f43b31cb16c82da37f35117a6d1c ]

Fix potential memory leak when setting beacon and inband discovery commands.

Fixes e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 10 ++++++++--
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +8 -2
index 4278eacf43845..411157e93865b 100644
@@ -1922,8 +1922,10 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
 		skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
 	}
 
-	if (!skb)
+	if (!skb) {
+		dev_kfree_skb(rskb);
 		return -EINVAL;
+	}
 
 	info = IEEE80211_SKB_CB(skb);
 	info->control.vif = vif;
@@ -1935,6 +1937,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
 
 	if (skb->len > MT7915_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
+		dev_kfree_skb(rskb);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -1991,11 +1994,14 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		goto out;
 
 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
-	if (!skb)
+	if (!skb) {
+		dev_kfree_skb(rskb);
 		return -EINVAL;
+	}
 
 	if (skb->len > MT7915_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
+		dev_kfree_skb(rskb);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +8 -2
index ac06450a79512..60cc3fdca9463 100644
@@ -1942,11 +1942,14 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
 		return PTR_ERR(rskb);
 
 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
-	if (!skb)
+	if (!skb) {
+		dev_kfree_skb(rskb);
 		return -EINVAL;
+	}
 
 	if (skb->len > MT7996_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
+		dev_kfree_skb(rskb);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -2006,11 +2009,14 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
 		skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
 	}
 
-	if (!skb)
+	if (!skb) {
+		dev_kfree_skb(rskb);
 		return -EINVAL;
+	}
 
 	if (skb->len > MT7996_MAX_BEACON_SIZE) {
 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
+		dev_kfree_skb(rskb);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
Signature · 1 line
2.42.0
author maintainer
#94 lore raw

PATCH 94/550 wifi: mt76: get rid of false alamrs of tx emission issues

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: StanleyYP Wang <[email protected]>

[ Upstream commit 413f05d68d11981f5984b49214d3a5a0d88079b1 ]

When the set_chan_info command is set with CH_SWITCH_NORMAL reason, even if the action is UNI_CHANNEL_RX_PATH, it'll still generate some unexpected tones, which might confuse DFS CAC tests that there are some tone leakages. To get rid of these kinds of false alarms, always bypass DPD calibration when IEEE80211_CONF_IDLE is set.

Stable-dep-of: c685034cabc5 ("wifi: mt76: fix per-band IEEE80211_CONF_MONITOR flag comparison")

---
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 6 +++---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +3 -3
index 411157e93865b..fa0f938f03a32 100644
@@ -2702,10 +2702,10 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
 	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
 		req.tx_path_num = fls(phy->mt76->antenna_mask);
 
-	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
-	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
 		req.switch_reason = CH_SWITCH_NORMAL;
-	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
+		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
 	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
 					  NL80211_IFTYPE_AP))
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +3 -3
index 60cc3fdca9463..c4492803ec16e 100644
@@ -2873,10 +2873,10 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
 		.channel_band = ch_band[chandef->chan->band],
 	};
 
-	if (tag == UNI_CHANNEL_RX_PATH ||
-	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
 		req.switch_reason = CH_SWITCH_NORMAL;
-	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
+		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
 	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
 					  NL80211_IFTYPE_AP))
Signature · 1 line
2.42.0
author maintainer
#95 lore raw

PATCH 95/550 wifi: mt76: fix per-band IEEE80211_CONF_MONITOR flag comparison

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Shayne Chen <[email protected]>

[ Upstream commit c685034cabc574dbdf16fa675010e202083cb4c2 ]

Use the correct ieee80211_conf of each band for IEEE80211_CONF_MONITOR comparison.

Fixes 24e69f6bc3ca ("mt76: fix monitor rx FCS error in DFS channel")
Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +1 -1
index 8d745c9730c72..955974a82180f 100644
@@ -2147,7 +2147,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
 	};
 
 	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
-	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+	    phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
 		req.switch_reason = CH_SWITCH_NORMAL;
 	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +1 -1
index fa0f938f03a32..4116434a8b313 100644
@@ -2702,7 +2702,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
 	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
 		req.tx_path_num = fls(phy->mt76->antenna_mask);
 
-	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+	if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
 		req.switch_reason = CH_SWITCH_NORMAL;
 	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
 		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +1 -1
index c4492803ec16e..c45a8afc7c18a 100644
@@ -2873,7 +2873,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
 		.channel_band = ch_band[chandef->chan->band],
 	};
 
-	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+	if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
 		req.switch_reason = CH_SWITCH_NORMAL;
 	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
 		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
Signature · 1 line
2.42.0
author maintainer
#96 lore raw

PATCH 96/550 wifi: mt76: mt7915: fix beamforming availability check

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: MeiChia Chiu <[email protected]>

[ Upstream commit ced1a0b8f3944e44e7f4eb3772dea1bada25d38a ]

Without this patch, when ap sets the tx stream number to 2, ap won't send any beamforming packet.

Fixes f89f297aef28 ("mt76: mt7915: fix txbf starec TLV issues")
---
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +2 -2
index 4116434a8b313..9a8b8356254b5 100644
@@ -1012,13 +1012,13 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
 			struct ieee80211_sta *sta, bool bfee)
 {
 	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-	int tx_ant = hweight8(phy->mt76->chainmask) - 1;
+	int sts = hweight16(phy->mt76->chainmask);
 
 	if (vif->type != NL80211_IFTYPE_STATION &&
 	    vif->type != NL80211_IFTYPE_AP)
 		return false;
 
-	if (!bfee && tx_ant < 2)
+	if (!bfee && sts < 2)
 		return false;
 
 	if (sta->deflink.he_cap.has_he) {
Signature · 1 line
2.42.0
author maintainer
#97 lore raw

PATCH 97/550 wifi: ath: dfs_pattern_detector: Fix a memory initialization issue

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christophe JAILLET <[email protected]>

[ Upstream commit 79bd60ee87e1136718a686d6617ced5de88ee350 ]

If an error occurs and channel_detector_exit() is called, it relies on entries of the 'detectors' array to be NULL.
Otherwise, it may access to un-initialized memory.

Fix it and initialize the memory, as what was done before the commit in Fixes.

---
 drivers/net/wireless/ath/dfs_pattern_detector.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/dfs_pattern_detector.c +1 -1
index 27f4d74a41c80..2788a1b06c17c 100644
@@ -206,7 +206,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
 
 	INIT_LIST_HEAD(&cd->head);
 	cd->freq = freq;
-	cd->detectors = kmalloc_array(dpd->num_radar_types,
+	cd->detectors = kcalloc(dpd->num_radar_types,
 				      sizeof(*cd->detectors), GFP_ATOMIC);
 	if (cd->detectors == NULL)
 		goto fail;
Signature · 1 line
2.42.0
author maintainer
#98 lore raw

PATCH 98/550 tcp_metrics: add missing barriers on delete

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit cbc3a153222805d65f821e10f4f78b6afce06f86 ]

When removing an item from RCU protected list, we must prevent store-tearing, using rcu_assign_pointer() or WRITE_ONCE().

Fixes 04f721c671656 ("tcp_metrics: Rewrite tcp_metrics_flush_all")
---
 net/ipv4/tcp_metrics.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv4/tcp_metrics.c +2 -2
index 99ac5efe244d3..61c573a72db63 100644
@@ -908,7 +908,7 @@ static void tcp_metrics_flush_all(struct net *net)
 			match = net ? net_eq(tm_net(tm), net) :
 				!refcount_read(&tm_net(tm)->ns.count);
 			if (match) {
-				*pp = tm->tcpm_next;
+				rcu_assign_pointer(*pp, tm->tcpm_next);
 				kfree_rcu(tm, rcu_head);
 			} else {
 				pp = &tm->tcpm_next;
@@ -949,7 +949,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 		if (addr_same(&tm->tcpm_daddr, &daddr) &&
 		    (!src || addr_same(&tm->tcpm_saddr, &saddr)) &&
 		    net_eq(tm_net(tm), net)) {
-			*pp = tm->tcpm_next;
+			rcu_assign_pointer(*pp, tm->tcpm_next);
 			kfree_rcu(tm, rcu_head);
 			found = true;
 		} else {
Signature · 1 line
2.42.0
author maintainer
#99 lore raw

PATCH 99/550 tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 081480014a64a69d901f8ef1ffdd56d6085cf87e ]

We need to set tp->snd_ssthresh to TCP_INFINITE_SSTHRESH in the case tcp_get_metrics() fails for some reason.

Fixes 9ad7c049f0f7 ("tcp: RFC2988bis + taking RTT sample from 3WHS for the passive open side")
---
 net/ipv4/tcp_metrics.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
net/ipv4/tcp_metrics.c +4 -5
index 61c573a72db63..5a08dc46a1130 100644
@@ -470,6 +470,10 @@ void tcp_init_metrics(struct sock *sk)
 	u32 val, crtt = 0; /* cached RTT scaled by 8 */
 
 	sk_dst_confirm(sk);
+	/* ssthresh may have been reduced unnecessarily during.
+	 * 3WHS. Restore it back to its initial default.
+	 */
+	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 	if (!dst)
 		goto reset;
 
@@ -489,11 +493,6 @@ void tcp_init_metrics(struct sock *sk)
 		tp->snd_ssthresh = val;
 		if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
 			tp->snd_ssthresh = tp->snd_cwnd_clamp;
-	} else {
-		/* ssthresh may have been reduced unnecessarily during.
-		 * 3WHS. Restore it back to its initial default.
-		 */
-		tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 	}
 	val = tcp_metric_get(tm, TCP_METRIC_REORDERING);
 	if (val && tp->reordering != val)
Signature · 1 line
2.42.0
author maintainer
#100 lore raw

PATCH 100/550 tcp_metrics: do not create an entry from tcp_init_metrics()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit a135798e6e200ecb2f864cecca6d257ba278370c ]

tcp_init_metrics() only wants to get metrics if they were previously stored in the cache. Creating an entry is adding useless costs, especially when tcp_no_metrics_save is set.

Fixes 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.")
---
 net/ipv4/tcp_metrics.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp_metrics.c +1 -1
index 5a08dc46a1130..a7364ff8b558d 100644
@@ -478,7 +478,7 @@ void tcp_init_metrics(struct sock *sk)
 		goto reset;
 
 	rcu_read_lock();
-	tm = tcp_get_metrics(sk, dst, true);
+	tm = tcp_get_metrics(sk, dst, false);
 	if (!tm) {
 		rcu_read_unlock();
 		goto reset;
Signature · 1 line
2.42.0
author maintainer
#101 lore raw

PATCH 101/550 wifi: rtlwifi: fix EDCA limit set by BT coexistence

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Antipov <[email protected]>

[ Upstream commit 3391ee7f9ea508c375d443cd712c2e699be235b4 ]

In 'rtl92c_dm_check_edca_turbo()', 'rtl88e_dm_check_edca_turbo()', and 'rtl8723e_dm_check_edca_turbo()', the DL limit should be set from the corresponding field of 'rtlpriv->btcoexist' rather than UL. Compile tested only.

Fixes 0529c6b81761 ("rtlwifi: rtl8723ae: Update driver to match 06/28/14 Realtek version")
Fixes c151aed6aa14 ("rtlwifi: rtl8188ee: Update driver to match Realtek release of 06282014")
Fixes beb5bc402043 ("rtlwifi: rtl8192c-common: Convert common dynamic management routines for addition of rtl8192se and rtl8192de")
---
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c       | 2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c | 2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +1 -1
index 6f61d6a106272..5a34894a533be 100644
@@ -799,7 +799,7 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
 	}
 
 	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
-		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
+		edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
 		bt_change_edca = true;
 	}
 
drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c +1 -1
index 0b6a15c2e5ccd..d92aad60edfe9 100644
@@ -640,7 +640,7 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
 	}
 
 	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
-		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
+		edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
 		bt_change_edca = true;
 	}
 
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c +1 -1
index 8ada31380efa4..0ff8e355c23a4 100644
@@ -466,7 +466,7 @@ static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw)
 	}
 
 	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
-		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
+		edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
 		bt_change_edca = true;
 	}
 
Signature · 1 line
2.42.0
author maintainer
#102 lore raw

PATCH 102/550 ACPI: property: Allow _DSD buffer data only for byte accessors

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Shevchenko <[email protected]>

[ Upstream commit 046ece773cc77ef5d2a1431b188ac3d0840ed150 ]

In accordance with ACPI specificication and _DSD data buffer representation the data there is an array of bytes. Hence, accessing it with something longer will create a sparse data which is against of how device property APIs work in general and also not defined in the ACPI specification (see [1]). Fix the code to emit an error if non-byte accessor is used to retrieve _DSD buffer data.

Fixes 369af6bf2c28 ("ACPI: property: Read buffer properties as integers")
[ rjw: Add missing braces ]
---
 drivers/acpi/property.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/acpi/property.c +10 -9
index 413e4fcadcaf7..99b4e33554355 100644
@@ -1102,25 +1102,26 @@ static int acpi_data_prop_read(const struct acpi_device_data *data,
 	switch (proptype) {
 	case DEV_PROP_STRING:
 		break;
-	case DEV_PROP_U8 ... DEV_PROP_U64:
+	default:
 		if (obj->type == ACPI_TYPE_BUFFER) {
 			if (nval > obj->buffer.length)
 				return -EOVERFLOW;
-			break;
+		} else {
+			if (nval > obj->package.count)
+				return -EOVERFLOW;
 		}
-		fallthrough;
-	default:
-		if (nval > obj->package.count)
-			return -EOVERFLOW;
 		break;
 	}
 	if (nval == 0)
 		return -EINVAL;
 
-	if (obj->type != ACPI_TYPE_BUFFER)
-		items = obj->package.elements;
-	else
+	if (obj->type == ACPI_TYPE_BUFFER) {
+		if (proptype != DEV_PROP_U8)
+			return -EPROTO;
 		items = obj;
+	} else {
+		items = obj->package.elements;
+	}
 
 	switch (proptype) {
 	case DEV_PROP_U8:
Signature · 1 line
2.42.0
author maintainer
#103 lore raw

PATCH 103/550 =?UTF-8?q?ACPI:=20video:=20Add=20acpi=5Fbacklight=3Dvendor=20quir?= =?UTF-8?q?k=20for=20Toshiba=20Port=C3=A9g=C3=A9=20R100?=

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ondrej Zary <[email protected]>

[ Upstream commit 35a341c9b25da6a479bd8013bcb11a680a7233e3 ]

Toshiba Portégé R100 has both acpi_video and toshiba_acpi vendor backlight driver working. But none of them gets activated as it has a VGA with no kernel driver (Trident CyberBlade XP4m32).

The DMI strings are very generic ("Portable PC") so add a custom callback function to check for Trident CyberBlade XP4m32 PCI device before enabling the vendor backlight driver (better than acpi_video as it has more brightness steps).

Fixes 5aa9d943e9b6 ("ACPI: video: Don't enable fallback path for creating ACPI backlight by default")
---
 drivers/acpi/video_detect.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
drivers/acpi/video_detect.c +26 -0
index 442396f6ed1f9..31205fee59d4a 100644
@@ -130,6 +130,16 @@ static int video_detect_force_native(const struct dmi_system_id *d)
 	return 0;
 }
 
+static int video_detect_portege_r100(const struct dmi_system_id *d)
+{
+	struct pci_dev *dev;
+	/* Search for Trident CyberBlade XP4m32 to confirm Portégé R100 */
+	dev = pci_get_device(PCI_VENDOR_ID_TRIDENT, 0x2100, NULL);
+	if (dev)
+		acpi_backlight_dmi = acpi_backlight_vendor;
+	return 0;
+}
+
 static const struct dmi_system_id video_detect_dmi_table[] = {
 	/*
 	 * Models which should use the vendor backlight interface,
@@ -270,6 +280,22 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
 		},
 	},
 
+	/*
+	 * Toshiba Portégé R100 has working both acpi_video and toshiba_acpi
+	 * vendor driver. But none of them gets activated as it has a VGA with
+	 * no kernel driver (Trident CyberBlade XP4m32).
+	 * The DMI strings are generic so check for the VGA chip in callback.
+	 */
+	{
+	 .callback = video_detect_portege_r100,
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
+		DMI_MATCH(DMI_BOARD_NAME, "Portable PC")
+		},
+	},
+
 	/*
 	 * Models which need acpi_video backlight control where the GPU drivers
 	 * do not call acpi_video_register_backlight() because no internal panel
Signature · 1 line
2.42.0
author maintainer
#104 lore raw

PATCH 104/550 can: etas_es58x: rework the version check logic to silence -Wformat-truncation

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vincent Mailhol <[email protected]>

[ Upstream commit 107e6f6fe6f38577baecf0e01f517c8607a3a625 ]

Following [1], es58x_devlink.c now triggers the following format-truncation GCC warnings:

drivers/net/can/usb/etas_es58x/es58x_devlink.c: In function ‘es58x_devlink_info_get’:
drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=]

    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                                         ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:30: note: directive argument in the range [0, 255]
    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                              ^~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9
    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    202 |     fw_ver->major, fw_ver->minor, fw_ver->revision);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=]
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                                         ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:30: note: directive argument in the range [0, 255]
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                              ^~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    212 |     bl_ver->major, bl_ver->minor, bl_ver->revision);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:38: warning: ‘%03u’ directive output may be truncated writing between 3 and 5 bytes into a region of size between 2 and 4 [-Wformat-truncation=]
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |                                      ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:30: note: directive argument in the range [0, 65535]
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |                              ^~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:3: note: ‘snprintf’ output between 9 and 13 bytes into a destination of size 9
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    222 |     hw_rev->letter, hw_rev->major, hw_rev->minor);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is not an actual bug because the sscanf() parsing makes sure that the u8 are only two digits long and the u16 only three digits long. Thus below declaration:

	char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))];

allocates just what is needed to represent either of the versions.

This warning was known but ignored because, at the time of writing, -Wformat-truncation was not present in the kernel, not even at W=3 [2].

One way to silence this warning is to check the range of all sub version numbers are valid: [0, 99] for u8 and range [0, 999] for u16.

The module already has a logic which considers that when all the sub version numbers are zero, the version number is not set. Note that not having access to the device specification, this was an arbitrary decision. This logic can thus be removed in favor of global check that would cover both cases:

- the version number is not set (parsing failed)
- the version number is not valid (paranoiac check to please gcc)

Before starting to parse the product info string, set the version sub-numbers to the maximum unsigned integer thus violating the definitions of struct es58x_sw_version or struct es58x_hw_revision.

Then, rework the es58x_sw_version_is_set() and es58x_hw_revision_is_set() functions: remove the check that the sub-numbers are non zero and replace it by a check that they fit in the expected number of digits. This done, rename the functions to reflect the change and rewrite the documentation. While doing so, also add a description of the return value.

Finally, the previous version only checked that &es58x_hw_revision.letter was not the null character. Replace this check by an alphanumeric character check to make sure that we never return a special character or a non-printable one and update the documentation of struct es58x_hw_revision accordingly.

All those extra checks are paranoid but have the merit to silence the newly introduced W=1 format-truncation warning [1].

[1] commit 6d4ab2e97dcf ("extrawarn: enable format and stringop overflow warnings in W=1")

[2] https://lore.kernel.org/all/CAMZ6Rq+K+6gbaZ35SOJcR9qQaTJ7KR0jW=XoDKFkobjhj8CHhw@mail.gmail.com/

---
 drivers/net/can/usb/etas_es58x/es58x_core.h   |  6 +-
 .../net/can/usb/etas_es58x/es58x_devlink.c    | 57 +++++++++++++------
 2 files changed, 42 insertions(+), 21 deletions(-)
drivers/net/can/usb/etas_es58x/es58x_core.h +3 -3
index c1ba1a4e8857b..2e183bdeedd72 100644
@@ -378,13 +378,13 @@ struct es58x_sw_version {
 
 /**
  * struct es58x_hw_revision - Hardware revision number.
- * @letter: Revision letter.
+ * @letter: Revision letter, an alphanumeric character.
  * @major: Version major number, represented on three digits.
  * @minor: Version minor number, represented on three digits.
  *
  * The hardware revision uses its own format: "axxx/xxx" where 'a' is
- * a letter and 'x' a digit. It can be retrieved from the product
- * information string.
+ * an alphanumeric character and 'x' a digit. It can be retrieved from
+ * the product information string.
  */
 struct es58x_hw_revision {
 	char letter;
drivers/net/can/usb/etas_es58x/es58x_devlink.c +39 -18

103 lines not on this page · raw message

Signature · 1 line
2.42.0
author maintainer
#105 lore raw

PATCH 105/550 can: etas_es58x: add missing a blank line after declaration

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vincent Mailhol <[email protected]>

[ Upstream commit 4f8005092cafc194ba6a8e5f39626ba0b9f08271 ]

Fix below checkpatch warning:

  WARNING: Missing a blank line after declarations
  #2233: FILE: drivers/net/can/usb/etas_es58x/es58x_core.c:2233:
  +		int ret = es58x_init_netdev(es58x_dev, ch_idx);
  +		if (ret) {
Fixes d8f26fd689dd ("can: etas_es58x: remove es58x_get_product_info()")
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/can/usb/etas_es58x/es58x_core.c +1 -0
index 0c7f7505632cd..5e3a72b7c4691 100644
@@ -2230,6 +2230,7 @@ static int es58x_probe(struct usb_interface *intf,
 
 	for (ch_idx = 0; ch_idx < es58x_dev->num_can_ch; ch_idx++) {
 		int ret = es58x_init_netdev(es58x_dev, ch_idx);
+
 		if (ret) {
 			es58x_free_netdevs(es58x_dev);
 			return ret;
Signature · 1 line
2.42.0
author maintainer
#106 lore raw

PATCH 106/550 wifi: ath11k: fix Tx power value during active CAC

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aditya Kumar Singh <[email protected]>

[ Upstream commit 77f1ee6fd8b6e470f721d05a2e269039d5cafcb7 ]

Tx power is fetched from firmware's pdev stats. However, during active CAC, firmware does not fill the current Tx power and sends the max initialised value filled during firmware init. If host sends this power to user space, this is wrong since in certain situations, the Tx power could be greater than the max allowed by the regulatory. Hence, host should not be fetching the Tx power during an active CAC.

Fix this issue by returning -EAGAIN error so that user space knows that there's no valid value available.

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1

---
 drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/net/wireless/ath/ath11k/mac.c +8 -0
index 8c77ade49437f..1cc016c5ca44b 100644
@@ -9042,6 +9042,14 @@ static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw,
 	if (ar->state != ATH11K_STATE_ON)
 		goto err_fallback;
 
+	/* Firmware doesn't provide Tx power during CAC hence no need to fetch
+	 * the stats.
+	 */
+	if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
+		mutex_unlock(&ar->conf_mutex);
+		return -EAGAIN;
+	}
+
 	req_param.pdev_id = ar->pdev->pdev_id;
 	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
 
Signature · 1 line
2.42.0
author maintainer
#107 lore raw

PATCH 107/550 can: dev: can_restart(): dont crash kernel if carrier is OK

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marc Kleine-Budde <[email protected]>

[ Upstream commit fe5c9940dfd8ba0c73672dddb30acd1b7a11d4c7 ]

During testing, I triggered a can_restart() with the netif carrier being OK [1]. The BUG_ON, which checks if the carrier is OK, results in a fatal kernel crash. This is neither helpful for debugging nor for a production system.

[1] The root cause is a race condition in can_restart() which will be fixed in the next patch.

Do not crash the kernel, issue an error message instead, and continue restarting the CAN device anyway.

---
 drivers/net/can/dev/dev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/can/dev/dev.c +2 -1
index 7f9334a8af500..a5bbdfa9a2693 100644
@@ -132,7 +132,8 @@ static void can_restart(struct net_device *dev)
 	struct can_frame *cf;
 	int err;
 
-	BUG_ON(netif_carrier_ok(dev));
+	if (netif_carrier_ok(dev))
+		netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n");
 
 	/* No synchronization needed because the device is bus-off and
 	 * no messages can come in or go out.
Signature · 1 line
2.42.0
author maintainer
#108 lore raw

PATCH 108/550 can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on()

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marc Kleine-Budde <[email protected]>

[ Upstream commit 6841cab8c4504835e4011689cbdb3351dec693fd ]

This race condition was discovered while updating the at91_can driver to use can_bus_off(). The following scenario describes how the converted at91_can driver would behave.

When a CAN device goes into BUS-OFF state, the driver usually stops/resets the CAN device and calls can_bus_off().

This function sets the netif carrier to off, and (if configured by user space) schedules a delayed work that calls can_restart() to restart the CAN device.

The can_restart() function first checks if the carrier is off and triggers an error message if the carrier is OK.

Then it calls the driver's do_set_mode() function to restart the device, then it sets the netif carrier to on. There is a race window between these two calls.

The at91 CAN controller (observed on the sama5d3, a single core 32 bit ARM CPU) has a hardware limitation. If the device goes into bus-off while sending a CAN frame, there is no way to abort the sending of this frame. After the controller is enabled again, another attempt is made to send it.

If the bus is still faulty, the device immediately goes back to the bus-off state. The driver calls can_bus_off(), the netif carrier is switched off and another can_restart is scheduled. This occurs within the race window before the original can_restart() handler marks the netif carrier as OK. This would cause the 2nd can_restart() to be called with an OK netif carrier, resulting in an error message.

The flow of the 1st can_restart() looks like this:

can_restart()

    // bail out if netif_carrier is OK

    netif_carrier_ok(dev)
    priv->do_set_mode(dev, CAN_MODE_START)
        // enable CAN controller
        // sama5d3 restarts sending old message

        // CAN devices goes into BUS_OFF, triggers IRQ

// IRQ handler start

    at91_irq()
        at91_irq_err_line()
            can_bus_off()
                netif_carrier_off()
                schedule_delayed_work()

// IRQ handler end

netif_carrier_on()

The 2nd can_restart() will be called with an OK netif carrier and the error message will be printed.

To close the race window, first set the netif carrier to on, then restart the controller. In case the restart fails with an error code, roll back the netif carrier to off.

---
 drivers/net/can/dev/dev.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/can/dev/dev.c +4 -3
index a5bbdfa9a2693..735d5de3caa0e 100644
@@ -154,11 +154,12 @@ static void can_restart(struct net_device *dev)
 	priv->can_stats.restarts++;
 
 	/* Now restart the device */
-	err = priv->do_set_mode(dev, CAN_MODE_START);
-
 	netif_carrier_on(dev);
-	if (err)
+	err = priv->do_set_mode(dev, CAN_MODE_START);
+	if (err) {
 		netdev_err(dev, "Error %d during restart", err);
+		netif_carrier_off(dev);
+	}
 }
 
 static void can_restart_work(struct work_struct *work)
Signature · 1 line
2.42.0
author maintainer
#109 lore raw

PATCH 109/550 can: dev: can_put_echo_skb(): dont crash kernel if can_priv::echo_skb is accessed out of bounds

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marc Kleine-Budde <[email protected]>

[ Upstream commit 6411959c10fe917288cbb1038886999148560057 ]

If the "struct can_priv::echoo_skb" is accessed out of bounds, this would cause a kernel crash. Instead, issue a meaningful warning message and return with an error.

---
 drivers/net/can/dev/skb.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/can/dev/skb.c +5 -1
index f6d05b3ef59ab..3ebd4f779b9bd 100644
@@ -49,7 +49,11 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	BUG_ON(idx >= priv->echo_skb_max);
+	if (idx >= priv->echo_skb_max) {
+		netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+			   __func__, idx, priv->echo_skb_max);
+		return -EINVAL;
+	}
 
 	/* check flag whether this packet has to be looped back */
 	if (!(dev->flags & IFF_ECHO) ||
Signature · 1 line
2.42.0
author maintainer
#110 lore raw

PATCH 110/550 PM / devfreq: rockchip-dfi: Make pmu regmap mandatory

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sascha Hauer <[email protected]>

[ Upstream commit 1e0731c05c985deb68a97fa44c1adcd3305dda90 ]

As a matter of fact the regmap_pmu already is mandatory because it is used unconditionally in the driver. Bail out gracefully in probe() rather than crashing later.

Fixes b9d1262bca0af ("PM / devfreq: event: support rockchip dfi controller")
---
 drivers/devfreq/event/rockchip-dfi.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/devfreq/event/rockchip-dfi.c +8 -7
index 39ac069cabc75..74893c06aa087 100644
@@ -193,14 +193,15 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(data->clk),
 				     "Cannot get the clk pclk_ddr_mon\n");
 
-	/* try to find the optional reference to the pmu syscon */
 	node = of_parse_phandle(np, "rockchip,pmu", 0);
-	if (node) {
-		data->regmap_pmu = syscon_node_to_regmap(node);
-		of_node_put(node);
-		if (IS_ERR(data->regmap_pmu))
-			return PTR_ERR(data->regmap_pmu);
-	}
+	if (!node)
+		return dev_err_probe(&pdev->dev, -ENODEV, "Can't find pmu_grf registers\n");
+
+	data->regmap_pmu = syscon_node_to_regmap(node);
+	of_node_put(node);
+	if (IS_ERR(data->regmap_pmu))
+		return PTR_ERR(data->regmap_pmu);
+
 	data->dev = dev;
 
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
Signature · 1 line
2.42.0
author maintainer
#111 lore raw

PATCH 111/550 wifi: wfx: fix case where rates are out of order

In reply to Greg Kroah-Hartman

6.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felipe Negrelli Wolter <[email protected]>

[ Upstream commit ea2274ab0b18549dbf0e755e41d8c5e8b5232dc3 ]

When frames are sent over the air, the device always applies the data rates in descending order. The driver assumed Minstrel also provided rate in descending order.

However, in some cases, Minstrel can a choose a fallback rate greater than the primary rate. In this case, the two rates was inverted, the device try highest rate first and we get many retries.

Since the device always applies rates in descending order, the workaround is to drop the rate when it higher than its predecessor in the rate list. Thus [ 4, 5, 3 ] becomes [ 4, 3 ].

This patch has been tested in isolated room with a series of attenuators. Here are the Minstrel statistics with 80dBm of attenuation:

Without the fix:

best ____________rate__________ ____statistics___ _____last____ ______sum-of________
mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]
HT20 LGI 1 S MCS0 0 1477 5.6 5.2 82.7 3 0 0 3 4
HT20 LGI 1 MCS1 1 738 10.6 0.0 0.0 0 0 0 0 1
HT20 LGI 1 D MCS2 2 492 14.9 13.5 81.5 5 0 0 5 9
HT20 LGI 1 C MCS3 3 369 18.8 17.6 84.3 5 0 0 76 96
HT20 LGI 1 A P MCS4 4 246 25.4 22.4 79.5 5 0 0 11268 14026
HT20 LGI 1 B S MCS5 5 185 30.7 19.7 57.7 5 8 9 3918 9793
HT20 LGI 1 MCS6 6 164 33.0 0.0 0.0 5 0 0 6 102
HT20 LGI 1 MCS7 7 148 35.1 0.0 0.0 0 0 0 0 44

With the fix:

                  best    ____________rate__________    ____statistics___    _____last____    ______sum-of________
    mode guard #  rate   [name   idx airtime  max_tp]  [avg(tp) avg(prob)]  [retry|suc|att]  [#success | #attempts]
    HT20  LGI  1       S  MCS0     0    1477     5.6       1.8      28.6       1     0 0             1   5
    HT20  LGI  1     DP   MCS1     1     738    10.6       9.7      82.6       4     0 0            14   34
    HT20  LGI  1          MCS2     2     492    14.9       9.2      55.4       5     0 0            52   77
    HT20  LGI  1   B   S  MCS3     3     369    18.8      15.6      74.9       5     1 1           417   554
    HT20  LGI  1  A       MCS4     4     246    25.4      16.7      59.2       5     1 1         13812   17951
    HT20  LGI  1    C  S  MCS5     5     185    30.7      14.0      41.0       5     1 5            57   640
    HT20  LGI  1          MCS6     6     164    33.0       0.0       0.0       0     0 1             0   48
    HT20  LGI  1       S  MCS7     7     148    35.1       0.0       0.0       0     0 0             0   36

We can notice the device try now to send with lower rates (and high success rates). At the end, we measured 20-25% better throughput with this patch.

---
 drivers/net/wireless/silabs/wfx/data_tx.c | 71 +++++++++--------------
 1 file changed, 29 insertions(+), 42 deletions(-)
drivers/net/wireless/silabs/wfx/data_tx.c +29 -42
index 6a5e52a96d183..caa22226b01bc 100644
@@ -226,53 +226,40 @@ static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 
 static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
 {
-	int i;
-	bool finished;
+	bool has_rate0 = false;
+	int i, j;
 
-	/* Firmware is not able to mix rates with different flags */
-	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
-		if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
-			rates[i].flags |= IEEE80211_TX_RC_SHORT_GI;
-		if (!(rates[0].flags & IEEE80211_TX_RC_SHORT_GI))
+	for (i = 1, j = 1; j < IEEE80211_TX_MAX_RATES; j++) {
+		if (rates[j].idx == -1)
+			break;
+		/* The device use the rates in descending order, whatever the request from minstrel.
+		 * We have to trade off here. Most important is to respect the primary rate
+		 * requested by minstrel. So, we drops the entries with rate higher than the
+		 * previous.
+		 */
+		if (rates[j].idx >= rates[i - 1].idx) {
+			rates[i - 1].count += rates[j].count;
+			rates[i - 1].count = min_t(u16, 15, rates[i - 1].count);
+		} else {
+			memcpy(rates + i, rates + j, sizeof(rates[i]));
+			if (rates[i].idx == 0)
+				has_rate0 = true;
+			/* The device apply Short GI only on the first rate */
 			rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
-		if (!(rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS))
-			rates[i].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
-	}
-
-	/* Sort rates and remove duplicates */
-	do {
-		finished = true;
-		for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) {
-			if (rates[i + 1].idx == rates[i].idx &&
-			    rates[i].idx != -1) {
-				rates[i].count += rates[i + 1].count;
-				if (rates[i].count > 15)
-					rates[i].count = 15;
-				rates[i + 1].idx = -1;
-				rates[i + 1].count = 0;
-
-				finished = false;
-			}
-			if (rates[i + 1].idx > rates[i].idx) {
-				swap(rates[i + 1], rates[i]);
-				finished = false;
-			}
+			i++;
 		}
-	} while (!finished);
+	}
 	/* Ensure that MCS0 or 1Mbps is present at the end of the retry list */
-	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
-		if (rates[i].idx == 0)
-			break;
-		if (rates[i].idx == -1) {
-			rates[i].idx = 0;
-			rates[i].count = 8; /* == hw->max_rate_tries */
-			rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS;
-			break;
-		}
+	if (!has_rate0 && i < IEEE80211_TX_MAX_RATES) {
+		rates[i].idx = 0;
+		rates[i].count = 8; /* == hw->max_rate_tries */
+		rates[i].flags = rates[0].flags & IEEE80211_TX_RC_MCS;
+		i++;
+	}
+	for (; i < IEEE80211_TX_MAX_RATES; i++) {
+		memset(rates + i, 0, sizeof(rates[i]));
+		rates[i].idx = -1;
 	}
-	/* All retries use long GI */
-	for (i = 1; i < IEEE80211_TX_MAX_RATES; i++)
-		rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
 }
 
 static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, struct ieee80211_tx_info *tx_info)
Signature · 1 line
2.42.0