Skip to contentSkip to conversation

6.9.6-rc1 review

PATCH In review Greg Kroah-Hartman 18 participants 311 messages Jun 19, 2024 – Jul 2, 2024 Page 1 of 3

Subsystems (6)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.9.6-rc1 review

This is the start of the stable review cycle for the 6.9.6 release. There are 281 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, 21 Jun 2024 12:55:11 +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.9.6-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.9.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 6.9.6-rc1

Oleg Nesterov <[email protected]>
zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING

Jean Delvare <[email protected]>
i2c: designware: Fix the functionality flags of the slave-only interface

Jean Delvare <[email protected]>
i2c: at91: Fix the functionality flags of the slave-only interface

Yongzhi Liu <[email protected]>
misc: microchip: pci1xxxx: Fix a memory leak in the error handling of gp_aux_bus_probe()

Hans de Goede <[email protected]>
mei: vsc: Fix wrong invocation of ACPI SID method

Shichao Lai <[email protected]>
usb-storage: alauda: Check whether the media is initialized

Rob Herring (Arm) <[email protected]>
dt-bindings: usb: realtek,rts5411: Add missing "additionalProperties" on child nodes

Andy Shevchenko <[email protected]>

    serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw

Stefan Berger <[email protected]>
ima: Fix use-after-free on a dentry's dname.name

Sicong Huang <[email protected]>
greybus: Fix use-after-free bug in gb_interface_release due to race condition.

Beleswar Padhi <[email protected]>
remoteproc: k3-r5: Jump to error handling labels in start/stop errors

Miaohe Lin <[email protected]>
mm/huge_memory: don't unpoison huge_zero_folio

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: mvm: fix a crash on 7265

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: mvm: support iwl_dev_tx_power_cmd_v8

Filipe Manana <[email protected]>
btrfs: zoned: fix use-after-free due to race with dev replace

Tomi Valkeinen <[email protected]>
pmdomain: ti-sci: Fix duplicate PD referrals

Alexander Shishkin <[email protected]>
intel_th: pci: Add Lunar Lake support

Alexander Shishkin <[email protected]>
intel_th: pci: Add Meteor Lake-S support

Alexander Shishkin <[email protected]>
intel_th: pci: Add Sapphire Rapids SOC support

Alexander Shishkin <[email protected]>
intel_th: pci: Add Granite Rapids SOC support

Alexander Shishkin <[email protected]>
intel_th: pci: Add Granite Rapids support

Imre Deak <[email protected]>
drm/i915: Fix audio component initialization

Vidya Srinivas <[email protected]>
drm/i915/dpt: Make DPT object unshrinkable

Niranjana Vishwanathapura <[email protected]>
drm/xe: Properly handle alloc_guc_id() failure

Wachowski, Karol <[email protected]>
drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE)

Chris Wilson <[email protected]>
drm/i915/gt: Disarm breadcrumbs if engines are already idle

Daniel Bristot de Oliveira <[email protected]>
rtla/auto-analysis: Replace \t with spaces

Daniel Bristot de Oliveira <[email protected]>
rtla/timerlat: Simplify "no value" printing on top

Nam Cao <[email protected]>
riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled

Nam Cao <[email protected]>
riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context

Wayne Lin <[email protected]>
drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2

Jean-Baptiste Maneyrol <[email protected]>
iio: invensense: fix interrupt timestamp alignment

Dimitri Fedrau <[email protected]>
iio: temperature: mcp9600: Fix temperature reading for negative values

Nuno Sa <[email protected]>
iio: adc: axi-adc: make sure AXI clock is enabled

Beleswar Padhi <[email protected]>
remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs

Apurva Nandan <[email protected]>
remoteproc: k3-r5: Wait for core0 power-up before powering up core1

Dmitry Baryshkov <[email protected]>
drm/bridge: aux-hpd-bridge: correct devm_drm_dp_hpd_bridge_add() stub

Nuno Sa <[email protected]>
dmaengine: axi-dmac: fix possible race in remove()

Rick Wertenbroek <[email protected]>
PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id

Mikulas Patocka <[email protected]>
dm-integrity: set discard_granularity to logical block size

Su Yue <[email protected]>
ocfs2: fix races between hole punching and AIO+DIO

Su Yue <[email protected]>
ocfs2: use coarse time for new created files

Su Yue <[email protected]>
ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link

Baoquan He <[email protected]>
kexec: fix the unexpected kexec_dprintk() macro

Rik van Riel <[email protected]>
fs/proc: fix softlockup in __read_vmcore

Trond Myklebust <[email protected]>
knfsd: LOOKUP can return an illegal error value

Vamshi Gajjela <[email protected]>
spmi: hisi-spmi-controller: Do not override device identifier

Hagar Gamal Halim Hemdan <[email protected]>
vmci: prevent speculation leaks by sanitizing event in event_deliver()

Fedor Pchelkin <[email protected]>
dma-buf: handle testing kthreads creation failure

Thadeu Lima de Souza Cascardo <[email protected]>
sock_map: avoid race between sock_map_close and sk_psock_put

Niklas Cassel <[email protected]>
ata: libata-core: Add ATA_HORKAGE_NOLPM for AMD Radeon S3 SSD

Niklas Cassel <[email protected]>
ata: libata-core: Add ATA_HORKAGE_NOLPM for Crucial CT240BX500SSD1

Niklas Cassel <[email protected]>
ata: libata-core: Add ATA_HORKAGE_NOLPM for Apacer AS340

Jason Nader <[email protected]>
ata: ahci: Do not apply Intel PCS quirk on Intel Alder Lake

Damien Le Moal <[email protected]>
null_blk: Print correct max open zones limit in null_init_zoned_dev()

Matthias Maennich <[email protected]>
kheaders: explicitly define file modes for archived headers

Steven Rostedt (Google) <[email protected]>
tracing/selftests: Fix kprobe event name test for .isra. functions

Nam Cao <[email protected]>
riscv: fix overlap of allocated page and PTR_ERR

Carlos Llamas <[email protected]>

    locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc

Johannes Berg <[email protected]>
wifi: mt76: mt7615: add missing chanctx ops

Bitterblue Smith <[email protected]>
wifi: rtlwifi: Ignore IEEE80211_CONF_CHANGE_RETRY_LIMITS

Johannes Berg <[email protected]>
wifi: cfg80211: validate HE operation element parsing

Adrian Hunter <[email protected]>
perf script: Show also errors for --insn-trace option

Adrian Hunter <[email protected]>
perf auxtrace: Fix multiple use of --itrace option

Haifeng Xu <[email protected]>
perf/core: Fix missing wakeup when waiting for context reference

Yazen Ghannam <[email protected]>
x86/amd_nb: Check for invalid SMN reads

David Kaplan <[email protected]>
x86/kexec: Fix bug with call depth tracking

Hagar Hemdan <[email protected]>
irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update()

Samuel Holland <[email protected]>
irqchip/sifive-plic: Chain to parent IRQ after handlers are ready

YonglongLi <[email protected]>
mptcp: pm: update add_addr counters after connect

YonglongLi <[email protected]>
mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID

Paolo Abeni <[email protected]>
mptcp: ensure snd_una is properly initialized on connect

Marek Szyprowski <[email protected]>

    drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found

Jani Nikula <[email protected]>
drm/exynos/vidi: fix memory leak in .get_modes()

Jan Beulich <[email protected]>
memblock: make memblock_set_node() also warn about use of MAX_NUMNODES

Jan Beulich <[email protected]>
x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()

Rafael J. Wysocki <[email protected]>
thermal: ACPI: Invalidate trip points with temperature of 0 or below

Mario Limonciello <[email protected]>
ACPI: x86: Force StorageD3Enable on more products

Yazen Ghannam <[email protected]>
RAS/AMD/ATL: Use system settings for MI300 DRAM to normalized address translation

Yazen Ghannam <[email protected]>
RAS/AMD/ATL: Fix MI300 bank hash

John David Anglin <[email protected]>
parisc: Try to fix random segmentation faults in package builds

Dirk Behme <[email protected]>
drivers: core: synchronize really_probe() and dev_uevent()

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: delete unneeded update watermark call

Harshit Mogalapalli <[email protected]>
iio: temperature: mlx90635: Fix ERR_PTR dereference in mlx90635_probe()

Adam Rizkalla <[email protected]>
iio: pressure: bmp280: Fix BMP580 temperature reading

Jean-Baptiste Maneyrol <[email protected]>
iio: invensense: fix odr switching to same value

Vasileios Amoiridis <[email protected]>
iio: imu: bmi323: Fix trigger notification in case of error

Marc Ferland <[email protected]>
iio: dac: ad5592r: fix temperature channel scaling value

David Lechner <[email protected]>
iio: adc: ad9467: fix scan type sign

Benjamin Segall <[email protected]>
x86/boot: Don't add the EFI stub to targets, again

Hans de Goede <[email protected]>
leds: class: Revert: "If no default trigger is given, make hw_control trigger the default trigger"

Oleg Nesterov <[email protected]>
tick/nohz_full: Don't abuse smp_call_function_single() in tick_setup_device()

Namjae Jeon <[email protected]>
ksmbd: fix missing use of get_write in in smb2_set_ea()

Namjae Jeon <[email protected]>
ksmbd: move leading slash check to smb2_get_name()

Yongzhi Liu <[email protected]>
misc: microchip: pci1xxxx: fix double free in the error handling of gp_aux_bus_probe()

Aleksandr Mishin <[email protected]>
bnxt_en: Adjust logging of firmware messages in case of released token in __hwrm_send()

Rao Shoaib <[email protected]>
af_unix: Read with MSG_PEEK loops if the first unread byte is OOB

Michael Chan <[email protected]>
bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response

Taehee Yoo <[email protected]>
ionic: fix use after netif_napi_del()

Riana Tauro <[email protected]>
drm/xe: move disable_c6 call

Rodrigo Vivi <[email protected]>
drm/xe: Remove mem_access from guc_pc calls

Andrzej Hajda <[email protected]>
drm/xe: flush engine buffers before signalling user fence on all engines

Riana Tauro <[email protected]>
drm/xe/xe_gt_idle: use GT forcewake domain assertion

Nikolay Aleksandrov <[email protected]>
net: bridge: mst: fix suspicious rcu usage in br_mst_set_state

Nikolay Aleksandrov <[email protected]>
net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state

Petr Pavlu <[email protected]>
net/ipv6: Fix the RT cache flush via sysctl using a previous delay

Daniel Wagner <[email protected]>
nvmet-passthru: propagate status from id override functions

Chengming Zhou <[email protected]>
block: fix request.queuelist usage in flush

Su Hui <[email protected]>
block: sed-opal: avoid possible wrong address reference in read_sed_opal_key()

Xiaolei Wang <[email protected]>

    net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs parameters

Joshua Washington <[email protected]>
gve: ignore nonrelevant GSO type bits when processing TSO headers

Kory Maincent <[email protected]>
net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP

Ziqi Chen <[email protected]>
scsi: ufs: core: Quiesce request queues before checking pending cmds

Kees Cook <[email protected]>
x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking

Uros Bizjak <[email protected]>
x86/asm: Use %c/%n instead of %P operand modifier in asm templates

Jozsef Kadlecsik <[email protected]>
netfilter: ipset: Fix race between namespace cleanup and gc in the list:set type

Davide Ornaghi <[email protected]>
netfilter: nft_inner: validate mandatory meta and payload

Vasily Khoruzhick <[email protected]>
drm/nouveau: don't attempt to schedule hpd_work on headless cards

Eric Dumazet <[email protected]>
tcp: use signed arithmetic in tcp_rtx_probe0_timed_out()

Johannes Berg <[email protected]>
net/sched: initialize noop_qdisc owner

Pauli Virtanen <[email protected]>
Bluetooth: fix connection setup in l2cap_connect

Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ

Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_sync: Fix not using correct handle

Gal Pressman <[email protected]>
net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) packets

Gal Pressman <[email protected]>
geneve: Fix incorrect inner network header offset when innerprotoinherit is set

Andy Shevchenko <[email protected]>
net dsa: qca8k: fix usages of device_get_named_child_node()

Eric Dumazet <[email protected]>
tcp: fix race in tcp_v6_syn_recv_sock()

Adam Miotk <[email protected]>
drm/bridge/panel: Fix runtime warning on panel bridge release

Amjad Ouled-Ameur <[email protected]>
drm/komeda: check for error-valued pointer

David Wei <[email protected]>
netdevsim: fix backwards compatibility in nsim_get_iflink()

Sagar Cheluvegowda <[email protected]>
net: stmmac: dwmac-qcom-ethqos: Configure host DMA width

Aleksandr Mishin <[email protected]>
liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet

Rafael J. Wysocki <[email protected]>
thermal: core: Do not fail cdev registration because of invalid initial state

Jie Wang <[email protected]>
net: hns3: add cond_resched() to hns3 ring buffer init process

Yonglong Liu <[email protected]>
net: hns3: fix kernel crash problem in concurrent scenario

Csókás, Bence <[email protected]>
net: sfp: Always call sfp_sm_mod_remove() on remove

Masahiro Yamada <[email protected]>
modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of sk->sk_state in unix_accept().

Ian Forbes <[email protected]>
drm/vmwgfx: Don't memcmp equivalent pointers

Ian Forbes <[email protected]>
drm/vmwgfx: Remove STDU logic from generic mode_valid function

Ian Forbes <[email protected]>
drm/vmwgfx: 3D disabled should not effect STDU memory limits

Ian Forbes <[email protected]>
drm/vmwgfx: Filter modes which exceed graphics memory

José Expósito <[email protected]>
HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()

Su Hui <[email protected]>
io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue()

Breno Leitao <[email protected]>

    io_uring/io-wq: Use set_bit() and test_bit() at worker->flags

Lu Baolu <[email protected]>
iommu: Return right value in iommu_sva_bind_device()

Kun(llfl) <[email protected]>
iommu/amd: Fix sysfs leak in iommu init

Nikita Zhandarovich <[email protected]>
HID: core: remove unnecessary WARN_ON() in implement()

Matthias Schiffer <[email protected]>
gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type

Matthias Schiffer <[email protected]>
gpio: tqmx86: store IRQ trigger type and unmask status separately

Matthias Schiffer <[email protected]>
gpio: tqmx86: introduce shadow register for GPIO output value

Gregor Herburger <[email protected]>
gpio: tqmx86: fix typo in Kconfig label

Armin Wolf <[email protected]>
platform/x86: dell-smbios: Fix wrong token data in sysfs

Chen Ni <[email protected]>
drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation

Weiwen Hu <[email protected]>
nvme: fix nvme_pr_* status code parsing

John Hubbard <[email protected]>
selftests/futex: don't pass a const char* to asprintf(3)

Masami Hiramatsu (Google) <[email protected]>
selftests/tracing: Fix event filter test to retry up to 10 times

NeilBrown <[email protected]>
NFS: add barriers when testing for NFS_FSDATA_BLOCKED

Chen Hanxiao <[email protected]>
SUNRPC: return proper error from gss_wrap_req_priv

Olga Kornievskaia <[email protected]>
NFSv4.1 enforce rootpath check in fs_location query

Samuel Holland <[email protected]>
clk: sifive: Do not register clkdevs for PRCI clocks

Masami Hiramatsu (Google) <[email protected]>
selftests/ftrace: Fix to check required event file

Mark Brown <[email protected]>
kselftest/alsa: Ensure _GNU_SOURCE is defined

Baokun Li <[email protected]>
cachefiles: flush all requests after setting CACHEFILES_DEAD

Baokun Li <[email protected]>
cachefiles: defer exposing anon_fd until after copy_to_user() succeeds

Baokun Li <[email protected]>
cachefiles: never get a new anonymous fd if ondemand_id is valid

Baokun Li <[email protected]>
cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()

Baokun Li <[email protected]>
cachefiles: add spin_lock for cachefiles_ondemand_info

Baokun Li <[email protected]>
cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()

Baokun Li <[email protected]>
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()

Baokun Li <[email protected]>
cachefiles: remove requests from xarray during flushing requests

Baokun Li <[email protected]>
cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd

Li Zhijian <[email protected]>
cxl/region: Fix memregion leaks in devm_cxl_add_region()

Dave Jiang <[email protected]>
cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c

Chen Ni <[email protected]>
HID: nvidia-shield: Add missing check for input_ff_create_memless

Michael Ellerman <[email protected]>
powerpc/uaccess: Fix build errors seen with GCC 13/14

Hari Bathini <[email protected]>
powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP

Ziwei Xiao <[email protected]>

    gve: Clear napi->skb before dev_kfree_skb_any()

Martin K. Petersen <[email protected]>
scsi: sd: Use READ(16) when reading block zero on large capacity disks

Breno Leitao <[email protected]>
scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory

Damien Le Moal <[email protected]>
scsi: mpi3mr: Fix ATA NCQ priority support

Damien Le Moal <[email protected]>
scsi: core: Disable CDL by default

Damien Le Moal <[email protected]>
ata: libata-scsi: Set the RMB bit only for removable media devices

Aapo Vienamo <[email protected]>
thunderbolt: debugfs: Fix margin debugfs node creation condition

Kuangyi Chiang <[email protected]>
xhci: Apply broken streams quirk to Etron EJ188 xHCI host

Hector Martin <[email protected]>
xhci: Handle TD clearing for multiple streams case

Kuangyi Chiang <[email protected]>
xhci: Apply reset resume quirk to Etron EJ188 xHCI host

Mathias Nyman <[email protected]>
xhci: Set correct transferred length for cancelled bulk transfers

Greg Kroah-Hartman <[email protected]>
jfs: xattr: fix buffer overflow for invalid xattr

Mickaël Salaün <[email protected]>
landlock: Fix d_parent walk

Douglas Anderson <[email protected]>
serial: port: Don't block system suspend even if bytes are left to xmit

Doug Brown <[email protected]>
serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level

Ilpo Järvinen <[email protected]>
tty: n_tty: Fix buffer offsets when lookahead is used

Wentong Wu <[email protected]>
mei: vsc: Don't stop/restart mei device during system suspend/resume

Tomas Winkler <[email protected]>
mei: me: release irq in mei_me_pci_resume error path

Kyle Tso <[email protected]>
usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state

Amit Sunil Dhamne <[email protected]>
usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps

John Ernberg <[email protected]>
USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected

Andrey Konovalov <[email protected]>
kcov, usb: disable interrupts in kcov_remote_start_usb_softirq

Alan Stern <[email protected]>
USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages

Pavel Begunkov <[email protected]>

    io_uring: fix cancellation overwriting req->flags

Pavel Begunkov <[email protected]>
io_uring/rsrc: don't lock while !TASK_RUNNING

Greg Kroah-Hartman <[email protected]>
.editorconfig: remove trim_trailing_whitespace option

Steven Rostedt (Google) <[email protected]>
eventfs: Update all the eventfs_inodes from the events descriptor

Dev Jain <[email protected]>
selftests/mm: compaction_test: fix bogus test success and reduce probability of OOM-killer invocation

Nathan Chancellor <[email protected]>
selftests/mm: ksft_exit functions do not return

Dave Hansen <[email protected]>
x86/cpu: Provide default cache line size if not enumerated

Borislav Petkov (AMD) <[email protected]>
x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes()

Matthew Brost <[email protected]>
drm/xe: Use ordered WQ for G2H handler

Su Hui <[email protected]>
net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool()

Eric Dumazet <[email protected]>
ipv6: fix possible race in __fib6_drop_pcpu_from()

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().

Kuniyuki Iwashima <[email protected]>
af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().

Kuniyuki Iwashima <[email protected]>
af_unix: Use skb_queue_empty_lockless() in unix_release_sock().

Kuniyuki Iwashima <[email protected]>
af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-races around sk->sk_sndbuf.

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of sk->sk_state in unix_stream_connect().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-races around sk->sk_state in unix_write_space() and poll().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annotate data-race of sk->sk_state in unix_inq_len().

Kuniyuki Iwashima <[email protected]>

    af_unix: Annodate data-races around sk->sk_state for writers.

Kuniyuki Iwashima <[email protected]>

    af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted peer.

Aleksandr Mishin <[email protected]>
net: wwan: iosm: Fix tainted pointer delete is case of region creation fail

Sasha Neftin <[email protected]>
igc: Fix Energy Efficient Ethernet support declaration

Larysa Zaremba <[email protected]>
ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors()

Larysa Zaremba <[email protected]>
ice: add flag to distinguish reset from .ndo_bpf in XDP rings config

Larysa Zaremba <[email protected]>
ice: remove af_xdp_zc_qps bitmap

Jacob Keller <[email protected]>
ice: fix reads from NVM Shadow RAM on E830 and E825-C devices

Jacob Keller <[email protected]>
ice: fix iteration of TLVs in Preserved Fields Area

Karol Kolacinski <[email protected]>
ptp: Fix error message on failed pin verification

Eric Dumazet <[email protected]>
net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP

Aleksandr Mishin <[email protected]>
net/mlx5: Fix tainted pointer delete is case of flow rules creation fail

Shay Drory <[email protected]>
net/mlx5: Always stop health timer during driver removal

Moshe Shemesh <[email protected]>
net/mlx5: Stop waiting for PCI if pci channel is offline

Frank Wunderlich <[email protected]>
net: ethernet: mtk_eth_soc: handle dma buffer size soc specific

Jakub Kicinski <[email protected]>
rtnetlink: make the "split" NLM_DONE handling generic

Jason Xing <[email protected]>
mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB

Jason Xing <[email protected]>
tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB

Hangyu Hua <[email protected]>
net: sched: sch_multiq: fix possible OOB write in multiq_tune()

Taehee Yoo <[email protected]>
ionic: fix kernel panic in XDP_TX action

Tristram Ha <[email protected]>
net: phy: Micrel KSZ8061: fix errata solution not taking effect problem

Wen Gu <[email protected]>
net/smc: avoid overwriting when adjusting sock bufsizes

Subbaraya Sundeep <[email protected]>
octeontx2-af: Always allocate PF entries from low prioriy zone

Jiri Olsa <[email protected]>
bpf: Set run context for rawtp test_run callback

Jakub Kicinski <[email protected]>
net: tls: fix marking packets as decrypted

Eric Dumazet <[email protected]>
ipv6: sr: block BH in seg6_output_core() and seg6_input_core()

Eric Dumazet <[email protected]>
ipv6: ioam: block BH from ioam6_output()

Matthias Stocker <[email protected]>
vmxnet3: disable rx data ring on dma allocation failure

Ravi Bangoria <[email protected]>
KVM: SEV-ES: Delegate LBR virtualization to the processor

Ravi Bangoria <[email protected]>
KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent

Cong Wang <[email protected]>
bpf: Fix a potential use-after-free in bpf_link_free()

Tristram Ha <[email protected]>
net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume

DelphineCCChiu <[email protected]>
net/ncsi: Fix the multi thread manner of NCSI driver

Duoming Zhou <[email protected]>

    ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put()

Lars Kellogg-Stedman <[email protected]>
ax25: Fix refcount imbalance on inbound connections

Heng Qi <[email protected]>
virtio_net: fix possible dim status unrecoverable

Quan Zhou <[email protected]>
RISC-V: KVM: Fix incorrect reg_subtype labels in kvm_riscv_vcpu_set_reg_isa_ext function

Yong-Xuan Wang <[email protected]>
RISC-V: KVM: No need to use mask when hart-index-bit is 0

Chanwoo Lee <[email protected]>
scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort()

Lingbo Kong <[email protected]>
wifi: mac80211: correctly parse Spatial Reuse Parameter Set element

Lingbo Kong <[email protected]>
wifi: mac80211: fix Spatial Reuse element size check

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: mvm: don't read past the mfuart notifcation

Miri Korenblit <[email protected]>
wifi: iwlwifi: mvm: check n_ssids before accessing the ssids

Shahar S Matityahu <[email protected]>
wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef

Mordechay Goodstein <[email protected]>
wifi: iwlwifi: mvm: set properly mac header

Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64

Miri Korenblit <[email protected]>
wifi: iwlwifi: mvm: don't initialize csa_work twice

Aditya Kumar Singh <[email protected]>
wifi: mac80211: pass proper link id for channel switch started notification

Lin Ma <[email protected]>
wifi: cfg80211: pmsr: use correct nla_get_uX functions

Remi Pommarel <[email protected]>

    wifi: cfg80211: Lock wiphy in cfg80211_get_station

Johannes Berg <[email protected]>
wifi: cfg80211: fully move wiphy work to unbound workqueue

Remi Pommarel <[email protected]>

    wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()

Nicolas Escande <[email protected]>
wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects

Arnd Bergmann <[email protected]>
cpufreq: amd-pstate: remove global header file

Perry Yuan <[email protected]>
cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing

Perry Yuan <[email protected]>
cpufreq: amd-pstate: Unify computation of {max,min,nominal,lowest_nonlinear}_freq

Baochen Qiang <[email protected]>
wifi: ath11k: move power type check to ASSOC stage when connecting to 6 GHz AP

Carl Huang <[email protected]>
wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs

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

Diffstat:

 .editorconfig                                      |   3 -
 .../devicetree/bindings/usb/realtek,rts5411.yaml   |   1 +
 MAINTAINERS                                        |   1 -
 Makefile                                           |   4 +-
 arch/parisc/include/asm/cacheflush.h               |  15 +-
 arch/parisc/include/asm/pgtable.h                  |  27 +-
 arch/parisc/kernel/cache.c                         | 421 +++++++++++++--------
 arch/powerpc/include/asm/uaccess.h                 |  16 +
 arch/powerpc/platforms/85xx/smp.c                  |   9 +-
 arch/riscv/kvm/aia_device.c                        |   7 +-
 arch/riscv/kvm/vcpu_onereg.c                       |   4 +-
 arch/riscv/mm/init.c                               |  24 +-
 arch/riscv/mm/pageattr.c                           |  28 +-
 arch/x86/boot/compressed/Makefile                  |   4 +-
 arch/x86/boot/main.c                               |   4 +-
 arch/x86/include/asm/alternative.h                 |  22 +-
 arch/x86/include/asm/atomic64_32.h                 |   2 +-
 arch/x86/include/asm/cpufeature.h                  |   2 +-
 arch/x86/include/asm/irq_stack.h                   |   2 +-
 arch/x86/include/asm/uaccess.h                     |   6 +-
 arch/x86/kernel/amd_nb.c                           |   9 +-
 arch/x86/kernel/cpu/common.c                       |  21 +-
 arch/x86/kernel/machine_kexec_64.c                 |  11 +-
 arch/x86/kvm/svm/sev.c                             |  19 +-
 arch/x86/kvm/svm/svm.c                             |  24 +-
 arch/x86/kvm/svm/svm.h                             |   4 +-
 arch/x86/lib/getuser.S                             |   6 +-
 arch/x86/mm/numa.c                                 |   6 +-
 block/blk-flush.c                                  |   3 +-
 block/sed-opal.c                                   |   2 +-
 drivers/acpi/thermal.c                             |   8 +-
 drivers/acpi/x86/utils.c                           |  24 +-
 drivers/ata/ahci.c                                 |   1 -
 drivers/ata/libata-core.c                          |   9 +-
 drivers/ata/libata-scsi.c                          |   8 +-
 drivers/base/core.c                                |   3 +
 drivers/block/null_blk/zoned.c                     |   2 +-
 drivers/clk/sifive/sifive-prci.c                   |   8 -
 drivers/cpufreq/amd-pstate-ut.c                    |   3 +-
 drivers/cpufreq/amd-pstate.c                       | 209 ++++++----
 {include/linux => drivers/cpufreq}/amd-pstate.h    |  27 --
 drivers/cxl/core/region.c                          |  18 +-
 drivers/dma-buf/st-dma-fence.c                     |   6 +
 drivers/dma/dma-axi-dmac.c                         |   2 +-
 drivers/gpio/Kconfig                               |   2 +-
 drivers/gpio/gpio-tqmx86.c                         | 110 ++++--
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |   2 +-
 .../drm/arm/display/komeda/komeda_pipeline_state.c |   2 +-
 drivers/gpu/drm/bridge/panel.c                     |   7 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c      |   4 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c             |   3 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.c           |   7 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c               |   7 +-
 drivers/gpu/drm/i915/display/intel_audio.c         |  32 +-
 drivers/gpu/drm/i915/display/intel_audio.h         |   1 +
 .../gpu/drm/i915/display/intel_display_driver.c    |   2 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c        |   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h         |   4 +-
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c        |  15 +-
 drivers/gpu/drm/nouveau/dispnv04/disp.c            |   2 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c            |   4 +-
 drivers/gpu/drm/nouveau/nouveau_display.c          |   6 +-
 drivers/gpu/drm/nouveau/nouveau_drv.h              |   1 +
 drivers/gpu/drm/panel/panel-sitronix-st7789v.c     |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                |   7 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h                |   3 -
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c                |  28 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c               |  45 ++-
 drivers/gpu/drm/xe/xe_gt_idle.c                    |   9 +-
 drivers/gpu/drm/xe/xe_guc_ct.c                     |   4 +
 drivers/gpu/drm/xe/xe_guc_pc.c                     |  70 +---
 drivers/gpu/drm/xe/xe_guc_submit.c                 |   1 +
 drivers/gpu/drm/xe/xe_ring_ops.c                   |  18 +-
 drivers/greybus/interface.c                        |   1 +
 drivers/hid/hid-core.c                             |   1 -
 drivers/hid/hid-logitech-dj.c                      |   4 +-
 drivers/hid/hid-nvidia-shield.c                    |   4 +-
 drivers/hwtracing/intel_th/pci.c                   |  25 ++
 drivers/i2c/busses/i2c-at91-slave.c                |   3 +-
 drivers/i2c/busses/i2c-designware-slave.c          |   2 +-
 drivers/iio/adc/ad9467.c                           |   4 +-
 drivers/iio/adc/adi-axi-adc.c                      |   5 +
 .../iio/common/inv_sensors/inv_sensors_timestamp.c |  15 +-
 drivers/iio/dac/ad5592r-base.c                     |   2 +-
 drivers/iio/imu/bmi323/bmi323_core.c               |   5 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c  |   4 -
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c   |   4 -
 drivers/iio/pressure/bmp280-core.c                 |  10 +-
 drivers/iio/temperature/mcp9600.c                  |   3 +-
 drivers/iio/temperature/mlx90635.c                 |   6 +-
 drivers/iommu/amd/init.c                           |   9 +
 drivers/irqchip/irq-gic-v3-its.c                   |  44 +--
 drivers/irqchip/irq-sifive-plic.c                  |  34 +-
 drivers/leds/led-class.c                           |   6 -
 drivers/md/dm-integrity.c                          |   1 +
 drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c      |   9 +-
 drivers/misc/mei/pci-me.c                          |   4 +-
 drivers/misc/mei/platform-vsc.c                    |  39 +-
 drivers/misc/mei/vsc-fw-loader.c                   |   2 +-
 drivers/misc/vmw_vmci/vmci_event.c                 |   6 +-
 drivers/net/dsa/qca/qca8k-leds.c                   |  12 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h          |  51 +++
 drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c     |   2 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c    |  12 +-
 drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c  |  11 +-
 drivers/net/ethernet/google/gve/gve_rx_dqo.c       |   8 +-
 drivers/net/ethernet/google/gve/gve_tx_dqo.c       |  20 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c    |   4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h    |   2 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    |  21 +-
 drivers/net/ethernet/intel/ice/ice.h               |  44 ++-
 drivers/net/ethernet/intel/ice/ice_base.c          |   3 +
 drivers/net/ethernet/intel/ice/ice_lib.c           |  29 +-
 drivers/net/ethernet/intel/ice/ice_main.c          | 144 ++++---
 drivers/net/ethernet/intel/ice/ice_nvm.c           | 116 +++++-
 drivers/net/ethernet/intel/ice/ice_type.h          |  14 +-
 drivers/net/ethernet/intel/ice/ice_xsk.c           |  13 +-
 drivers/net/ethernet/intel/igc/igc_ethtool.c       |   9 +-
 drivers/net/ethernet/intel/igc/igc_main.c          |   4 +
 .../net/ethernet/marvell/octeontx2/af/rvu_npc.c    |  33 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 106 ++++--
 drivers/net/ethernet/mediatek/mtk_eth_soc.h        |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   3 +-
 drivers/net/ethernet/mellanox/mlx5/core/fw.c       |   4 +
 drivers/net/ethernet/mellanox/mlx5/core/health.c   |   8 +
 .../net/ethernet/mellanox/mlx5/core/lag/port_sel.c |   8 +-
 .../net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c  |   4 +
 drivers/net/ethernet/mellanox/mlx5/core/main.c     |   3 +
 drivers/net/ethernet/pensando/ionic/ionic_lif.c    |   4 +-
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c   |   1 +
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |   4 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c    |  25 +-
 drivers/net/geneve.c                               |  10 +-
 drivers/net/netdevsim/netdev.c                     |   3 +-
 drivers/net/phy/micrel.c                           | 104 ++++-
 drivers/net/phy/sfp.c                              |   3 +-
 drivers/net/virtio_net.c                           |   2 +-
 drivers/net/vmxnet3/vmxnet3_drv.c                  |   2 +-
 drivers/net/wireless/ath/ath11k/core.c             |   2 +-
 drivers/net/wireless/ath/ath11k/mac.c              |  38 +-
 drivers/net/wireless/intel/iwlwifi/fw/api/power.h  |  30 ++
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c       |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c        |  18 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |   4 +-
 .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c  |   2 -
 drivers/net/wireless/intel/iwlwifi/mvm/rs.h        |   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c      |   5 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c      |   4 +-
 drivers/net/wireless/mediatek/mt76/mt7615/main.c   |   4 +
 drivers/net/wireless/realtek/rtlwifi/core.c        |  15 -
 drivers/net/wwan/iosm/iosm_ipc_devlink.c           |   2 +-
 drivers/nvme/host/pr.c                             |   2 +-
 drivers/nvme/target/passthru.c                     |   6 +-
 drivers/pci/controller/pcie-rockchip-ep.c          |   6 +-
 drivers/platform/x86/dell/dell-smbios-base.c       |  92 ++---
 drivers/pmdomain/ti/ti_sci_pm_domains.c            |  20 +-
 drivers/ptp/ptp_chardev.c                          |   3 +-
 drivers/ras/amd/atl/internal.h                     |   2 +-
 drivers/ras/amd/atl/system.c                       |   2 +-
 drivers/ras/amd/atl/umc.c                          | 160 +++++---
 drivers/remoteproc/ti_k3_r5_remoteproc.c           |  58 ++-
 drivers/scsi/mpi3mr/mpi3mr_app.c                   |  62 +++
 drivers/scsi/mpt3sas/mpt3sas_base.c                |  19 +
 drivers/scsi/mpt3sas/mpt3sas_base.h                |   3 -
 drivers/scsi/mpt3sas/mpt3sas_ctl.c                 |   4 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c               |  23 --
 drivers/scsi/scsi.c                                |   7 +
 drivers/scsi/scsi_transport_sas.c                  |  23 ++
 drivers/scsi/sd.c                                  |  17 +-
 drivers/spmi/hisi-spmi-controller.c                |   1 -
 drivers/thermal/thermal_core.c                     |  13 +-
 drivers/thunderbolt/debugfs.c                      |   5 +-
 drivers/tty/n_tty.c                                |  22 +-
 drivers/tty/serial/8250/8250_dw.c                  |   9 +-
 drivers/tty/serial/8250/8250_dwlib.c               |   3 +-
 drivers/tty/serial/8250/8250_dwlib.h               |   3 +-
 drivers/tty/serial/8250/8250_pxa.c                 |   1 +
 drivers/tty/serial/serial_port.c                   |   7 +
 drivers/ufs/core/ufs-mcq.c                         |  17 +-
 drivers/ufs/core/ufshcd.c                          |   6 +-
 drivers/usb/Makefile                               |   1 +
 drivers/usb/class/cdc-wdm.c                        |   4 +-
 drivers/usb/core/hcd.c                             |  12 +-
 drivers/usb/host/xhci-pci.c                        |   7 +
 drivers/usb/host/xhci-ring.c                       |  59 ++-
 drivers/usb/host/xhci.h                            |   1 +
 drivers/usb/storage/alauda.c                       |   9 +-
 drivers/usb/typec/tcpm/tcpm.c                      |   5 +-
 fs/btrfs/zoned.c                                   |  13 +-
 fs/cachefiles/daemon.c                             |   3 +-
 fs/cachefiles/internal.h                           |   5 +
 fs/cachefiles/ondemand.c                           | 165 +++++---
 fs/jfs/xattr.c                                     |   4 +-
 fs/nfs/dir.c                                       |  47 ++-
 fs/nfs/nfs4proc.c                                  |  23 +-
 fs/nfsd/nfsfh.c                                    |   4 +-
 fs/ocfs2/file.c                                    |   2 +
 fs/ocfs2/namei.c                                   |   4 +-
 fs/proc/vmcore.c                                   |   2 +
 fs/smb/server/smb2pdu.c                            |  22 +-
 fs/smb/server/vfs.c                                |  17 +-
 fs/smb/server/vfs.h                                |   3 +-
 fs/smb/server/vfs_cache.c                          |   3 +-
 fs/tracefs/event_inode.c                           |  59 ++-
 include/drm/bridge/aux-bridge.h                    |   2 +-
 include/drm/display/drm_dp_mst_helper.h            |   1 -
 include/linux/atomic/atomic-arch-fallback.h        |   6 +-
 include/linux/atomic/atomic-instrumented.h         |   8 +-
 include/linux/atomic/atomic-long.h                 |   4 +-
 include/linux/io_uring_types.h                     |   3 +-
 include/linux/iommu.h                              |   2 +-
 include/linux/kcov.h                               |  47 ++-
 include/linux/kexec.h                              |   6 +-
 include/linux/pse-pd/pse.h                         |   4 +-
 include/net/bluetooth/hci_core.h                   |  36 +-
 include/net/ip_tunnels.h                           |   5 +-
 include/net/rtnetlink.h                            |   1 +
 include/scsi/scsi_transport_sas.h                  |   2 +
 include/trace/events/cachefiles.h                  |   8 +-
 io_uring/cancel.h                                  |   4 +-
 io_uring/io-wq.c                                   |  57 +--
 io_uring/io_uring.c                                |   1 +
 io_uring/rsrc.c                                    |   1 +
 kernel/bpf/syscall.c                               |  11 +-
 kernel/events/core.c                               |  13 +
 kernel/gen_kheaders.sh                             |   2 +-
 kernel/pid_namespace.c                             |   1 +
 kernel/time/tick-common.c                          |  42 +-
 mm/memblock.c                                      |   4 +
 mm/memory-failure.c                                |   7 +
 net/ax25/af_ax25.c                                 |   6 +
 net/ax25/ax25_dev.c                                |   2 +-
 net/bluetooth/hci_sync.c                           |   2 +-
 net/bluetooth/l2cap_core.c                         |  12 +-
 net/bpf/test_run.c                                 |   6 +
 net/bridge/br_mst.c                                |  13 +-
 net/core/rtnetlink.c                               |  44 ++-
 net/core/sock_map.c                                |  16 +-
 net/ethtool/ioctl.c                                |   2 +-
 net/ipv4/devinet.c                                 |   2 +-
 net/ipv4/fib_frontend.c                            |   7 +-
 net/ipv4/tcp.c                                     |   9 +-
 net/ipv4/tcp_timer.c                               |   6 +-
 net/ipv6/ioam6_iptunnel.c                          |   8 +-
 net/ipv6/ip6_fib.c                                 |   6 +-
 net/ipv6/route.c                                   |   5 +-
 net/ipv6/seg6_iptunnel.c                           |  14 +-
 net/ipv6/tcp_ipv6.c                                |   3 +-
 net/mac80211/cfg.c                                 |   4 +-
 net/mac80211/he.c                                  |  10 +-
 net/mac80211/mesh_pathtbl.c                        |  13 +
 net/mac80211/parse.c                               |   2 +-
 net/mac80211/sta_info.c                            |   4 +-
 net/mptcp/pm_netlink.c                             |  21 +-
 net/mptcp/protocol.c                               |  10 +-
 net/ncsi/internal.h                                |   2 +
 net/ncsi/ncsi-manage.c                             |  75 ++--
 net/ncsi/ncsi-rsp.c                                |   4 +-
 net/netfilter/ipset/ip_set_core.c                  |  93 +++--
 net/netfilter/ipset/ip_set_list_set.c              |  30 +-
 net/netfilter/nft_meta.c                           |   3 +
 net/netfilter/nft_payload.c                        |   4 +
 net/sched/sch_generic.c                            |   1 +
 net/sched/sch_multiq.c                             |   2 +-
 net/sched/sch_taprio.c                             |  15 +-
 net/smc/af_smc.c                                   |  22 +-
 net/sunrpc/auth_gss/auth_gss.c                     |   4 +-
 net/unix/af_unix.c                                 | 108 +++---
 net/unix/diag.c                                    |  12 +-
 net/wireless/core.c                                |   2 +-
 net/wireless/pmsr.c                                |   8 +-
 net/wireless/scan.c                                |   3 +-
 net/wireless/sysfs.c                               |   4 +-
 net/wireless/util.c                                |   7 +-
 scripts/atomic/kerneldoc/sub_and_test              |   2 +-
 scripts/mod/modpost.c                              |   5 +-
 security/integrity/ima/ima_api.c                   |  16 +-
 security/integrity/ima/ima_template_lib.c          |  17 +-
 security/landlock/fs.c                             |  13 +-
 tools/perf/builtin-script.c                        |   2 +-
 tools/perf/util/auxtrace.c                         |   4 +-
 tools/testing/cxl/test/mem.c                       |   1 +
 tools/testing/selftests/alsa/Makefile              |   2 +-
 .../ftrace/test.d/dynevent/test_duplicates.tc      |   2 +-
 .../ftrace/test.d/filter/event-filter-function.tc  |  20 +-
 .../ftrace/test.d/kprobe/kprobe_eventname.tc       |   3 +-
 .../selftests/futex/functional/futex_requeue_pi.c  |   2 +-
 tools/testing/selftests/mm/compaction_test.c       |  77 ++--
 tools/testing/selftests/mm/cow.c                   |   2 +-
 tools/testing/selftests/mm/gup_longterm.c          |   2 +-
 tools/testing/selftests/mm/gup_test.c              |   4 +-
 tools/testing/selftests/mm/ksm_functional_tests.c  |   2 +-
 tools/testing/selftests/mm/madv_populate.c         |   2 +-
 tools/testing/selftests/mm/mkdirty.c               |   2 +-
 tools/testing/selftests/mm/pagemap_ioctl.c         |   4 +-
 tools/testing/selftests/mm/soft-dirty.c            |   2 +-
 tools/testing/selftests/net/mptcp/mptcp_join.sh    |   5 +-
 tools/tracing/rtla/src/timerlat_aa.c               | 109 +++---
 tools/tracing/rtla/src/timerlat_top.c              |  17 +-
 299 files changed, 3209 insertions(+), 1761 deletions(-)
author maintainer
#1 lore raw

PATCH 1/281 wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs

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

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

From: Carl Huang <[email protected]>

[ Upstream commit ed281c6ab6eb8a914f06c74dfeaebde15b34a3f4 ]

WCN6750 firmware crashes because of num_vdevs changed from 4 to 17 in ath11k_init_wmi_config_qca6390() as the ab->hw_params.num_vdevs is 17. This is caused by commit f019f4dff2e4 ("wifi: ath11k: support 2 station interfaces") which assigns ab->hw_params.num_vdevs directly to config->num_vdevs in ath11k_init_wmi_config_qca6390(), therefore WCN6750 firmware crashes as it can't support such a big num_vdevs.

Fix it by assign 3 to num_vdevs in hw_params for WCN6750 as 3 is sufficient too.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01371-QCAMSLSWPLZ-1

---
 drivers/net/wireless/ath/ath11k/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/core.c +1 -1
index c78bce19bd754..5d07585e59c17 100644
@@ -595,7 +595,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 		.coldboot_cal_ftm = true,
 		.cbcal_restart_fw = false,
 		.fw_mem_mode = 0,
-		.num_vdevs = 16 + 1,
+		.num_vdevs = 3,
 		.num_peers = 512,
 		.supports_suspend = false,
 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
Signature · 1 line
2.43.0
author maintainer
#2 lore raw

PATCH 2/281 wifi: ath11k: move power type check to ASSOC stage when connecting to 6 GHz AP

In reply to Greg Kroah-Hartman

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

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

From: Baochen Qiang <[email protected]>

[ Upstream commit 6e16782d6b4a724f9c9dcd49471219643593b60c ]

With commit bc8a0fac8677 ("wifi: mac80211: don't set bss_conf in parsing") ath11k fails to connect to 6 GHz AP.

This is because currently ath11k checks AP's power type in ath11k_mac_op_assign_vif_chanctx() which would be called in AUTH stage. However with above commit power type is not available until ASSOC stage. As a result power type check fails and therefore connection fails.

Fix this by moving power type check to ASSOC stage, also move regulatory rules update there because it depends on power type.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30

Fixes bc8a0fac8677 ("wifi: mac80211: don't set bss_conf in parsing")
---
 drivers/net/wireless/ath/ath11k/mac.c | 38 ++++++++++++++++++---------
 1 file changed, 25 insertions(+), 13 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +25 -13
index 2fca415322aec..790277f547bb4 100644
@@ -7889,8 +7889,6 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
 	struct ath11k_base *ab = ar->ab;
 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
 	int ret;
-	struct cur_regulatory_info *reg_info;
-	enum ieee80211_ap_reg_power power_type;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -7901,17 +7899,6 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
 	if (ath11k_wmi_supports_6ghz_cc_ext(ar) &&
 	    ctx->def.chan->band == NL80211_BAND_6GHZ &&
 	    arvif->vdev_type == WMI_VDEV_TYPE_STA) {
-		reg_info = &ab->reg_info_store[ar->pdev_idx];
-		power_type = vif->bss_conf.power_type;
-
-		ath11k_dbg(ab, ATH11K_DBG_MAC, "chanctx power type %d\n", power_type);
-
-		if (power_type == IEEE80211_REG_UNSET_AP) {
-			ret = -EINVAL;
-			goto out;
-		}
-
-		ath11k_reg_handle_chan_list(ab, reg_info, power_type);
 		arvif->chanctx = *ctx;
 		ath11k_mac_parse_tx_pwr_env(ar, vif, ctx);
 	}
@@ -9525,6 +9512,8 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 	struct ath11k *ar = hw->priv;
 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
 	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+	enum ieee80211_ap_reg_power power_type;
+	struct cur_regulatory_info *reg_info;
 	struct ath11k_peer *peer;
 	int ret = 0;
 
@@ -9604,6 +9593,29 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 				ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n",
 					    sta->addr, arvif->vdev_id, ret);
 		}
+
+		if (!ret &&
+		    ath11k_wmi_supports_6ghz_cc_ext(ar) &&
+		    arvif->vdev_type == WMI_VDEV_TYPE_STA &&
+		    arvif->chanctx.def.chan &&
+		    arvif->chanctx.def.chan->band == NL80211_BAND_6GHZ) {
+			reg_info = &ar->ab->reg_info_store[ar->pdev_idx];
+			power_type = vif->bss_conf.power_type;
+
+			if (power_type == IEEE80211_REG_UNSET_AP) {
+				ath11k_warn(ar->ab, "invalid power type %d\n",
+					    power_type);
+				ret = -EINVAL;
+			} else {
+				ret = ath11k_reg_handle_chan_list(ar->ab,
+								  reg_info,
+								  power_type);
+				if (ret)
+					ath11k_warn(ar->ab,
+						    "failed to handle chan list with power type %d\n",
+						    power_type);
+			}
+		}
 	} else if (old_state == IEEE80211_STA_AUTHORIZED &&
 		   new_state == IEEE80211_STA_ASSOC) {
 		spin_lock_bh(&ar->ab->base_lock);
Signature · 1 line
2.43.0
author maintainer
#3 lore raw

PATCH 3/281 cpufreq: amd-pstate: Unify computation of {max,min,nominal,lowest_nonlinear}_freq

In reply to Greg Kroah-Hartman

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

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

From: Perry Yuan <[email protected]>

[ Upstream commit 5547c0ebfc2efdab6ee93a7fd4d9c411ad87013e ]

Currently the amd_get_{min, max, nominal, lowest_nonlinear}_freq() helpers computes the values of min_freq, max_freq, nominal_freq and lowest_nominal_freq respectively afresh from cppc_get_perf_caps(). This is not necessary as there are fields in cpudata to cache these values.

To simplify this, add a single helper function named amd_pstate_init_freq() which computes all these frequencies at once, and caches it in cpudata.

Use the cached values everywhere else in the code.

Stable-dep-of: 779b8a14afde ("cpufreq: amd-pstate: remove global header file")

---
 drivers/cpufreq/amd-pstate.c | 126 ++++++++++++++++-------------------
 1 file changed, 59 insertions(+), 67 deletions(-)
drivers/cpufreq/amd-pstate.c +59 -67
index e263db0385ab7..e8385ca32f1fc 100644
@@ -622,74 +622,22 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
 
 static int amd_get_min_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	/* Switch to khz */
-	return cppc_perf.lowest_freq * 1000;
+	return READ_ONCE(cpudata->min_freq);
 }
 
 static int amd_get_max_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-	u32 max_perf, max_freq, nominal_freq, nominal_perf;
-	u64 boost_ratio;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	nominal_freq = cppc_perf.nominal_freq;
-	nominal_perf = READ_ONCE(cpudata->nominal_perf);
-	max_perf = READ_ONCE(cpudata->highest_perf);
-
-	boost_ratio = div_u64(max_perf << SCHED_CAPACITY_SHIFT,
-			      nominal_perf);
-
-	max_freq = nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT;
-
-	/* Switch to khz */
-	return max_freq * 1000;
+	return READ_ONCE(cpudata->max_freq);
 }
 
 static int amd_get_nominal_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	/* Switch to khz */
-	return cppc_perf.nominal_freq * 1000;
+	return READ_ONCE(cpudata->nominal_freq);
 }
 
 static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-	u32 lowest_nonlinear_freq, lowest_nonlinear_perf,
-	    nominal_freq, nominal_perf;
-	u64 lowest_nonlinear_ratio;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	nominal_freq = cppc_perf.nominal_freq;
-	nominal_perf = READ_ONCE(cpudata->nominal_perf);
-
-	lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
-
-	lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
-					 nominal_perf);
-
-	lowest_nonlinear_freq = nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT;
-
-	/* Switch to khz */
-	return lowest_nonlinear_freq * 1000;
+	return READ_ONCE(cpudata->lowest_nonlinear_freq);
 }
 
 static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
@@ -844,6 +792,53 @@ static void amd_pstate_update_limits(unsigned int cpu)
 	mutex_unlock(&amd_pstate_driver_lock);
 }
 
+/**
+ * amd_pstate_init_freq: Initialize the max_freq, min_freq,
+ *                       nominal_freq and lowest_nonlinear_freq for
+ *                       the @cpudata object.
+ *
+ *  Requires: highest_perf, lowest_perf, nominal_perf and
+ *            lowest_nonlinear_perf members of @cpudata to be
+ *            initialized.
+ *
+ *  Returns 0 on success, non-zero value on failure.
+ */
+static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
+{
+	int ret;
+	u32 min_freq;
+	u32 highest_perf, max_freq;
+	u32 nominal_perf, nominal_freq;
+	u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
+	u32 boost_ratio, lowest_nonlinear_ratio;
+	struct cppc_perf_caps cppc_perf;
+
+
+	ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+	if (ret)
+		return ret;
+
+	min_freq = cppc_perf.lowest_freq * 1000;
+	nominal_freq = cppc_perf.nominal_freq;
+	nominal_perf = READ_ONCE(cpudata->nominal_perf);
+
+	highest_perf = READ_ONCE(cpudata->highest_perf);
+	boost_ratio = div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
+	max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
+
+	lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
+	lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
+					 nominal_perf);
+	lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
+
+	WRITE_ONCE(cpudata->min_freq, min_freq);
+	WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);
+	WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
+	WRITE_ONCE(cpudata->max_freq, max_freq);
+
+	return 0;
+}
+
 static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 {
 	int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
@@ -871,6 +866,10 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 	if (ret)
 		goto free_cpudata1;
 
+	ret = amd_pstate_init_freq(cpudata);
+	if (ret)
+		goto free_cpudata1;
+
 	min_freq = amd_get_min_freq(cpudata);
 	max_freq = amd_get_max_freq(cpudata);
 	nominal_freq = amd_get_nominal_freq(cpudata);
@@ -912,13 +911,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 		goto free_cpudata2;
 	}
 
-	/* Initial processor data capability frequencies */
-	cpudata->max_freq = max_freq;
-	cpudata->min_freq = min_freq;
 	cpudata->max_limit_freq = max_freq;
 	cpudata->min_limit_freq = min_freq;
-	cpudata->nominal_freq = nominal_freq;
-	cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
 
 	policy->driver_data = cpudata;
 
@@ -1333,6 +1327,10 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 	if (ret)
 		goto free_cpudata1;
 
+	ret = amd_pstate_init_freq(cpudata);
+	if (ret)
+		goto free_cpudata1;
+
 	min_freq = amd_get_min_freq(cpudata);
 	max_freq = amd_get_max_freq(cpudata);
 	nominal_freq = amd_get_nominal_freq(cpudata);
@@ -1349,12 +1347,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 	/* It will be updated by governor */
 	policy->cur = policy->cpuinfo.min_freq;
 
-	/* Initial processor data capability frequencies */
-	cpudata->max_freq = max_freq;
-	cpudata->min_freq = min_freq;
-	cpudata->nominal_freq = nominal_freq;
-	cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
-
 	policy->driver_data = cpudata;
 
 	cpudata->epp_cached = amd_pstate_get_epp(cpudata, 0);
Signature · 1 line
2.43.0
author maintainer
#4 lore raw

PATCH 4/281 cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing

In reply to Greg Kroah-Hartman

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

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

From: Perry Yuan <[email protected]>

[ Upstream commit eb8b6c36820214df96e7e86d8614d93f6b028f28 ]

Add quirks table to get CPPC capabilities issue fixed by providing correct perf or frequency values while driver loading.

If CPPC capabilities are not defined in the ACPI tables or wrongly defined by platform firmware, it needs to use quick to get those issues fixed with correct workaround values to make pstate driver can be loaded even though there are CPPC capabilities errors.

The workaround will match the broken BIOS which lack of CPPC capabilities nominal_freq and lowest_freq definition in the ACPI table.

$ cat /sys/devices/system/cpu/cpu0/acpi_cppc/lowest_freq
0
$ cat /sys/devices/system/cpu/cpu0/acpi_cppc/nominal_freq
0

Stable-dep-of: 779b8a14afde ("cpufreq: amd-pstate: remove global header file")

---
 drivers/cpufreq/amd-pstate.c | 53 ++++++++++++++++++++++++++++++++++--
 include/linux/amd-pstate.h   |  6 ++++
 2 files changed, 57 insertions(+), 2 deletions(-)
drivers/cpufreq/amd-pstate.c +51 -2
index e8385ca32f1fc..605b037913ff8 100644
@@ -68,6 +68,7 @@ static struct cpufreq_driver amd_pstate_epp_driver;
 static int cppc_state = AMD_PSTATE_UNDEFINED;
 static bool cppc_enabled;
 static bool amd_pstate_prefcore = true;
+static struct quirk_entry *quirks;
 
 /*
  * AMD Energy Preference Performance (EPP)
@@ -112,6 +113,41 @@ static unsigned int epp_values[] = {
 
 typedef int (*cppc_mode_transition_fn)(int);
 
+static struct quirk_entry quirk_amd_7k62 = {
+	.nominal_freq = 2600,
+	.lowest_freq = 550,
+};
+
+static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
+{
+	/**
+	 * match the broken bios for family 17h processor support CPPC V2
+	 * broken BIOS lack of nominal_freq and lowest_freq capabilities
+	 * definition in ACPI tables
+	 */
+	if (boot_cpu_has(X86_FEATURE_ZEN2)) {
+		quirks = dmi->driver_data;
+		pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
+		return 1;
+	}
+
+	return 0;
+}
+
+static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
+	{
+		.callback = dmi_matched_7k62_bios_bug,
+		.ident = "AMD EPYC 7K62",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VERSION, "5.14"),
+			DMI_MATCH(DMI_BIOS_RELEASE, "12/12/2019"),
+		},
+		.driver_data = &quirk_amd_7k62,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table);
+
 static inline int get_mode_idx_from_str(const char *str, size_t size)
 {
 	int i;
@@ -818,8 +854,16 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
 	if (ret)
 		return ret;
 
-	min_freq = cppc_perf.lowest_freq * 1000;
-	nominal_freq = cppc_perf.nominal_freq;
+	if (quirks && quirks->lowest_freq)
+		min_freq = quirks->lowest_freq * 1000;
+	else
+		min_freq = cppc_perf.lowest_freq * 1000;
+
+	if (quirks && quirks->nominal_freq)
+		nominal_freq = quirks->nominal_freq ;
+	else
+		nominal_freq = cppc_perf.nominal_freq;
+
 	nominal_perf = READ_ONCE(cpudata->nominal_perf);
 
 	highest_perf = READ_ONCE(cpudata->highest_perf);
@@ -1664,6 +1708,11 @@ static int __init amd_pstate_init(void)
 	if (cpufreq_get_current_driver())
 		return -EEXIST;
 
+	quirks = NULL;
+
+	/* check if this machine need CPPC quirks */
+	dmi_check_system(amd_pstate_quirks_table);
+
 	switch (cppc_state) {
 	case AMD_PSTATE_UNDEFINED:
 		/* Disable on the following configs by default:
include/linux/amd-pstate.h +6 -0
index d21838835abda..7b2cbb892fd91 100644
@@ -124,4 +124,10 @@ static const char * const amd_pstate_mode_string[] = {
 	[AMD_PSTATE_GUIDED]      = "guided",
 	NULL,
 };
+
+struct quirk_entry {
+	u32 nominal_freq;
+	u32 lowest_freq;
+};
+
 #endif /* _LINUX_AMD_PSTATE_H */
Signature · 1 line
2.43.0
author maintainer
#5 lore raw

PATCH 5/281 cpufreq: amd-pstate: remove global header file

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

[ Upstream commit 779b8a14afde110dd3502566be907289eba72447 ]

When extra warnings are enabled, gcc points out a global variable definition in a header:

In file included from drivers/cpufreq/amd-pstate-ut.c:29:
include/linux/amd-pstate.h:123:27: error: 'amd_pstate_mode_string' defined but not used [-Werror=unused-const-variable=]

  123 | static const char * const amd_pstate_mode_string[] = {
      |                           ^~~~~~~~~~~~~~~~~~~~~~

This header is only included from two files in the same directory, and one of them uses only a single definition from it, so clean it up by moving most of the contents into the driver that uses them, and making shared bits a local header file.

Fixes 36c5014e5460 ("cpufreq: amd-pstate: optimize driver working mode selection in amd_pstate_param()")
---
 MAINTAINERS                                   |  1 -
 drivers/cpufreq/amd-pstate-ut.c               |  3 +-
 drivers/cpufreq/amd-pstate.c                  | 34 ++++++++++++++++++-
 .../linux => drivers/cpufreq}/amd-pstate.h    | 33 ------------------
 4 files changed, 35 insertions(+), 36 deletions(-)
 rename {include/linux => drivers/cpufreq}/amd-pstate.h (81%)
MAINTAINERS +0 -1
index 28e20975c26f5..3121709d99e3b 100644
@@ -1066,7 +1066,6 @@ L:	[email protected]
 S:	Supported
 F:	Documentation/admin-guide/pm/amd-pstate.rst
 F:	drivers/cpufreq/amd-pstate*
-F:	include/linux/amd-pstate.h
 F:	tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
 
 AMD PTDMA DRIVER
drivers/cpufreq/amd-pstate-ut.c +2 -1
index f04ae67dda372..fc275d41d51e9 100644
@@ -26,10 +26,11 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/fs.h>
-#include <linux/amd-pstate.h>
 
 #include <acpi/cppc_acpi.h>
 
+#include "amd-pstate.h"
+
 /*
  * Abbreviations:
  * amd_pstate_ut: used as a shortform for AMD P-State unit test.
drivers/cpufreq/amd-pstate.c +33 -1
index 605b037913ff8..6c989d859b396 100644
@@ -36,7 +36,6 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/static_call.h>
-#include <linux/amd-pstate.h>
 #include <linux/topology.h>
 
 #include <acpi/processor.h>
@@ -46,6 +45,8 @@
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_device_id.h>
+
+#include "amd-pstate.h"
 #include "amd-pstate-trace.h"
 
 #define AMD_PSTATE_TRANSITION_LATENCY	20000
@@ -53,6 +54,37 @@
 #define CPPC_HIGHEST_PERF_PERFORMANCE	196
 #define CPPC_HIGHEST_PERF_DEFAULT	166
 
+#define AMD_CPPC_EPP_PERFORMANCE		0x00
+#define AMD_CPPC_EPP_BALANCE_PERFORMANCE	0x80
+#define AMD_CPPC_EPP_BALANCE_POWERSAVE		0xBF
+#define AMD_CPPC_EPP_POWERSAVE			0xFF
+
+/*
+ * enum amd_pstate_mode - driver working mode of amd pstate
+ */
+enum amd_pstate_mode {
+	AMD_PSTATE_UNDEFINED = 0,
+	AMD_PSTATE_DISABLE,
+	AMD_PSTATE_PASSIVE,
+	AMD_PSTATE_ACTIVE,
+	AMD_PSTATE_GUIDED,
+	AMD_PSTATE_MAX,
+};
+
+static const char * const amd_pstate_mode_string[] = {
+	[AMD_PSTATE_UNDEFINED]   = "undefined",
+	[AMD_PSTATE_DISABLE]     = "disable",
+	[AMD_PSTATE_PASSIVE]     = "passive",
+	[AMD_PSTATE_ACTIVE]      = "active",
+	[AMD_PSTATE_GUIDED]      = "guided",
+	NULL,
+};
+
+struct quirk_entry {
+	u32 nominal_freq;
+	u32 lowest_freq;
+};
+
 /*
  * TODO: We need more time to fine tune processors with shared memory solution
  * with community together.
drivers/cpufreq/amd-pstate.h renamed from include/linux/amd-pstate.h +0 -33
similarity index 81%
rename from include/linux/amd-pstate.h
rename to drivers/cpufreq/amd-pstate.h
index 7b2cbb892fd91..bc341f35908d7 100644
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * linux/include/linux/amd-pstate.h
- *
  * Copyright (C) 2022 Advanced Micro Devices, Inc.
  *
  * Author: Meng Li <[email protected]>
@@ -12,11 +10,6 @@
 
 #include <linux/pm_qos.h>
 
-#define AMD_CPPC_EPP_PERFORMANCE		0x00
-#define AMD_CPPC_EPP_BALANCE_PERFORMANCE	0x80
-#define AMD_CPPC_EPP_BALANCE_POWERSAVE		0xBF
-#define AMD_CPPC_EPP_POWERSAVE			0xFF
-
 /*********************************************************************
  *                        AMD P-state INTERFACE                       *
  *********************************************************************/
@@ -104,30 +97,4 @@ struct amd_cpudata {
 	bool	suspended;
 };
 
-/*
- * enum amd_pstate_mode - driver working mode of amd pstate
- */
-enum amd_pstate_mode {
-	AMD_PSTATE_UNDEFINED = 0,
-	AMD_PSTATE_DISABLE,
-	AMD_PSTATE_PASSIVE,
-	AMD_PSTATE_ACTIVE,
-	AMD_PSTATE_GUIDED,
-	AMD_PSTATE_MAX,
-};
-
-static const char * const amd_pstate_mode_string[] = {
-	[AMD_PSTATE_UNDEFINED]   = "undefined",
-	[AMD_PSTATE_DISABLE]     = "disable",
-	[AMD_PSTATE_PASSIVE]     = "passive",
-	[AMD_PSTATE_ACTIVE]      = "active",
-	[AMD_PSTATE_GUIDED]      = "guided",
-	NULL,
-};
-
-struct quirk_entry {
-	u32 nominal_freq;
-	u32 lowest_freq;
-};
-
 #endif /* _LINUX_AMD_PSTATE_H */
Signature · 1 line
2.43.0
author maintainer
#6 lore raw

PATCH 6/281 wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects

In reply to Greg Kroah-Hartman

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

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

From: Nicolas Escande <[email protected]>

[ Upstream commit b7d7f11a291830fdf69d3301075dd0fb347ced84 ]

The hwmp code use objects of type mesh_preq_queue, added to a list in ieee80211_if_mesh, to keep track of mpath we need to resolve. If the mpath gets deleted, ex mesh interface is removed, the entries in that list will never get cleaned. Fix this by flushing all corresponding items of the preq_queue in mesh_path_flush_pending().

This should take care of KASAN reports like this:

unreferenced object 0xffff00000668d800 (size 128):
comm "kworker/u8:4", pid 67, jiffies 4295419552 (age 1836.444s) hex dump (first 32 bytes):

    00 1f 05 09 00 00 ff ff 00 d5 68 06 00 00 ff ff  ..........h.....
    8e 97 ea eb 3e b8 01 00 00 00 00 00 00 00 00 00  ....>...........
  backtrace:
    [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c
    [<00000000049bd418>] kmalloc_trace+0x34/0x80
    [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8
    [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c
    [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4
    [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764
    [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4
    [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440
    [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c
    [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4
    [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508
    [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c
    [<00000000b36425d1>] worker_thread+0x9c/0x634
    [<0000000005852dd5>] kthread+0x1bc/0x1c4
    [<000000005fccd770>] ret_from_fork+0x10/0x20
unreferenced object 0xffff000009051f00 (size 128):
  comm "kworker/u8:4", pid 67, jiffies 4295419553 (age 1836.440s)
  hex dump (first 32 bytes):
    90 d6 92 0d 00 00 ff ff 00 d8 68 06 00 00 ff ff  ..........h.....
    36 27 92 e4 02 e0 01 00 00 58 79 06 00 00 ff ff  6'.......Xy.....
  backtrace:
    [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c
    [<00000000049bd418>] kmalloc_trace+0x34/0x80
    [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8
    [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c
    [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4
    [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764
    [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4
    [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440
    [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c
    [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4
    [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508
    [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c
    [<00000000b36425d1>] worker_thread+0x9c/0x634
    [<0000000005852dd5>] kthread+0x1bc/0x1c4
    [<000000005fccd770>] ret_from_fork+0x10/0x20
Fixes 050ac52cbe1f ("mac80211: code for on-demand Hybrid Wireless Mesh Protocol")
---
 net/mac80211/mesh_pathtbl.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
net/mac80211/mesh_pathtbl.c +13 -0
index a6b62169f0848..c0a5c75cddcb9 100644
@@ -1017,10 +1017,23 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
  */
 void mesh_path_flush_pending(struct mesh_path *mpath)
 {
+	struct ieee80211_sub_if_data *sdata = mpath->sdata;
+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	struct mesh_preq_queue *preq, *tmp;
 	struct sk_buff *skb;
 
 	while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
 		mesh_path_discard_frame(mpath->sdata, skb);
+
+	spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
+	list_for_each_entry_safe(preq, tmp, &ifmsh->preq_queue.list, list) {
+		if (ether_addr_equal(mpath->dst, preq->dst)) {
+			list_del(&preq->list);
+			kfree(preq);
+			--ifmsh->preq_queue_len;
+		}
+	}
+	spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
 }
 
 /**
Signature · 1 line
2.43.0
author maintainer
#7 lore raw

PATCH 7/281 wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()

In reply to Greg Kroah-Hartman

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

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

From: Remi Pommarel <[email protected]>

[ Upstream commit 44c06bbde6443de206b30f513100b5670b23fc5e ]

The ieee80211_sta_ps_deliver_wakeup() function takes sta->ps_lock to synchronizes with ieee80211_tx_h_unicast_ps_buf() which is called from softirq context. However using only spin_lock() to get sta->ps_lock in ieee80211_sta_ps_deliver_wakeup() does not prevent softirq to execute on this same CPU, to run ieee80211_tx_h_unicast_ps_buf() and try to take this same lock ending in deadlock. Below is an example of rcu stall that arises in such situation.

 rcu: INFO: rcu_sched self-detected stall on CPU
 rcu:    2-....: (42413413 ticks this GP) idle=b154/1/0x4000000000000000 softirq=1763/1765 fqs=21206996
 rcu:    (t=42586894 jiffies g=2057 q=362405 ncpus=4)
 CPU: 2 PID: 719 Comm: wpa_supplicant Tainted: G        W          6.4.0-02158-g1b062f552873 #742
 Hardware name: RPT (r1) (DT)
 pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : queued_spin_lock_slowpath+0x58/0x2d0
 lr : invoke_tx_handlers_early+0x5b4/0x5c0
 sp : ffff00001ef64660
 x29: ffff00001ef64660 x28: ffff000009bc1070 x27: ffff000009bc0ad8
 x26: ffff000009bc0900 x25: ffff00001ef647a8 x24: 0000000000000000
 x23: ffff000009bc0900 x22: ffff000009bc0900 x21: ffff00000ac0e000
 x20: ffff00000a279e00 x19: ffff00001ef646e8 x18: 0000000000000000
 x17: ffff800016468000 x16: ffff00001ef608c0 x15: 0010533c93f64f80
 x14: 0010395c9faa3946 x13: 0000000000000000 x12: 00000000fa83b2da
 x11: 000000012edeceea x10: ffff0000010fbe00 x9 : 0000000000895440
 x8 : 000000000010533c x7 : ffff00000ad8b740 x6 : ffff00000c350880
 x5 : 0000000000000007 x4 : 0000000000000001 x3 : 0000000000000000
 x2 : 0000000000000000 x1 : 0000000000000001 x0 : ffff00000ac0e0e8
 Call trace:
  queued_spin_lock_slowpath+0x58/0x2d0
  ieee80211_tx+0x80/0x12c
  ieee80211_tx_pending+0x110/0x278
  tasklet_action_common.constprop.0+0x10c/0x144
  tasklet_action+0x20/0x28
  _stext+0x11c/0x284
  ____do_softirq+0xc/0x14
  call_on_irq_stack+0x24/0x34
  do_softirq_own_stack+0x18/0x20
  do_softirq+0x74/0x7c
  __local_bh_enable_ip+0xa0/0xa4
  _ieee80211_wake_txqs+0x3b0/0x4b8
  __ieee80211_wake_queue+0x12c/0x168
  ieee80211_add_pending_skbs+0xec/0x138
  ieee80211_sta_ps_deliver_wakeup+0x2a4/0x480
  ieee80211_mps_sta_status_update.part.0+0xd8/0x11c
  ieee80211_mps_sta_status_update+0x18/0x24
  sta_apply_parameters+0x3bc/0x4c0
  ieee80211_change_station+0x1b8/0x2dc
  nl80211_set_station+0x444/0x49c
  genl_family_rcv_msg_doit.isra.0+0xa4/0xfc
  genl_rcv_msg+0x1b0/0x244
  netlink_rcv_skb+0x38/0x10c
  genl_rcv+0x34/0x48
  netlink_unicast+0x254/0x2bc
  netlink_sendmsg+0x190/0x3b4
  ____sys_sendmsg+0x1e8/0x218
  ___sys_sendmsg+0x68/0x8c
  __sys_sendmsg+0x44/0x84
  __arm64_sys_sendmsg+0x20/0x28
  do_el0_svc+0x6c/0xe8
  el0_svc+0x14/0x48
  el0t_64_sync_handler+0xb0/0xb4
  el0t_64_sync+0x14c/0x150

Using spin_lock_bh()/spin_unlock_bh() instead prevents softirq to raise on the same CPU that is holding the lock.

---
 net/mac80211/sta_info.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac80211/sta_info.c +2 -2
index da5fdd6f5c852..aa22f09e6d145 100644
@@ -1724,7 +1724,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 	skb_queue_head_init(&pending);
 
 	/* sync with ieee80211_tx_h_unicast_ps_buf */
-	spin_lock(&sta->ps_lock);
+	spin_lock_bh(&sta->ps_lock);
 	/* Send all buffered frames to the station */
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		int count = skb_queue_len(&pending), tmp;
@@ -1753,7 +1753,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 	 */
 	clear_sta_flag(sta, WLAN_STA_PSPOLL);
 	clear_sta_flag(sta, WLAN_STA_UAPSD);
-	spin_unlock(&sta->ps_lock);
+	spin_unlock_bh(&sta->ps_lock);
 
 	atomic_dec(&ps->num_sta_ps);
 
Signature · 1 line
2.43.0
author maintainer
#8 lore raw

PATCH 8/281 wifi: cfg80211: fully move wiphy work to unbound workqueue

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

[ Upstream commit e296c95eac655008d5a709b8cf54d0018da1c916 ]

Previously I had moved the wiphy work to the unbound system workqueue, but missed that when it restarts and during resume it was still using the normal system workqueue. Fix that.

---
 net/wireless/core.c  | 2 +-
 net/wireless/sysfs.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
net/wireless/core.c +1 -1
index 3fb1b637352a9..4b1f45e3070e0 100644
@@ -431,7 +431,7 @@ static void cfg80211_wiphy_work(struct work_struct *work)
 	if (wk) {
 		list_del_init(&wk->entry);
 		if (!list_empty(&rdev->wiphy_work_list))
-			schedule_work(work);
+			queue_work(system_unbound_wq, work);
 		spin_unlock_irq(&rdev->wiphy_work_lock);
 
 		wk->func(&rdev->wiphy, wk);
net/wireless/sysfs.c +2 -2
index 565511a3f461e..62f26618f6747 100644
@@ -5,7 +5,7 @@
  *
  * Copyright 2005-2006	Jiri Benc <[email protected]>
  * Copyright 2006	Johannes Berg <[email protected]>
- * Copyright (C) 2020-2021, 2023 Intel Corporation
+ * Copyright (C) 2020-2021, 2023-2024 Intel Corporation
  */
 
 #include <linux/device.h>
@@ -137,7 +137,7 @@ static int wiphy_resume(struct device *dev)
 	if (rdev->wiphy.registered && rdev->ops->resume)
 		ret = rdev_resume(rdev);
 	rdev->suspended = false;
-	schedule_work(&rdev->wiphy_work);
+	queue_work(system_unbound_wq, &rdev->wiphy_work);
 	wiphy_unlock(&rdev->wiphy);
 
 	if (ret)
Signature · 1 line
2.43.0
author maintainer
#9 lore raw

PATCH 9/281 wifi: cfg80211: Lock wiphy in cfg80211_get_station

In reply to Greg Kroah-Hartman

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

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

From: Remi Pommarel <[email protected]>

[ Upstream commit 642f89daa34567d02f312d03e41523a894906dae ]

Wiphy should be locked before calling rdev_get_station() (see lockdep assert in ieee80211_get_station()).

This fixes the following kernel NULL dereference:

 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050
 Mem abort info:
   ESR = 0x0000000096000006
   EC = 0x25: DABT (current EL), IL = 32 bits
   SET = 0, FnV = 0
   EA = 0, S1PTW = 0
   FSC = 0x06: level 2 translation fault
 Data abort info:
   ISV = 0, ISS = 0x00000006
   CM = 0, WnR = 0
 user pgtable: 4k pages, 48-bit VAs, pgdp=0000000003001000
 [0000000000000050] pgd=0800000002dca003, p4d=0800000002dca003, pud=08000000028e9003, pmd=0000000000000000
 Internal error: Oops: 0000000096000006 [#1] SMP
 Modules linked in: netconsole dwc3_meson_g12a dwc3_of_simple dwc3 ip_gre gre ath10k_pci ath10k_core ath9k ath9k_common ath9k_hw ath
 CPU: 0 PID: 1091 Comm: kworker/u8:0 Not tainted 6.4.0-02144-g565f9a3a7911-dirty #705
 Hardware name: RPT (r1) (DT)
 Workqueue: bat_events batadv_v_elp_throughput_metric_update
 pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : ath10k_sta_statistics+0x10/0x2dc [ath10k_core]
 lr : sta_set_sinfo+0xcc/0xbd4
 sp : ffff000007b43ad0
 x29: ffff000007b43ad0 x28: ffff0000071fa900 x27: ffff00000294ca98
 x26: ffff000006830880 x25: ffff000006830880 x24: ffff00000294c000
 x23: 0000000000000001 x22: ffff000007b43c90 x21: ffff800008898acc
 x20: ffff00000294c6e8 x19: ffff000007b43c90 x18: 0000000000000000
 x17: 445946354d552d78 x16: 62661f7200000000 x15: 57464f445946354d
 x14: 0000000000000000 x13: 00000000000000e3 x12: d5f0acbcebea978e
 x11: 00000000000000e3 x10: 000000010048fe41 x9 : 0000000000000000
 x8 : ffff000007b43d90 x7 : 000000007a1e2125 x6 : 0000000000000000
 x5 : ffff0000024e0900 x4 : ffff800000a0250c x3 : ffff000007b43c90
 x2 : ffff00000294ca98 x1 : ffff000006831920 x0 : 0000000000000000
 Call trace:
  ath10k_sta_statistics+0x10/0x2dc [ath10k_core]
  sta_set_sinfo+0xcc/0xbd4
  ieee80211_get_station+0x2c/0x44
  cfg80211_get_station+0x80/0x154
  batadv_v_elp_get_throughput+0x138/0x1fc
  batadv_v_elp_throughput_metric_update+0x1c/0xa4
  process_one_work+0x1ec/0x414
  worker_thread+0x70/0x46c
  kthread+0xdc/0xe0
  ret_from_fork+0x10/0x20
 Code: a9bb7bfd 910003fd a90153f3 f9411c40 (f9402814)

This happens because STA has time to disconnect and reconnect before batadv_v_elp_throughput_metric_update() delayed work gets scheduled. In this situation, ath10k_sta_state() can be in the middle of resetting arsta data when the work queue get chance to be scheduled and ends up accessing it. Locking wiphy prevents that.

---
 net/wireless/util.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/wireless/util.c +6 -1
index 2bde8a3546313..082c6f9c5416e 100644
@@ -2549,6 +2549,7 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
 {
 	struct cfg80211_registered_device *rdev;
 	struct wireless_dev *wdev;
+	int ret;
 
 	wdev = dev->ieee80211_ptr;
 	if (!wdev)
@@ -2560,7 +2561,11 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
 
 	memset(sinfo, 0, sizeof(*sinfo));
 
-	return rdev_get_station(rdev, dev, mac_addr, sinfo);
+	wiphy_lock(&rdev->wiphy);
+	ret = rdev_get_station(rdev, dev, mac_addr, sinfo);
+	wiphy_unlock(&rdev->wiphy);
+
+	return ret;
 }
 EXPORT_SYMBOL(cfg80211_get_station);
 
Signature · 1 line
2.43.0
author maintainer
#10 lore raw

PATCH 10/281 wifi: cfg80211: pmsr: use correct nla_get_uX functions

In reply to Greg Kroah-Hartman

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

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

From: Lin Ma <[email protected]>

[ Upstream commit ab904521f4de52fef4f179d2dfc1877645ef5f5c ]

The commit 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM initiator API") defines four attributes NL80211_PMSR_FTM_REQ_ATTR_ {NUM_BURSTS_EXP}/{BURST_PERIOD}/{BURST_DURATION}/{FTMS_PER_BURST} in following ways.

static const struct nla_policy

nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
    ...
    [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
        NLA_POLICY_MAX(NLA_U8, 15),
    [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
    [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
        NLA_POLICY_MAX(NLA_U8, 15),
    [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
        NLA_POLICY_MAX(NLA_U8, 31),
    ...
};

That is, those attributes are expected to be NLA_U8 and NLA_U16 types. However, the consumers of these attributes in pmsr_parse_ftm blindly all use nla_get_u32, which is incorrect and causes functionality issues on little-endian platforms. Hence, fix them with the correct nla_get_u8 and nla_get_u16 functions.

Fixes 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM initiator API")
---
 net/wireless/pmsr.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/wireless/pmsr.c +4 -4
index e106dcea39778..c569c37da3175 100644
@@ -56,7 +56,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 	out->ftm.burst_period = 0;
 	if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD])
 		out->ftm.burst_period =
-			nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]);
+			nla_get_u16(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]);
 
 	out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP];
 	if (out->ftm.asap && !capa->ftm.asap) {
@@ -75,7 +75,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 	out->ftm.num_bursts_exp = 0;
 	if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP])
 		out->ftm.num_bursts_exp =
-			nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]);
+			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]);
 
 	if (capa->ftm.max_bursts_exponent >= 0 &&
 	    out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) {
@@ -88,7 +88,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 	out->ftm.burst_duration = 15;
 	if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION])
 		out->ftm.burst_duration =
-			nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]);
+			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]);
 
 	out->ftm.ftms_per_burst = 0;
 	if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST])
@@ -107,7 +107,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 	out->ftm.ftmr_retries = 3;
 	if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES])
 		out->ftm.ftmr_retries =
-			nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]);
+			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]);
 
 	out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI];
 	if (out->ftm.request_lci && !capa->ftm.request_lci) {
Signature · 1 line
2.43.0
author maintainer
#11 lore raw

PATCH 11/281 wifi: mac80211: pass proper link id for channel switch started notification

In reply to Greg Kroah-Hartman

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

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

From: Aditya Kumar Singh <[email protected]>

[ Upstream commit 8ecc4d7a7cd3e9704b63b8e4f6cd8b6b7314210f ]

Original changes[1] posted is having proper changes. However, at the same time, there was chandef puncturing changes which had a conflict with this. While applying, two errors crept in -
a) Whitespace error.
b) Link ID being passed to channel switch started notifier function is
0. However proper link ID is present in the function.

Fix these now.

[1] https://lore.kernel.org/all/[email protected]/

Fixes 1a96bb4e8a79 ("wifi: mac80211: start and finalize channel switch on link basis")
---
 net/mac80211/cfg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac80211/cfg.c +2 -2
index 07abaf7820c56..51dc2d9dd6b84 100644
@@ -4012,7 +4012,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 		goto out;
 	}
 
-	link_data->csa_chanreq = chanreq; 
+	link_data->csa_chanreq = chanreq;
 	link_conf->csa_active = true;
 
 	if (params->block_tx &&
@@ -4023,7 +4023,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 	}
 
 	cfg80211_ch_switch_started_notify(sdata->dev,
-					  &link_data->csa_chanreq.oper, 0,
+					  &link_data->csa_chanreq.oper, link_id,
 					  params->count, params->block_tx);
 
 	if (changed) {
Signature · 1 line
2.43.0
author maintainer
#12 lore raw

PATCH 12/281 wifi: iwlwifi: mvm: dont initialize csa_work twice

In reply to Greg Kroah-Hartman

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

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

From: Miri Korenblit <[email protected]>

[ Upstream commit 92158790ce4391ce4c35d8dfbce759195e4724cb ]

The initialization of this worker moved to iwl_mvm_mac_init_mvmvif but we removed only from the pre-MLD version of the add_interface callback. Remove it also from the MLD version.

---
 drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 2 --
 1 file changed, 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +0 -2
index df183a79db4c8..43f3002ede464 100644
@@ -75,8 +75,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
 		goto out_free_bf;
 
 	iwl_mvm_tcm_add_vif(mvm, vif);
-	INIT_DELAYED_WORK(&mvmvif->csa_work,
-			  iwl_mvm_channel_switch_disconnect_wk);
 
 	if (vif->type == NL80211_IFTYPE_MONITOR) {
 		mvm->monitor_on = true;
Signature · 1 line
2.43.0
author maintainer
#13 lore raw

PATCH 13/281 wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

[ Upstream commit 4a7aace2899711592327463c1a29ffee44fcc66e ]

We don't actually support >64 even for HE devices, so revert back to 64. This fixes an issue where the session is refused because the queue is configured differently from the actual session later.

---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/rs.h +2 -7
index 376b23b409dca..6cd4ec4d8f344 100644
@@ -122,13 +122,8 @@ enum {
 
 #define LINK_QUAL_AGG_FRAME_LIMIT_DEF	(63)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MAX	(63)
-/*
- * FIXME - various places in firmware API still use u8,
- * e.g. LQ command and SCD config command.
- * This should be 256 instead.
- */
-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF	(255)
-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX	(255)
+#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF	(64)
+#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX	(64)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MIN	(0)
 
 #define LQ_SIZE		2	/* 2 mode tables:  "Active" and "Search" */
Signature · 1 line
2.43.0
author maintainer
#14 lore raw

PATCH 14/281 wifi: iwlwifi: mvm: set properly mac header

In reply to Greg Kroah-Hartman

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

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

From: Mordechay Goodstein <[email protected]>

[ Upstream commit 0f2e9f6f21d1ff292363cdfb5bc4d492eeaff76e ]

In the driver we only use skb_put* for adding data to the skb, hence data never moves and skb_reset_mac_haeder would set mac_header to the first time data was added and not to mac80211 header, fix this my using the actual len of bytes added for setting the mac header.

---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +4 -1
index ce8d83c771a70..8ac5c045fcfcb 100644
@@ -2456,8 +2456,11 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
 	 *
 	 * We mark it as mac header, for upper layers to know where
 	 * all radio tap header ends.
+	 *
+	 * Since data doesn't move data while putting data on skb and that is
+	 * the only way we use, data + len is the next place that hdr would be put
 	 */
-	skb_reset_mac_header(skb);
+	skb_set_mac_header(skb, skb->len);
 
 	/*
 	 * Override the nss from the rx_vec since the rate_n_flags has
Signature · 1 line
2.43.0
author maintainer
#15 lore raw

PATCH 15/281 wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef

In reply to Greg Kroah-Hartman

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

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

From: Shahar S Matityahu <[email protected]>

[ Upstream commit 87821b67dea87addbc4ab093ba752753b002176a ]

The driver should call iwl_dbg_tlv_free even if debugfs is not defined since ini mode does not depend on debugfs ifdef.

---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/iwl-drv.c +1 -1
index 1b7254569a37a..6c27ef2f7c7e5 100644
@@ -1821,8 +1821,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
 err_fw:
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 	debugfs_remove_recursive(drv->dbgfs_drv);
-	iwl_dbg_tlv_free(drv->trans);
 #endif
+	iwl_dbg_tlv_free(drv->trans);
 	kfree(drv);
 err:
 	return ERR_PTR(ret);
Signature · 1 line
2.43.0
author maintainer
#16 lore raw

PATCH 16/281 wifi: iwlwifi: mvm: check n_ssids before accessing the ssids

In reply to Greg Kroah-Hartman

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

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

From: Miri Korenblit <[email protected]>

[ Upstream commit 60d62757df30b74bf397a2847a6db7385c6ee281 ]

In some versions of cfg80211, the ssids poinet might be a valid one even though n_ssids is 0. Accessing the pointer in this case will cuase an out-of-bound access. Fix this by checking n_ssids first.

---
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/scan.c +2 -2
index 22bc032cffc8b..525d8efcc1475 100644
@@ -1303,7 +1303,7 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
 		if (IWL_MVM_ADWELL_MAX_BUDGET)
 			cmd->v7.adwell_max_budget =
 				cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
-		else if (params->ssids && params->ssids[0].ssid_len)
+		else if (params->n_ssids && params->ssids[0].ssid_len)
 			cmd->v7.adwell_max_budget =
 				cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
 		else
@@ -1405,7 +1405,7 @@ iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm *mvm,
 	if (IWL_MVM_ADWELL_MAX_BUDGET)
 		general_params->adwell_max_budget =
 			cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
-	else if (params->ssids && params->ssids[0].ssid_len)
+	else if (params->n_ssids && params->ssids[0].ssid_len)
 		general_params->adwell_max_budget =
 			cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
 	else
Signature · 1 line
2.43.0
author maintainer
#17 lore raw

PATCH 17/281 wifi: iwlwifi: mvm: dont read past the mfuart notifcation

In reply to Greg Kroah-Hartman

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

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

From: Emmanuel Grumbach <[email protected]>

[ Upstream commit 4bb95f4535489ed830cf9b34b0a891e384d1aee4 ]

In case the firmware sends a notification that claims it has more data than it has, we will read past that was allocated for the notification. Remove the print of the buffer, we won't see it by default. If needed, we can see the content with tracing.

This was reported by KFENCE.

---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 ----------
 1 file changed, 10 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/fw.c +0 -10
index e1c2b7fc92ab9..c56212c2c3066 100644
@@ -94,20 +94,10 @@ void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm,
 {
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_mfu_assert_dump_notif *mfu_dump_notif = (void *)pkt->data;
-	__le32 *dump_data = mfu_dump_notif->data;
-	int n_words = le32_to_cpu(mfu_dump_notif->data_size) / sizeof(__le32);
-	int i;
 
 	if (mfu_dump_notif->index_num == 0)
 		IWL_INFO(mvm, "MFUART assert id 0x%x occurred\n",
 			 le32_to_cpu(mfu_dump_notif->assert_id));
-
-	for (i = 0; i < n_words; i++)
-		IWL_DEBUG_INFO(mvm,
-			       "MFUART assert dump, dword %u: 0x%08x\n",
-			       le16_to_cpu(mfu_dump_notif->index_num) *
-			       n_words + i,
-			       le32_to_cpu(dump_data[i]));
 }
 
 static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
Signature · 1 line
2.43.0
author maintainer
#18 lore raw

PATCH 18/281 wifi: mac80211: fix Spatial Reuse element size check

In reply to Greg Kroah-Hartman

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

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

From: Lingbo Kong <[email protected]>

[ Upstream commit 0c2fd18f7ec552796179c14f13a0e06942f09d16 ]

Currently, the way to check the size of Spatial Reuse IE data in the ieee80211_parse_extension_element() is incorrect.

This is because the len variable in the ieee80211_parse_extension_element() function is equal to the size of Spatial Reuse IE data minus one and the value of returned by the ieee80211_he_spr_size() function is equal to the length of Spatial Reuse IE data. So the result of the
len >= ieee80211_he_spr_size(data) statement always false.

To address this issue and make it consistent with the logic used elsewhere with ieee80211_he_oper_size(), change the
"len >= ieee80211_he_spr_size(data)" to
“len >= ieee80211_he_spr_size(data) - 1”.

Fixes 9d0480a7c05b ("wifi: mac80211: move element parsing to a new file")
---
 net/mac80211/parse.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/parse.c +1 -1
index 55e5497f89781..055a60e90979b 100644
@@ -111,7 +111,7 @@ ieee80211_parse_extension_element(u32 *crc,
 		if (params->mode < IEEE80211_CONN_MODE_HE)
 			break;
 		if (len >= sizeof(*elems->he_spr) &&
-		    len >= ieee80211_he_spr_size(data))
+		    len >= ieee80211_he_spr_size(data) - 1)
 			elems->he_spr = data;
 		break;
 	case WLAN_EID_EXT_HE_6GHZ_CAPA:
Signature · 1 line
2.43.0
author maintainer
#19 lore raw

PATCH 19/281 wifi: mac80211: correctly parse Spatial Reuse Parameter Set element

In reply to Greg Kroah-Hartman

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

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

From: Lingbo Kong <[email protected]>

[ Upstream commit a26d8dc5227f449a54518a8b40733a54c6600a8b ]

Currently, the way of parsing Spatial Reuse Parameter Set element is incorrect and some members of struct ieee80211_he_obss_pd are not assigned.

To address this issue, it must be parsed in the order of the elements of Spatial Reuse Parameter Set defined in the IEEE Std 802.11ax specification.

The diagram of the Spatial Reuse Parameter Set element (IEEE Std 802.11ax -2021-9.4.2.252).

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

|       |      |         |       |Non-SRG|  SRG  | SRG   | SRG  | SRG   |
|Element|Length| Element |  SR   |OBSS PD|OBSS PD|OBSS PD| BSS  |Partial|
|   ID  |      |   ID    |Control|  Max  |  Min  | Max   |Color | BSSID |
|       |      |Extension|       | Offset| Offset|Offset |Bitmap|Bitmap |

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

Fixes 1ced169cc1c2 ("mac80211: allow setting spatial reuse parameters from bss_conf")
---
 net/mac80211/he.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
net/mac80211/he.c +8 -2
index 9f5ffdc9db284..ecbb042dd0433 100644
@@ -230,15 +230,21 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
 
 	if (!he_spr_ie_elem)
 		return;
+
+	he_obss_pd->sr_ctrl = he_spr_ie_elem->he_sr_control;
 	data = he_spr_ie_elem->optional;
 
 	if (he_spr_ie_elem->he_sr_control &
 	    IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
-		data++;
+		he_obss_pd->non_srg_max_offset = *data++;
+
 	if (he_spr_ie_elem->he_sr_control &
 	    IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) {
-		he_obss_pd->max_offset = *data++;
 		he_obss_pd->min_offset = *data++;
+		he_obss_pd->max_offset = *data++;
+		memcpy(he_obss_pd->bss_color_bitmap, data, 8);
+		data += 8;
+		memcpy(he_obss_pd->partial_bssid_bitmap, data, 8);
 		he_obss_pd->enable = true;
 	}
 }
Signature · 1 line
2.43.0
author maintainer
#20 lore raw

PATCH 20/281 scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort()

In reply to Greg Kroah-Hartman

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

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

From: Chanwoo Lee <[email protected]>

[ Upstream commit d53b681ce9ca7db5ef4ecb8d2cf465ae4a031264 ]

An error unrelated to ufshcd_try_to_abort_task is being logged and can cause confusion. Modify ufshcd_mcq_abort() to print the result of the abort failure. For readability, return immediately instead of 'goto'.

---
 drivers/ufs/core/ufs-mcq.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/ufs/core/ufs-mcq.c +8 -9
index 005d63ab1f441..8944548c30fa1 100644
@@ -634,20 +634,20 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
 	struct ufshcd_lrb *lrbp = &hba->lrb[tag];
 	struct ufs_hw_queue *hwq;
 	unsigned long flags;
-	int err = FAILED;
+	int err;
 
 	if (!ufshcd_cmd_inflight(lrbp->cmd)) {
 		dev_err(hba->dev,
 			"%s: skip abort. cmd at tag %d already completed.\n",
 			__func__, tag);
-		goto out;
+		return FAILED;
 	}
 
 	/* Skip task abort in case previous aborts failed and report failure */
 	if (lrbp->req_abort_skip) {
 		dev_err(hba->dev, "%s: skip abort. tag %d failed earlier\n",
 			__func__, tag);
-		goto out;
+		return FAILED;
 	}
 
 	hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
@@ -659,7 +659,7 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
 		 */
 		dev_err(hba->dev, "%s: cmd found in sq. hwq=%d, tag=%d\n",
 			__func__, hwq->id, tag);
-		goto out;
+		return FAILED;
 	}
 
 	/*
@@ -667,18 +667,17 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
 	 * in the completion queue either. Query the device to see if
 	 * the command is being processed in the device.
 	 */
-	if (ufshcd_try_to_abort_task(hba, tag)) {
+	err = ufshcd_try_to_abort_task(hba, tag);
+	if (err) {
 		dev_err(hba->dev, "%s: device abort failed %d\n", __func__, err);
 		lrbp->req_abort_skip = true;
-		goto out;
+		return FAILED;
 	}
 
-	err = SUCCESS;
 	spin_lock_irqsave(&hwq->cq_lock, flags);
 	if (ufshcd_cmd_inflight(lrbp->cmd))
 		ufshcd_release_scsi_cmd(hba, lrbp);
 	spin_unlock_irqrestore(&hwq->cq_lock, flags);
 
-out:
-	return err;
+	return SUCCESS;
 }
Signature · 1 line
2.43.0
author maintainer
#21 lore raw

PATCH 21/281 RISC-V: KVM: No need to use mask when hart-index-bit is 0

In reply to Greg Kroah-Hartman

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

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

From: Yong-Xuan Wang <[email protected]>

[ Upstream commit 2d707b4e37f9b0c37b8b2392f91b04c5b63ea538 ]

When the maximum hart number within groups is 1, hart-index-bit is set to
0. Consequently, there is no need to restore the hart ID from IMSIC addresses and hart-index-bit settings. Currently, QEMU and kvmtool do not pass correct hart-index-bit values when the maximum hart number is a power of 2, thereby avoiding this issue. Corresponding patches for QEMU and kvmtool will also be dispatched.

Fixes 89d01306e34d ("RISC-V: KVM: Implement device interface for AIA irqchip")
---
 arch/riscv/kvm/aia_device.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/riscv/kvm/aia_device.c +4 -3
index 0eb689351b7d0..5cd407c6a8e4f 100644
@@ -237,10 +237,11 @@ static gpa_t aia_imsic_ppn(struct kvm_aia *aia, gpa_t addr)
 
 static u32 aia_imsic_hart_index(struct kvm_aia *aia, gpa_t addr)
 {
-	u32 hart, group = 0;
+	u32 hart = 0, group = 0;
 
-	hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
-		GENMASK_ULL(aia->nr_hart_bits - 1, 0);
+	if (aia->nr_hart_bits)
+		hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
+		       GENMASK_ULL(aia->nr_hart_bits - 1, 0);
 	if (aia->nr_group_bits)
 		group = (addr >> aia->nr_group_shift) &
 			GENMASK_ULL(aia->nr_group_bits - 1, 0);
Signature · 1 line
2.43.0
author maintainer
#22 lore raw

PATCH 22/281 RISC-V: KVM: Fix incorrect reg_subtype labels in kvm_riscv_vcpu_set_reg_isa_ext function

In reply to Greg Kroah-Hartman

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

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

From: Quan Zhou <[email protected]>

[ Upstream commit c66f3b40b17d3dfc4b6abb5efde8e71c46971821 ]

In the function kvm_riscv_vcpu_set_reg_isa_ext, the original code used incorrect reg_subtype labels KVM_REG_RISCV_SBI_MULTI_EN/DIS. These have been corrected to KVM_REG_RISCV_ISA_MULTI_EN/DIS respectively. Although they are numerically equivalent, the actual processing will not result in errors, but it may lead to ambiguous code semantics.

---
 arch/riscv/kvm/vcpu_onereg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/riscv/kvm/vcpu_onereg.c +2 -2
index 994adc26db4b1..e5706f5f2c71a 100644
@@ -718,9 +718,9 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
 	switch (reg_subtype) {
 	case KVM_REG_RISCV_ISA_SINGLE:
 		return riscv_vcpu_set_isa_ext_single(vcpu, reg_num, reg_val);
-	case KVM_REG_RISCV_SBI_MULTI_EN:
+	case KVM_REG_RISCV_ISA_MULTI_EN:
 		return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, true);
-	case KVM_REG_RISCV_SBI_MULTI_DIS:
+	case KVM_REG_RISCV_ISA_MULTI_DIS:
 		return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false);
 	default:
 		return -ENOENT;
Signature · 1 line
2.43.0
author maintainer
#23 lore raw

PATCH 23/281 virtio_net: fix possible dim status unrecoverable

In reply to Greg Kroah-Hartman

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

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

From: Heng Qi <[email protected]>

[ Upstream commit 9e0945b1901c9eed4fbee3b8a3870487b2bdc936 ]

When the dim worker is scheduled, if it no longer needs to issue commands, dim may not be able to return to the working state later.

For example, the following single queue scenario:
1. The dim worker of rxq0 is scheduled, and the dim status is

     changed to DIM_APPLY_NEW_PROFILE;

2. dim is disabled or parameters have not been modified;
3. virtnet_rx_dim_work exits directly;

Then, even if net_dim is invoked again, it cannot work because the state is not restored to DIM_START_MEASURE.

---
 drivers/net/virtio_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/virtio_net.c +1 -1
index 115c3c5414f2a..574b052a517d7 100644
@@ -3589,10 +3589,10 @@ static void virtnet_rx_dim_work(struct work_struct *work)
 			if (err)
 				pr_debug("%s: Failed to send dim parameters on rxq%d\n",
 					 dev->name, qnum);
-			dim->state = DIM_START_MEASURE;
 		}
 	}
 
+	dim->state = DIM_START_MEASURE;
 	rtnl_unlock();
 }
 
Signature · 1 line
2.43.0
author maintainer
#24 lore raw

PATCH 24/281 ax25: Fix refcount imbalance on inbound connections

In reply to Greg Kroah-Hartman

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

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

From: Lars Kellogg-Stedman <[email protected]>

[ Upstream commit 3c34fb0bd4a4237592c5ecb5b2e2531900c55774 ]

When releasing a socket in ax25_release(), we call netdev_put() to decrease the refcount on the associated ax.25 device. However, the execution path for accepting an incoming connection never calls netdev_hold(). This imbalance leads to refcount errors, and ultimately to kernel crashes.

A typical call trace for the above situation will start with one of the following errors:

refcount_t: decrement hit 0; leaking memory.
refcount_t: underflow; use-after-free.

And will then have a trace like:

    Call Trace:
    <TASK>
    ? show_regs+0x64/0x70
    ? __warn+0x83/0x120
    ? refcount_warn_saturate+0xb2/0x100
    ? report_bug+0x158/0x190
    ? prb_read_valid+0x20/0x30
    ? handle_bug+0x3e/0x70
    ? exc_invalid_op+0x1c/0x70
    ? asm_exc_invalid_op+0x1f/0x30
    ? refcount_warn_saturate+0xb2/0x100
    ? refcount_warn_saturate+0xb2/0x100
    ax25_release+0x2ad/0x360
    __sock_release+0x35/0xa0
    sock_close+0x19/0x20
    [...]

On reboot (or any attempt to remove the interface), the kernel gets stuck in an infinite loop:

unregister_netdevice: waiting for ax0 to become free. Usage count = 0

This patch corrects these issues by ensuring that we call netdev_hold() and ax25_dev_hold() for new connections in ax25_accept(). This makes the logic leading to ax25_accept() match the logic for ax25_bind(): in both cases we increment the refcount, which is ultimately decremented in ax25_release().

---
 net/ax25/af_ax25.c | 6 ++++++
 1 file changed, 6 insertions(+)
net/ax25/af_ax25.c +6 -0
index 9169efb2f43aa..5fff5930e4deb 100644
@@ -1378,8 +1378,10 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags,
 {
 	struct sk_buff *skb;
 	struct sock *newsk;
+	ax25_dev *ax25_dev;
 	DEFINE_WAIT(wait);
 	struct sock *sk;
+	ax25_cb *ax25;
 	int err = 0;
 
 	if (sock->state != SS_UNCONNECTED)
@@ -1434,6 +1436,10 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags,
 	kfree_skb(skb);
 	sk_acceptq_removed(sk);
 	newsock->state = SS_CONNECTED;
+	ax25 = sk_to_ax25(newsk);
+	ax25_dev = ax25->ax25_dev;
+	netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
+	ax25_dev_hold(ax25_dev);
 
 out:
 	release_sock(sk);
Signature · 1 line
2.43.0
author maintainer
#25 lore raw

PATCH 25/281 ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put()

In reply to Greg Kroah-Hartman

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

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

From: Duoming Zhou <[email protected]>

[ Upstream commit 166fcf86cd34e15c7f383eda4642d7a212393008 ]

The object "ax25_dev" is managed by reference counting. Thus it should not be directly released by kfree(), replace with ax25_dev_put().

---
 net/ax25/ax25_dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ax25/ax25_dev.c +1 -1
index c9d55b99a7a57..67ae6b8c52989 100644
@@ -193,7 +193,7 @@ void __exit ax25_dev_free(void)
 	list_for_each_entry_safe(s, n, &ax25_dev_list, list) {
 		netdev_put(s->dev, &s->dev_tracker);
 		list_del(&s->list);
-		kfree(s);
+		ax25_dev_put(s);
 	}
 	spin_unlock_bh(&ax25_dev_lock);
 }
Signature · 1 line
2.43.0
author maintainer
#26 lore raw

PATCH 26/281 net/ncsi: Fix the multi thread manner of NCSI driver

In reply to Greg Kroah-Hartman

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

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

From: DelphineCCChiu <[email protected]>

[ Upstream commit e85e271dec0270982afed84f70dc37703fcc1d52 ]

Currently NCSI driver will send several NCSI commands back to back without waiting the response of previous NCSI command or timeout in some state when NIC have multi channel. This operation against the single thread manner defined by NCSI SPEC(section 6.3.2.3 in DSP0222_1.1.1)

According to NCSI SPEC(section 6.2.13.1 in DSP0222_1.1.1), we should probe one channel at a time by sending NCSI commands (Clear initial state, Get version ID, Get capabilities...), than repeat this steps until the max number of channels which we got from NCSI command (Get capabilities) has been probed.

Fixes e6f44ed6d04d ("net/ncsi: Package and channel management")
---
 net/ncsi/internal.h    |  2 ++
 net/ncsi/ncsi-manage.c | 73 +++++++++++++++++++++---------------------
 net/ncsi/ncsi-rsp.c    |  4 ++-
 3 files changed, 41 insertions(+), 38 deletions(-)
net/ncsi/internal.h +2 -0
index 374412ed780b6..ef0f8f73826f5 100644
@@ -325,6 +325,7 @@ struct ncsi_dev_priv {
 	spinlock_t          lock;            /* Protect the NCSI device    */
 	unsigned int        package_probe_id;/* Current ID during probe    */
 	unsigned int        package_num;     /* Number of packages         */
+	unsigned int        channel_probe_id;/* Current cahnnel ID during probe */
 	struct list_head    packages;        /* List of packages           */
 	struct ncsi_channel *hot_channel;    /* Channel was ever active    */
 	struct ncsi_request requests[256];   /* Request table              */
@@ -343,6 +344,7 @@ struct ncsi_dev_priv {
 	bool                multi_package;   /* Enable multiple packages   */
 	bool                mlx_multi_host;  /* Enable multi host Mellanox */
 	u32                 package_whitelist; /* Packages to configure    */
+	unsigned char       channel_count;     /* Num of channels to probe   */
 };
 
 struct ncsi_cmd_arg {
net/ncsi/ncsi-manage.c +36 -37

128 lines not on this page · raw message

net/ncsi/ncsi-rsp.c +3 -1
index bee290d0f48b6..e28be33bdf2c4 100644
@@ -795,12 +795,13 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
 	struct ncsi_rsp_gc_pkt *rsp;
 	struct ncsi_dev_priv *ndp = nr->ndp;
 	struct ncsi_channel *nc;
+	struct ncsi_package *np;
 	size_t size;
 
 	/* Find the channel */
 	rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
 	ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
-				      NULL, &nc);
+				      &np, &nc);
 	if (!nc)
 		return -ENODEV;
 
@@ -835,6 +836,7 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
 	 */
 	nc->vlan_filter.bitmap = U64_MAX;
 	nc->vlan_filter.n_vids = rsp->vlan_cnt;
+	np->ndp->channel_count = rsp->channel_cnt;
 
 	return 0;
 }
Signature · 1 line
2.43.0
author maintainer
#27 lore raw

PATCH 27/281 net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume

In reply to Greg Kroah-Hartman

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

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

From: Tristram Ha <[email protected]>

[ Upstream commit 6149db4997f582e958da675092f21c666e3b67b7 ]

When the PHY is powered up after powered down most of the registers are reset, so the PHY setup code needs to be done again. In addition the interrupt register will need to be setup again so that link status indication works again.

Fixes 26dd2974c5b5 ("net: phy: micrel: Move KSZ9477 errata fixes to PHY driver")
---
 drivers/net/phy/micrel.c | 62 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 6 deletions(-)
drivers/net/phy/micrel.c +56 -6
index 13370439a7cae..c2d99344ade41 100644
@@ -1858,7 +1858,7 @@ static const struct ksz9477_errata_write ksz9477_errata_writes[] = {
 	{0x1c, 0x20, 0xeeee},
 };
 
-static int ksz9477_config_init(struct phy_device *phydev)
+static int ksz9477_phy_errata(struct phy_device *phydev)
 {
 	int err;
 	int i;
@@ -1886,16 +1886,30 @@ static int ksz9477_config_init(struct phy_device *phydev)
 			return err;
 	}
 
+	err = genphy_restart_aneg(phydev);
+	if (err)
+		return err;
+
+	return err;
+}
+
+static int ksz9477_config_init(struct phy_device *phydev)
+{
+	int err;
+
+	/* Only KSZ9897 family of switches needs this fix. */
+	if ((phydev->phy_id & 0xf) == 1) {
+		err = ksz9477_phy_errata(phydev);
+		if (err)
+			return err;
+	}
+
 	/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
 	 * in this switch shall be regarded as broken.
 	 */
 	if (phydev->dev_flags & MICREL_NO_EEE)
 		phydev->eee_broken_modes = -1;
 
-	err = genphy_restart_aneg(phydev);
-	if (err)
-		return err;
-
 	return kszphy_config_init(phydev);
 }
 
@@ -2004,6 +2018,42 @@ static int kszphy_resume(struct phy_device *phydev)
 	return 0;
 }
 
+static int ksz9477_resume(struct phy_device *phydev)
+{
+	int ret;
+
+	/* No need to initialize registers if not powered down. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (!(ret & BMCR_PDOWN))
+		return 0;
+
+	genphy_resume(phydev);
+
+	/* After switching from power-down to normal mode, an internal global
+	 * reset is automatically generated. Wait a minimum of 1 ms before
+	 * read/write access to the PHY registers.
+	 */
+	usleep_range(1000, 2000);
+
+	/* Only KSZ9897 family of switches needs this fix. */
+	if ((phydev->phy_id & 0xf) == 1) {
+		ret = ksz9477_phy_errata(phydev);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable PHY Interrupts */
+	if (phy_interrupt_is_valid(phydev)) {
+		phydev->interrupts = PHY_INTERRUPT_ENABLED;
+		if (phydev->drv->config_intr)
+			phydev->drv->config_intr(phydev);
+	}
+
+	return 0;
+}
+
 static int kszphy_probe(struct phy_device *phydev)
 {
 	const struct kszphy_type *type = phydev->drv->driver_data;
@@ -4980,7 +5030,7 @@ static struct phy_driver ksphy_driver[] = {
 	.config_intr	= kszphy_config_intr,
 	.handle_interrupt = kszphy_handle_interrupt,
 	.suspend	= genphy_suspend,
-	.resume		= genphy_resume,
+	.resume		= ksz9477_resume,
 	.get_features	= ksz9477_get_features,
 } };
 
Signature · 1 line
2.43.0
author maintainer
#28 lore raw

PATCH 28/281 bpf: Fix a potential use-after-free in bpf_link_free()

In reply to Greg Kroah-Hartman

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

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

From: Cong Wang <[email protected]>

[ Upstream commit 2884dc7d08d98a89d8d65121524bb7533183a63a ]

After commit 1a80dbcb2dba, bpf_link can be freed by link->ops->dealloc_deferred, but the code still tests and uses link->ops->dealloc afterward, which leads to a use-after-free as reported by syzbot. Actually, one of them should be sufficient, so just call one of them instead of both. Also add a WARN_ON() in case of any problematic implementation.

Fixes 1a80dbcb2dba ("bpf: support deferring bpf_link dealloc to after RCU grace period")
Reported-by [email protected]
---
 kernel/bpf/syscall.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
kernel/bpf/syscall.c +6 -5
index cb61d8880dbe0..52ffe33356418 100644
@@ -2985,6 +2985,7 @@ static int bpf_obj_get(const union bpf_attr *attr)
 void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
 		   const struct bpf_link_ops *ops, struct bpf_prog *prog)
 {
+	WARN_ON(ops->dealloc && ops->dealloc_deferred);
 	atomic64_set(&link->refcnt, 1);
 	link->type = type;
 	link->id = 0;
@@ -3043,16 +3044,17 @@ static void bpf_link_defer_dealloc_mult_rcu_gp(struct rcu_head *rcu)
 /* bpf_link_free is guaranteed to be called from process context */
 static void bpf_link_free(struct bpf_link *link)
 {
+	const struct bpf_link_ops *ops = link->ops;
 	bool sleepable = false;
 
 	bpf_link_free_id(link->id);
 	if (link->prog) {
 		sleepable = link->prog->sleepable;
 		/* detach BPF program, clean up used resources */
-		link->ops->release(link);
+		ops->release(link);
 		bpf_prog_put(link->prog);
 	}
-	if (link->ops->dealloc_deferred) {
+	if (ops->dealloc_deferred) {
 		/* schedule BPF link deallocation; if underlying BPF program
 		 * is sleepable, we need to first wait for RCU tasks trace
 		 * sync, then go through "classic" RCU grace period
@@ -3061,9 +3063,8 @@ static void bpf_link_free(struct bpf_link *link)
 			call_rcu_tasks_trace(&link->rcu, bpf_link_defer_dealloc_mult_rcu_gp);
 		else
 			call_rcu(&link->rcu, bpf_link_defer_dealloc_rcu_gp);
-	}
-	if (link->ops->dealloc)
-		link->ops->dealloc(link);
+	} else if (ops->dealloc)
+		ops->dealloc(link);
 }
 
 static void bpf_link_put_deferred(struct work_struct *work)
Signature · 1 line
2.43.0
author maintainer
#29 lore raw

PATCH 29/281 KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent

In reply to Greg Kroah-Hartman

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

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

From: Ravi Bangoria <[email protected]>

[ Upstream commit d922056215617eedfbdbc29fe49953423686fe5e ]

As documented in APM[1], LBR Virtualization must be enabled for SEV-ES guests. So, prevent SEV-ES guests when LBRV support is missing.

[1]: AMD64 Architecture Programmer's Manual Pub. 40332, Rev. 4.07 - June

     2023, Vol 2, 15.35.2 Enabling SEV-ES.
     https://bugzilla.kernel.org/attachment.cgi?id=304653
Fixes 376c6d285017 ("KVM: SVM: Provide support for SEV-ES vCPU creation/loading")

Message-ID: <[email protected]>

---
 arch/x86/kvm/svm/sev.c |  6 ++++++
 arch/x86/kvm/svm/svm.c | 16 +++++++---------
 arch/x86/kvm/svm/svm.h |  1 +
 3 files changed, 14 insertions(+), 9 deletions(-)
arch/x86/kvm/svm/sev.c +6 -0
index 759581bb2128d..43b7d76a27a56 100644
@@ -2269,6 +2269,12 @@ void __init sev_hardware_setup(void)
 	if (!boot_cpu_has(X86_FEATURE_SEV_ES))
 		goto out;
 
+	if (!lbrv) {
+		WARN_ONCE(!boot_cpu_has(X86_FEATURE_LBRV),
+			  "LBRV must be present for SEV-ES support");
+		goto out;
+	}
+
 	/* Has the system been allocated ASIDs for SEV-ES? */
 	if (min_sev_asid == 1)
 		goto out;
arch/x86/kvm/svm/svm.c +7 -9
index 308416b50b036..3363e5ba0fff5 100644
@@ -215,7 +215,7 @@ int vgif = true;
 module_param(vgif, int, 0444);
 
 /* enable/disable LBR virtualization */
-static int lbrv = true;
+int lbrv = true;
 module_param(lbrv, int, 0444);
 
 static int tsc_scaling = true;
@@ -5260,6 +5260,12 @@ static __init int svm_hardware_setup(void)
 
 	nrips = nrips && boot_cpu_has(X86_FEATURE_NRIPS);
 
+	if (lbrv) {
+		if (!boot_cpu_has(X86_FEATURE_LBRV))
+			lbrv = false;
+		else
+			pr_info("LBR virtualization supported\n");
+	}
 	/*
 	 * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which
 	 * may be modified by svm_adjust_mmio_mask()), as well as nrips.
@@ -5313,14 +5319,6 @@ static __init int svm_hardware_setup(void)
 		svm_x86_ops.set_vnmi_pending = NULL;
 	}
 
-
-	if (lbrv) {
-		if (!boot_cpu_has(X86_FEATURE_LBRV))
-			lbrv = false;
-		else
-			pr_info("LBR virtualization supported\n");
-	}
-
 	if (!enable_pmu)
 		pr_info("PMU virtualization is disabled\n");
 
arch/x86/kvm/svm/svm.h +1 -0
index 33878efdebc82..4bf9af529ae03 100644
@@ -39,6 +39,7 @@ extern int vgif;
 extern bool intercept_smi;
 extern bool x2avic_enabled;
 extern bool vnmi;
+extern int lbrv;
 
 /*
  * Clean bits in VMCB.
Signature · 1 line
2.43.0
author maintainer
#30 lore raw

PATCH 30/281 KVM: SEV-ES: Delegate LBR virtualization to the processor

In reply to Greg Kroah-Hartman

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

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

From: Ravi Bangoria <[email protected]>

[ Upstream commit b7e4be0a224fe5c6be30c1c8bdda8d2317ad6ba4 ]

As documented in APM[1], LBR Virtualization must be enabled for SEV-ES guests. Although KVM currently enforces LBRV for SEV-ES guests, there are multiple issues with it:

o MSR_IA32_DEBUGCTLMSR is still intercepted. Since MSR_IA32_DEBUGCTLMSR interception is used to dynamically toggle LBRV for performance reasons, this can be fatal for SEV-ES guests. For ex SEV-ES guest on Zen3:

[guest ~]# wrmsr 0x1d9 0x4
KVM: entry failed, hardware error 0xffffffff EAX=00000004 EBX=00000000 ECX=000001d9 EDX=00000000

Fix this by never intercepting MSR_IA32_DEBUGCTLMSR for SEV-ES guests. No additional save/restore logic is required since MSR_IA32_DEBUGCTLMSR is of swap type A.

o KVM will disable LBRV if userspace sets MSR_IA32_DEBUGCTLMSR before the VMSA is encrypted. Fix this by moving LBRV enablement code post VMSA encryption.

[1]: AMD64 Architecture Programmer's Manual Pub. 40332, Rev. 4.07 - June

     2023, Vol 2, 15.35.2 Enabling SEV-ES.
     https://bugzilla.kernel.org/attachment.cgi?id=304653
Fixes 376c6d285017 ("KVM: SVM: Provide support for SEV-ES vCPU creation/loading")

Message-ID: <[email protected]>

---
 arch/x86/kvm/svm/sev.c | 13 ++++++++-----
 arch/x86/kvm/svm/svm.c |  8 +++++++-
 arch/x86/kvm/svm/svm.h |  3 ++-
 3 files changed, 17 insertions(+), 7 deletions(-)
arch/x86/kvm/svm/sev.c +8 -5
index 43b7d76a27a56..4471b4e08d23d 100644
@@ -666,6 +666,14 @@ static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
 	  return ret;
 
 	vcpu->arch.guest_state_protected = true;
+
+	/*
+	 * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it
+	 * only after setting guest_state_protected because KVM_SET_MSRS allows
+	 * dynamic toggling of LBRV (for performance reason) on write access to
+	 * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+	 */
+	svm_enable_lbrv(vcpu);
 	return 0;
 }
 
@@ -3040,7 +3048,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
 	struct kvm_vcpu *vcpu = &svm->vcpu;
 
 	svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE;
-	svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK;
 
 	/*
 	 * An SEV-ES guest requires a VMSA area that is a separate from the
@@ -3092,10 +3099,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
 	/* Clear intercepts on selected MSRs */
 	set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
 }
 
 void sev_init_vmcb(struct vcpu_svm *svm)
arch/x86/kvm/svm/svm.c +7 -1
index 3363e5ba0fff5..4650153afa465 100644
@@ -99,6 +99,7 @@ static const struct svm_direct_access_msrs {
 	{ .index = MSR_IA32_SPEC_CTRL,			.always = false },
 	{ .index = MSR_IA32_PRED_CMD,			.always = false },
 	{ .index = MSR_IA32_FLUSH_CMD,			.always = false },
+	{ .index = MSR_IA32_DEBUGCTLMSR,		.always = false },
 	{ .index = MSR_IA32_LASTBRANCHFROMIP,		.always = false },
 	{ .index = MSR_IA32_LASTBRANCHTOIP,		.always = false },
 	{ .index = MSR_IA32_LASTINTFROMIP,		.always = false },
@@ -990,7 +991,7 @@ void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb)
 	vmcb_mark_dirty(to_vmcb, VMCB_LBR);
 }
 
-static void svm_enable_lbrv(struct kvm_vcpu *vcpu)
+void svm_enable_lbrv(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -1000,6 +1001,9 @@ static void svm_enable_lbrv(struct kvm_vcpu *vcpu)
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
 
+	if (sev_es_guest(vcpu->kvm))
+		set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, 1, 1);
+
 	/* Move the LBR msrs to the vmcb02 so that the guest can see them. */
 	if (is_guest_mode(vcpu))
 		svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr);
@@ -1009,6 +1013,8 @@ static void svm_disable_lbrv(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm);
+
 	svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK;
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0);
arch/x86/kvm/svm/svm.h +2 -1
index 4bf9af529ae03..2ed3015e03f13 100644
@@ -30,7 +30,7 @@
 #define	IOPM_SIZE PAGE_SIZE * 3
 #define	MSRPM_SIZE PAGE_SIZE * 2
 
-#define MAX_DIRECT_ACCESS_MSRS	47
+#define MAX_DIRECT_ACCESS_MSRS	48
 #define MSRPM_OFFSETS	32
 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
@@ -544,6 +544,7 @@ u32 *svm_vcpu_alloc_msrpm(void);
 void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm);
 void svm_vcpu_free_msrpm(u32 *msrpm);
 void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb);
+void svm_enable_lbrv(struct kvm_vcpu *vcpu);
 void svm_update_lbrv(struct kvm_vcpu *vcpu);
 
 int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer);
Signature · 1 line
2.43.0
author maintainer
#31 lore raw

PATCH 31/281 vmxnet3: disable rx data ring on dma allocation failure

In reply to Greg Kroah-Hartman

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

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

From: Matthias Stocker <[email protected]>

[ Upstream commit ffbe335b8d471f79b259e950cb20999700670456 ]

When vmxnet3_rq_create() fails to allocate memory for rq->data_ring.base, the subsequent call to vmxnet3_rq_destroy_all_rxdataring does not reset rq->data_ring.desc_size for the data ring that failed, which presumably causes the hypervisor to reference it on packet reception.

To fix this bug, rq->data_ring.desc_size needs to be set to 0 to tell the hypervisor to disable this feature.

[   95.436876] kernel BUG at net/core/skbuff.c:207!
[   95.439074] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
[   95.440411] CPU: 7 PID: 0 Comm: swapper/7 Not tainted 6.9.3-dirty #1
[   95.441558] Hardware name: VMware, Inc. VMware Virtual
Platform/440BX Desktop Reference Platform, BIOS 6.00 12/12/2018
[   95.443481] RIP: 0010:skb_panic+0x4d/0x4f
[   95.444404] Code: 4f 70 50 8b 87 c0 00 00 00 50 8b 87 bc 00 00 00 50
ff b7 d0 00 00 00 4c 8b 8f c8 00 00 00 48 c7 c7 68 e8 be 9f e8 63 58 f9
ff <0f> 0b 48 8b 14 24 48 c7 c1 d0 73 65 9f e8 a1 ff ff ff 48 8b 14 24
[   95.447684] RSP: 0018:ffffa13340274dd0 EFLAGS: 00010246
[   95.448762] RAX: 0000000000000089 RBX: ffff8fbbc72b02d0 RCX: 000000000000083f
[   95.450148] RDX: 0000000000000000 RSI: 00000000000000f6 RDI: 000000000000083f
[   95.451520] RBP: 000000000000002d R08: 0000000000000000 R09: ffffa13340274c60
[   95.452886] R10: ffffffffa04ed468 R11: 0000000000000002 R12: 0000000000000000
[   95.454293] R13: ffff8fbbdab3c2d0 R14: ffff8fbbdbd829e0 R15: ffff8fbbdbd809e0
[   95.455682] FS:  0000000000000000(0000) GS:ffff8fbeefd80000(0000) knlGS:0000000000000000
[   95.457178] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   95.458340] CR2: 00007fd0d1f650c8 CR3: 0000000115f28000 CR4: 00000000000406f0
[   95.459791] Call Trace:
[   95.460515]  <IRQ>
[   95.461180]  ? __die_body.cold+0x19/0x27
[   95.462150]  ? die+0x2e/0x50
[   95.462976]  ? do_trap+0xca/0x110
[   95.463973]  ? do_error_trap+0x6a/0x90
[   95.464966]  ? skb_panic+0x4d/0x4f
[   95.465901]  ? exc_invalid_op+0x50/0x70
[   95.466849]  ? skb_panic+0x4d/0x4f
[   95.467718]  ? asm_exc_invalid_op+0x1a/0x20
[   95.468758]  ? skb_panic+0x4d/0x4f
[   95.469655]  skb_put.cold+0x10/0x10
[   95.470573]  vmxnet3_rq_rx_complete+0x862/0x11e0 [vmxnet3]
[   95.471853]  vmxnet3_poll_rx_only+0x36/0xb0 [vmxnet3]
[   95.473185]  __napi_poll+0x2b/0x160
[   95.474145]  net_rx_action+0x2c6/0x3b0
[   95.475115]  handle_softirqs+0xe7/0x2a0
[   95.476122]  __irq_exit_rcu+0x97/0xb0
[   95.477109]  common_interrupt+0x85/0xa0
[   95.478102]  </IRQ>
[   95.478846]  <TASK>
[   95.479603]  asm_common_interrupt+0x26/0x40
[   95.480657] RIP: 0010:pv_native_safe_halt+0xf/0x20
[   95.481801] Code: 22 d7 e9 54 87 01 00 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa eb 07 0f 00 2d 93 ba 3b 00 fb f4 <e9> 2c 87 01 00 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90
[   95.485563] RSP: 0018:ffffa133400ffe58 EFLAGS: 00000246
[   95.486882] RAX: 0000000000004000 RBX: ffff8fbbc1d14064 RCX: 0000000000000000
[   95.488477] RDX: ffff8fbeefd80000 RSI: ffff8fbbc1d14000 RDI: 0000000000000001
[   95.490067] RBP: ffff8fbbc1d14064 R08: ffffffffa0652260 R09: 00000000000010d3
[   95.491683] R10: 0000000000000018 R11: ffff8fbeefdb4764 R12: ffffffffa0652260
[   95.493389] R13: ffffffffa06522e0 R14: 0000000000000001 R15: 0000000000000000
[   95.495035]  acpi_safe_halt+0x14/0x20
[   95.496127]  acpi_idle_do_entry+0x2f/0x50
[   95.497221]  acpi_idle_enter+0x7f/0xd0
[   95.498272]  cpuidle_enter_state+0x81/0x420
[   95.499375]  cpuidle_enter+0x2d/0x40
[   95.500400]  do_idle+0x1e5/0x240
[   95.501385]  cpu_startup_entry+0x29/0x30
[   95.502422]  start_secondary+0x11c/0x140
[   95.503454]  common_startup_64+0x13e/0x141
[   95.504466]  </TASK>
[   95.505197] Modules linked in: nft_fib_inet nft_fib_ipv4

nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 rfkill ip_set nf_tables vsock_loopback vmw_vsock_virtio_transport_common qrtr vmw_vsock_vmci_transport vsock sunrpc binfmt_misc pktcdvd vmw_balloon pcspkr vmw_vmci i2c_piix4 joydev loop dm_multipath nfnetlink zram crct10dif_pclmul crc32_pclmul vmwgfx crc32c_intel polyval_clmulni polyval_generic ghash_clmulni_intel sha512_ssse3 sha256_ssse3 vmxnet3 sha1_ssse3 drm_ttm_helper vmw_pvscsi ttm ata_generic pata_acpi serio_raw scsi_dh_rdac scsi_dh_emc scsi_dh_alua ip6_tables ip_tables fuse

[   95.516536] ---[ end trace 0000000000000000 ]---
Fixes 6f4833383e85 ("net: vmxnet3: Fix NULL pointer dereference in vmxnet3_rq_rx_complete()")
---
 drivers/net/vmxnet3/vmxnet3_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/vmxnet3/vmxnet3_drv.c +1 -1
index 0578864792b60..beebe09eb88ff 100644
@@ -2034,8 +2034,8 @@ vmxnet3_rq_destroy_all_rxdataring(struct vmxnet3_adapter *adapter)
 					  rq->data_ring.base,
 					  rq->data_ring.basePA);
 			rq->data_ring.base = NULL;
-			rq->data_ring.desc_size = 0;
 		}
+		rq->data_ring.desc_size = 0;
 	}
 }
 
Signature · 1 line
2.43.0
author maintainer
#32 lore raw

PATCH 32/281 ipv6: ioam: block BH from ioam6_output()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 2fe40483ec257de2a0d819ef88e3e76c7e261319 ]

As explained in commit 1378817486d6 ("tipc: block BH before using dst_cache"), net/core/dst_cache.c helpers need to be called with BH disabled.

Disabling preemption in ioam6_output() is not good enough, because ioam6_output() is called from process context, lwtunnel_output() only uses rcu_read_lock().

We might be interrupted by a softirq, re-enter ioam6_output() and corrupt dst_cache data structures.

Fix the race by using local_bh_disable() instead of preempt_disable().

Fixes 8cb3bf8bff3c ("ipv6: ioam: Add support for the ip6ip6 encapsulation")
Cc Justin Iurman <[email protected]>
---
 net/ipv6/ioam6_iptunnel.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/ipv6/ioam6_iptunnel.c +4 -4
index 7563f8c6aa87c..bf7120ecea1eb 100644
@@ -351,9 +351,9 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 		goto drop;
 
 	if (!ipv6_addr_equal(&orig_daddr, &ipv6_hdr(skb)->daddr)) {
-		preempt_disable();
+		local_bh_disable();
 		dst = dst_cache_get(&ilwt->cache);
-		preempt_enable();
+		local_bh_enable();
 
 		if (unlikely(!dst)) {
 			struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -373,9 +373,9 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 				goto drop;
 			}
 
-			preempt_disable();
+			local_bh_disable();
 			dst_cache_set_ip6(&ilwt->cache, dst, &fl6.saddr);
-			preempt_enable();
+			local_bh_enable();
 		}
 
 		skb_dst_drop(skb);
Signature · 1 line
2.43.0
author maintainer
#33 lore raw

PATCH 33/281 ipv6: sr: block BH in seg6_output_core() and seg6_input_core()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit c0b98ac1cc104f48763cdb27b1e9ac25fd81fc90 ]

As explained in commit 1378817486d6 ("tipc: block BH before using dst_cache"), net/core/dst_cache.c helpers need to be called with BH disabled.

Disabling preemption in seg6_output_core() is not good enough, because seg6_output_core() is called from process context, lwtunnel_output() only uses rcu_read_lock().

We might be interrupted by a softirq, re-enter seg6_output_core() and corrupt dst_cache data structures.

Fix the race by using local_bh_disable() instead of preempt_disable().

Apply a similar change in seg6_input_core().

Fixes fa79581ea66c ("ipv6: sr: fix several BUGs when preemption is enabled")
Fixes 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
Cc David Lebrun <[email protected]>
---
 net/ipv6/seg6_iptunnel.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
net/ipv6/seg6_iptunnel.c +6 -8
index a75df2ec8db0d..098632adc9b5a 100644
@@ -464,23 +464,21 @@ static int seg6_input_core(struct net *net, struct sock *sk,
 
 	slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
 
-	preempt_disable();
+	local_bh_disable();
 	dst = dst_cache_get(&slwt->cache);
-	preempt_enable();
 
 	if (!dst) {
 		ip6_route_input(skb);
 		dst = skb_dst(skb);
 		if (!dst->error) {
-			preempt_disable();
 			dst_cache_set_ip6(&slwt->cache, dst,
 					  &ipv6_hdr(skb)->saddr);
-			preempt_enable();
 		}
 	} else {
 		skb_dst_drop(skb);
 		skb_dst_set(skb, dst);
 	}
+	local_bh_enable();
 
 	err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev));
 	if (unlikely(err))
@@ -536,9 +534,9 @@ static int seg6_output_core(struct net *net, struct sock *sk,
 
 	slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
 
-	preempt_disable();
+	local_bh_disable();
 	dst = dst_cache_get(&slwt->cache);
-	preempt_enable();
+	local_bh_enable();
 
 	if (unlikely(!dst)) {
 		struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -558,9 +556,9 @@ static int seg6_output_core(struct net *net, struct sock *sk,
 			goto drop;
 		}
 
-		preempt_disable();
+		local_bh_disable();
 		dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr);
-		preempt_enable();
+		local_bh_enable();
 	}
 
 	skb_dst_drop(skb);
Signature · 1 line
2.43.0
author maintainer
#34 lore raw

PATCH 34/281 net: tls: fix marking packets as decrypted

In reply to Greg Kroah-Hartman

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

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

From: Jakub Kicinski <[email protected]>

[ Upstream commit a535d59432370343058755100ee75ab03c0e3f91 ]

For TLS offload we mark packets with skb->decrypted to make sure they don't escape the host without getting encrypted first. The crypto state lives in the socket, so it may get detached by a call to skb_orphan(). As a safety check - the egress path drops all packets with skb->decrypted and no "crypto-safe" socket.

The skb marking was added to sendpage only (and not sendmsg), because tls_device injected data into the TCP stack using sendpage. This special case was missed when sendpage got folded into sendmsg.

Fixes c5c37af6ecad ("tcp: Convert do_tcp_sendpages() to use MSG_SPLICE_PAGES")
---
 net/ipv4/tcp.c | 3 +++
 1 file changed, 3 insertions(+)
net/ipv4/tcp.c +3 -0
index 66d77faca64f6..5c79836e4c9e7 100644
@@ -1159,6 +1159,9 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
 
 			process_backlog++;
 
+#ifdef CONFIG_SKB_DECRYPTED
+			skb->decrypted = !!(flags & MSG_SENDPAGE_DECRYPTED);
+#endif
 			tcp_skb_entail(sk, skb);
 			copy = size_goal;
 
Signature · 1 line
2.43.0
author maintainer
#35 lore raw

PATCH 35/281 bpf: Set run context for rawtp test_run callback

In reply to Greg Kroah-Hartman

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

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

From: Jiri Olsa <[email protected]>

[ Upstream commit d0d1df8ba18abc57f28fb3bc053b2bf319367f2c ]

syzbot reported crash when rawtp program executed through the test_run interface calls bpf_get_attach_cookie helper or any other helper that touches task->bpf_ctx pointer.

Setting the run context (task->bpf_ctx pointer) for test_run callback.

---
 net/bpf/test_run.c | 6 ++++++
 1 file changed, 6 insertions(+)
net/bpf/test_run.c +6 -0
index 61efeadaff8db..4cd29fb490f7c 100644
@@ -719,10 +719,16 @@ static void
 __bpf_prog_test_run_raw_tp(void *data)
 {
 	struct bpf_raw_tp_test_run_info *info = data;
+	struct bpf_trace_run_ctx run_ctx = {};
+	struct bpf_run_ctx *old_run_ctx;
+
+	old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
 
 	rcu_read_lock();
 	info->retval = bpf_prog_run(info->prog, info->ctx);
 	rcu_read_unlock();
+
+	bpf_reset_run_ctx(old_run_ctx);
 }
 
 int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
Signature · 1 line
2.43.0
author maintainer
#36 lore raw

PATCH 36/281 octeontx2-af: Always allocate PF entries from low prioriy zone

In reply to Greg Kroah-Hartman

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

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

From: Subbaraya Sundeep <[email protected]>

[ Upstream commit 8b0f7410942cdc420c4557eda02bfcdf60ccec17 ]

PF mcam entries has to be at low priority always so that VF can install longest prefix match rules at higher priority. This was taken care currently but when priority allocation wrt reference entry is requested then entries are allocated from mid-zone instead of low priority zone. Fix this and always allocate entries from low priority zone for PFs.

Fixes 7df5b4b260dd ("octeontx2-af: Allocate low priority entries for PF")
---
 .../ethernet/marvell/octeontx2/af/rvu_npc.c   | 33 ++++++++++++-------
 1 file changed, 22 insertions(+), 11 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +22 -11
index e8b73b9d75e31..97722ce8c4cb3 100644
@@ -2519,7 +2519,17 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
 	 * - when available free entries are less.
 	 * Lower priority ones out of avaialble free entries are always
 	 * chosen when 'high vs low' question arises.
+	 *
+	 * For a VF base MCAM match rule is set by its PF. And all the
+	 * further MCAM rules installed by VF on its own are
+	 * concatenated with the base rule set by its PF. Hence PF entries
+	 * should be at lower priority compared to VF entries. Otherwise
+	 * base rule is hit always and rules installed by VF will be of
+	 * no use. Hence if the request is from PF then allocate low
+	 * priority entries.
 	 */
+	if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+		goto lprio_alloc;
 
 	/* Get the search range for priority allocation request */
 	if (req->priority) {
@@ -2528,17 +2538,6 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
 		goto alloc;
 	}
 
-	/* For a VF base MCAM match rule is set by its PF. And all the
-	 * further MCAM rules installed by VF on its own are
-	 * concatenated with the base rule set by its PF. Hence PF entries
-	 * should be at lower priority compared to VF entries. Otherwise
-	 * base rule is hit always and rules installed by VF will be of
-	 * no use. Hence if the request is from PF and NOT a priority
-	 * allocation request then allocate low priority entries.
-	 */
-	if (!(pcifunc & RVU_PFVF_FUNC_MASK))
-		goto lprio_alloc;
-
 	/* Find out the search range for non-priority allocation request
 	 *
 	 * Get MCAM free entry count in middle zone.
@@ -2568,6 +2567,18 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
 		reverse = true;
 		start = 0;
 		end = mcam->bmap_entries;
+		/* Ensure PF requests are always at bottom and if PF requests
+		 * for higher/lower priority entry wrt reference entry then
+		 * honour that criteria and start search for entries from bottom
+		 * and not in mid zone.
+		 */
+		if (!(pcifunc & RVU_PFVF_FUNC_MASK) &&
+		    req->priority == NPC_MCAM_HIGHER_PRIO)
+			end = req->ref_entry;
+
+		if (!(pcifunc & RVU_PFVF_FUNC_MASK) &&
+		    req->priority == NPC_MCAM_LOWER_PRIO)
+			start = req->ref_entry;
 	}
 
 alloc:
Signature · 1 line
2.43.0
author maintainer
#37 lore raw

PATCH 37/281 net/smc: avoid overwriting when adjusting sock bufsizes

In reply to Greg Kroah-Hartman

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

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

From: Wen Gu <[email protected]>

[ Upstream commit fb0aa0781a5f457e3864da68af52c3b1f4f7fd8f ]

When copying smc settings to clcsock, avoid setting clcsock's sk_sndbuf to sysctl_tcp_wmem[1], since this may overwrite the value set by tcp_sndbuf_expand() in TCP connection establishment.

And the other setting sk_{snd|rcv}buf to sysctl value in smc_adjust_sock_bufsizes() can also be omitted since the initialization of smc sock and clcsock has set sk_{snd|rcv}buf to smc.sysctl_{w|r}mem or ipv4_sysctl_tcp_{w|r}mem[1].

Fixes 30c3c4a4497c ("net/smc: Use correct buffer sizes when switching between TCP and SMC")
---
 net/smc/af_smc.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)
net/smc/af_smc.c +2 -20
index 4b52b3b159c0e..5f9f3d4c1df5f 100644
@@ -460,29 +460,11 @@ static int smc_bind(struct socket *sock, struct sockaddr *uaddr,
 static void smc_adjust_sock_bufsizes(struct sock *nsk, struct sock *osk,
 				     unsigned long mask)
 {
-	struct net *nnet = sock_net(nsk);
-
 	nsk->sk_userlocks = osk->sk_userlocks;
-	if (osk->sk_userlocks & SOCK_SNDBUF_LOCK) {
+	if (osk->sk_userlocks & SOCK_SNDBUF_LOCK)
 		nsk->sk_sndbuf = osk->sk_sndbuf;
-	} else {
-		if (mask == SK_FLAGS_SMC_TO_CLC)
-			WRITE_ONCE(nsk->sk_sndbuf,
-				   READ_ONCE(nnet->ipv4.sysctl_tcp_wmem[1]));
-		else
-			WRITE_ONCE(nsk->sk_sndbuf,
-				   2 * READ_ONCE(nnet->smc.sysctl_wmem));
-	}
-	if (osk->sk_userlocks & SOCK_RCVBUF_LOCK) {
+	if (osk->sk_userlocks & SOCK_RCVBUF_LOCK)
 		nsk->sk_rcvbuf = osk->sk_rcvbuf;
-	} else {
-		if (mask == SK_FLAGS_SMC_TO_CLC)
-			WRITE_ONCE(nsk->sk_rcvbuf,
-				   READ_ONCE(nnet->ipv4.sysctl_tcp_rmem[1]));
-		else
-			WRITE_ONCE(nsk->sk_rcvbuf,
-				   2 * READ_ONCE(nnet->smc.sysctl_rmem));
-	}
 }
 
 static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk,
Signature · 1 line
2.43.0
author maintainer
#38 lore raw

PATCH 38/281 net: phy: Micrel KSZ8061: fix errata solution not taking effect problem

In reply to Greg Kroah-Hartman

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

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

From: Tristram Ha <[email protected]>

[ Upstream commit 0a8d3f2e3e8d8aea8af017e14227b91d5989b696 ]

KSZ8061 needs to write to a MMD register at driver initialization to fix an errata. This worked in 5.0 kernel but not in newer kernels. The issue is the main phylib code no longer resets PHY at the very beginning. Calling phy resuming code later will reset the chip if it is already powered down at the beginning. This wipes out the MMD register write. Solution is to implement a phy resume function for KSZ8061 to take care of this problem.

Fixes 232ba3a51cc2 ("net: phy: Micrel KSZ8061: link failure after cable connect")
---
 drivers/net/phy/micrel.c | 42 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)
drivers/net/phy/micrel.c +41 -1
index c2d99344ade41..4b22bb6393e26 100644
@@ -785,6 +785,17 @@ static int ksz8061_config_init(struct phy_device *phydev)
 {
 	int ret;
 
+	/* Chip can be powered down by the bootstrap code. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (ret & BMCR_PDOWN) {
+		ret = phy_write(phydev, MII_BMCR, ret & ~BMCR_PDOWN);
+		if (ret < 0)
+			return ret;
+		usleep_range(1000, 2000);
+	}
+
 	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
 	if (ret)
 		return ret;
@@ -2054,6 +2065,35 @@ static int ksz9477_resume(struct phy_device *phydev)
 	return 0;
 }
 
+static int ksz8061_resume(struct phy_device *phydev)
+{
+	int ret;
+
+	/* This function can be called twice when the Ethernet device is on. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (!(ret & BMCR_PDOWN))
+		return 0;
+
+	genphy_resume(phydev);
+	usleep_range(1000, 2000);
+
+	/* Re-program the value after chip is reset. */
+	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
+	if (ret)
+		return ret;
+
+	/* Enable PHY Interrupts */
+	if (phy_interrupt_is_valid(phydev)) {
+		phydev->interrupts = PHY_INTERRUPT_ENABLED;
+		if (phydev->drv->config_intr)
+			phydev->drv->config_intr(phydev);
+	}
+
+	return 0;
+}
+
 static int kszphy_probe(struct phy_device *phydev)
 {
 	const struct kszphy_type *type = phydev->drv->driver_data;
@@ -4876,7 +4916,7 @@ static struct phy_driver ksphy_driver[] = {
 	.config_intr	= kszphy_config_intr,
 	.handle_interrupt = kszphy_handle_interrupt,
 	.suspend	= kszphy_suspend,
-	.resume		= kszphy_resume,
+	.resume		= ksz8061_resume,
 }, {
 	.phy_id		= PHY_ID_KSZ9021,
 	.phy_id_mask	= 0x000ffffe,
Signature · 1 line
2.43.0
author maintainer
#39 lore raw

PATCH 39/281 ionic: fix kernel panic in XDP_TX action

In reply to Greg Kroah-Hartman

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

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

From: Taehee Yoo <[email protected]>

[ Upstream commit 491aee894a08bc9b8bb52e7363b9d4bc6403f363 ]

In the XDP_TX path, ionic driver sends a packet to the TX path with rx page and corresponding dma address.
After tx is done, ionic_tx_clean() frees that page.
But RX ring buffer isn't reset to NULL.
So, it uses a freed page, which causes kernel panic.

BUG: unable to handle page fault for address: ffff8881576c110c
PGD 773801067 P4D 773801067 PUD 87f086067 PMD 87efca067 PTE 800ffffea893e060
Oops: Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC KASAN NOPTI
CPU: 1 PID: 25 Comm: ksoftirqd/1 Not tainted 6.9.0+ #11
Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021
RIP: 0010:bpf_prog_f0b8caeac1068a55_balancer_ingress+0x3b/0x44f
Code: 00 53 41 55 41 56 41 57 b8 01 00 00 00 48 8b 5f 08 4c 8b 77 00 4c 89 f7 48 83 c7 0e 48 39 d8
RSP: 0018:ffff888104e6fa28 EFLAGS: 00010283
RAX: 0000000000000002 RBX: ffff8881576c1140 RCX: 0000000000000002
RDX: ffffffffc0051f64 RSI: ffffc90002d33048 RDI: ffff8881576c110e
RBP: ffff888104e6fa88 R08: 0000000000000000 R09: ffffed1027a04a23
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8881b03a21a8
R13: ffff8881589f800f R14: ffff8881576c1100 R15: 00000001576c1100
FS: 0000000000000000(0000) GS:ffff88881ae00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff8881576c110c CR3: 0000000767a90000 CR4: 00000000007506f0
PKRU: 55555554
Call Trace:
<TASK>
? __die+0x20/0x70
? page_fault_oops+0x254/0x790
? __pfx_page_fault_oops+0x10/0x10
? __pfx_is_prefetch.constprop.0+0x10/0x10
? search_bpf_extables+0x165/0x260
? fixup_exception+0x4a/0x970
? exc_page_fault+0xcb/0xe0
? asm_exc_page_fault+0x22/0x30
? 0xffffffffc0051f64
? bpf_prog_f0b8caeac1068a55_balancer_ingress+0x3b/0x44f
? do_raw_spin_unlock+0x54/0x220
ionic_rx_service+0x11ab/0x3010 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
? ionic_tx_clean+0x29b/0xc60 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
? __pfx_ionic_tx_clean+0x10/0x10 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
? __pfx_ionic_rx_service+0x10/0x10 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
? ionic_tx_cq_service+0x25d/0xa00 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
? __pfx_ionic_rx_service+0x10/0x10 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
ionic_cq_service+0x69/0x150 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
ionic_txrx_napi+0x11a/0x540 [ionic 9180c3001ab627d82bbc5f3ebe8a0decaf6bb864]
__napi_poll.constprop.0+0xa0/0x440
net_rx_action+0x7e7/0xc30
? __pfx_net_rx_action+0x10/0x10
Fixes 8eeed8373e1c ("ionic: Add XDP_TX support")
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/pensando/ionic/ionic_txrx.c +1 -0
index 5dba6d2d633cb..2427610f4306d 100644
@@ -586,6 +586,7 @@ static bool ionic_run_xdp(struct ionic_rx_stats *stats,
 			netdev_dbg(netdev, "tx ionic_xdp_post_frame err %d\n", err);
 			goto out_xdp_abort;
 		}
+		buf_info->page = NULL;
 		stats->xdp_tx++;
 
 		/* the Tx completion will free the buffers */
Signature · 1 line
2.43.0
author maintainer
#40 lore raw

PATCH 40/281 net: sched: sch_multiq: fix possible OOB write in multiq_tune()

In reply to Greg Kroah-Hartman

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

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

From: Hangyu Hua <[email protected]>

[ Upstream commit affc18fdc694190ca7575b9a86632a73b9fe043d ]

q->bands will be assigned to qopt->bands to execute subsequent code logic after kmalloc. So the old q->bands should not be used in kmalloc. Otherwise, an out-of-bounds write will occur.

Fixes c2999f7fb05b ("net: sched: multiq: don't call qdisc_put() while holding tree lock")
---
 net/sched/sch_multiq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/sch_multiq.c +1 -1
index 79e93a19d5fab..06e03f5cd7ce1 100644
@@ -185,7 +185,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
 
 	qopt->bands = qdisc_dev(sch)->real_num_tx_queues;
 
-	removed = kmalloc(sizeof(*removed) * (q->max_bands - q->bands),
+	removed = kmalloc(sizeof(*removed) * (q->max_bands - qopt->bands),
 			  GFP_KERNEL);
 	if (!removed)
 		return -ENOMEM;
Signature · 1 line
2.43.0
author maintainer
#41 lore raw

PATCH 41/281 tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB

In reply to Greg Kroah-Hartman

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

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

From: Jason Xing <[email protected]>

[ Upstream commit a46d0ea5c94205f40ecf912d1bb7806a8a64704f ]

According to RFC 1213, we should also take CLOSE-WAIT sockets into consideration:

"tcpCurrEstab OBJECT-TYPE
...
The number of TCP connections for which the current state is either ESTABLISHED or CLOSE- WAIT."

After this, CurrEstab counter will display the total number of ESTABLISHED and CLOSE-WAIT sockets.

The logic of counting
When we increment the counter?
a) if we change the state to ESTABLISHED.
b) if we change the state from SYN-RECEIVED to CLOSE-WAIT.

When we decrement the counter?
a) if the socket leaves ESTABLISHED and will never go into CLOSE-WAIT, say, on the client side, changing from ESTABLISHED to FIN-WAIT-1.
b) if the socket leaves CLOSE-WAIT, say, on the server side, changing from CLOSE-WAIT to LAST-ACK.

Please note: there are two chances that old state of socket can be changed to CLOSE-WAIT in tcp_fin(). One is SYN-RECV, the other is ESTABLISHED. So we have to take care of the former case.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/ipv4/tcp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
net/ipv4/tcp.c +5 -1
index 5c79836e4c9e7..77ee1eda3fd86 100644
@@ -2640,6 +2640,10 @@ void tcp_set_state(struct sock *sk, int state)
 		if (oldstate != TCP_ESTABLISHED)
 			TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB);
 		break;
+	case TCP_CLOSE_WAIT:
+		if (oldstate == TCP_SYN_RECV)
+			TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB);
+		break;
 
 	case TCP_CLOSE:
 		if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
@@ -2651,7 +2655,7 @@ void tcp_set_state(struct sock *sk, int state)
 			inet_put_port(sk);
 		fallthrough;
 	default:
-		if (oldstate == TCP_ESTABLISHED)
+		if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT)
 			TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB);
 	}
 
Signature · 1 line
2.43.0
author maintainer
#42 lore raw

PATCH 42/281 mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB

In reply to Greg Kroah-Hartman

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

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

From: Jason Xing <[email protected]>

[ Upstream commit 9633e9377e6af0244f7381e86b9aac5276f5be97 ]

Like previous patch does in TCP, we need to adhere to RFC 1213:

"tcpCurrEstab OBJECT-TYPE
...
The number of TCP connections for which the current state is either ESTABLISHED or CLOSE- WAIT."

So let's consider CLOSE-WAIT sockets.

The logic of counting
When we increment the counter?
a) Only if we change the state to ESTABLISHED.

When we decrement the counter?
a) if the socket leaves ESTABLISHED and will never go into CLOSE-WAIT, say, on the client side, changing from ESTABLISHED to FIN-WAIT-1.
b) if the socket leaves CLOSE-WAIT, say, on the server side, changing from CLOSE-WAIT to LAST-ACK.

Fixes d9cd27b8cd19 ("mptcp: add CurrEstab MIB counter support")
---
 net/mptcp/protocol.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
net/mptcp/protocol.c +7 -2
index 965eb69dc5de3..327dcf06edd47 100644
@@ -2907,9 +2907,14 @@ void mptcp_set_state(struct sock *sk, int state)
 		if (oldstate != TCP_ESTABLISHED)
 			MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB);
 		break;
-
+	case TCP_CLOSE_WAIT:
+		/* Unlike TCP, MPTCP sk would not have the TCP_SYN_RECV state:
+		 * MPTCP "accepted" sockets will be created later on. So no
+		 * transition from TCP_SYN_RECV to TCP_CLOSE_WAIT.
+		 */
+		break;
 	default:
-		if (oldstate == TCP_ESTABLISHED)
+		if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT)
 			MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB);
 	}
 
Signature · 1 line
2.43.0
author maintainer
#43 lore raw

PATCH 43/281 rtnetlink: make the "split" NLM_DONE handling generic

In reply to Greg Kroah-Hartman

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

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

From: Jakub Kicinski <[email protected]>

[ Upstream commit 5b4b62a169e10401cca34a6e7ac39161986f5605 ]

Jaroslav reports Dell's OMSA Systems Management Data Engine expects NLM_DONE in a separate recvmsg(), both for rtnl_dump_ifinfo() and inet_dump_ifaddr(). We already added a similar fix previously in commit 460b0d33cf10 ("inet: bring NLM_DONE out to a separate recv() again")

Instead of modifying all the dump handlers, and making them look different than modern for_each_netdev_dump()-based dump handlers - put the workaround in rtnetlink code. This will also help us move the custom rtnl-locking from af_netlink in the future (in net-next).

Note that this change is not touching rtnl_dump_all(). rtnl_dump_all() is different kettle of fish and a potential problem. We now mix families in a single recvmsg(), but NLM_DONE is not coalesced.

Tested:

  ./cli.py --dbg-small-recv 4096 --spec netlink/specs/rt_addr.yaml \
           --dump getaddr --json '{"ifa-family": 2}'

  ./cli.py --dbg-small-recv 4096 --spec netlink/specs/rt_route.yaml \
           --dump getroute --json '{"rtm-family": 2}'

  ./cli.py --dbg-small-recv 4096 --spec netlink/specs/rt_link.yaml \
           --dump getlink
Fixes 3e41af90767d ("rtnetlink: use xarray iterator to implement rtnl_dump_ifinfo()")
Fixes cdb2f80f1c10 ("inet: use xa_array iterator to implement inet_dump_ifaddr()")
---
 include/net/rtnetlink.h |  1 +
 net/core/rtnetlink.c    | 44 +++++++++++++++++++++++++++++++++++++++--
 net/ipv4/devinet.c      |  2 +-
 net/ipv4/fib_frontend.c |  7 +------
 4 files changed, 45 insertions(+), 9 deletions(-)
include/net/rtnetlink.h +1 -0
index 3bfb80bad1739..b45d57b5968af 100644
@@ -13,6 +13,7 @@ enum rtnl_link_flags {
 	RTNL_FLAG_DOIT_UNLOCKED		= BIT(0),
 	RTNL_FLAG_BULK_DEL_SUPPORTED	= BIT(1),
 	RTNL_FLAG_DUMP_UNLOCKED		= BIT(2),
+	RTNL_FLAG_DUMP_SPLIT_NLM_DONE	= BIT(3),	/* legacy behavior */
 };
 
 enum rtnl_kinds {
net/core/rtnetlink.c +42 -2

62 lines not on this page · raw message

net/ipv4/devinet.c +1 -1
index 8382cc998bff8..84b5d1ccf716a 100644
@@ -2801,7 +2801,7 @@ void __init devinet_init(void)
 	rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, 0);
 	rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, 0);
 	rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr,
-		      RTNL_FLAG_DUMP_UNLOCKED);
+		      RTNL_FLAG_DUMP_UNLOCKED | RTNL_FLAG_DUMP_SPLIT_NLM_DONE);
 	rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf,
 		      inet_netconf_dump_devconf,
 		      RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED);
net/ipv4/fib_frontend.c +1 -6
index c484b1c0fc00a..7ad2cafb92763 100644
@@ -1050,11 +1050,6 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 			e++;
 		}
 	}
-
-	/* Don't let NLM_DONE coalesce into a message, even if it could.
-	 * Some user space expects NLM_DONE in a separate recv().
-	 */
-	err = skb->len;
 out:
 
 	cb->args[1] = e;
@@ -1665,5 +1660,5 @@ void __init ip_fib_init(void)
 	rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, 0);
 	rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, 0);
 	rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib,
-		      RTNL_FLAG_DUMP_UNLOCKED);
+		      RTNL_FLAG_DUMP_UNLOCKED | RTNL_FLAG_DUMP_SPLIT_NLM_DONE);
 }
Signature · 1 line
2.43.0
author maintainer
#44 lore raw

PATCH 44/281 net: ethernet: mtk_eth_soc: handle dma buffer size soc specific

In reply to Greg Kroah-Hartman

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

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

From: Frank Wunderlich <[email protected]>

[ Upstream commit c57e558194430d10d5e5f4acd8a8655b68dade13 ]

The mainline MTK ethernet driver suffers long time from rarly but annoying tx queue timeouts. We think that this is caused by fixed dma sizes hardcoded for all SoCs.

We suspect this problem arises from a low level of free TX DMADs, the TX Ring alomost full.

The transmit timeout is caused by the Tx queue not waking up. The Tx queue stops when the free counter is less than ring->thres, and it will wake up once the free counter is greater than ring->thres. If the CPU is too late to wake up the Tx queues, it may cause a transmit timeout.
Therefore, we increased the TX and RX DMADs to improve this error situation.

Use the dma-size implementation from SDK in a per SoC manner. In difference to SDK we have no RSS feature yet, so all RX/TX sizes should be raised from 512 to 2048 byte except fqdma on mt7988 to avoid the tx timeout issue.

Fixes 656e705243fd ("net-next: mediatek: add support for MT7623 ethernet")
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 104 +++++++++++++-------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |   9 +-
 2 files changed, 77 insertions(+), 36 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +70 -34
index d7d73295f0dc4..41d9b0684be74 100644
@@ -1131,9 +1131,9 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
 {
 	const struct mtk_soc_data *soc = eth->soc;
 	dma_addr_t phy_ring_tail;
-	int cnt = MTK_QDMA_RING_SIZE;
+	int cnt = soc->tx.fq_dma_size;
 	dma_addr_t dma_addr;
-	int i;
+	int i, j, len;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
 		eth->scratch_ring = eth->sram_base;
@@ -1142,40 +1142,46 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
 						       cnt * soc->tx.desc_size,
 						       &eth->phy_scratch_ring,
 						       GFP_KERNEL);
+
 	if (unlikely(!eth->scratch_ring))
 		return -ENOMEM;
 
-	eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
-	if (unlikely(!eth->scratch_head))
-		return -ENOMEM;
+	phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
 
-	dma_addr = dma_map_single(eth->dma_dev,
-				  eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
-				  DMA_FROM_DEVICE);
-	if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
-		return -ENOMEM;
+	for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
+		len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
+		eth->scratch_head[j] = kcalloc(len, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
 
-	phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
+		if (unlikely(!eth->scratch_head[j]))
+			return -ENOMEM;
 
-	for (i = 0; i < cnt; i++) {
-		dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
-		struct mtk_tx_dma_v2 *txd;
+		dma_addr = dma_map_single(eth->dma_dev,
+					  eth->scratch_head[j], len * MTK_QDMA_PAGE_SIZE,
+					  DMA_FROM_DEVICE);
 
-		txd = eth->scratch_ring + i * soc->tx.desc_size;
-		txd->txd1 = addr;
-		if (i < cnt - 1)
-			txd->txd2 = eth->phy_scratch_ring +
-				    (i + 1) * soc->tx.desc_size;
+		if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
+			return -ENOMEM;
 
-		txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
-		if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
-			txd->txd3 |= TX_DMA_PREP_ADDR64(addr);
-		txd->txd4 = 0;
-		if (mtk_is_netsys_v2_or_greater(eth)) {
-			txd->txd5 = 0;
-			txd->txd6 = 0;
-			txd->txd7 = 0;
-			txd->txd8 = 0;
+		for (i = 0; i < cnt; i++) {
+			struct mtk_tx_dma_v2 *txd;
+
+			txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
+			txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
+			if (j * MTK_FQ_DMA_LENGTH + i < cnt)
+				txd->txd2 = eth->phy_scratch_ring +
+					    (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
+
+			txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+			if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
+				txd->txd3 |= TX_DMA_PREP_ADDR64(dma_addr + i * MTK_QDMA_PAGE_SIZE);
+
+			txd->txd4 = 0;
+			if (mtk_is_netsys_v2_or_greater(eth)) {
+				txd->txd5 = 0;
+				txd->txd6 = 0;
+				txd->txd7 = 0;
+				txd->txd8 = 0;
+			}
 		}
 	}
 
@@ -2457,7 +2463,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
 	if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
 		ring_size = MTK_QDMA_RING_SIZE;
 	else
-		ring_size = MTK_DMA_SIZE;
+		ring_size = soc->tx.dma_size;
 
 	ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
 			       GFP_KERNEL);
@@ -2465,8 +2471,8 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
 		goto no_tx_mem;
 
 	if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
-		ring->dma = eth->sram_base + ring_size * sz;
-		ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
+		ring->dma = eth->sram_base + soc->tx.fq_dma_size * sz;
+		ring->phys = eth->phy_scratch_ring + soc->tx.fq_dma_size * (dma_addr_t)sz;
 	} else {
 		ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
 					       &ring->phys, GFP_KERNEL);
@@ -2588,6 +2594,7 @@ static void mtk_tx_clean(struct mtk_eth *eth)
 static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
 {
 	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+	const struct mtk_soc_data *soc = eth->soc;
 	struct mtk_rx_ring *ring;
 	int rx_data_len, rx_dma_size, tx_ring_size;
 	int i;
@@ -2595,7 +2602,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 		tx_ring_size = MTK_QDMA_RING_SIZE;
 	else
-		tx_ring_size = MTK_DMA_SIZE;
+		tx_ring_size = soc->tx.dma_size;
 
 	if (rx_flag == MTK_RX_FLAGS_QDMA) {
 		if (ring_no)
@@ -2610,7 +2617,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
 		rx_dma_size = MTK_HW_LRO_DMA_SIZE;
 	} else {
 		rx_data_len = ETH_DATA_LEN;
-		rx_dma_size = MTK_DMA_SIZE;
+		rx_dma_size = soc->rx.dma_size;
 	}
 
 	ring->frag_size = mtk_max_frag_size(rx_data_len);
@@ -3139,7 +3146,10 @@ static void mtk_dma_free(struct mtk_eth *eth)
 			mtk_rx_clean(eth, &eth->rx_ring[i], false);
 	}
 
-	kfree(eth->scratch_head);
+	for (i = 0; i < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); i++) {
+		kfree(eth->scratch_head[i]);
+		eth->scratch_head[i] = NULL;
+	}
 }
 
 static bool mtk_hw_reset_check(struct mtk_eth *eth)
@@ -5043,11 +5053,14 @@ static const struct mtk_soc_data mt2701_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
 		.irq_done_mask = MTK_RX_DONE_INT,
 		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5067,11 +5080,14 @@ static const struct mtk_soc_data mt7621_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
 		.irq_done_mask = MTK_RX_DONE_INT,
 		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5093,11 +5109,14 @@ static const struct mtk_soc_data mt7622_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
 		.irq_done_mask = MTK_RX_DONE_INT,
 		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5118,11 +5137,14 @@ static const struct mtk_soc_data mt7623_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
 		.irq_done_mask = MTK_RX_DONE_INT,
 		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5141,11 +5163,14 @@ static const struct mtk_soc_data mt7629_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
 		.irq_done_mask = MTK_RX_DONE_INT,
 		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5167,6 +5192,8 @@ static const struct mtk_soc_data mt7981_data = {
 		.desc_size = sizeof(struct mtk_tx_dma_v2),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
@@ -5174,6 +5201,7 @@ static const struct mtk_soc_data mt7981_data = {
 		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5193,6 +5221,8 @@ static const struct mtk_soc_data mt7986_data = {
 		.desc_size = sizeof(struct mtk_tx_dma_v2),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
@@ -5200,6 +5230,7 @@ static const struct mtk_soc_data mt7986_data = {
 		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5219,6 +5250,8 @@ static const struct mtk_soc_data mt7988_data = {
 		.desc_size = sizeof(struct mtk_tx_dma_v2),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(4K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma_v2),
@@ -5226,6 +5259,7 @@ static const struct mtk_soc_data mt7988_data = {
 		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5240,6 +5274,7 @@ static const struct mtk_soc_data rt5350_data = {
 		.desc_size = sizeof(struct mtk_tx_dma),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 	.rx = {
 		.desc_size = sizeof(struct mtk_rx_dma),
@@ -5247,6 +5282,7 @@ static const struct mtk_soc_data rt5350_data = {
 		.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
drivers/net/ethernet/mediatek/mtk_eth_soc.h +7 -2
index 39b50de1decbf..a25c33b9a4f34 100644
@@ -32,7 +32,9 @@
 #define MTK_TX_DMA_BUF_LEN	0x3fff
 #define MTK_TX_DMA_BUF_LEN_V2	0xffff
 #define MTK_QDMA_RING_SIZE	2048
-#define MTK_DMA_SIZE		512
+#define MTK_DMA_SIZE(x)		(SZ_##x)
+#define MTK_FQ_DMA_HEAD		32
+#define MTK_FQ_DMA_LENGTH	2048
 #define MTK_RX_ETH_HLEN		(ETH_HLEN + ETH_FCS_LEN)
 #define MTK_RX_HLEN		(NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
 #define MTK_DMA_DUMMY_DESC	0xffffffff
@@ -1176,6 +1178,8 @@ struct mtk_soc_data {
 		u32	desc_size;
 		u32	dma_max_len;
 		u32	dma_len_offset;
+		u32	dma_size;
+		u32	fq_dma_size;
 	} tx;
 	struct {
 		u32	desc_size;
@@ -1183,6 +1187,7 @@ struct mtk_soc_data {
 		u32	dma_l4_valid;
 		u32	dma_max_len;
 		u32	dma_len_offset;
+		u32	dma_size;
 	} rx;
 };
 
@@ -1264,7 +1269,7 @@ struct mtk_eth {
 	struct napi_struct		rx_napi;
 	void				*scratch_ring;
 	dma_addr_t			phy_scratch_ring;
-	void				*scratch_head;
+	void				*scratch_head[MTK_FQ_DMA_HEAD];
 	struct clk			*clks[MTK_CLK_MAX];
 
 	struct mii_bus			*mii_bus;
Signature · 1 line
2.43.0
author maintainer
#45 lore raw

PATCH 45/281 net/mlx5: Stop waiting for PCI if pci channel is offline

In reply to Greg Kroah-Hartman

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

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

From: Moshe Shemesh <[email protected]>

[ Upstream commit 33afbfcc105a572159750f2ebee834a8a70fdd96 ]

In case pci channel becomes offline the driver should not wait for PCI reads during health dump and recovery flow. The driver has timeout for each of these loops trying to read PCI, so it would fail anyway. However, in case of recovery waiting till timeout may cause the pci error_detected() callback fail to meet pci_dpc_recovered() wait timeout.

Fixes b3bd076f7501 ("net/mlx5: Report devlink health on FW fatal issues")
---
 drivers/net/ethernet/mellanox/mlx5/core/fw.c          | 4 ++++
 drivers/net/ethernet/mellanox/mlx5/core/health.c      | 8 ++++++++
 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 4 ++++
 3 files changed, 16 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/fw.c +4 -0
index e7faf7e73ca48..6c7f2471fe629 100644
@@ -373,6 +373,10 @@ int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev)
 	do {
 		if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED)
 			break;
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n");
+			return -EACCES;
+		}
 
 		cond_resched();
 	} while (!time_after(jiffies, end));
drivers/net/ethernet/mellanox/mlx5/core/health.c +8 -0
index ad38e31822df1..a6329ca2d9bff 100644
@@ -248,6 +248,10 @@ void mlx5_error_sw_reset(struct mlx5_core_dev *dev)
 	do {
 		if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED)
 			break;
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n");
+			goto unlock;
+		}
 
 		msleep(20);
 	} while (!time_after(jiffies, end));
@@ -317,6 +321,10 @@ int mlx5_health_wait_pci_up(struct mlx5_core_dev *dev)
 			mlx5_core_warn(dev, "device is being removed, stop waiting for PCI\n");
 			return -ENODEV;
 		}
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for PCI\n");
+			return -EACCES;
+		}
 		msleep(100);
 	}
 	return 0;
drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +4 -0
index 6b774e0c27665..d0b595ba61101 100644
@@ -74,6 +74,10 @@ int mlx5_vsc_gw_lock(struct mlx5_core_dev *dev)
 			ret = -EBUSY;
 			goto pci_unlock;
 		}
+		if (pci_channel_offline(dev->pdev)) {
+			ret = -EACCES;
+			goto pci_unlock;
+		}
 
 		/* Check if semaphore is already locked */
 		ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
Signature · 1 line
2.43.0
author maintainer
#46 lore raw

PATCH 46/281 net/mlx5: Always stop health timer during driver removal

In reply to Greg Kroah-Hartman

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

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

From: Shay Drory <[email protected]>

[ Upstream commit c8b3f38d2dae0397944814d691a419c451f9906f ]

Currently, if teardown_hca fails to execute during driver removal, mlx5 does not stop the health timer. Afterwards, mlx5 continue with driver teardown. This may lead to a UAF bug, which results in page fault Oops[1], since the health timer invokes after resources were freed.

Hence, stop the health monitor even if teardown_hca fails.

[1]
mlx5_core 0000:18:00.0: E-Switch: Unload vfs: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) mlx5_core 0000:18:00.0: E-Switch: Disable: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) mlx5_core 0000:18:00.0: E-Switch: Disable: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) mlx5_core 0000:18:00.0: E-Switch: cleanup
mlx5_core 0000:18:00.0: wait_func:1155:(pid 1967079): TEARDOWN_HCA(0x103) timeout. Will cause a leak of a command resource mlx5_core 0000:18:00.0: mlx5_function_close:1288:(pid 1967079): tear_down_hca failed, skip cleanup

BUG: unable to handle page fault for address: ffffa26487064230
PGD 100c00067 P4D 100c00067 PUD 100e5a067 PMD 105ed7067 PTE 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G           OE     -------  ---  6.7.0-68.fc38.x86_64 #1
Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0013.121520200651 12/15/2020
RIP: 0010:ioread32be+0x34/0x60
RSP: 0018:ffffa26480003e58 EFLAGS: 00010292
RAX: ffffa26487064200 RBX: ffff9042d08161a0 RCX: ffff904c108222c0
RDX: 000000010bbf1b80 RSI: ffffffffc055ddb0 RDI: ffffa26487064230
RBP: ffff9042d08161a0 R08: 0000000000000022 R09: ffff904c108222e8
R10: 0000000000000004 R11: 0000000000000441 R12: ffffffffc055ddb0
R13: ffffa26487064200 R14: ffffa26480003f00 R15: ffff904c108222c0
FS:  0000000000000000(0000) GS:ffff904c10800000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffa26487064230 CR3: 00000002c4420006 CR4: 00000000007706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
 <IRQ>
 ? __die+0x23/0x70
 ? page_fault_oops+0x171/0x4e0
 ? exc_page_fault+0x175/0x180
 ? asm_exc_page_fault+0x26/0x30
 ? __pfx_poll_health+0x10/0x10 [mlx5_core]
 ? __pfx_poll_health+0x10/0x10 [mlx5_core]
 ? ioread32be+0x34/0x60
 mlx5_health_check_fatal_sensors+0x20/0x100 [mlx5_core]
 ? __pfx_poll_health+0x10/0x10 [mlx5_core]
 poll_health+0x42/0x230 [mlx5_core]
 ? __next_timer_interrupt+0xbc/0x110
 ? __pfx_poll_health+0x10/0x10 [mlx5_core]
 call_timer_fn+0x21/0x130
 ? __pfx_poll_health+0x10/0x10 [mlx5_core]
 __run_timers+0x222/0x2c0
 run_timer_softirq+0x1d/0x40
 __do_softirq+0xc9/0x2c8
 __irq_exit_rcu+0xa6/0xc0
 sysvec_apic_timer_interrupt+0x72/0x90
 </IRQ>
 <TASK>
 asm_sysvec_apic_timer_interrupt+0x1a/0x20
RIP: 0010:cpuidle_enter_state+0xcc/0x440
 ? cpuidle_enter_state+0xbd/0x440
 cpuidle_enter+0x2d/0x40
 do_idle+0x20d/0x270
 cpu_startup_entry+0x2a/0x30
 rest_init+0xd0/0xd0
 arch_call_rest_init+0xe/0x30
 start_kernel+0x709/0xa90
 x86_64_start_reservations+0x18/0x30
 x86_64_start_kernel+0x96/0xa0
 secondary_startup_64_no_verify+0x18f/0x19b
---[ end trace 0000000000000000 ]---
Fixes 9b98d395b85d ("net/mlx5: Start health poll at earlier stage of driver load")
---
 drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/main.c +3 -0
index 6574c145dc1e2..459a836a5d9c1 100644
@@ -1298,6 +1298,9 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot)
 
 	if (!err)
 		mlx5_function_disable(dev, boot);
+	else
+		mlx5_stop_health_poll(dev, boot);
+
 	return err;
 }
 
Signature · 1 line
2.43.0
author maintainer
#47 lore raw

PATCH 47/281 net/mlx5: Fix tainted pointer delete is case of flow rules creation fail

In reply to Greg Kroah-Hartman

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

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

From: Aleksandr Mishin <[email protected]>

[ Upstream commit 229bedbf62b13af5aba6525ad10b62ad38d9ccb5 ]

In case of flow rule creation fail in mlx5_lag_create_port_sel_table(), instead of previously created rules, the tainted pointer is deleted deveral times.
Fix this bug by using correct flow rules pointers.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

---
 drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +6 -2
index 101b3bb908638..e12bc4cd80661 100644
@@ -88,9 +88,13 @@ static int mlx5_lag_create_port_sel_table(struct mlx5_lag *ldev,
 								      &dest, 1);
 			if (IS_ERR(lag_definer->rules[idx])) {
 				err = PTR_ERR(lag_definer->rules[idx]);
-				while (i--)
-					while (j--)
+				do {
+					while (j--) {
+						idx = i * ldev->buckets + j;
 						mlx5_del_flow_rules(lag_definer->rules[idx]);
+					}
+					j = ldev->buckets;
+				} while (i--);
 				goto destroy_fg;
 			}
 		}
Signature · 1 line
2.43.0
author maintainer
#48 lore raw

PATCH 48/281 net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit f921a58ae20852d188f70842431ce6519c4fdc36 ]

If one TCA_TAPRIO_ATTR_PRIOMAP attribute has been provided, taprio_parse_mqprio_opt() must validate it, or userspace can inject arbitrary data to the kernel, the second time taprio_change() is called.

First call (with valid attributes) sets dev->num_tc to a non zero value.

Second call (with arbitrary mqprio attributes)
returns early from taprio_parse_mqprio_opt()
and bad things can happen.

---
 net/sched/sch_taprio.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)
net/sched/sch_taprio.c +6 -9
index 5c3f8a278fc2f..0b150b13bee7a 100644
@@ -1176,16 +1176,13 @@ static int taprio_parse_mqprio_opt(struct net_device *dev,
 {
 	bool allow_overlapping_txqs = TXTIME_ASSIST_IS_ENABLED(taprio_flags);
 
-	if (!qopt && !dev->num_tc) {
-		NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary");
-		return -EINVAL;
-	}
-
-	/* If num_tc is already set, it means that the user already
-	 * configured the mqprio part
-	 */
-	if (dev->num_tc)
+	if (!qopt) {
+		if (!dev->num_tc) {
+			NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary");
+			return -EINVAL;
+		}
 		return 0;
+	}
 
 	/* taprio imposes that traffic classes map 1:n to tx queues */
 	if (qopt->num_tc > dev->num_tx_queues) {
Signature · 1 line
2.43.0
author maintainer
#49 lore raw

PATCH 49/281 ptp: Fix error message on failed pin verification

In reply to Greg Kroah-Hartman

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

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

From: Karol Kolacinski <[email protected]>

[ Upstream commit 323a359f9b077f382f4483023d096a4d316fd135 ]

On failed verification of PTP clock pin, error message prints channel number instead of pin index after "pin", which is incorrect.

Fix error message by adding channel number to the message and printing pin number instead of channel number.

---
 drivers/ptp/ptp_chardev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/ptp/ptp_chardev.c +2 -1
index 7513018c9f9ac..2067b0120d083 100644
@@ -85,7 +85,8 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
 	}
 
 	if (info->verify(info, pin, func, chan)) {
-		pr_err("driver cannot use function %u on pin %u\n", func, chan);
+		pr_err("driver cannot use function %u and channel %u on pin %u\n",
+		       func, chan, pin);
 		return -EOPNOTSUPP;
 	}
 
Signature · 1 line
2.43.0
author maintainer
#50 lore raw

PATCH 50/281 ice: fix iteration of TLVs in Preserved Fields Area

In reply to Greg Kroah-Hartman

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

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

From: Jacob Keller <[email protected]>

[ Upstream commit 03e4a092be8ce3de7c1baa7ae14e68b64e3ea644 ]

The ice_get_pfa_module_tlv() function iterates over the Type-Length-Value structures in the Preserved Fields Area (PFA) of the NVM. This is used by the driver to access data such as the Part Board Assembly identifier.

The function uses simple logic to iterate over the PFA. First, the pointer to the PFA in the NVM is read. Then the total length of the PFA is read from the first word.

A pointer to the first TLV is initialized, and a simple loop iterates over each TLV. The pointer is moved forward through the NVM until it exceeds the PFA area.

The logic seems sound, but it is missing a key detail. The Preserved Fields Area length includes one additional final word. This is documented in the device data sheet as a dummy word which contains 0xFFFF. All NVMs have this extra word.

If the driver tries to scan for a TLV that is not in the PFA, it will read past the size of the PFA. It reads and interprets the last dummy word of the PFA as a TLV with type 0xFFFF. It then reads the word following the PFA as a length.

The PFA resides within the Shadow RAM portion of the NVM, which is relatively small. All of its offsets are within a 16-bit size. The PFA pointer and TLV pointer are stored by the driver as 16-bit values.

In almost all cases, the word following the PFA will be such that interpreting it as a length will result in 16-bit arithmetic overflow. Once overflowed, the new next_tlv value is now below the maximum offset of the PFA. Thus, the driver will continue to iterate the data as TLVs. In the worst case, the driver hits on a sequence of reads which loop back to reading the same offsets in an endless loop.

To fix this, we need to correct the loop iteration check to account for this extra word at the end of the PFA. This alone is sufficient to resolve the known cases of this issue in the field. However, it is plausible that an NVM could be misconfigured or have corrupt data which results in the same kind of overflow. Protect against this by using check_add_overflow when calculating both the maximum offset of the TLVs, and when calculating the next_tlv offset at the end of each loop iteration. This ensures that the driver will not get stuck in an infinite loop when scanning the PFA.

---
 drivers/net/ethernet/intel/ice/ice_nvm.c | 28 ++++++++++++++++++------
 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/net/ethernet/intel/ice/ice_nvm.c +21 -7
index d4e05d2cb30c4..a0ad950cc76d9 100644
@@ -441,8 +441,7 @@ int
 ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
 		       u16 module_type)
 {
-	u16 pfa_len, pfa_ptr;
-	u16 next_tlv;
+	u16 pfa_len, pfa_ptr, next_tlv, max_tlv;
 	int status;
 
 	status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
@@ -455,11 +454,23 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
 		ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
 		return status;
 	}
+
+	/* The Preserved Fields Area contains a sequence of Type-Length-Value
+	 * structures which define its contents. The PFA length includes all
+	 * of the TLVs, plus the initial length word itself, *and* one final
+	 * word at the end after all of the TLVs.
+	 */
+	if (check_add_overflow(pfa_ptr, pfa_len - 1, &max_tlv)) {
+		dev_warn(ice_hw_to_dev(hw), "PFA starts at offset %u. PFA length of %u caused 16-bit arithmetic overflow.\n",
+			 pfa_ptr, pfa_len);
+		return -EINVAL;
+	}
+
 	/* Starting with first TLV after PFA length, iterate through the list
 	 * of TLVs to find the requested one.
 	 */
 	next_tlv = pfa_ptr + 1;
-	while (next_tlv < pfa_ptr + pfa_len) {
+	while (next_tlv < max_tlv) {
 		u16 tlv_sub_module_type;
 		u16 tlv_len;
 
@@ -483,10 +494,13 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
 			}
 			return -EINVAL;
 		}
-		/* Check next TLV, i.e. current TLV pointer + length + 2 words
-		 * (for current TLV's type and length)
-		 */
-		next_tlv = next_tlv + tlv_len + 2;
+
+		if (check_add_overflow(next_tlv, 2, &next_tlv) ||
+		    check_add_overflow(next_tlv, tlv_len, &next_tlv)) {
+			dev_warn(ice_hw_to_dev(hw), "TLV of type %u and length 0x%04x caused 16-bit arithmetic overflow. The PFA starts at 0x%04x and has length of 0x%04x\n",
+				 tlv_sub_module_type, tlv_len, pfa_ptr, pfa_len);
+			return -EINVAL;
+		}
 	}
 	/* Module does not exist */
 	return -ENOENT;
Signature · 1 line
2.43.0
author maintainer
#51 lore raw

PATCH 51/281 ice: fix reads from NVM Shadow RAM on E830 and E825-C devices

In reply to Greg Kroah-Hartman

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

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

From: Jacob Keller <[email protected]>

[ Upstream commit cfa747a66e5da34793ac08c26b814e7709613fab ]

The ice driver reads data from the Shadow RAM portion of the NVM during initialization, including data used to identify the NVM image and device, such as the ETRACK ID used to populate devlink dev info fw.bundle.

Currently it is using a fixed offset defined by ICE_CSS_HEADER_LENGTH to compute the appropriate offset. This worked fine for E810 and E822 devices which both have CSS header length of 330 words.

Other devices, including both E825-C and E830 devices have different sizes for their CSS header. The use of a hard coded value results in the driver reading from the wrong block in the NVM when attempting to access the Shadow RAM copy. This results in the driver reporting the fw.bundle as 0x0 in both the devlink dev info and ethtool -i output.

The first E830 support was introduced by commit ba20ecb1d1bb ("ice: Hook up 4 E830 devices by adding their IDs") and the first E825-C support was introducted by commit f64e18944233 ("ice: introduce new E825C devices family")

The NVM actually contains the CSS header length embedded in it. Remove the hard coded value and replace it with logic to read the length from the NVM directly. This is more resilient against all existing and future hardware, vs looking up the expected values from a table. It ensures the driver will read from the appropriate place when determining the ETRACK ID value used for populating the fw.bundle_id and for reporting in ethtool -i.

The CSS header length for both the active and inactive flash bank is stored in the ice_bank_info structure to avoid unnecessary duplicate work when accessing multiple words of the Shadow RAM. Both banks are read in the unlikely event that the header length is different for the NVM in the inactive bank, rather than being different only by the overall device family.

---
 drivers/net/ethernet/intel/ice/ice_nvm.c  | 88 ++++++++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_type.h | 14 ++--
 2 files changed, 93 insertions(+), 9 deletions(-)
drivers/net/ethernet/intel/ice/ice_nvm.c +87 -1
index a0ad950cc76d9..8510a02afedcc 100644
@@ -375,11 +375,25 @@ ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u1
  *
  * Read the specified word from the copy of the Shadow RAM found in the
  * specified NVM module.
+ *
+ * Note that the Shadow RAM copy is always located after the CSS header, and
+ * is aligned to 64-byte (32-word) offsets.
  */
 static int
 ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
 {
-	return ice_read_nvm_module(hw, bank, ICE_NVM_SR_COPY_WORD_OFFSET + offset, data);
+	u32 sr_copy;
+
+	switch (bank) {
+	case ICE_ACTIVE_FLASH_BANK:
+		sr_copy = roundup(hw->flash.banks.active_css_hdr_len, 32);
+		break;
+	case ICE_INACTIVE_FLASH_BANK:
+		sr_copy = roundup(hw->flash.banks.inactive_css_hdr_len, 32);
+		break;
+	}
+
+	return ice_read_nvm_module(hw, bank, sr_copy + offset, data);
 }
 
 /**
@@ -1024,6 +1038,72 @@ static int ice_determine_active_flash_banks(struct ice_hw *hw)
 	return 0;
 }
 
+/**
+ * ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header
+ * @hw: pointer to the HW struct
+ * @bank: whether to read from the active or inactive flash bank
+ * @hdr_len: storage for header length in words
+ *
+ * Read the CSS header length from the NVM CSS header and add the Authentication
+ * header size, and then convert to words.
+ *
+ * Return: zero on success, or a negative error code on failure.
+ */
+static int
+ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
+			u32 *hdr_len)
+{
+	u16 hdr_len_l, hdr_len_h;
+	u32 hdr_len_dword;
+	int status;
+
+	status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
+				     &hdr_len_l);
+	if (status)
+		return status;
+
+	status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_H,
+				     &hdr_len_h);
+	if (status)
+		return status;
+
+	/* CSS header length is in DWORD, so convert to words and add
+	 * authentication header size
+	 */
+	hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
+	*hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
+
+	return 0;
+}
+
+/**
+ * ice_determine_css_hdr_len - Discover CSS header length for the device
+ * @hw: pointer to the HW struct
+ *
+ * Determine the size of the CSS header at the start of the NVM module. This
+ * is useful for locating the Shadow RAM copy in the NVM, as the Shadow RAM is
+ * always located just after the CSS header.
+ *
+ * Return: zero on success, or a negative error code on failure.
+ */
+static int ice_determine_css_hdr_len(struct ice_hw *hw)
+{
+	struct ice_bank_info *banks = &hw->flash.banks;
+	int status;
+
+	status = ice_get_nvm_css_hdr_len(hw, ICE_ACTIVE_FLASH_BANK,
+					 &banks->active_css_hdr_len);
+	if (status)
+		return status;
+
+	status = ice_get_nvm_css_hdr_len(hw, ICE_INACTIVE_FLASH_BANK,
+					 &banks->inactive_css_hdr_len);
+	if (status)
+		return status;
+
+	return 0;
+}
+
 /**
  * ice_init_nvm - initializes NVM setting
  * @hw: pointer to the HW struct
@@ -1070,6 +1150,12 @@ int ice_init_nvm(struct ice_hw *hw)
 		return status;
 	}
 
+	status = ice_determine_css_hdr_len(hw);
+	if (status) {
+		ice_debug(hw, ICE_DBG_NVM, "Failed to determine Shadow RAM copy offsets.\n");
+		return status;
+	}
+
 	status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
 	if (status) {
 		ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
drivers/net/ethernet/intel/ice/ice_type.h +6 -8
index 9ff92dba58236..0aacd0d050b8e 100644
@@ -481,6 +481,8 @@ struct ice_bank_info {
 	u32 orom_size;				/* Size of OROM bank */
 	u32 netlist_ptr;			/* Pointer to 1st Netlist bank */
 	u32 netlist_size;			/* Size of Netlist bank */
+	u32 active_css_hdr_len;			/* Active CSS header length */
+	u32 inactive_css_hdr_len;		/* Inactive CSS header length */
 	enum ice_flash_bank nvm_bank;		/* Active NVM bank */
 	enum ice_flash_bank orom_bank;		/* Active OROM bank */
 	enum ice_flash_bank netlist_bank;	/* Active Netlist bank */
@@ -1084,17 +1086,13 @@ struct ice_aq_get_set_rss_lut_params {
 #define ICE_SR_SECTOR_SIZE_IN_WORDS	0x800
 
 /* CSS Header words */
+#define ICE_NVM_CSS_HDR_LEN_L			0x02
+#define ICE_NVM_CSS_HDR_LEN_H			0x03
 #define ICE_NVM_CSS_SREV_L			0x14
 #define ICE_NVM_CSS_SREV_H			0x15
 
-/* Length of CSS header section in words */
-#define ICE_CSS_HEADER_LENGTH			330
-
-/* Offset of Shadow RAM copy in the NVM bank area. */
-#define ICE_NVM_SR_COPY_WORD_OFFSET		roundup(ICE_CSS_HEADER_LENGTH, 32)
-
-/* Size in bytes of Option ROM trailer */
-#define ICE_NVM_OROM_TRAILER_LENGTH		(2 * ICE_CSS_HEADER_LENGTH)
+/* Length of Authentication header section in words */
+#define ICE_NVM_AUTH_HEADER_LEN			0x08
 
 /* The Link Topology Netlist section is stored as a series of words. It is
  * stored in the NVM as a TLV, with the first two words containing the type
Signature · 1 line
2.43.0
author maintainer
#52 lore raw

PATCH 52/281 ice: remove af_xdp_zc_qps bitmap

In reply to Greg Kroah-Hartman

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

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

From: Larysa Zaremba <[email protected]>

[ Upstream commit adbf5a42341f6ea038d3626cd4437d9f0ad0b2dd ]

Referenced commit has introduced a bitmap to distinguish between ZC and copy-mode AF_XDP queues, because xsk_get_pool_from_qid() does not do this for us.

The bitmap would be especially useful when restoring previous state after rebuild, if only it was not reallocated in the process. This leads to e.g. xdpsock dying after changing number of queues.

Instead of preserving the bitmap during the rebuild, remove it completely and distinguish between ZC and copy-mode queues based on the presence of a device associated with the pool.

---
 drivers/net/ethernet/intel/ice/ice.h     | 32 ++++++++++++++++--------
 drivers/net/ethernet/intel/ice/ice_lib.c |  8 ------
 drivers/net/ethernet/intel/ice/ice_xsk.c | 13 +++++-----
 3 files changed, 27 insertions(+), 26 deletions(-)
drivers/net/ethernet/intel/ice/ice.h +21 -11
index 365c03d1c4622..ca9b56d625841 100644
@@ -412,7 +412,6 @@ struct ice_vsi {
 	struct ice_tc_cfg tc_cfg;
 	struct bpf_prog *xdp_prog;
 	struct ice_tx_ring **xdp_rings;	 /* XDP ring array */
-	unsigned long *af_xdp_zc_qps;	 /* tracks AF_XDP ZC enabled qps */
 	u16 num_xdp_txq;		 /* Used XDP queues */
 	u8 xdp_mapping_mode;		 /* ICE_MAP_MODE_[CONTIG|SCATTER] */
 
@@ -748,6 +747,25 @@ static inline void ice_set_ring_xdp(struct ice_tx_ring *ring)
 	ring->flags |= ICE_TX_FLAGS_RING_XDP;
 }
 
+/**
+ * ice_get_xp_from_qid - get ZC XSK buffer pool bound to a queue ID
+ * @vsi: pointer to VSI
+ * @qid: index of a queue to look at XSK buff pool presence
+ *
+ * Return: A pointer to xsk_buff_pool structure if there is a buffer pool
+ * attached and configured as zero-copy, NULL otherwise.
+ */
+static inline struct xsk_buff_pool *ice_get_xp_from_qid(struct ice_vsi *vsi,
+							u16 qid)
+{
+	struct xsk_buff_pool *pool = xsk_get_pool_from_qid(vsi->netdev, qid);
+
+	if (!ice_is_xdp_ena_vsi(vsi))
+		return NULL;
+
+	return (pool && pool->dev) ? pool : NULL;
+}
+
 /**
  * ice_xsk_pool - get XSK buffer pool bound to a ring
  * @ring: Rx ring to use
@@ -760,10 +778,7 @@ static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring)
 	struct ice_vsi *vsi = ring->vsi;
 	u16 qid = ring->q_index;
 
-	if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps))
-		return NULL;
-
-	return xsk_get_pool_from_qid(vsi->netdev, qid);
+	return ice_get_xp_from_qid(vsi, qid);
 }
 
 /**
@@ -788,12 +803,7 @@ static inline void ice_tx_xsk_pool(struct ice_vsi *vsi, u16 qid)
 	if (!ring)
 		return;
 
-	if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) {
-		ring->xsk_pool = NULL;
-		return;
-	}
-
-	ring->xsk_pool = xsk_get_pool_from_qid(vsi->netdev, qid);
+	ring->xsk_pool = ice_get_xp_from_qid(vsi, qid);
 }
 
 /**
drivers/net/ethernet/intel/ice/ice_lib.c +0 -8
index 558422120312b..7d401a4dc4513 100644
@@ -117,14 +117,8 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi)
 	if (!vsi->q_vectors)
 		goto err_vectors;
 
-	vsi->af_xdp_zc_qps = bitmap_zalloc(max_t(int, vsi->alloc_txq, vsi->alloc_rxq), GFP_KERNEL);
-	if (!vsi->af_xdp_zc_qps)
-		goto err_zc_qps;
-
 	return 0;
 
-err_zc_qps:
-	devm_kfree(dev, vsi->q_vectors);
 err_vectors:
 	devm_kfree(dev, vsi->rxq_map);
 err_rxq_map:
@@ -328,8 +322,6 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi)
 
 	dev = ice_pf_to_dev(pf);
 
-	bitmap_free(vsi->af_xdp_zc_qps);
-	vsi->af_xdp_zc_qps = NULL;
 	/* free the ring and vector containers */
 	devm_kfree(dev, vsi->q_vectors);
 	vsi->q_vectors = NULL;
drivers/net/ethernet/intel/ice/ice_xsk.c +6 -7
index 1857220d27fee..86a865788e345 100644
@@ -269,7 +269,6 @@ static int ice_xsk_pool_disable(struct ice_vsi *vsi, u16 qid)
 	if (!pool)
 		return -EINVAL;
 
-	clear_bit(qid, vsi->af_xdp_zc_qps);
 	xsk_pool_dma_unmap(pool, ICE_RX_DMA_ATTR);
 
 	return 0;
@@ -300,8 +299,6 @@ ice_xsk_pool_enable(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
 	if (err)
 		return err;
 
-	set_bit(qid, vsi->af_xdp_zc_qps);
-
 	return 0;
 }
 
@@ -349,11 +346,13 @@ ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present)
 int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc)
 {
 	struct ice_rx_ring *rx_ring;
-	unsigned long q;
+	uint i;
+
+	ice_for_each_rxq(vsi, i) {
+		rx_ring = vsi->rx_rings[i];
+		if (!rx_ring->xsk_pool)
+			continue;
 
-	for_each_set_bit(q, vsi->af_xdp_zc_qps,
-			 max_t(int, vsi->alloc_txq, vsi->alloc_rxq)) {
-		rx_ring = vsi->rx_rings[q];
 		if (ice_realloc_rx_xdp_bufs(rx_ring, zc))
 			return -ENOMEM;
 	}
Signature · 1 line
2.43.0
author maintainer
#53 lore raw

PATCH 53/281 ice: add flag to distinguish reset from .ndo_bpf in XDP rings config

In reply to Greg Kroah-Hartman

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

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

From: Larysa Zaremba <[email protected]>

[ Upstream commit 744d197162c2070a6045a71e2666ed93a57cc65d ]

Commit 6624e780a577 ("ice: split ice_vsi_setup into smaller functions") has placed ice_vsi_free_q_vectors() after ice_destroy_xdp_rings() in the rebuild process. The behaviour of the XDP rings config functions is context-dependent, so the change of order has led to ice_destroy_xdp_rings() doing additional work and removing XDP prog, when it was supposed to be preserved.

Also, dependency on the PF state reset flags creates an additional, fortunately less common problem:

* PFR is requested e.g. by tx_timeout handler
* .ndo_bpf() is asked to delete the program, calls ice_destroy_xdp_rings(), but reset flag is set, so rings are destroyed without deleting the program
* ice_vsi_rebuild tries to delete non-existent XDP rings, because the program is still on the VSI
* system crashes

With a similar race, when requested to attach a program, ice_prepare_xdp_rings() can actually skip setting the program in the VSI and nevertheless report success.

Instead of reverting to the old order of function calls, add an enum argument to both ice_prepare_xdp_rings() and ice_destroy_xdp_rings() in order to distinguish between calls from rebuild and .ndo_bpf().

---
 drivers/net/ethernet/intel/ice/ice.h      | 11 +++++++++--
 drivers/net/ethernet/intel/ice/ice_lib.c  |  5 +++--
 drivers/net/ethernet/intel/ice/ice_main.c | 22 ++++++++++++----------
 3 files changed, 24 insertions(+), 14 deletions(-)
drivers/net/ethernet/intel/ice/ice.h +9 -2
index ca9b56d625841..a3286964d6c31 100644
@@ -932,9 +932,16 @@ int ice_down(struct ice_vsi *vsi);
 int ice_down_up(struct ice_vsi *vsi);
 int ice_vsi_cfg_lan(struct ice_vsi *vsi);
 struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
+
+enum ice_xdp_cfg {
+	ICE_XDP_CFG_FULL,	/* Fully apply new config in .ndo_bpf() */
+	ICE_XDP_CFG_PART,	/* Save/use part of config in VSI rebuild */
+};
+
 int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
-int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog);
-int ice_destroy_xdp_rings(struct ice_vsi *vsi);
+int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+			  enum ice_xdp_cfg cfg_type);
+int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type);
 int
 ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
 	     u32 flags);
drivers/net/ethernet/intel/ice/ice_lib.c +3 -2
index 7d401a4dc4513..5de7c50b439e1 100644
@@ -2334,7 +2334,8 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
 			ret = ice_vsi_determine_xdp_res(vsi);
 			if (ret)
 				goto unroll_vector_base;
-			ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog);
+			ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog,
+						    ICE_XDP_CFG_PART);
 			if (ret)
 				goto unroll_vector_base;
 		}
@@ -2485,7 +2486,7 @@ void ice_vsi_decfg(struct ice_vsi *vsi)
 		/* return value check can be skipped here, it always returns
 		 * 0 if reset is in progress
 		 */
-		ice_destroy_xdp_rings(vsi);
+		ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_PART);
 
 	ice_vsi_clear_rings(vsi);
 	ice_vsi_free_q_vectors(vsi);
drivers/net/ethernet/intel/ice/ice_main.c +12 -10
index 33a164fa325ac..b53fe27dbed7d 100644
@@ -2674,10 +2674,12 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog)
  * ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
  * @vsi: VSI to bring up Tx rings used by XDP
  * @prog: bpf program that will be assigned to VSI
+ * @cfg_type: create from scratch or restore the existing configuration
  *
  * Return 0 on success and negative value on error
  */
-int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
+int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+			  enum ice_xdp_cfg cfg_type)
 {
 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
 	int xdp_rings_rem = vsi->num_xdp_txq;
@@ -2753,7 +2755,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
 	 * taken into account at the end of ice_vsi_rebuild, where
 	 * ice_cfg_vsi_lan is being called
 	 */
-	if (ice_is_reset_in_progress(pf->state))
+	if (cfg_type == ICE_XDP_CFG_PART)
 		return 0;
 
 	/* tell the Tx scheduler that right now we have
@@ -2805,22 +2807,21 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
 /**
  * ice_destroy_xdp_rings - undo the configuration made by ice_prepare_xdp_rings
  * @vsi: VSI to remove XDP rings
+ * @cfg_type: disable XDP permanently or allow it to be restored later
  *
  * Detach XDP rings from irq vectors, clean up the PF bitmap and free
  * resources
  */
-int ice_destroy_xdp_rings(struct ice_vsi *vsi)
+int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
 {
 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
 	struct ice_pf *pf = vsi->back;
 	int i, v_idx;
 
 	/* q_vectors are freed in reset path so there's no point in detaching
-	 * rings; in case of rebuild being triggered not from reset bits
-	 * in pf->state won't be set, so additionally check first q_vector
-	 * against NULL
+	 * rings
 	 */
-	if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
+	if (cfg_type == ICE_XDP_CFG_PART)
 		goto free_qmap;
 
 	ice_for_each_q_vector(vsi, v_idx) {
@@ -2861,7 +2862,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi)
 	if (static_key_enabled(&ice_xdp_locking_key))
 		static_branch_dec(&ice_xdp_locking_key);
 
-	if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
+	if (cfg_type == ICE_XDP_CFG_PART)
 		return 0;
 
 	ice_vsi_assign_bpf_prog(vsi, NULL);
@@ -2972,7 +2973,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
 		if (xdp_ring_err) {
 			NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
 		} else {
-			xdp_ring_err = ice_prepare_xdp_rings(vsi, prog);
+			xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
+							     ICE_XDP_CFG_FULL);
 			if (xdp_ring_err)
 				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
 		}
@@ -2983,7 +2985,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
 			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
 	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
 		xdp_features_clear_redirect_target(vsi->netdev);
-		xdp_ring_err = ice_destroy_xdp_rings(vsi);
+		xdp_ring_err = ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_FULL);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
 		/* reallocate Rx queues that were used for zero-copy */
Signature · 1 line
2.43.0
author maintainer
#54 lore raw

PATCH 54/281 ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors()

In reply to Greg Kroah-Hartman

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

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

From: Larysa Zaremba <[email protected]>

[ Upstream commit f3df4044254c98128890b512bf19cc05588f1fe5 ]

ice_pf_dcb_recfg() re-maps queues to vectors with ice_vsi_map_rings_to_vectors(), which does not restore the previous state for XDP queues. This leads to no AF_XDP traffic after rebuild.

Map XDP queues to vectors in ice_vsi_map_rings_to_vectors(). Also, move the code around, so XDP queues are mapped independently only through .ndo_bpf().

---
 drivers/net/ethernet/intel/ice/ice.h      |  1 +
 drivers/net/ethernet/intel/ice/ice_base.c |  3 +
 drivers/net/ethernet/intel/ice/ice_lib.c  | 14 ++--
 drivers/net/ethernet/intel/ice/ice_main.c | 96 ++++++++++++++---------
 4 files changed, 68 insertions(+), 46 deletions(-)
drivers/net/ethernet/intel/ice/ice.h +1 -0
index a3286964d6c31..8e40f26aa5060 100644
@@ -942,6 +942,7 @@ int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
 int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
 			  enum ice_xdp_cfg cfg_type);
 int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type);
+void ice_map_xdp_rings(struct ice_vsi *vsi);
 int
 ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
 	     u32 flags);
drivers/net/ethernet/intel/ice/ice_base.c +3 -0
index a545a7917e4fc..9d23a436d2a6a 100644
@@ -860,6 +860,9 @@ void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)
 		}
 		rx_rings_rem -= rx_rings_per_v;
 	}
+
+	if (ice_is_xdp_ena_vsi(vsi))
+		ice_map_xdp_rings(vsi);
 }
 
 /**
drivers/net/ethernet/intel/ice/ice_lib.c +7 -7
index 5de7c50b439e1..acf732ce04ed6 100644
@@ -2323,13 +2323,6 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
 		if (ret)
 			goto unroll_vector_base;
 
-		ice_vsi_map_rings_to_vectors(vsi);
-
-		/* Associate q_vector rings to napi */
-		ice_vsi_set_napi_queues(vsi);
-
-		vsi->stat_offsets_loaded = false;
-
 		if (ice_is_xdp_ena_vsi(vsi)) {
 			ret = ice_vsi_determine_xdp_res(vsi);
 			if (ret)
@@ -2340,6 +2333,13 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
 				goto unroll_vector_base;
 		}
 
+		ice_vsi_map_rings_to_vectors(vsi);
+
+		/* Associate q_vector rings to napi */
+		ice_vsi_set_napi_queues(vsi);
+
+		vsi->stat_offsets_loaded = false;
+
 		/* ICE_VSI_CTRL does not need RSS so skip RSS processing */
 		if (vsi->type != ICE_VSI_CTRL)
 			/* Do not exit if configuring RSS had an issue, at
drivers/net/ethernet/intel/ice/ice_main.c +57 -39

126 lines not on this page · raw message

Signature · 1 line
2.43.0
author maintainer
#55 lore raw

PATCH 55/281 igc: Fix Energy Efficient Ethernet support declaration

In reply to Greg Kroah-Hartman

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

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

From: Sasha Neftin <[email protected]>

[ Upstream commit 7d67d11fbe194f71298263f48e33ae2afa38197e ]

The commit 01cf893bf0f4 ("net: intel: i40e/igc: Remove setting Autoneg in EEE capabilities") removed SUPPORTED_Autoneg field but left inappropriate ethtool_keee structure initialization. When "ethtool --show <device>" (get_eee) invoke, the 'ethtool_keee' structure was accidentally overridden. Remove the 'ethtool_keee' overriding and add EEE declaration as per IEEE specification that allows reporting Energy Efficient Ethernet capabilities.

Examples:
Before fix:
ethtool --show-eee enp174s0
EEE settings for enp174s0:
EEE status: not supported

After fix:
EEE settings for enp174s0:
EEE status: disabled
Tx LPI: disabled
Supported EEE link modes: 100baseT/Full
1000baseT/Full
2500baseT/Full

---
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 9 +++++++--
 drivers/net/ethernet/intel/igc/igc_main.c    | 4 ++++
 2 files changed, 11 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igc/igc_ethtool.c +7 -2
index 1a64f1ca6ca86..e699412d22f68 100644
@@ -1629,12 +1629,17 @@ static int igc_ethtool_get_eee(struct net_device *netdev,
 	struct igc_hw *hw = &adapter->hw;
 	u32 eeer;
 
+	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+			 edata->supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+			 edata->supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+			 edata->supported);
+
 	if (hw->dev_spec._base.eee_enable)
 		mii_eee_cap1_mod_linkmode_t(edata->advertised,
 					    adapter->eee_advert);
 
-	*edata = adapter->eee;
-
 	eeer = rd32(IGC_EEER);
 
 	/* EEE status on negotiated link */
drivers/net/ethernet/intel/igc/igc_main.c +4 -0
index 4d975d620a8e4..58bc96021bb4c 100644
@@ -12,6 +12,7 @@
 #include <linux/bpf_trace.h>
 #include <net/xdp_sock_drv.h>
 #include <linux/pci.h>
+#include <linux/mdio.h>
 
 #include <net/ipv6.h>
 
@@ -4876,6 +4877,9 @@ void igc_up(struct igc_adapter *adapter)
 	/* start the watchdog. */
 	hw->mac.get_link_status = true;
 	schedule_work(&adapter->watchdog_task);
+
+	adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T |
+			      MDIO_EEE_2_5GT;
 }
 
 /**
Signature · 1 line
2.43.0
author maintainer
#56 lore raw

PATCH 56/281 net: wwan: iosm: Fix tainted pointer delete is case of region creation fail

In reply to Greg Kroah-Hartman

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

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

From: Aleksandr Mishin <[email protected]>

[ Upstream commit b0c9a26435413b81799047a7be53255640432547 ]

In case of region creation fail in ipc_devlink_create_region(), previously created regions delete process starts from tainted pointer which actually holds error code value.
Fix this bug by decreasing region index before delete.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

---
 drivers/net/wwan/iosm/iosm_ipc_devlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wwan/iosm/iosm_ipc_devlink.c +1 -1
index 2fe724d623c06..33c5a46f1b922 100644
@@ -210,7 +210,7 @@ static int ipc_devlink_create_region(struct iosm_devlink *devlink)
 			rc = PTR_ERR(devlink->cd_regions[i]);
 			dev_err(devlink->dev, "Devlink region fail,err %d", rc);
 			/* Delete previously created regions */
-			for ( ; i >= 0; i--)
+			for (i--; i >= 0; i--)
 				devlink_region_destroy(devlink->cd_regions[i]);
 			goto region_create_fail;
 		}
Signature · 1 line
2.43.0
author maintainer
#57 lore raw

PATCH 57/281 af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted peer.

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 26bfb8b57063f52b867f9b6c8d1742fcb5bd656c ]

When a SOCK_DGRAM socket connect()s to another socket, the both sockets' sk->sk_state are changed to TCP_ESTABLISHED so that we can register them to BPF SOCKMAP.

When the socket disconnects from the peer by connect(AF_UNSPEC), the state is set back to TCP_CLOSE.

Then, the peer's state is also set to TCP_CLOSE, but the update is done locklessly and unconditionally.

Let's say socket A connect()ed to B, B connect()ed to C, and A disconnects from B.

After the first two connect()s, all three sockets' sk->sk_state are TCP_ESTABLISHED:

  $ ss -xa
  Netid State  Recv-Q Send-Q  Local Address:Port  Peer Address:PortProcess
  u_dgr ESTAB  0      0       @A 641              * 642
  u_dgr ESTAB  0      0       @B 642              * 643
  u_dgr ESTAB  0      0       @C 643              * 0

And after the disconnect, B's state is TCP_CLOSE even though it's still connected to C and C's state is TCP_ESTABLISHED.

  $ ss -xa
  Netid State  Recv-Q Send-Q  Local Address:Port  Peer Address:PortProcess
  u_dgr UNCONN 0      0       @A 641              * 0
  u_dgr UNCONN 0      0       @B 642              * 643
  u_dgr ESTAB  0      0       @C 643              * 0

In this case, we cannot register B to SOCKMAP.

So, when a socket disconnects from the peer, we should not set TCP_CLOSE to the peer if the peer is connected to yet another socket, and this must be done under unix_state_lock().

Note that we use WRITE_ONCE() for sk->sk_state as there are many lockless readers. These data-races will be fixed in the following patches.

Fixes 83301b5367a9 ("af_unix: Set TCP_ESTABLISHED for datagram sockets too")
---
 net/unix/af_unix.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
net/unix/af_unix.c +8 -2
index 439c531744a27..c0cf7137979c7 100644
@@ -570,7 +570,6 @@ static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
 			sk_error_report(other);
 		}
 	}
-	other->sk_state = TCP_CLOSE;
 }
 
 static void unix_sock_destructor(struct sock *sk)
@@ -1424,8 +1423,15 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
 
 		unix_state_double_unlock(sk, other);
 
-		if (other != old_peer)
+		if (other != old_peer) {
 			unix_dgram_disconnected(sk, old_peer);
+
+			unix_state_lock(old_peer);
+			if (!unix_peer(old_peer))
+				WRITE_ONCE(old_peer->sk_state, TCP_CLOSE);
+			unix_state_unlock(old_peer);
+		}
+
 		sock_put(old_peer);
 	} else {
 		unix_peer(sk) = other;
Signature · 1 line
2.43.0
author maintainer
#58 lore raw

PATCH 58/281 af_unix: Annodate data-races around sk->sk_state for writers.

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 942238f9735a4a4ebf8274b218d9a910158941d1 ]

sk->sk_state is changed under unix_state_lock(), but it's read locklessly in many places.

This patch adds WRITE_ONCE() on the writer side.

We will add READ_ONCE() to the lockless readers in the following patches.

Fixes 83301b5367a9 ("af_unix: Set TCP_ESTABLISHED for datagram sockets too")
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
net/unix/af_unix.c +8 -6
index c0cf7137979c7..0a9c3975d4303 100644
@@ -616,7 +616,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
 	u->path.dentry = NULL;
 	u->path.mnt = NULL;
 	state = sk->sk_state;
-	sk->sk_state = TCP_CLOSE;
+	WRITE_ONCE(sk->sk_state, TCP_CLOSE);
 
 	skpair = unix_peer(sk);
 	unix_peer(sk) = NULL;
@@ -738,7 +738,8 @@ static int unix_listen(struct socket *sock, int backlog)
 	if (backlog > sk->sk_max_ack_backlog)
 		wake_up_interruptible_all(&u->peer_wait);
 	sk->sk_max_ack_backlog	= backlog;
-	sk->sk_state		= TCP_LISTEN;
+	WRITE_ONCE(sk->sk_state, TCP_LISTEN);
+
 	/* set credentials so connect can copy them */
 	init_peercred(sk);
 	err = 0;
@@ -1401,7 +1402,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
 		if (err)
 			goto out_unlock;
 
-		sk->sk_state = other->sk_state = TCP_ESTABLISHED;
+		WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED);
+		WRITE_ONCE(other->sk_state, TCP_ESTABLISHED);
 	} else {
 		/*
 		 *	1003.1g breaking connected state with AF_UNSPEC
@@ -1418,7 +1420,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
 
 		unix_peer(sk) = other;
 		if (!other)
-			sk->sk_state = TCP_CLOSE;
+			WRITE_ONCE(sk->sk_state, TCP_CLOSE);
 		unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
 
 		unix_state_double_unlock(sk, other);
@@ -1638,7 +1640,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	copy_peercred(sk, other);
 
 	sock->state	= SS_CONNECTED;
-	sk->sk_state	= TCP_ESTABLISHED;
+	WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED);
 	sock_hold(newsk);
 
 	smp_mb__after_atomic();	/* sock_hold() does an atomic_inc() */
@@ -2097,7 +2099,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
 			unix_peer(sk) = NULL;
 			unix_dgram_peer_wake_disconnect_wakeup(sk, other);
 
-			sk->sk_state = TCP_CLOSE;
+			WRITE_ONCE(sk->sk_state, TCP_CLOSE);
 			unix_state_unlock(sk);
 
 			unix_dgram_disconnected(sk, other);
Signature · 1 line
2.43.0
author maintainer
#59 lore raw

PATCH 59/281 af_unix: Annotate data-race of sk->sk_state in unix_inq_len().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 3a0f38eb285c8c2eead4b3230c7ac2983707599d ]

ioctl(SIOCINQ) calls unix_inq_len() that checks sk->sk_state first and returns -EINVAL if it's TCP_LISTEN.

Then, for SOCK_STREAM sockets, unix_inq_len() returns the number of bytes in recvq.

However, unix_inq_len() does not hold unix_state_lock(), and the concurrent listen() might change the state after checking sk->sk_state.

If the race occurs, 0 is returned for the listener, instead of -EINVAL, because the length of skb with embryo is 0.

We could hold unix_state_lock() in unix_inq_len(), but it's overkill given the result is true for pre-listen() TCP_CLOSE state.

So, let's use READ_ONCE() for sk->sk_state in unix_inq_len().

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
index 0a9c3975d4303..989c2c76dce66 100644
@@ -3064,7 +3064,7 @@ long unix_inq_len(struct sock *sk)
 	struct sk_buff *skb;
 	long amount = 0;
 
-	if (sk->sk_state == TCP_LISTEN)
+	if (READ_ONCE(sk->sk_state) == TCP_LISTEN)
 		return -EINVAL;
 
 	spin_lock(&sk->sk_receive_queue.lock);
Signature · 1 line
2.43.0
author maintainer
#60 lore raw

PATCH 60/281 af_unix: Annotate data-races around sk->sk_state in unix_write_space() and poll().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit eb0718fb3e97ad0d6f4529b810103451c90adf94 ]

unix_poll() and unix_dgram_poll() read sk->sk_state locklessly and calls unix_writable() which also reads sk->sk_state without holding unix_state_lock().

Let's use READ_ONCE() in unix_poll() and unix_dgram_poll() and pass it to unix_writable().

While at it, we remove TCP_SYN_SENT check in unix_dgram_poll() as that state does not exist for AF_UNIX socket since the code was added.

Fixes 1586a5877db9 ("af_unix: do not report POLLOUT on listeners")
Fixes 3c73419c09a5 ("af_unix: fix 'poll for write'/ connected DGRAM sockets")
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)
net/unix/af_unix.c +12 -13
index 989c2c76dce66..a3eb241eb064e 100644
@@ -530,9 +530,9 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
 	return 0;
 }
 
-static int unix_writable(const struct sock *sk)
+static int unix_writable(const struct sock *sk, unsigned char state)
 {
-	return sk->sk_state != TCP_LISTEN &&
+	return state != TCP_LISTEN &&
 	       (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
 }
 
@@ -541,7 +541,7 @@ static void unix_write_space(struct sock *sk)
 	struct socket_wq *wq;
 
 	rcu_read_lock();
-	if (unix_writable(sk)) {
+	if (unix_writable(sk, READ_ONCE(sk->sk_state))) {
 		wq = rcu_dereference(sk->sk_wq);
 		if (skwq_has_sleeper(wq))
 			wake_up_interruptible_sync_poll(&wq->wait,
@@ -3176,12 +3176,14 @@ static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
 static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
 {
 	struct sock *sk = sock->sk;
+	unsigned char state;
 	__poll_t mask;
 	u8 shutdown;
 
 	sock_poll_wait(file, sock, wait);
 	mask = 0;
 	shutdown = READ_ONCE(sk->sk_shutdown);
+	state = READ_ONCE(sk->sk_state);
 
 	/* exceptional events? */
 	if (READ_ONCE(sk->sk_err))
@@ -3203,14 +3205,14 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa
 
 	/* Connection-based need to check for termination and startup */
 	if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
-	    sk->sk_state == TCP_CLOSE)
+	    state == TCP_CLOSE)
 		mask |= EPOLLHUP;
 
 	/*
 	 * we set writable also when the other side has shut down the
 	 * connection. This prevents stuck sockets.
 	 */
-	if (unix_writable(sk))
+	if (unix_writable(sk, state))
 		mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
 
 	return mask;
@@ -3221,12 +3223,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
 {
 	struct sock *sk = sock->sk, *other;
 	unsigned int writable;
+	unsigned char state;
 	__poll_t mask;
 	u8 shutdown;
 
 	sock_poll_wait(file, sock, wait);
 	mask = 0;
 	shutdown = READ_ONCE(sk->sk_shutdown);
+	state = READ_ONCE(sk->sk_state);
 
 	/* exceptional events? */
 	if (READ_ONCE(sk->sk_err) ||
@@ -3246,19 +3250,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
 		mask |= EPOLLIN | EPOLLRDNORM;
 
 	/* Connection-based need to check for termination and startup */
-	if (sk->sk_type == SOCK_SEQPACKET) {
-		if (sk->sk_state == TCP_CLOSE)
-			mask |= EPOLLHUP;
-		/* connection hasn't started yet? */
-		if (sk->sk_state == TCP_SYN_SENT)
-			return mask;
-	}
+	if (sk->sk_type == SOCK_SEQPACKET && state == TCP_CLOSE)
+		mask |= EPOLLHUP;
 
 	/* No write status requested, avoid expensive OUT tests. */
 	if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
 		return mask;
 
-	writable = unix_writable(sk);
+	writable = unix_writable(sk, state);
 	if (writable) {
 		unix_state_lock(sk);
 
Signature · 1 line
2.43.0
author maintainer
#61 lore raw

PATCH 61/281 af_unix: Annotate data-race of sk->sk_state in unix_stream_connect().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit a9bf9c7dc6a5899c01cb8f6e773a66315a5cd4b7 ]

As small optimisation, unix_stream_connect() prefetches the client's sk->sk_state without unix_state_lock() and checks if it's TCP_CLOSE.

Later, sk->sk_state is checked again under unix_state_lock().

Let's use READ_ONCE() for the first check and TCP_CLOSE directly for the second check.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
net/unix/af_unix.c +2 -5
index a3eb241eb064e..f95aba56425fa 100644
@@ -1481,7 +1481,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	struct sk_buff *skb = NULL;
 	long timeo;
 	int err;
-	int st;
 
 	err = unix_validate_addr(sunaddr, addr_len);
 	if (err)
@@ -1571,9 +1570,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 
 	   Well, and we have to recheck the state after socket locked.
 	 */
-	st = sk->sk_state;
-
-	switch (st) {
+	switch (READ_ONCE(sk->sk_state)) {
 	case TCP_CLOSE:
 		/* This is ok... continue with connect */
 		break;
@@ -1588,7 +1585,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 
 	unix_state_lock_nested(sk, U_LOCK_SECOND);
 
-	if (sk->sk_state != st) {
+	if (sk->sk_state != TCP_CLOSE) {
 		unix_state_unlock(sk);
 		unix_state_unlock(other);
 		sock_put(other);
Signature · 1 line
2.43.0
author maintainer
#62 lore raw

PATCH 62/281 af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 8a34d4e8d9742a24f74998f45a6a98edd923319b ]

The following functions read sk->sk_state locklessly and proceed only if the state is TCP_ESTABLISHED.

* unix_stream_sendmsg
* unix_stream_read_generic
* unix_seqpacket_sendmsg
* unix_seqpacket_recvmsg

Let's use READ_ONCE() there.

Fixes a05d2ad1c1f3 ("af_unix: Only allow recv on connected seqpacket sockets.")
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/unix/af_unix.c +4 -4
index f95aba56425fa..d92e664032121 100644
@@ -2273,7 +2273,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 	}
 
 	if (msg->msg_namelen) {
-		err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
+		err = READ_ONCE(sk->sk_state) == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
 		goto out_err;
 	} else {
 		err = -ENOTCONN;
@@ -2387,7 +2387,7 @@ static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (err)
 		return err;
 
-	if (sk->sk_state != TCP_ESTABLISHED)
+	if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)
 		return -ENOTCONN;
 
 	if (msg->msg_namelen)
@@ -2401,7 +2401,7 @@ static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
 {
 	struct sock *sk = sock->sk;
 
-	if (sk->sk_state != TCP_ESTABLISHED)
+	if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)
 		return -ENOTCONN;
 
 	return unix_dgram_recvmsg(sock, msg, size, flags);
@@ -2730,7 +2730,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
 	size_t size = state->size;
 	unsigned int last_len;
 
-	if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
+	if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) {
 		err = -EINVAL;
 		goto out;
 	}
Signature · 1 line
2.43.0
author maintainer
#63 lore raw

PATCH 63/281 af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit af4c733b6b1aded4dc808fafece7dfe6e9d2ebb3 ]

unix_stream_read_skb() is called from sk->sk_data_ready() context where unix_state_lock() is not held.

Let's use READ_ONCE() there.

Fixes 77462de14a43 ("af_unix: Add read_sock for stream socket types")
---
 net/unix/af_unix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
index d92e664032121..9f266a7679cbc 100644
@@ -2706,7 +2706,7 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
 
 static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
 {
-	if (unlikely(sk->sk_state != TCP_ESTABLISHED))
+	if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED))
 		return -ENOTCONN;
 
 	return unix_read_skb(sk, recv_actor);
Signature · 1 line
2.43.0
author maintainer
#64 lore raw

PATCH 64/281 af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 0aa3be7b3e1f8f997312cc4705f8165e02806f8f ]

While dumping AF_UNIX sockets via UNIX_DIAG, sk->sk_state is read locklessly.

Let's use READ_ONCE() there.

Note that the result could be inconsistent if the socket is dumped during the state change. This is common for other SOCK_DIAG and similar interfaces.

Fixes c9da99e6475f ("unix_diag: Fixup RQLEN extension report")
Fixes 2aac7a2cb0d9 ("unix_diag: Pending connections IDs NLA")
Fixes 45a96b9be6ec ("unix_diag: Dumping all sockets core")
---
 net/unix/diag.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/unix/diag.c +4 -4
index ae39538c5042b..116cf508aea4a 100644
@@ -65,7 +65,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
 	u32 *buf;
 	int i;
 
-	if (sk->sk_state == TCP_LISTEN) {
+	if (READ_ONCE(sk->sk_state) == TCP_LISTEN) {
 		spin_lock(&sk->sk_receive_queue.lock);
 
 		attr = nla_reserve(nlskb, UNIX_DIAG_ICONS,
@@ -103,7 +103,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
 {
 	struct unix_diag_rqlen rql;
 
-	if (sk->sk_state == TCP_LISTEN) {
+	if (READ_ONCE(sk->sk_state) == TCP_LISTEN) {
 		rql.udiag_rqueue = sk->sk_receive_queue.qlen;
 		rql.udiag_wqueue = sk->sk_max_ack_backlog;
 	} else {
@@ -136,7 +136,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
 	rep = nlmsg_data(nlh);
 	rep->udiag_family = AF_UNIX;
 	rep->udiag_type = sk->sk_type;
-	rep->udiag_state = sk->sk_state;
+	rep->udiag_state = READ_ONCE(sk->sk_state);
 	rep->pad = 0;
 	rep->udiag_ino = sk_ino;
 	sock_diag_save_cookie(sk, rep->udiag_cookie);
@@ -215,7 +215,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 		sk_for_each(sk, &net->unx.table.buckets[slot]) {
 			if (num < s_num)
 				goto next;
-			if (!(req->udiag_states & (1 << sk->sk_state)))
+			if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state))))
 				goto next;
 			if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
 					 NETLINK_CB(cb->skb).portid,
Signature · 1 line
2.43.0
author maintainer
#65 lore raw

PATCH 65/281 af_unix: Annotate data-races around sk->sk_sndbuf.

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit b0632e53e0da8054e36bc973f0eec69d30f1b7c6 ]

sk_setsockopt() changes sk->sk_sndbuf under lock_sock(), but it's not used in af_unix.c.

Let's use READ_ONCE() to read sk->sk_sndbuf in unix_writable(), unix_dgram_sendmsg(), and unix_stream_sendmsg().

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/unix/af_unix.c +3 -3
index 9f266a7679cbc..84bc1de2fd967 100644
@@ -533,7 +533,7 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
 static int unix_writable(const struct sock *sk, unsigned char state)
 {
 	return state != TCP_LISTEN &&
-	       (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
+		(refcount_read(&sk->sk_wmem_alloc) << 2) <= READ_ONCE(sk->sk_sndbuf);
 }
 
 static void unix_write_space(struct sock *sk)
@@ -2014,7 +2014,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
 	}
 
 	err = -EMSGSIZE;
-	if (len > sk->sk_sndbuf - 32)
+	if (len > READ_ONCE(sk->sk_sndbuf) - 32)
 		goto out;
 
 	if (len > SKB_MAX_ALLOC) {
@@ -2294,7 +2294,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 						   &err, 0);
 		} else {
 			/* Keep two messages in the pipe so it schedules better */
-			size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
+			size = min_t(int, size, (READ_ONCE(sk->sk_sndbuf) >> 1) - 64);
 
 			/* allow fallback to order-0 allocations */
 			size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
Signature · 1 line
2.43.0
author maintainer
#66 lore raw

PATCH 66/281 af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit bd9f2d05731f6a112d0c7391a0d537bfc588dbe6 ]

net->unx.sysctl_max_dgram_qlen is exposed as a sysctl knob and can be changed concurrently.

Let's use READ_ONCE() in unix_create1().

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
index 84bc1de2fd967..0c217ac17e053 100644
@@ -976,7 +976,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern,
 	sk->sk_hash		= unix_unbound_hash(sk);
 	sk->sk_allocation	= GFP_KERNEL_ACCOUNT;
 	sk->sk_write_space	= unix_write_space;
-	sk->sk_max_ack_backlog	= net->unx.sysctl_max_dgram_qlen;
+	sk->sk_max_ack_backlog	= READ_ONCE(net->unx.sysctl_max_dgram_qlen);
 	sk->sk_destruct		= unix_sock_destructor;
 	u = unix_sk(sk);
 	u->inflight = 0;
Signature · 1 line
2.43.0
author maintainer
#67 lore raw

PATCH 67/281 af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 45d872f0e65593176d880ec148f41ad7c02e40a7 ]

Once sk->sk_state is changed to TCP_LISTEN, it never changes.

unix_accept() takes advantage of this characteristics; it does not hold the listener's unix_state_lock() and only acquires recvq lock to pop one skb.

It means unix_state_lock() does not prevent the queue length from changing in unix_stream_connect().

Thus, we need to use unix_recvq_full_lockless() to avoid data-race.

Now we remove unix_recvq_full() as no one uses it.

Note that we can remove READ_ONCE() for sk->sk_max_ack_backlog in unix_recvq_full_lockless() because of the following reasons:

(1) For SOCK_DGRAM, it is a written-once field in unix_create1()

(2) For SOCK_STREAM and SOCK_SEQPACKET, it is changed under the listener's unix_state_lock() in unix_listen(), and we hold the lock in unix_stream_connect()

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
net/unix/af_unix.c +2 -8
index 0c217ac17e053..f0760afad71fe 100644
@@ -221,15 +221,9 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk)
 	return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
 }
 
-static inline int unix_recvq_full(const struct sock *sk)
-{
-	return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
-}
-
 static inline int unix_recvq_full_lockless(const struct sock *sk)
 {
-	return skb_queue_len_lockless(&sk->sk_receive_queue) >
-		READ_ONCE(sk->sk_max_ack_backlog);
+	return skb_queue_len_lockless(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
 }
 
 struct sock *unix_peer_get(struct sock *s)
@@ -1545,7 +1539,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	if (other->sk_shutdown & RCV_SHUTDOWN)
 		goto out_unlock;
 
-	if (unix_recvq_full(other)) {
+	if (unix_recvq_full_lockless(other)) {
 		err = -EAGAIN;
 		if (!timeo)
 			goto out_unlock;
Signature · 1 line
2.43.0
author maintainer
#68 lore raw

PATCH 68/281 af_unix: Use skb_queue_empty_lockless() in unix_release_sock().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 83690b82d228b3570565ebd0b41873933238b97f ]

If the socket type is SOCK_STREAM or SOCK_SEQPACKET, unix_release_sock() checks the length of the peer socket's recvq under unix_state_lock().

However, unix_stream_read_generic() calls skb_unlink() after releasing the lock. Also, for SOCK_SEQPACKET, __skb_try_recv_datagram() unlinks skb without unix_state_lock().

Thues, unix_state_lock() does not protect qlen.

Let's use skb_queue_empty_lockless() in unix_release_sock().

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/unix/af_unix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
index f0760afad71fe..cbc011ceb89b4 100644
@@ -631,7 +631,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
 			unix_state_lock(skpair);
 			/* No more writes */
 			WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK);
-			if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
+			if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion)
 				WRITE_ONCE(skpair->sk_err, ECONNRESET);
 			unix_state_unlock(skpair);
 			skpair->sk_state_change(skpair);
Signature · 1 line
2.43.0
author maintainer
#69 lore raw

PATCH 69/281 af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 5d915e584d8408211d4567c22685aae8820bfc55 ]

We can dump the socket queue length via UNIX_DIAG by specifying UDIAG_SHOW_RQLEN.

If sk->sk_state is TCP_LISTEN, we return the recv queue length, but here we do not hold recvq lock.

Let's use skb_queue_len_lockless() in sk_diag_show_rqlen().

Fixes c9da99e6475f ("unix_diag: Fixup RQLEN extension report")
---
 net/unix/diag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/diag.c +1 -1
index 116cf508aea4a..321336f91a0af 100644
@@ -104,7 +104,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
 	struct unix_diag_rqlen rql;
 
 	if (READ_ONCE(sk->sk_state) == TCP_LISTEN) {
-		rql.udiag_rqueue = sk->sk_receive_queue.qlen;
+		rql.udiag_rqueue = skb_queue_len_lockless(&sk->sk_receive_queue);
 		rql.udiag_wqueue = sk->sk_max_ack_backlog;
 	} else {
 		rql.udiag_rqueue = (u32) unix_inq_len(sk);
Signature · 1 line
2.43.0
author maintainer
#70 lore raw

PATCH 70/281 af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit efaf24e30ec39ebbea9112227485805a48b0ceb1 ]

While dumping sockets via UNIX_DIAG, we do not hold unix_state_lock().

Let's use READ_ONCE() to read sk->sk_shutdown.

Fixes e4e541a84863 ("sock-diag: Report shutdown for inet and unix sockets (v2)")
---
 net/unix/diag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/diag.c +1 -1
index 321336f91a0af..937edf4afed41 100644
@@ -165,7 +165,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
 	    sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO))
 		goto out_nlmsg_trim;
 
-	if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown))
+	if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, READ_ONCE(sk->sk_shutdown)))
 		goto out_nlmsg_trim;
 
 	if ((req->udiag_show & UDIAG_SHOW_UID) &&
Signature · 1 line
2.43.0
author maintainer
#71 lore raw

PATCH 71/281 ipv6: fix possible race in __fib6_drop_pcpu_from()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit b01e1c030770ff3b4fe37fc7cc6bca03f594133f ]

syzbot found a race in __fib6_drop_pcpu_from() [1]

If compiler reads more than once (*ppcpu_rt), second read could read NULL, if another cpu clears the value in rt6_get_pcpu_route().

Add a READ_ONCE() to prevent this race.

Also add rcu_read_lock()/rcu_read_unlock() because we rely on RCU protection while dereferencing pcpu_rt.

[1]

Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] PREEMPT SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
CPU: 0 PID: 7543 Comm: kworker/u8:17 Not tainted 6.10.0-rc1-syzkaller-00013-g2bfcfd584ff5 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024
Workqueue: netns cleanup_net
 RIP: 0010:__fib6_drop_pcpu_from.part.0+0x10a/0x370 net/ipv6/ip6_fib.c:984
Code: f8 48 c1 e8 03 80 3c 28 00 0f 85 16 02 00 00 4d 8b 3f 4d 85 ff 74 31 e8 74 a7 fa f7 49 8d bf 90 00 00 00 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 1e 02 00 00 49 8b 87 90 00 00 00 48 8b 0c 24 48
RSP: 0018:ffffc900040df070 EFLAGS: 00010206
RAX: 0000000000000012 RBX: 0000000000000001 RCX: ffffffff89932e16
RDX: ffff888049dd1e00 RSI: ffffffff89932d7c RDI: 0000000000000091
RBP: dffffc0000000000 R08: 0000000000000005 R09: 0000000000000007
R10: 0000000000000001 R11: 0000000000000006 R12: ffff88807fa080b8
R13: fffffbfff1a9a07d R14: ffffed100ff41022 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff8880b9200000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32c26000 CR3: 000000005d56e000 CR4: 00000000003526f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
  __fib6_drop_pcpu_from net/ipv6/ip6_fib.c:966 [inline]
  fib6_drop_pcpu_from net/ipv6/ip6_fib.c:1027 [inline]
  fib6_purge_rt+0x7f2/0x9f0 net/ipv6/ip6_fib.c:1038
  fib6_del_route net/ipv6/ip6_fib.c:1998 [inline]
  fib6_del+0xa70/0x17b0 net/ipv6/ip6_fib.c:2043
  fib6_clean_node+0x426/0x5b0 net/ipv6/ip6_fib.c:2205
  fib6_walk_continue+0x44f/0x8d0 net/ipv6/ip6_fib.c:2127
  fib6_walk+0x182/0x370 net/ipv6/ip6_fib.c:2175
  fib6_clean_tree+0xd7/0x120 net/ipv6/ip6_fib.c:2255
  __fib6_clean_all+0x100/0x2d0 net/ipv6/ip6_fib.c:2271
  rt6_sync_down_dev net/ipv6/route.c:4906 [inline]
  rt6_disable_ip+0x7ed/0xa00 net/ipv6/route.c:4911
  addrconf_ifdown.isra.0+0x117/0x1b40 net/ipv6/addrconf.c:3855
  addrconf_notify+0x223/0x19e0 net/ipv6/addrconf.c:3778
  notifier_call_chain+0xb9/0x410 kernel/notifier.c:93
  call_netdevice_notifiers_info+0xbe/0x140 net/core/dev.c:1992
  call_netdevice_notifiers_extack net/core/dev.c:2030 [inline]
  call_netdevice_notifiers net/core/dev.c:2044 [inline]
  dev_close_many+0x333/0x6a0 net/core/dev.c:1585
  unregister_netdevice_many_notify+0x46d/0x19f0 net/core/dev.c:11193
  unregister_netdevice_many net/core/dev.c:11276 [inline]
  default_device_exit_batch+0x85b/0xae0 net/core/dev.c:11759
  ops_exit_list+0x128/0x180 net/core/net_namespace.c:178
  cleanup_net+0x5b7/0xbf0 net/core/net_namespace.c:640
  process_one_work+0x9fb/0x1b60 kernel/workqueue.c:3231
  process_scheduled_works kernel/workqueue.c:3312 [inline]
  worker_thread+0x6c8/0xf70 kernel/workqueue.c:3393
  kthread+0x2c1/0x3a0 kernel/kthread.c:389
  ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
Fixes d52d3997f843 ("ipv6: Create percpu rt6_info")
Cc Martin KaFai Lau <[email protected]>
---
 net/ipv6/ip6_fib.c | 6 +++++-
 net/ipv6/route.c   | 1 +
 2 files changed, 6 insertions(+), 1 deletion(-)
net/ipv6/ip6_fib.c +5 -1
index c1f62352a4814..1ace4ac3ee04c 100644
@@ -965,6 +965,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh,
 	if (!fib6_nh->rt6i_pcpu)
 		return;
 
+	rcu_read_lock();
 	/* release the reference to this fib entry from
 	 * all of its cached pcpu routes
 	 */
@@ -973,7 +974,9 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh,
 		struct rt6_info *pcpu_rt;
 
 		ppcpu_rt = per_cpu_ptr(fib6_nh->rt6i_pcpu, cpu);
-		pcpu_rt = *ppcpu_rt;
+
+		/* Paired with xchg() in rt6_get_pcpu_route() */
+		pcpu_rt = READ_ONCE(*ppcpu_rt);
 
 		/* only dropping the 'from' reference if the cached route
 		 * is using 'match'. The cached pcpu_rt->from only changes
@@ -987,6 +990,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh,
 			fib6_info_release(from);
 		}
 	}
+	rcu_read_unlock();
 }
 
 struct fib6_nh_pcpu_arg {
net/ipv6/route.c +1 -0
index f090e7bcb784f..bca6f33c7bb9e 100644
@@ -1409,6 +1409,7 @@ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res)
 		struct rt6_info *prev, **p;
 
 		p = this_cpu_ptr(res->nh->rt6i_pcpu);
+		/* Paired with READ_ONCE() in __fib6_drop_pcpu_from() */
 		prev = xchg(p, NULL);
 		if (prev) {
 			dst_dev_put(&prev->dst);
Signature · 1 line
2.43.0
author maintainer
#72 lore raw

PATCH 72/281 net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool()

In reply to Greg Kroah-Hartman

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

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

From: Su Hui <[email protected]>

[ Upstream commit 0dcc53abf58d572d34c5313de85f607cd33fc691 ]

Clang static checker (scan-build) warning:
net/ethtool/ioctl.c:line 2233, column 2 Called function pointer is null (null dereference).

Return '-EOPNOTSUPP' when 'ops->get_ethtool_phy_stats' is NULL to fix this typo error.

Fixes 201ed315f967 ("net/ethtool/ioctl: split ethtool_get_phy_stats into multiple helpers")
---
 net/ethtool/ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ethtool/ioctl.c +1 -1
index 5a55270aa86e8..e645d751a5e89 100644
@@ -2220,7 +2220,7 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
 	const struct ethtool_ops *ops = dev->ethtool_ops;
 	int n_stats, ret;
 
-	if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats)
+	if (!ops || !ops->get_sset_count || !ops->get_ethtool_phy_stats)
 		return -EOPNOTSUPP;
 
 	n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
Signature · 1 line
2.43.0
author maintainer
#73 lore raw

PATCH 73/281 drm/xe: Use ordered WQ for G2H handler

In reply to Greg Kroah-Hartman

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

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

From: Matthew Brost <[email protected]>

[ Upstream commit 2d9c72f676e6f79a021b74c6c1c88235e7d5b722 ]

System work queues are shared, use a dedicated work queue for G2H processing to avoid G2H processing getting block behind system tasks.

Fixes dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)
---
 drivers/gpu/drm/xe/xe_guc_ct.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/xe/xe_guc_ct.c +4 -0
index 8bbfa45798e2e..6ac86936faaf9 100644
@@ -146,6 +146,10 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
 
 	xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
 
+	ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
+	if (!ct->g2h_wq)
+		return -ENOMEM;
+
 	ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
 	if (!ct->g2h_wq)
 		return -ENOMEM;
Signature · 1 line
2.43.0
#74 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 1 line · Greg Kroah-Hartman

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

Hi Greg,

This patch seems to be a duplicate and should be dropped.

Thanks,
Francois

Quoted 42 lines

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

From: Matthew Brost <[email protected]>

[ Upstream commit 2d9c72f676e6f79a021b74c6c1c88235e7d5b722 ]

System work queues are shared, use a dedicated work queue for G2H processing to avoid G2H processing getting block behind system tasks.

Fixes dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)
---
 drivers/gpu/drm/xe/xe_guc_ct.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/xe/xe_guc_ct.c +4 -0
index 8bbfa45798e2e..6ac86936faaf9 100644
@@ -146,6 +146,10 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
 
 	xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
 
+	ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
+	if (!ct->g2h_wq)
+		return -ENOMEM;
+
 	ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
 	if (!ct->g2h_wq)
 		return -ENOMEM;
Signature · 1 line
2.43.0
author maintainer
#75 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 6 lines · Francois Dugast
Quoted 1 line · Greg Kroah-Hartman

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

Hi Greg,

This patch seems to be a duplicate and should be dropped.

How are we supposed to be able to determine this?

When you all check in commits into multiple branches, and tag them for
stable: and then they hit Linus's tree, and all hell breaks loose on our scripts. "Normally" this tag:

Quoted 1 line
Quoted 1 line

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't. Why not, what went wrong?

I'll go drop this, but ugh, what a mess. It makes me dread every drm patch that gets tagged for stable, and so I postpone taking them until I am done with everything else and can't ignore them anymore.

Please fix your broken process.

greg k-h

#76 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 7 lines · Greg Kroah-Hartman
Quoted 6 lines · Francois Dugast
Quoted 1 line · Greg Kroah-Hartman

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

Hi Greg,

This patch seems to be a duplicate and should be dropped.

Please also drop the 6.9.7-rc1:

https://lore.kernel.org/stable/[email protected]/T/#u

Quoted 10 lines

How are we supposed to be able to determine this?

When you all check in commits into multiple branches, and tag them for
stable: and then they hit Linus's tree, and all hell breaks loose on our scripts. "Normally" this tag:

Quoted 1 line
Quoted 1 line

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Quoted 1 line

Why not, what went wrong?

worst thing in this case is that git applied this cleanly, although the change was already there.

But also a timing thing. The faulty patch was already in the master. At the moment we applied the fix in our drm-xe-next, we had already sent the latest changes to the upcoming merge-window, so it propagated there as a cherry-pick, but we had to also send to the current -rc cycle and then the second cherry-pick also goes there.

This fast propagation to the current active development branch in general shouldn't be a problem, but a good thing so it is ensured that the fix gets quickly there. But clearly this configure a problem to the later propagation to the stable trees.

Quoted 6 lines

I'll go drop this, but ugh, what a mess. It makes me dread every drm patch that gets tagged for stable, and so I postpone taking them until I am done with everything else and can't ignore them anymore.

Please fix your broken process.

When you say drm, do you have same problem with patches coming from other drm drivers, drm-misc, or is it really only Intel trees? (only drm-intel (i915) and drm-xe)?

Quoted 2 lines

greg k-h

author maintainer
#77 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 5 lines · Rodrigo Vivi
Quoted 4 lines · Greg Kroah-Hartman
Quoted 3 lines · Francois Dugast
Quoted 1 line · Greg Kroah-Hartman

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

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

Hi Greg,

This patch seems to be a duplicate and should be dropped.

Please also drop the 6.9.7-rc1:

https://lore.kernel.org/stable/[email protected]/T/#u

Done.

Quoted 6 lines
Quoted 6 lines

How are we supposed to be able to determine this?

When you all check in commits into multiple branches, and tag them for
stable: and then they hit Linus's tree, and all hell breaks loose on our scripts. "Normally" this tag:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines
Quoted 1 line

Why not, what went wrong?

worst thing in this case is that git applied this cleanly, although the change was already there.

Yup.

Quoted 10 lines

But also a timing thing. The faulty patch was already in the master. At the moment we applied the fix in our drm-xe-next, we had already sent the latest changes to the upcoming merge-window, so it propagated there as a cherry-pick, but we had to also send to the current -rc cycle and then the second cherry-pick also goes there.

This fast propagation to the current active development branch in general shouldn't be a problem, but a good thing so it is ensured that the fix gets quickly there. But clearly this configure a problem to the later propagation to the stable trees.

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

Quoted 9 lines
Quoted 5 lines

I'll go drop this, but ugh, what a mess. It makes me dread every drm patch that gets tagged for stable, and so I postpone taking them until I am done with everything else and can't ignore them anymore.

Please fix your broken process.

When you say drm, do you have same problem with patches coming from other drm drivers, drm-misc, or is it really only Intel trees? (only drm-intel (i915) and drm-xe)?

Intel trees have traditionally been the worst, but normally you all give me some cherry-pick clue on the commits so I can weed them out. That didn't happen here.

But, I will note that the AMD drm tree is now starting to do this, in much worse ways than the Intel tree because there is NO cherry-pick information anywhere, so again, I have no idea what to do and massive conflicts happen.

So AMD is copying your bad behavior, please, both of you stop and fix this so that it isn't so broken.

Again, I understand the need/want to have multiple versions of the same patch in different branches to get fixes merged quicker, but when you do that, please give me a way to determine this, otherwise we have no chance.

thanks,

greg k-h

#78 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 80 lines · Greg Kroah-Hartman
Quoted 5 lines · Rodrigo Vivi
Quoted 4 lines · Greg Kroah-Hartman
Quoted 3 lines · Francois Dugast
Quoted 1 line · Greg Kroah-Hartman

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

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

Hi Greg,

This patch seems to be a duplicate and should be dropped.

Please also drop the 6.9.7-rc1:

https://lore.kernel.org/stable/[email protected]/T/#u

Done.

Quoted 6 lines
Quoted 6 lines

How are we supposed to be able to determine this?

When you all check in commits into multiple branches, and tag them for
stable: and then they hit Linus's tree, and all hell breaks loose on our scripts. "Normally" this tag:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines
Quoted 1 line

Why not, what went wrong?

worst thing in this case is that git applied this cleanly, although the change was already there.

Yup.

Quoted 10 lines

But also a timing thing. The faulty patch was already in the master. At the moment we applied the fix in our drm-xe-next, we had already sent the latest changes to the upcoming merge-window, so it propagated there as a cherry-pick, but we had to also send to the current -rc cycle and then the second cherry-pick also goes there.

This fast propagation to the current active development branch in general shouldn't be a problem, but a good thing so it is ensured that the fix gets quickly there. But clearly this configure a problem to the later propagation to the stable trees.

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

Quoted 9 lines
Quoted 5 lines

I'll go drop this, but ugh, what a mess. It makes me dread every drm patch that gets tagged for stable, and so I postpone taking them until I am done with everything else and can't ignore them anymore.

Please fix your broken process.

When you say drm, do you have same problem with patches coming from other drm drivers, drm-misc, or is it really only Intel trees? (only drm-intel (i915) and drm-xe)?

Intel trees have traditionally been the worst, but normally you all give me some cherry-pick clue on the commits so I can weed them out. That didn't happen here.

But, I will note that the AMD drm tree is now starting to do this, in much worse ways than the Intel tree because there is NO cherry-pick information anywhere, so again, I have no idea what to do and massive conflicts happen.

Quoted 7 lines

So AMD is copying your bad behavior, please, both of you stop and fix this so that it isn't so broken.

Again, I understand the need/want to have multiple versions of the same patch in different branches to get fixes merged quicker, but when you do that, please give me a way to determine this, otherwise we have no chance.

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

BR,
Jani.

[1] https://lore.kernel.org/r/Zjz7SzCvfA3vQRxu@fedora
[2] https://lore.kernel.org/r/c3rduifdp5wipkljdpuq4x6uowkc2uyzgdoft4txvp6mgvzjaj@7zw7c6uw4wrf

Signature · 1 line
Jani Nikula, Intel
author maintainer
#79 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 89 lines · Jani Nikula
Quoted 80 lines · Greg Kroah-Hartman
Quoted 5 lines · Rodrigo Vivi
Quoted 4 lines · Greg Kroah-Hartman
Quoted 3 lines · Francois Dugast
Quoted 1 line · Greg Kroah-Hartman

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

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

Hi Greg,

This patch seems to be a duplicate and should be dropped.

Please also drop the 6.9.7-rc1:

https://lore.kernel.org/stable/[email protected]/T/#u

Done.

Quoted 6 lines
Quoted 6 lines

How are we supposed to be able to determine this?

When you all check in commits into multiple branches, and tag them for
stable: and then they hit Linus's tree, and all hell breaks loose on our scripts. "Normally" this tag:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines
Quoted 1 line

Why not, what went wrong?

worst thing in this case is that git applied this cleanly, although the change was already there.

Yup.

Quoted 10 lines

But also a timing thing. The faulty patch was already in the master. At the moment we applied the fix in our drm-xe-next, we had already sent the latest changes to the upcoming merge-window, so it propagated there as a cherry-pick, but we had to also send to the current -rc cycle and then the second cherry-pick also goes there.

This fast propagation to the current active development branch in general shouldn't be a problem, but a good thing so it is ensured that the fix gets quickly there. But clearly this configure a problem to the later propagation to the stable trees.

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

Quoted 9 lines
Quoted 5 lines

I'll go drop this, but ugh, what a mess. It makes me dread every drm patch that gets tagged for stable, and so I postpone taking them until I am done with everything else and can't ignore them anymore.

Please fix your broken process.

When you say drm, do you have same problem with patches coming from other drm drivers, drm-misc, or is it really only Intel trees? (only drm-intel (i915) and drm-xe)?

Intel trees have traditionally been the worst, but normally you all give me some cherry-pick clue on the commits so I can weed them out. That didn't happen here.

But, I will note that the AMD drm tree is now starting to do this, in much worse ways than the Intel tree because there is NO cherry-pick information anywhere, so again, I have no idea what to do and massive conflicts happen.

Quoted 7 lines

So AMD is copying your bad behavior, please, both of you stop and fix this so that it isn't so broken.

Again, I understand the need/want to have multiple versions of the same patch in different branches to get fixes merged quicker, but when you do that, please give me a way to determine this, otherwise we have no chance.

Quoted 5 lines

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

any cherry-pick SHOULD have the git id referenced when they are cherry-picked, that's what the id is there for. Please always do that.

greg k-h

#80 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

My thought was on the stable scripts doing something like that.

For each candidate commit, check if it has the tag line (cherry picked from commit <original-hash>)

if so, then something like:
if git rev-parse --quiet --verify <original-hash> || \
git log --grep="cherry picked from commit <original-hash> -E --oneline >/dev/null; then
echo "One version of this patch is already in tree. Skipping..." # send-email?!
else
#attempt to apply the candidate commit...

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

I'm afraid this is not accurate. Our tooling is taking care of that for us. More details below.

Quoted 5 lines
Quoted 5 lines

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

Also I don't believe there's anything wrong here. It was a coincidence on the timing, but one is
drm-xe-next-fixes-2024-05-09-1
and the other
drm-xe-fixes-2024-05-09

both maintained by different people at that time.

Quoted 3 lines

any cherry-pick SHOULD have the git id referenced when they are cherry-picked, that's what the id is there for. Please always do that.

Original commit hash is 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de 50aec9665e0b ("drm/xe: Use ordered WQ for G2H handler")

drm-xe-next-fixes-2024-05-09-1
has commit 2d9c72f676e6 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

drm-xe-fixes-2024-05-09
has commit c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Perhaps git itself should be smart to avoid it since the info is there, but unfortunately it is not. So probably a script on top like above could help us to minimize cases like this.

Thanks a lot from the support and patience here.

Quoted 2 lines

greg k-h

author maintainer
#81 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 18 lines · Rodrigo Vivi
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines

My thought was on the stable scripts doing something like that.

For each candidate commit, check if it has the tag line (cherry picked from commit <original-hash>)

Right there, that fails with how the drm tree works. So you are going to have to come up with something else for how to check this. Or fix your process to make this work.

Look at the commits tagged for stable in the -rc1 merge window. They don't have the "cherry picked" wording as they were not cherry picked! They were the "originals" that were cherry picked from.

Quoted 8 lines

if so, then something like:
if git rev-parse --quiet --verify <original-hash> || \
git log --grep="cherry picked from commit <original-hash> -E --oneline >/dev/null; then
echo "One version of this patch is already in tree. Skipping..." # send-email?!
else
#attempt to apply the candidate commit...

Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

I'm afraid this is not accurate. Our tooling is taking care of that for us.

Then your tooling needs to be fixed.

Quoted 12 lines
Quoted 5 lines
Quoted 5 lines

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

Also I don't believe there's anything wrong here. It was a coincidence on the timing, but one is
drm-xe-next-fixes-2024-05-09-1
and the other
drm-xe-fixes-2024-05-09

Quoted 8 lines

both maintained by different people at that time.

Quoted 3 lines

any cherry-pick SHOULD have the git id referenced when they are cherry-picked, that's what the id is there for. Please always do that.

Original commit hash is 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de 50aec9665e0b ("drm/xe: Use ordered WQ for G2H handler")

And that's not in Linus's tree.

Quoted 11 lines

drm-xe-next-fixes-2024-05-09-1
has commit 2d9c72f676e6 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

drm-xe-fixes-2024-05-09
has commit c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Ok, but again, the original is not in Linus's tree.

So how am I do know that the cherry picked line was already in the tree? Added it twice is odd, but really, that's not the common failure here at all. The real problem is the -rc1 window where there is NOT a commit id that can be matched up with (as it happening with a few commits here, and with lots of AMD patches now.)

thanks,

greg k-h

#82 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 77 lines · Greg Kroah-Hartman
Quoted 18 lines · Rodrigo Vivi
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines

My thought was on the stable scripts doing something like that.

For each candidate commit, check if it has the tag line (cherry picked from commit <original-hash>)

Right there, that fails with how the drm tree works. So you are going to have to come up with something else for how to check this. Or fix your process to make this work.

Look at the commits tagged for stable in the -rc1 merge window. They don't have the "cherry picked" wording as they were not cherry picked! They were the "originals" that were cherry picked from.

Quoted 8 lines

if so, then something like:
if git rev-parse --quiet --verify <original-hash> || \
git log --grep="cherry picked from commit <original-hash> -E --oneline >/dev/null; then
echo "One version of this patch is already in tree. Skipping..." # send-email?!
else
#attempt to apply the candidate commit...

Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

I'm afraid this is not accurate. Our tooling is taking care of that for us.

Then your tooling needs to be fixed.

Quoted 12 lines
Quoted 5 lines
Quoted 5 lines

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

Also I don't believe there's anything wrong here. It was a coincidence on the timing, but one is
drm-xe-next-fixes-2024-05-09-1
and the other
drm-xe-fixes-2024-05-09

Quoted 8 lines

both maintained by different people at that time.

Quoted 3 lines

any cherry-pick SHOULD have the git id referenced when they are cherry-picked, that's what the id is there for. Please always do that.

Original commit hash is 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de 50aec9665e0b ("drm/xe: Use ordered WQ for G2H handler")

And that's not in Linus's tree.

Quoted 6 lines

drm-xe-next-fixes-2024-05-09-1
has commit 2d9c72f676e6 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)
Quoted 7 lines
Quoted 5 lines

drm-xe-fixes-2024-05-09
has commit c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Ok, but again, the original is not in Linus's tree.

current workflow is:

All patches go to drm-xe-next which may be targeting the next kernel release or the next->next. Then the fixes (and less frequently, other commits which are not important here) are cherry-picked by maintainers to the current or next kernel release. In other words, the cherry-pick always targets a version 1 less than the original patch.

couple of issues I see:

1) original commit not being in Linus's tree

If you are traversing the branch and you have a "Fixes: XXXX" where XXXX is from a previous release, you will most likely see the "cherry picked from <original>" *before* the <original> commit showing up in that tree.

Examples looking at the most recent fixes in Linus's tree with

	$ git rev-parse origin/master
	6d6444ba82053c716fb5ac83346202659023044e
	$ git log --format="%h %s%n%(trailers)" -n3 --grep "^Fixes:" \
		6d6444ba82053c716fb5ac83346202659023044e \
		-- drivers/gpu/drm/xe

d21d44dbdde8 in v6.10-rc5, fixes aef4eb7c7dec from v6.9 but f0ccd2d805e55e12b430d5d6b9acd9f891af455e is not in any tag.

2470b141bfae in v6.10-rc4, fixes 975e4a3795d4 from v6.8 but 6800e63cf97bae62bca56d8e691544540d945f53 is not in any tag.

cd554e1e118a in v6.10-rc4, fixes 0698ff57bf32 from v6.10-rc3 but b321cb83a375bcc18cd0a4b62bdeaf6905cca769 is not in any tag.

Without a change in the workflow, I don't think you can rely on the original commit hash being present in Linus's tree, unless you wait one entire kernel release cycle.

2) Duplicate commits with "cherry picked from ... "

This only happened because it was cherry-picked in 2 branches, both for current and for next kernel releases. This can only happen during the last rcN as drm-xe-next-fixes is only used there.

I think (2) is easier to fix: we should really add more checks in dim to avoid that: if a commit is a candidate to drm-xe-fixes it should never be a candidate to drm-xe-next-fixes.

As for (1), I don't see how it could be fixed without a workflow change. That would require committers to add the commits to the right branch rather than relying on maintainers to cherry-pick them to the -fixes branch after they are merged in drm-xe-next. What dim could do is to automate that for the committer and figure out the branch by itself based on the 2 commit hashes.

For all the above I used drm-xe-* as example, but it applies to drm-intel-* too.

Without the fix to (2) and workflow change from (1), this situation can be avoided from the -stable scripts by checking if the commit or any cherry-pick thereof is already in the stable tree:

	git merge-base --is-ancestor $original_commit HEAD
	git log -n1 --grep "^(cherry picked from commit $original_commit)"

the second search is very expensive though.... probably need to find a way to limit the search space.

Lucas De Marchi

Quoted 10 lines

So how am I do know that the cherry picked line was already in the tree? Added it twice is odd, but really, that's not the common failure here at all. The real problem is the -rc1 window where there is NOT a commit id that can be matched up with (as it happening with a few commits here, and with lots of AMD patches now.)

thanks,

greg k-h

author maintainer
#83 lore raw

Re: [PATCH 6.9 073/281] drm/xe: Use ordered WQ for G2H handler

Quoted 86 lines · Lucas De Marchi
Quoted 77 lines · Greg Kroah-Hartman
Quoted 18 lines · Rodrigo Vivi
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Would help out here, but it doesn't.

I wonder if there would be a way of automate this on stable scripts to avoid attempting a cherry pick that is already there.

Please tell me how to do so.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

But I do understand that any change like this would cause a 'latency' on the scripts and slow down everything.

Depends, I already put a huge latency on drm stable patches because of this mess. And I see few, if any, actual backports for when I report FAILED stable patches, so what is going to get slower than it currently is?

Quoted 4 lines

My thought was on the stable scripts doing something like that.

For each candidate commit, check if it has the tag line (cherry picked from commit <original-hash>)

Right there, that fails with how the drm tree works. So you are going to have to come up with something else for how to check this. Or fix your process to make this work.

Look at the commits tagged for stable in the -rc1 merge window. They don't have the "cherry picked" wording as they were not cherry picked! They were the "originals" that were cherry picked from.

Quoted 8 lines

if so, then something like:
if git rev-parse --quiet --verify <original-hash> || \
git log --grep="cherry picked from commit <original-hash> -E --oneline >/dev/null; then
echo "One version of this patch is already in tree. Skipping..." # send-email?!
else
#attempt to apply the candidate commit...

Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

Normally you all tag these cherry-picks as such. You didn't do that here or either place, so there was no way for anyone to know. Please fix that.

I'm afraid this is not accurate. Our tooling is taking care of that for us.

Then your tooling needs to be fixed.

Quoted 12 lines
Quoted 5 lines
Quoted 5 lines

To be fair, this one seems to have been an accident. The same commit was cherry-picked to *two* different branches by two different people [1][2], and this is something we try not to do. Any cherry-picks should go to one tree only, it's checked by our scripts, but it's not race free when two people are doing this roughly at the same time.

Also I don't believe there's anything wrong here. It was a coincidence on the timing, but one is
drm-xe-next-fixes-2024-05-09-1
and the other
drm-xe-fixes-2024-05-09

Quoted 8 lines

both maintained by different people at that time.

Quoted 3 lines

any cherry-pick SHOULD have the git id referenced when they are cherry-picked, that's what the id is there for. Please always do that.

Original commit hash is 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de 50aec9665e0b ("drm/xe: Use ordered WQ for G2H handler")

And that's not in Linus's tree.

Quoted 6 lines

drm-xe-next-fixes-2024-05-09-1
has commit 2d9c72f676e6 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)
Quoted 7 lines
Quoted 5 lines

drm-xe-fixes-2024-05-09
has commit c002bfe644a2 ("drm/xe: Use ordered WQ for G2H handler") which contains:

(cherry picked from commit 50aec9665e0babd62b9eee4e613d9a1ef8d2b7de)

Ok, but again, the original is not in Linus's tree.

Quoted 7 lines

current workflow is:

All patches go to drm-xe-next which may be targeting the next kernel release or the next->next. Then the fixes (and less frequently, other commits which are not important here) are cherry-picked by maintainers to the current or next kernel release. In other words, the cherry-pick always targets a version 1 less than the original patch.

That's fine, as long as that cherry-pick references the git id of the original one. Which did not happen here, and does NOT happen at all for all drm branches (like AMD right now).

Quoted 23 lines

couple of issues I see:

1) original commit not being in Linus's tree

If you are traversing the branch and you have a "Fixes: XXXX" where XXXX is from a previous release, you will most likely see the "cherry picked from <original>" *before* the <original> commit showing up in that tree.

Examples looking at the most recent fixes in Linus's tree with

	$ git rev-parse origin/master
	6d6444ba82053c716fb5ac83346202659023044e
	$ git log --format="%h %s%n%(trailers)" -n3 --grep "^Fixes:" \
		6d6444ba82053c716fb5ac83346202659023044e \
		-- drivers/gpu/drm/xe

d21d44dbdde8 in v6.10-rc5, fixes aef4eb7c7dec from v6.9 but f0ccd2d805e55e12b430d5d6b9acd9f891af455e is not in any tag.

2470b141bfae in v6.10-rc4, fixes 975e4a3795d4 from v6.8 but 6800e63cf97bae62bca56d8e691544540d945f53 is not in any tag.

Quoted 6 lines

cd554e1e118a in v6.10-rc4, fixes 0698ff57bf32 from v6.10-rc3 but b321cb83a375bcc18cd0a4b62bdeaf6905cca769 is not in any tag.

Without a change in the workflow, I don't think you can rely on the original commit hash being present in Linus's tree, unless you wait one entire kernel release cycle.

Which you obviously do not want me to do as you wanted that fix in the tree sooner.

So this is a pain, but I'm kind of used to it by now as you all seem to like this workflow for whatever reason...

Quoted 9 lines

2) Duplicate commits with "cherry picked from ... "

This only happened because it was cherry-picked in 2 branches, both for current and for next kernel releases. This can only happen during the last rcN as drm-xe-next-fixes is only used there.

I think (2) is easier to fix: we should really add more checks in dim to avoid that: if a commit is a candidate to drm-xe-fixes it should never be a candidate to drm-xe-next-fixes.

Please fix.

Quoted 14 lines

As for (1), I don't see how it could be fixed without a workflow change. That would require committers to add the commits to the right branch rather than relying on maintainers to cherry-pick them to the -fixes branch after they are merged in drm-xe-next. What dim could do is to automate that for the committer and figure out the branch by itself based on the 2 commit hashes.

For all the above I used drm-xe-* as example, but it applies to drm-intel-* too.

Without the fix to (2) and workflow change from (1), this situation can be avoided from the -stable scripts by checking if the commit or any cherry-pick thereof is already in the stable tree:

Quoted 5 lines
	git merge-base --is-ancestor $original_commit HEAD
	git log -n1 --grep "^(cherry picked from commit $original_commit)"

the second search is very expensive though.... probably need to find a way to limit the search space.

That's still a major pain, as is your current workflow. So until you all fix this up, I will continue to complain as the existing way drm patches flow into stable trees is a major pain which causes me to dread looking at them every time.

greg k-h

author maintainer
#84 lore raw

PATCH 74/281 x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes()

In reply to Greg Kroah-Hartman

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

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

From: Borislav Petkov (AMD) <[email protected]>

[ Upstream commit 95bfb35269b2e85cff0dd2c957b2d42ebf95ae5f ]

Drop 'vp_bits_from_cpuid' as it is not really needed.

No functional changes.

Stable-dep-of: 2a38e4ca3022 ("x86/cpu: Provide default cache line size if not enumerated")

---
 arch/x86/kernel/cpu/common.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
arch/x86/kernel/cpu/common.c +7 -10
index ae987a26f26e4..d636991536a5f 100644
@@ -1053,18 +1053,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
 void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 {
 	u32 eax, ebx, ecx, edx;
-	bool vp_bits_from_cpuid = true;
 
 	if (!cpu_has(c, X86_FEATURE_CPUID) ||
-	    (c->extended_cpuid_level < 0x80000008))
-		vp_bits_from_cpuid = false;
-
-	if (vp_bits_from_cpuid) {
-		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
-
-		c->x86_virt_bits = (eax >> 8) & 0xff;
-		c->x86_phys_bits = eax & 0xff;
-	} else {
+	    (c->extended_cpuid_level < 0x80000008)) {
 		if (IS_ENABLED(CONFIG_X86_64)) {
 			c->x86_clflush_size = 64;
 			c->x86_phys_bits = 36;
@@ -1078,7 +1069,13 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 			    cpu_has(c, X86_FEATURE_PSE36))
 				c->x86_phys_bits = 36;
 		}
+	} else {
+		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
+
+		c->x86_virt_bits = (eax >> 8) & 0xff;
+		c->x86_phys_bits = eax & 0xff;
 	}
+
 	c->x86_cache_bits = c->x86_phys_bits;
 	c->x86_cache_alignment = c->x86_clflush_size;
 }
Signature · 1 line
2.43.0
author maintainer
#85 lore raw

PATCH 75/281 x86/cpu: Provide default cache line size if not enumerated

In reply to Greg Kroah-Hartman

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

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

From: Dave Hansen <[email protected]>

[ Upstream commit 2a38e4ca302280fdcce370ba2bee79bac16c4587 ]

tl;dr: CPUs with CPUID.80000008H but without CPUID.01H:EDX[CLFSH] will end up reporting cache_line_size()==0 and bad things happen. Fill in a default on those to avoid the problem.

Long Story:

The kernel dies a horrible death if c->x86_cache_alignment (aka. cache_line_size() is 0. Normally, this value is populated from c->x86_clflush_size.

Right now the code is set up to get c->x86_clflush_size from two places. First, modern CPUs get it from CPUID. Old CPUs that don't have leaf 0x80000008 (or CPUID at all) just get some sane defaults from the kernel in get_cpu_address_sizes().

The vast majority of CPUs that have leaf 0x80000008 also get ->x86_clflush_size from CPUID. But there are oddballs.

Intel Quark CPUs[1] and others[2] have leaf 0x80000008 but don't set CPUID.01H:EDX[CLFSH], so they skip over filling in ->x86_clflush_size:

	cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
	if (cap0 & (1<<19))
		c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;

So they: land in get_cpu_address_sizes() and see that CPUID has level 0x80000008 and jump into the side of the if() that does not fill in c->x86_clflush_size. That assigns a 0 to c->x86_cache_alignment, and hilarity ensues in code like:

buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()),
GFP_KERNEL);

To fix this, always provide a sane value for ->x86_clflush_size.

Big thanks to Andy Shevchenko for finding and reporting this and also providing a first pass at a fix. But his fix was only partial and only worked on the Quark CPUs. It would not, for instance, have worked on the QEMU config.

1. https://raw.githubusercontent.com/InstLatx64/InstLatx64/master/GenuineIntel/GenuineIntel0000590_Clanton_03_CPUID.txt
2. You can also get this behavior if you use "-cpu 486,+clzero"
in QEMU.

[ dhansen: remove 'vp_bits_from_cpuid' reference in changelog
because bpetkov brutally murdered it recently. ]

---
 arch/x86/kernel/cpu/common.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kernel/cpu/common.c +4 -0
index d636991536a5f..1982007828276 100644
@@ -1074,6 +1074,10 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 
 		c->x86_virt_bits = (eax >> 8) & 0xff;
 		c->x86_phys_bits = eax & 0xff;
+
+		/* Provide a sane default if not enumerated: */
+		if (!c->x86_clflush_size)
+			c->x86_clflush_size = 32;
 	}
 
 	c->x86_cache_bits = c->x86_phys_bits;
Signature · 1 line
2.43.0
author maintainer
#86 lore raw

PATCH 76/281 selftests/mm: ksft_exit functions do not return

In reply to Greg Kroah-Hartman

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

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

From: Nathan Chancellor <[email protected]>

[ Upstream commit 69e545edbe8b17c26aa06ef7e430d0be7f08d876 ]

After commit f7d5bcd35d42 ("selftests: kselftest: Mark functions that unconditionally call exit() as __noreturn"), ksft_exit_...() functions are marked as __noreturn, which means the return type should not be 'int' but 'void' because they are not returning anything (and never were since exit() has always been called).

To facilitate updating the return type of these functions, remove 'return' before the calls to ksft_exit_...(), as __noreturn prevents the compiler from warning that a caller of the ksft_exit functions does not return a value because the program will terminate upon calling these functions.

Stable-dep-of: fb9293b6b015 ("selftests/mm: compaction_test: fix bogus test success and reduce probability of OOM-killer invocation")

---
 tools/testing/selftests/mm/compaction_test.c      | 6 +++---
 tools/testing/selftests/mm/cow.c                  | 2 +-
 tools/testing/selftests/mm/gup_longterm.c         | 2 +-
 tools/testing/selftests/mm/gup_test.c             | 4 ++--
 tools/testing/selftests/mm/ksm_functional_tests.c | 2 +-
 tools/testing/selftests/mm/madv_populate.c        | 2 +-
 tools/testing/selftests/mm/mkdirty.c              | 2 +-
 tools/testing/selftests/mm/pagemap_ioctl.c        | 4 ++--
 tools/testing/selftests/mm/soft-dirty.c           | 2 +-
 9 files changed, 13 insertions(+), 13 deletions(-)
tools/testing/selftests/mm/compaction_test.c +3 -3
index 326a893647bab..5e9bd1da9370c 100644
@@ -185,7 +185,7 @@ int main(int argc, char **argv)
 	ksft_print_header();
 
 	if (prereq() || geteuid())
-		return ksft_exit_skip("Prerequisites unsatisfied\n");
+		ksft_exit_skip("Prerequisites unsatisfied\n");
 
 	ksft_set_plan(1);
 
@@ -233,7 +233,7 @@ int main(int argc, char **argv)
 	}
 
 	if (check_compaction(mem_free, hugepage_size) == 0)
-		return ksft_exit_pass();
+		ksft_exit_pass();
 
-	return ksft_exit_fail();
+	ksft_exit_fail();
 }
tools/testing/selftests/mm/cow.c +1 -1
index 363bf5f801be5..fe078d6e18064 100644
@@ -1779,5 +1779,5 @@ int main(int argc, char **argv)
 	if (err)
 		ksft_exit_fail_msg("%d out of %d tests failed\n",
 				   err, ksft_test_num());
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/gup_longterm.c +1 -1
index ad168d35b23b7..d7eaca5bbe9b1 100644
@@ -456,5 +456,5 @@ int main(int argc, char **argv)
 	if (err)
 		ksft_exit_fail_msg("%d out of %d tests failed\n",
 				   err, ksft_test_num());
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/gup_test.c +2 -2
index 7821cf45c323b..bdeaac67ff9aa 100644
@@ -229,7 +229,7 @@ int main(int argc, char **argv)
 			break;
 		}
 		ksft_test_result_skip("Please run this test as root\n");
-		return ksft_exit_pass();
+		ksft_exit_pass();
 	}
 
 	p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0);
@@ -268,5 +268,5 @@ int main(int argc, char **argv)
 
 	free(tid);
 
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/ksm_functional_tests.c +1 -1
index d615767e396be..508287560c455 100644
@@ -646,5 +646,5 @@ int main(int argc, char **argv)
 	if (err)
 		ksft_exit_fail_msg("%d out of %d tests failed\n",
 				   err, ksft_test_num());
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/madv_populate.c +1 -1
index 17bcb07f19f34..ef7d911da13e0 100644
@@ -307,5 +307,5 @@ int main(int argc, char **argv)
 	if (err)
 		ksft_exit_fail_msg("%d out of %d tests failed\n",
 				   err, ksft_test_num());
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/mkdirty.c +1 -1
index 301abb99e027e..b8a7efe9204ea 100644
@@ -375,5 +375,5 @@ int main(void)
 	if (err)
 		ksft_exit_fail_msg("%d out of %d tests failed\n",
 				   err, ksft_test_num());
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/pagemap_ioctl.c +2 -2
index d59517ed3d48b..2d785aca72a5c 100644
@@ -1484,7 +1484,7 @@ int main(int argc, char *argv[])
 	ksft_print_header();
 
 	if (init_uffd())
-		return ksft_exit_pass();
+		ksft_exit_pass();
 
 	ksft_set_plan(115);
 
@@ -1660,5 +1660,5 @@ int main(int argc, char *argv[])
 	userfaultfd_tests();
 
 	close(pagemap_fd);
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
tools/testing/selftests/mm/soft-dirty.c +1 -1
index 7dbfa53d93a05..d9dbf879748b2 100644
@@ -209,5 +209,5 @@ int main(int argc, char **argv)
 
 	close(pagemap_fd);
 
-	return ksft_exit_pass();
+	ksft_exit_pass();
 }
Signature · 1 line
2.43.0
author maintainer
#87 lore raw

PATCH 77/281 selftests/mm: compaction_test: fix bogus test success and reduce probability of OOM-killer invocation

In reply to Greg Kroah-Hartman

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

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

From: Dev Jain <[email protected]>

[ Upstream commit fb9293b6b0156fbf6ab97a1625d99a29c36d9f0c ]

Reset nr_hugepages to zero before the start of the test.

If a non-zero number of hugepages is already set before the start of the test, the following problems arise:

- The probability of the test getting OOM-killed increases. Proof:
The test wants to run on 80% of available memory to prevent OOM-killing (see original code comments). Let the value of mem_free at the start of the test, when nr_hugepages = 0, be x. In the other case, when nr_hugepages > 0, let the memory consumed by hugepages be y. In the former case, the test operates on 0.8 * x of memory. In the latter, the test operates on 0.8 * (x - y) of memory, with y already filled, hence, memory consumed is y + 0.8 * (x - y) = 0.8 * x + 0.2 * y > 0.8 * x. Q.E.D

- The probability of a bogus test success increases. Proof: Let the memory consumed by hugepages be greater than 25% of x, with x and y defined as above. The definition of compaction_index is c_index = (x - y)/z where z is the memory consumed by hugepages after trying to increase them again. In check_compaction(), we set the number of hugepages to zero, and then increase them back; the probability that they will be set back to consume at least y amount of memory again is very high (since there is not much delay between the two attempts of changing nr_hugepages). Hence, z >= y > (x/4) (by the 25% assumption). Therefore, c_index = (x - y)/z <= (x - y)/y = x/y - 1 < 4 - 1 = 3 hence, c_index can always be forced to be less than 3, thereby the test succeeding always. Q.E.D

Fixes bd67d5c15cc1 ("Test compaction of mlocked memory")
Cc Anshuman Khandual <[email protected]>
Cc Shuah Khan <[email protected]>
Cc Sri Jayaramappa <[email protected]>
---
 tools/testing/selftests/mm/compaction_test.c | 71 ++++++++++++++------
 1 file changed, 49 insertions(+), 22 deletions(-)
tools/testing/selftests/mm/compaction_test.c +49 -22
index 5e9bd1da9370c..e140558e6f53f 100644
@@ -82,13 +82,16 @@ int prereq(void)
 	return -1;
 }
 
-int check_compaction(unsigned long mem_free, unsigned long hugepage_size)
+int check_compaction(unsigned long mem_free, unsigned long hugepage_size,
+		     unsigned long initial_nr_hugepages)
 {
 	unsigned long nr_hugepages_ul;
 	int fd, ret = -1;
 	int compaction_index = 0;
-	char initial_nr_hugepages[20] = {0};
 	char nr_hugepages[20] = {0};
+	char init_nr_hugepages[20] = {0};
+
+	sprintf(init_nr_hugepages, "%lu", initial_nr_hugepages);
 
 	/* We want to test with 80% of available memory. Else, OOM killer comes
 	   in to play */
@@ -102,23 +105,6 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size)
 		goto out;
 	}
 
-	if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) {
-		ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n",
-			       strerror(errno));
-		goto close_fd;
-	}
-
-	lseek(fd, 0, SEEK_SET);
-
-	/* Start with the initial condition of 0 huge pages*/
-	if (write(fd, "0", sizeof(char)) != sizeof(char)) {
-		ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n",
-			       strerror(errno));
-		goto close_fd;
-	}
-
-	lseek(fd, 0, SEEK_SET);
-
 	/* Request a large number of huge pages. The Kernel will allocate
 	   as much as it can */
 	if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
@@ -146,8 +132,8 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size)
 
 	lseek(fd, 0, SEEK_SET);
 
-	if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages))
-	    != strlen(initial_nr_hugepages)) {
+	if (write(fd, init_nr_hugepages, strlen(init_nr_hugepages))
+	    != strlen(init_nr_hugepages)) {
 		ksft_print_msg("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n",
 			       strerror(errno));
 		goto close_fd;
@@ -171,6 +157,41 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size)
 	return ret;
 }
 
+int set_zero_hugepages(unsigned long *initial_nr_hugepages)
+{
+	int fd, ret = -1;
+	char nr_hugepages[20] = {0};
+
+	fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK);
+	if (fd < 0) {
+		ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n",
+			       strerror(errno));
+		goto out;
+	}
+	if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
+		ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n",
+			       strerror(errno));
+		goto close_fd;
+	}
+
+	lseek(fd, 0, SEEK_SET);
+
+	/* Start with the initial condition of 0 huge pages */
+	if (write(fd, "0", sizeof(char)) != sizeof(char)) {
+		ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n",
+			       strerror(errno));
+		goto close_fd;
+	}
+
+	*initial_nr_hugepages = strtoul(nr_hugepages, NULL, 10);
+	ret = 0;
+
+ close_fd:
+	close(fd);
+
+ out:
+	return ret;
+}
 
 int main(int argc, char **argv)
 {
@@ -181,6 +202,7 @@ int main(int argc, char **argv)
 	unsigned long mem_free = 0;
 	unsigned long hugepage_size = 0;
 	long mem_fragmentable_MB = 0;
+	unsigned long initial_nr_hugepages;
 
 	ksft_print_header();
 
@@ -189,6 +211,10 @@ int main(int argc, char **argv)
 
 	ksft_set_plan(1);
 
+	/* Start the test without hugepages reducing mem_free */
+	if (set_zero_hugepages(&initial_nr_hugepages))
+		ksft_exit_fail();
+
 	lim.rlim_cur = RLIM_INFINITY;
 	lim.rlim_max = RLIM_INFINITY;
 	if (setrlimit(RLIMIT_MEMLOCK, &lim))
@@ -232,7 +258,8 @@ int main(int argc, char **argv)
 		entry = entry->next;
 	}
 
-	if (check_compaction(mem_free, hugepage_size) == 0)
+	if (check_compaction(mem_free, hugepage_size,
+			     initial_nr_hugepages) == 0)
 		ksft_exit_pass();
 
 	ksft_exit_fail();
Signature · 1 line
2.43.0
author maintainer
#88 lore raw

PATCH 78/281 eventfs: Update all the eventfs_inodes from the events descriptor

In reply to Greg Kroah-Hartman

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

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

From: Steven Rostedt (Google) <[email protected]>

[ Upstream commit 340f0c7067a95281ad13734f8225f49c6cf52067 ]

The change to update the permissions of the eventfs_inode had the misconception that using the tracefs_inode would find all the eventfs_inodes that have been updated and reset them on remount. The problem with this approach is that the eventfs_inodes are freed when they are no longer used (basically the reason the eventfs system exists). When they are freed, the updated eventfs_inodes are not reset on a remount because their tracefs_inodes have been freed.

Instead, since the events directory eventfs_inode always has a tracefs_inode pointing to it (it is not freed when finished), and the events directory has a link to all its children, have the eventfs_remount() function only operate on the events eventfs_inode and have it descend into its children updating their uid and gids.

Cc Masami Hiramatsu <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Mathieu Desnoyers <[email protected]>
Cc Andrew Morton <[email protected]>
Fixes baa23a8d4360d ("tracefs: Reset permissions on remount if permissions are options")
---
 fs/tracefs/event_inode.c | 51 ++++++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 12 deletions(-)
fs/tracefs/event_inode.c +39 -12
index 55a40a730b10c..129d0f54ba62f 100644
@@ -305,33 +305,60 @@ static const struct file_operations eventfs_file_operations = {
 	.llseek		= generic_file_llseek,
 };
 
-/*
- * On a remount of tracefs, if UID or GID options are set, then
- * the mount point inode permissions should be used.
- * Reset the saved permission flags appropriately.
- */
-void eventfs_remount(struct tracefs_inode *ti, bool update_uid, bool update_gid)
+static void eventfs_set_attrs(struct eventfs_inode *ei, bool update_uid, kuid_t uid,
+			      bool update_gid, kgid_t gid, int level)
 {
-	struct eventfs_inode *ei = ti->private;
+	struct eventfs_inode *ei_child;
 
-	if (!ei)
+	/* Update events/<system>/<event> */
+	if (WARN_ON_ONCE(level > 3))
 		return;
 
-	if (update_uid)
+	if (update_uid) {
 		ei->attr.mode &= ~EVENTFS_SAVE_UID;
+		ei->attr.uid = uid;
+	}
 
-	if (update_gid)
+	if (update_gid) {
 		ei->attr.mode &= ~EVENTFS_SAVE_GID;
+		ei->attr.gid = gid;
+	}
+
+	list_for_each_entry(ei_child, &ei->children, list) {
+		eventfs_set_attrs(ei_child, update_uid, uid, update_gid, gid, level + 1);
+	}
 
 	if (!ei->entry_attrs)
 		return;
 
 	for (int i = 0; i < ei->nr_entries; i++) {
-		if (update_uid)
+		if (update_uid) {
 			ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_UID;
-		if (update_gid)
+			ei->entry_attrs[i].uid = uid;
+		}
+		if (update_gid) {
 			ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_GID;
+			ei->entry_attrs[i].gid = gid;
+		}
 	}
+
+}
+
+/*
+ * On a remount of tracefs, if UID or GID options are set, then
+ * the mount point inode permissions should be used.
+ * Reset the saved permission flags appropriately.
+ */
+void eventfs_remount(struct tracefs_inode *ti, bool update_uid, bool update_gid)
+{
+	struct eventfs_inode *ei = ti->private;
+
+	/* Only the events directory does the updates */
+	if (!ei || !ei->is_events || ei->is_freed)
+		return;
+
+	eventfs_set_attrs(ei, update_uid, ti->vfs_inode.i_uid,
+			  update_gid, ti->vfs_inode.i_gid, 0);
 }
 
 /* Return the evenfs_inode of the "events" directory */
Signature · 1 line
2.43.0
author maintainer
#89 lore raw

PATCH 79/281 .editorconfig: remove trim_trailing_whitespace option

In reply to Greg Kroah-Hartman

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

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

From: Greg Kroah-Hartman <[email protected]>

commit 7da9dfdd5a3dbfd3d2450d9c6a3d1d699d625c43 upstream.

Some editors (like the vim variants), when seeing "trim_whitespace" decide to do just that for all of the whitespace in the file you are saving, even if it is not on a line that you have modified. This plays havoc with diffs and is NOT something that should be intended.

As the "only trim whitespace on modified lines" is not part of the editorconfig standard yet, just delete these lines from the .editorconfig file so that we don't end up with diffs that are automatically rejected by maintainers for containing things they shouldn't.

Cc Danny Lin <[email protected]>
Cc Íñigo Huguet <[email protected]>
Cc Mickaël Salaün <[email protected]>
Cc Masahiro Yamada <[email protected]>
Fixes 5a602de99797 ("Add .editorconfig file for basic formatting")
---
 .editorconfig |    3 ---
 1 file changed, 3 deletions(-)
.editorconfig +0 -3
@@ -5,7 +5,6 @@ root = true
 [{*.{awk,c,dts,dtsi,dtso,h,mk,s,S},Kconfig,Makefile,Makefile.*}]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = true
 insert_final_newline = true
 indent_style = tab
 indent_size = 8
@@ -13,7 +12,6 @@ indent_size = 8
 [*.{json,py,rs}]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = true
 insert_final_newline = true
 indent_style = space
 indent_size = 4
@@ -26,7 +24,6 @@ indent_size = 8
 [*.yaml]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = unset
 insert_final_newline = true
 indent_style = space
 indent_size = 2
author maintainer
#90 lore raw

PATCH 80/281 io_uring/rsrc: dont lock while !TASK_RUNNING

In reply to Greg Kroah-Hartman

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

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

From: Pavel Begunkov <[email protected]>

commit 54559642b96116b45e4b5ca7fd9f7835b8561272 upstream.

There is a report of io_rsrc_ref_quiesce() locking a mutex while not TASK_RUNNING, which is due to forgetting restoring the state back after io_run_task_work_sig() and attempts to break out of the waiting loop.

do not call blocking ops when !TASK_RUNNING; state=1 set at [<ffffffff815d2494>] prepare_to_wait+0xa4/0x380 kernel/sched/wait.c:237

WARNING: CPU: 2 PID: 397056 at kernel/sched/core.c:10099
__might_sleep+0x114/0x160 kernel/sched/core.c:10099
RIP: 0010:__might_sleep+0x114/0x160 kernel/sched/core.c:10099
Call Trace:
 <TASK>
 __mutex_lock_common kernel/locking/mutex.c:585 [inline]
 __mutex_lock+0xb4/0x940 kernel/locking/mutex.c:752
 io_rsrc_ref_quiesce+0x590/0x940 io_uring/rsrc.c:253
 io_sqe_buffers_unregister+0xa2/0x340 io_uring/rsrc.c:799
 __io_uring_register io_uring/register.c:424 [inline]
 __do_sys_io_uring_register+0x5b9/0x2400 io_uring/register.c:613
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0xd8/0x270 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x6f/0x77
---
 io_uring/rsrc.c |    1 +
 1 file changed, 1 insertion(+)
io_uring/rsrc.c +1 -0
@@ -250,6 +250,7 @@ __cold static int io_rsrc_ref_quiesce(st
 
 		ret = io_run_task_work_sig(ctx);
 		if (ret < 0) {
+			__set_current_state(TASK_RUNNING);
 			mutex_lock(&ctx->uring_lock);
 			if (list_empty(&ctx->rsrc_ref_list))
 				ret = 0;
author maintainer
#91 lore raw

PATCH 81/281 io_uring: fix cancellation overwriting req->flags

In reply to Greg Kroah-Hartman

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

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

From: Pavel Begunkov <[email protected]>

commit f4a1254f2a076afb0edd473589bf40f9b4d36b41 upstream.

Only the current owner of a request is allowed to write into req->flags. Hence, the cancellation path should never touch it. Add a new field instead of the flag, move it into the 3rd cache line because it should always be initialised. poll_refs can move further as polling is an involved process anyway.

It's a minimal patch, in the future we can and should find a better place for it and remove now unused REQ_F_CANCEL_SEQ.

---
 include/linux/io_uring_types.h |    3 ++-
 io_uring/cancel.h              |    4 ++--
 io_uring/io_uring.c            |    1 +
 3 files changed, 5 insertions(+), 3 deletions(-)
include/linux/io_uring_types.h +2 -1
@@ -653,7 +653,7 @@ struct io_kiocb {
 	struct io_rsrc_node		*rsrc_node;
 
 	atomic_t			refs;
-	atomic_t			poll_refs;
+	bool				cancel_seq_set;
 	struct io_task_work		io_task_work;
 	/* for polled requests, i.e. IORING_OP_POLL_ADD and async armed poll */
 	struct hlist_node		hash_node;
@@ -662,6 +662,7 @@ struct io_kiocb {
 	/* opcode allocated if it needs to store data for async defer */
 	void				*async_data;
 	/* linked requests, IFF REQ_F_HARDLINK or REQ_F_LINK are set */
+	atomic_t			poll_refs;
 	struct io_kiocb			*link;
 	/* custom credentials, valid IFF REQ_F_CREDS is set */
 	const struct cred		*creds;
io_uring/cancel.h +2 -2
@@ -27,10 +27,10 @@ bool io_cancel_req_match(struct io_kiocb
 
 static inline bool io_cancel_match_sequence(struct io_kiocb *req, int sequence)
 {
-	if ((req->flags & REQ_F_CANCEL_SEQ) && sequence == req->work.cancel_seq)
+	if (req->cancel_seq_set && sequence == req->work.cancel_seq)
 		return true;
 
-	req->flags |= REQ_F_CANCEL_SEQ;
+	req->cancel_seq_set = true;
 	req->work.cancel_seq = sequence;
 	return false;
 }
io_uring/io_uring.c +1 -0
@@ -2211,6 +2211,7 @@ static int io_init_req(struct io_ring_ct
 	req->file = NULL;
 	req->rsrc_node = NULL;
 	req->task = current;
+	req->cancel_seq_set = false;
 
 	if (unlikely(opcode >= IORING_OP_LAST)) {
 		req->opcode = 0;
author maintainer
#92 lore raw

PATCH 82/281 USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages

In reply to Greg Kroah-Hartman

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

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

From: Alan Stern <[email protected]>

commit 22f00812862564b314784167a89f27b444f82a46 upstream.

The syzbot fuzzer found that the interrupt-URB completion callback in the cdc-wdm driver was taking too long, and the driver's immediate resubmission of interrupt URBs with -EPROTO status combined with the dummy-hcd emulation to cause a CPU lockup:

cdc_wdm 1-1:1.0: nonzero urb status received: -71
cdc_wdm 1-1:1.0: wdm_int_callback - 0 bytes

watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [syz-executor782:6625]
CPU#0 Utilization every 4s during lockup:
	#1:  98% system,	  0% softirq,	  3% hardirq,	  0% idle
	#2:  98% system,	  0% softirq,	  3% hardirq,	  0% idle
	#3:  98% system,	  0% softirq,	  3% hardirq,	  0% idle
	#4:  98% system,	  0% softirq,	  3% hardirq,	  0% idle
	#5:  98% system,	  1% softirq,	  3% hardirq,	  0% idle
Modules linked in:
irq event stamp: 73096
hardirqs last  enabled at (73095): [<ffff80008037bc00>] console_emit_next_record kernel/printk/printk.c:2935 [inline]
hardirqs last  enabled at (73095): [<ffff80008037bc00>] console_flush_all+0x650/0xb74 kernel/printk/printk.c:2994
hardirqs last disabled at (73096): [<ffff80008af10b00>] __el1_irq arch/arm64/kernel/entry-common.c:533 [inline]
hardirqs last disabled at (73096): [<ffff80008af10b00>] el1_interrupt+0x24/0x68 arch/arm64/kernel/entry-common.c:551
softirqs last  enabled at (73048): [<ffff8000801ea530>] softirq_handle_end kernel/softirq.c:400 [inline]
softirqs last  enabled at (73048): [<ffff8000801ea530>] handle_softirqs+0xa60/0xc34 kernel/softirq.c:582
softirqs last disabled at (73043): [<ffff800080020de8>] __do_softirq+0x14/0x20 kernel/softirq.c:588
CPU: 0 PID: 6625 Comm: syz-executor782 Tainted: G        W          6.10.0-rc2-syzkaller-g8867bbd4a056 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024

Testing showed that the problem did not occur if the two error messages -- the first two lines above -- were removed; apparently adding material to the kernel log takes a surprisingly large amount of time.

In any case, the best approach for preventing these lockups and to avoid spamming the log with thousands of error messages per second is to ratelimit the two dev_err() calls. Therefore we replace them with dev_err_ratelimited().

---
 drivers/usb/class/cdc-wdm.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/class/cdc-wdm.c +2 -2
@@ -266,14 +266,14 @@ static void wdm_int_callback(struct urb
 			dev_err(&desc->intf->dev, "Stall on int endpoint\n");
 			goto sw; /* halt is cleared in work */
 		default:
-			dev_err(&desc->intf->dev,
+			dev_err_ratelimited(&desc->intf->dev,
 				"nonzero urb status received: %d\n", status);
 			break;
 		}
 	}
 
 	if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
-		dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
+		dev_err_ratelimited(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
 			urb->actual_length);
 		goto exit;
 	}
author maintainer
#93 lore raw

PATCH 83/281 kcov, usb: disable interrupts in kcov_remote_start_usb_softirq

In reply to Greg Kroah-Hartman

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

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

From: Andrey Konovalov <[email protected]>

commit f85d39dd7ed89ffdd622bc1de247ffba8d961504 upstream.

After commit 8fea0c8fda30 ("usb: core: hcd: Convert from tasklet to BH workqueue"), usb_giveback_urb_bh() runs in the BH workqueue with interrupts enabled.

Thus, the remote coverage collection section in usb_giveback_urb_bh()-> __usb_hcd_giveback_urb() might be interrupted, and the interrupt handler might invoke __usb_hcd_giveback_urb() again.

This breaks KCOV, as it does not support nested remote coverage collection sections within the same context (neither in task nor in softirq).

Update kcov_remote_start/stop_usb_softirq() to disable interrupts for the duration of the coverage collection section to avoid nested sections in the softirq context (in addition to such in the task context, which are already handled).

---
 drivers/usb/core/hcd.c |   12 +++++++-----
 include/linux/kcov.h   |   47 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 45 insertions(+), 14 deletions(-)
drivers/usb/core/hcd.c +7 -5
@@ -1623,6 +1623,7 @@ static void __usb_hcd_giveback_urb(struc
 	struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
 	struct usb_anchor *anchor = urb->anchor;
 	int status = urb->unlinked;
+	unsigned long flags;
 
 	urb->hcpriv = NULL;
 	if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -1640,13 +1641,14 @@ static void __usb_hcd_giveback_urb(struc
 	/* pass ownership to the completion handler */
 	urb->status = status;
 	/*
-	 * This function can be called in task context inside another remote
-	 * coverage collection section, but kcov doesn't support that kind of
-	 * recursion yet. Only collect coverage in softirq context for now.
+	 * Only collect coverage in the softirq context and disable interrupts
+	 * to avoid scenarios with nested remote coverage collection sections
+	 * that KCOV does not support.
+	 * See the comment next to kcov_remote_start_usb_softirq() for details.
 	 */
-	kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
+	flags = kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
 	urb->complete(urb);
-	kcov_remote_stop_softirq();
+	kcov_remote_stop_softirq(flags);
 
 	usb_anchor_resume_wakeups(anchor);
 	atomic_dec(&urb->use_count);
include/linux/kcov.h +38 -9

67 lines not on this page · raw message

author maintainer
#94 lore raw

PATCH 84/281 USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected

In reply to Greg Kroah-Hartman

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

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

From: John Ernberg <[email protected]>

commit 8475ffcfb381a77075562207ce08552414a80326 upstream.

If no other USB HCDs are selected when compiling a small pure virutal machine, the Xen HCD driver cannot be built.

Fix it by traversing down host/ if CONFIG_USB_XEN_HCD is selected.

Fixes 494ed3997d75 ("usb: Introduce Xen pvUSB frontend (xen hcd)")
Cc [email protected] # v5.17+
---
 drivers/usb/Makefile |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/Makefile +1 -0
@@ -35,6 +35,7 @@ obj-$(CONFIG_USB_R8A66597_HCD)	+= host/
 obj-$(CONFIG_USB_FSL_USB2)	+= host/
 obj-$(CONFIG_USB_FOTG210_HCD)	+= host/
 obj-$(CONFIG_USB_MAX3421_HCD)	+= host/
+obj-$(CONFIG_USB_XEN_HCD)	+= host/
 
 obj-$(CONFIG_USB_C67X00_HCD)	+= c67x00/
 
author maintainer
#95 lore raw

PATCH 85/281 usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps

In reply to Greg Kroah-Hartman

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

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

From: Amit Sunil Dhamne <[email protected]>

commit e7e921918d905544500ca7a95889f898121ba886 upstream.

There could be a potential use-after-free case in tcpm_register_source_caps(). This could happen when:
* new (say invalid) source caps are advertised
* the existing source caps are unregistered
* tcpm_register_source_caps() returns with an error as usb_power_delivery_register_capabilities() fails

This causes port->partner_source_caps to hold on to the now freed source caps.

Reset port->partner_source_caps value to NULL after unregistering existing source caps.

---
 drivers/usb/typec/tcpm/tcpm.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/typec/tcpm/tcpm.c +3 -1
@@ -3014,8 +3014,10 @@ static int tcpm_register_source_caps(str
 	memcpy(caps.pdo, port->source_caps, sizeof(u32) * port->nr_source_caps);
 	caps.role = TYPEC_SOURCE;
 
-	if (cap)
+	if (cap) {
 		usb_power_delivery_unregister_capabilities(cap);
+		port->partner_source_caps = NULL;
+	}
 
 	cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps);
 	if (IS_ERR(cap))
author maintainer
#96 lore raw

PATCH 86/281 usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state

In reply to Greg Kroah-Hartman

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

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

From: Kyle Tso <[email protected]>

commit fc8fb9eea94d8f476e15f3a4a7addeb16b3b99d6 upstream.

Similar to what fixed in Commit a6fe37f428c1 ("usb: typec: tcpm: Skip hard reset when in error recovery"), the handling of the received Hard Reset has to be skipped during TOGGLING state.

[ 4086.021288] VBUS off
[ 4086.021295] pending state change SNK_READY -> SNK_UNATTACHED @ 650 ms [rev2 NONE_AMS]
[ 4086.022113] VBUS VSAFE0V
[ 4086.022117] state change SNK_READY -> SNK_UNATTACHED [rev2 NONE_AMS]
[ 4086.022447] VBUS off
[ 4086.022450] state change SNK_UNATTACHED -> SNK_UNATTACHED [rev2 NONE_AMS]
[ 4086.023060] VBUS VSAFE0V
[ 4086.023064] state change SNK_UNATTACHED -> SNK_UNATTACHED [rev2 NONE_AMS]
[ 4086.023070] disable BIST MODE TESTDATA
[ 4086.023766] disable vbus discharge ret:0
[ 4086.023911] Setting usb_comm capable false
[ 4086.028874] Setting voltage/current limit 0 mV 0 mA
[ 4086.028888] polarity 0
[ 4086.030305] Requesting mux state 0, usb-role 0, orientation 0
[ 4086.033539] Start toggling
[ 4086.038496] state change SNK_UNATTACHED -> TOGGLING [rev2 NONE_AMS]

// This Hard Reset is unexpected

[ 4086.038499] Received hard reset
[ 4086.038501] state change TOGGLING -> HARD_RESET_START [rev2 HARD_RESET]
Fixes f0690a25a140 ("staging: typec: USB Type-C Port Manager (tcpm)")
---
 drivers/usb/typec/tcpm/tcpm.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/typec/tcpm/tcpm.c +1 -0
@@ -6174,6 +6174,7 @@ static void _tcpm_pd_hard_reset(struct t
 		port->tcpc->set_bist_data(port->tcpc, false);
 
 	switch (port->state) {
+	case TOGGLING:
 	case ERROR_RECOVERY:
 	case PORT_RESET:
 	case PORT_RESET_WAIT_OFF:
author maintainer
#97 lore raw

PATCH 87/281 mei: me: release irq in mei_me_pci_resume error path

In reply to Greg Kroah-Hartman

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

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

From: Tomas Winkler <[email protected]>

commit 283cb234ef95d94c61f59e1cd070cd9499b51292 upstream.

The mei_me_pci_resume doesn't release irq on the error path, in case mei_start() fails.

Fixes 33ec08263147 ("mei: revamp mei reset state machine")
---
 drivers/misc/mei/pci-me.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/misc/mei/pci-me.c +3 -1
@@ -385,8 +385,10 @@ static int mei_me_pci_resume(struct devi
 	}
 
 	err = mei_restart(dev);
-	if (err)
+	if (err) {
+		free_irq(pdev->irq, dev);
 		return err;
+	}
 
 	/* Start timer if stopped in suspend */
 	schedule_delayed_work(&dev->timer_work, HZ);
author maintainer
#98 lore raw

PATCH 88/281 mei: vsc: Dont stop/restart mei device during system suspend/resume

In reply to Greg Kroah-Hartman

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

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

From: Wentong Wu <[email protected]>

commit 9b5e045029d8bded4c6979874ed3abc347c1415c upstream.

The dynamically created mei client device (mei csi) is used as one V4L2 sub device of the whole video pipeline, and the V4L2 connection graph is built by software node. The mei_stop() and mei_restart() will delete the old mei csi client device and create a new mei client device, which will cause the software node information saved in old mei csi device lost and the whole video pipeline will be broken.

Removing mei_stop()/mei_restart() during system suspend/resume can fix the issue above and won't impact hardware actual power saving logic.

---
 drivers/misc/mei/platform-vsc.c |   39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)
drivers/misc/mei/platform-vsc.c +15 -24
@@ -399,41 +399,32 @@ static void mei_vsc_remove(struct platfo
 
 static int mei_vsc_suspend(struct device *dev)
 {
-	struct mei_device *mei_dev = dev_get_drvdata(dev);
-	struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
+	struct mei_device *mei_dev;
+	int ret = 0;
 
-	mei_stop(mei_dev);
+	mei_dev = dev_get_drvdata(dev);
+	if (!mei_dev)
+		return -ENODEV;
 
-	mei_disable_interrupts(mei_dev);
+	mutex_lock(&mei_dev->device_lock);
 
-	vsc_tp_free_irq(hw->tp);
+	if (!mei_write_is_idle(mei_dev))
+		ret = -EAGAIN;
 
-	return 0;
+	mutex_unlock(&mei_dev->device_lock);
+
+	return ret;
 }
 
 static int mei_vsc_resume(struct device *dev)
 {
-	struct mei_device *mei_dev = dev_get_drvdata(dev);
-	struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
-	int ret;
-
-	ret = vsc_tp_request_irq(hw->tp);
-	if (ret)
-		return ret;
-
-	ret = mei_restart(mei_dev);
-	if (ret)
-		goto err_free;
+	struct mei_device *mei_dev;
 
-	/* start timer if stopped in suspend */
-	schedule_delayed_work(&mei_dev->timer_work, HZ);
+	mei_dev = dev_get_drvdata(dev);
+	if (!mei_dev)
+		return -ENODEV;
 
 	return 0;
-
-err_free:
-	vsc_tp_free_irq(hw->tp);
-
-	return ret;
 }
 
 static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume);
author maintainer
#99 lore raw

PATCH 89/281 tty: n_tty: Fix buffer offsets when lookahead is used

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

commit b19ab7ee2c4c1ec5f27c18413c3ab63907f7d55c upstream.

When lookahead has "consumed" some characters (la_count > 0), n_tty_receive_buf_standard() and n_tty_receive_buf_closing() for characters beyond the la_count are given wrong cp/fp offsets which leads to duplicating and losing some characters.

If la_count > 0, correct buffer pointers and make count consistent too (the latter is not strictly necessary to fix the issue but seems more logical to adjust all variables immediately to keep state consistent).

---
 drivers/tty/n_tty.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/tty/n_tty.c +16 -6
@@ -1619,15 +1619,25 @@ static void __receive_buf(struct tty_str
 	else if (ldata->raw || (L_EXTPROC(tty) && !preops))
 		n_tty_receive_buf_raw(tty, cp, fp, count);
 	else if (tty->closing && !L_EXTPROC(tty)) {
-		if (la_count > 0)
+		if (la_count > 0) {
 			n_tty_receive_buf_closing(tty, cp, fp, la_count, true);
-		if (count > la_count)
-			n_tty_receive_buf_closing(tty, cp, fp, count - la_count, false);
+			cp += la_count;
+			if (fp)
+				fp += la_count;
+			count -= la_count;
+		}
+		if (count > 0)
+			n_tty_receive_buf_closing(tty, cp, fp, count, false);
 	} else {
-		if (la_count > 0)
+		if (la_count > 0) {
 			n_tty_receive_buf_standard(tty, cp, fp, la_count, true);
-		if (count > la_count)
-			n_tty_receive_buf_standard(tty, cp, fp, count - la_count, false);
+			cp += la_count;
+			if (fp)
+				fp += la_count;
+			count -= la_count;
+		}
+		if (count > 0)
+			n_tty_receive_buf_standard(tty, cp, fp, count, false);
 
 		flush_echoes(tty);
 		if (tty->ops->flush_chars)
author maintainer
#100 lore raw

PATCH 90/281 serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level

In reply to Greg Kroah-Hartman

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

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

From: Doug Brown <[email protected]>

commit 5208e7ced520a813b4f4774451fbac4e517e78b2 upstream.

The FIFO is 64 bytes, but the FCR is configured to fire the TX interrupt when the FIFO is half empty (bit 3 = 0). Thus, we should only write 32 bytes when a TX interrupt occurs.

This fixes a problem observed on the PXA168 that dropped a bunch of TX bytes during large transmissions.

Fixes ab28f51c77cd ("serial: rewrite pxa2xx-uart to use 8250_core")
Cc stable <[email protected]>
---
 drivers/tty/serial/8250/8250_pxa.c |    1 +
 1 file changed, 1 insertion(+)
drivers/tty/serial/8250/8250_pxa.c +1 -0
@@ -125,6 +125,7 @@ static int serial_pxa_probe(struct platf
 	uart.port.iotype = UPIO_MEM32;
 	uart.port.regshift = 2;
 	uart.port.fifosize = 64;
+	uart.tx_loadsz = 32;
 	uart.dl_write = serial_pxa_dl_write;
 
 	ret = serial8250_register_8250_port(&uart);
author maintainer
#101 lore raw

PATCH 91/281 serial: port: Dont block system suspend even if bytes are left to xmit

In reply to Greg Kroah-Hartman

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

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

From: Douglas Anderson <[email protected]>

commit ca84cd379b45e9b1775b9e026f069a3a886b409d upstream.

Recently, suspend testing on sc7180-trogdor based devices has started to sometimes fail with messages like this:

port a88000.serial:0.0: PM: calling pm_runtime_force_suspend+0x0/0xf8 @ 28934, parent: a88000.serial:0 port a88000.serial:0.0: PM: dpm_run_callback(): pm_runtime_force_suspend+0x0/0xf8 returns -16 port a88000.serial:0.0: PM: pm_runtime_force_suspend+0x0/0xf8 returned -16 after 33 usecs port a88000.serial:0.0: PM: failed to suspend: error -16

I could reproduce these problems by logging in via an agetty on the debug serial port (which was _not_ used for kernel console) and running:
cat /var/log/messages
...and then (via an SSH session) forcing a few suspend/resume cycles.

Tracing through the code and doing some printf()-based debugging shows that the -16 (-EBUSY) comes from the recently added serial_port_runtime_suspend().

The idea of the serial_port_runtime_suspend() function is to prevent the port from being _runtime_ suspended if it still has bytes left to transmit. Having bytes left to transmit isn't a reason to block _system_ suspend, though. If a serdev device in the kernel needs to block system suspend it should block its own suspend and it can use serdev_device_wait_until_sent() to ensure bytes are sent.

The DEFINE_RUNTIME_DEV_PM_OPS() used by the serial_port code means that the system suspend function will be pm_runtime_force_suspend(). In pm_runtime_force_suspend() we can see that before calling the runtime suspend function we'll call pm_runtime_disable(). This should be a reliable way to detect that we're called from system suspend and that we shouldn't look for busyness.

---
 drivers/tty/serial/serial_port.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/tty/serial/serial_port.c +7 -0
@@ -63,6 +63,13 @@ static int serial_port_runtime_suspend(s
 	if (port->flags & UPF_DEAD)
 		return 0;
 
+	/*
+	 * Nothing to do on pm_runtime_force_suspend(), see
+	 * DEFINE_RUNTIME_DEV_PM_OPS.
+	 */
+	if (!pm_runtime_enabled(dev))
+		return 0;
+
 	uart_port_lock_irqsave(port, &flags);
 	if (!port_dev->tx_enabled) {
 		uart_port_unlock_irqrestore(port, flags);
author maintainer
#102 lore raw

PATCH 92/281 landlock: Fix d_parent walk

In reply to Greg Kroah-Hartman

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

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

From: Mickaël Salaün <[email protected]>

commit 88da52ccd66e65f2e63a6c35c9dff55d448ef4dc upstream.

The WARN_ON_ONCE() in collect_domain_accesses() can be triggered when trying to link a root mount point. This cannot work in practice because this directory is mounted, but the VFS check is done after the call to security_path_link().

Do not use source directory's d_parent when the source directory is the mount point.

Cc Günther Noack <[email protected]>
Cc Paul Moore <[email protected]>
Reported-by [email protected]
Fixes b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
[mic: Fix commit message]
---
 security/landlock/fs.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
security/landlock/fs.c +11 -2
@@ -950,6 +950,7 @@ static int current_check_refer_path(stru
 	bool allow_parent1, allow_parent2;
 	access_mask_t access_request_parent1, access_request_parent2;
 	struct path mnt_dir;
+	struct dentry *old_parent;
 	layer_mask_t layer_masks_parent1[LANDLOCK_NUM_ACCESS_FS] = {},
 		     layer_masks_parent2[LANDLOCK_NUM_ACCESS_FS] = {};
 
@@ -997,9 +998,17 @@ static int current_check_refer_path(stru
 	mnt_dir.mnt = new_dir->mnt;
 	mnt_dir.dentry = new_dir->mnt->mnt_root;
 
+	/*
+	 * old_dentry may be the root of the common mount point and
+	 * !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
+	 * OPEN_TREE_CLONE).  We do not need to call dget(old_parent) because
+	 * we keep a reference to old_dentry.
+	 */
+	old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
+						      old_dentry->d_parent;
+
 	/* new_dir->dentry is equal to new_dentry->d_parent */
-	allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry,
-						old_dentry->d_parent,
+	allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry, old_parent,
 						&layer_masks_parent1);
 	allow_parent2 = collect_domain_accesses(
 		dom, mnt_dir.dentry, new_dir->dentry, &layer_masks_parent2);
author maintainer
#103 lore raw

PATCH 93/281 jfs: xattr: fix buffer overflow for invalid xattr

In reply to Greg Kroah-Hartman

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

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

From: Greg Kroah-Hartman <[email protected]>

commit 7c55b78818cfb732680c4a72ab270cc2d2ee3d0f upstream.

When an xattr size is not what is expected, it is printed out to the kernel log in hex format as a form of debugging. But when that xattr size is bigger than the expected size, printing it out can cause an access off the end of the buffer.

Fix this all up by properly restricting the size of the debug hex dump in the kernel log.

---
 fs/jfs/xattr.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/jfs/xattr.c +3 -1
@@ -557,9 +557,11 @@ static int ea_get(struct inode *inode, s
 
       size_check:
 	if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
+		int size = min_t(int, EALIST_SIZE(ea_buf->xattr), ea_size);
+
 		printk(KERN_ERR "ea_get: invalid extended attribute\n");
 		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
-				     ea_buf->xattr, ea_size, 1);
+				     ea_buf->xattr, size, 1);
 		ea_release(inode, ea_buf);
 		rc = -EIO;
 		goto clean_up;
author maintainer
#104 lore raw

PATCH 94/281 xhci: Set correct transferred length for cancelled bulk transfers

In reply to Greg Kroah-Hartman

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

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

From: Mathias Nyman <[email protected]>

commit f0260589b439e2637ad54a2b25f00a516ef28a57 upstream.

The transferred length is set incorrectly for cancelled bulk transfer TDs in case the bulk transfer ring stops on the last transfer block with a 'Stop - Length Invalid' completion code.

length essentially ends up being set to the requested length:
urb->actual_length = urb->transfer_buffer_length

Length for 'Stop - Length Invalid' cases should be the sum of all TRB transfer block lengths up to the one the ring stopped on, _excluding_ the one stopped on.

Fix this by always summing up TRB lengths for 'Stop - Length Invalid' bulk cases.

This issue was discovered by Alan Stern while debugging
https://bugzilla.kernel.org/show_bug.cgi?id=218890, but does not solve that bug. Issue is older than 4.10 kernel but fix won't apply to those due to major reworks in that area.

---
 drivers/usb/host/xhci-ring.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-ring.c +2 -3
@@ -2535,9 +2535,8 @@ static int process_bulk_intr_td(struct x
 		goto finish_td;
 	case COMP_STOPPED_LENGTH_INVALID:
 		/* stopped on ep trb with invalid length, exclude it */
-		ep_trb_len	= 0;
-		remaining	= 0;
-		break;
+		td->urb->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb);
+		goto finish_td;
 	case COMP_USB_TRANSACTION_ERROR:
 		if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
 		    (ep->err_count++ > MAX_SOFT_RETRY) ||
author maintainer
#105 lore raw

PATCH 95/281 xhci: Apply reset resume quirk to Etron EJ188 xHCI host

In reply to Greg Kroah-Hartman

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

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

From: Kuangyi Chiang <[email protected]>

commit 17bd54555c2aaecfdb38e2734149f684a73fa584 upstream.

As described in commit c877b3b2ad5c ("xhci: Add reset on resume quirk for asrock p67 host"), EJ188 have the same issue as EJ168, where completely dies on resume. So apply XHCI_RESET_ON_RESUME quirk to EJ188 as well.

---
 drivers/usb/host/xhci-pci.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/usb/host/xhci-pci.c +5 -0
@@ -36,6 +36,7 @@
 
 #define PCI_VENDOR_ID_ETRON		0x1b6f
 #define PCI_DEVICE_ID_EJ168		0x7023
+#define PCI_DEVICE_ID_EJ188		0x7052
 
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31
@@ -402,6 +403,10 @@ static void xhci_pci_quirks(struct devic
 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 		xhci->quirks |= XHCI_BROKEN_STREAMS;
 	}
+	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+			pdev->device == PCI_DEVICE_ID_EJ188)
+		xhci->quirks |= XHCI_RESET_ON_RESUME;
+
 	if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
 	    pdev->device == 0x0014) {
 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
author maintainer
#106 lore raw

PATCH 96/281 xhci: Handle TD clearing for multiple streams case

In reply to Greg Kroah-Hartman

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

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

From: Hector Martin <[email protected]>

commit 5ceac4402f5d975e5a01c806438eb4e554771577 upstream.

When multiple streams are in use, multiple TDs might be in flight when an endpoint is stopped. We need to issue a Set TR Dequeue Pointer for each, to ensure everything is reset properly and the caches cleared. Change the logic so that any N>1 TDs found active for different streams are deferred until after the first one is processed, calling xhci_invalidate_cancelled_tds() again from xhci_handle_cmd_set_deq() to queue another command until we are done with all of them. Also change the error/"should never happen" paths to ensure we at least clear any affected TDs, even if we can't issue a command to clear the hardware cache, and complain loudly with an xhci_warn() if this ever happens.

This problem case dates back to commit e9df17eb1408 ("USB: xhci: Correct assumptions about number of rings per endpoint.") early on in the XHCI driver's life, when stream support was first added.
It was then identified but not fixed nor made into a warning in commit 674f8438c121 ("xhci: split handling halted endpoints into two steps"), which added a FIXME comment for the problem case (without materially changing the behavior as far as I can tell, though the new logic made the problem more obvious).

Then later, in commit 94f339147fc3 ("xhci: Fix failure to give back some cached cancelled URBs."), it was acknowledged again.

[Mathias: commit 94f339147fc3 ("xhci: Fix failure to give back some cached cancelled URBs.") was a targeted regression fix to the previously mentioned patch. Users reported issues with usb stuck after unmounting/disconnecting UAS devices. This rolled back the TD clearing of multiple streams to its original state.]

Apparently the commit author was aware of the problem (yet still chose to submit it): It was still mentioned as a FIXME, an xhci_dbg() was added to log the problem condition, and the remaining issue was mentioned in the commit description. The choice of making the log type xhci_dbg() for what is, at this point, a completely unhandled and known broken condition is puzzling and unfortunate, as it guarantees that no actual users would see the log in production, thereby making it nigh undebuggable (indeed, even if you turn on DEBUG, the message doesn't really hint at there being a problem at all).

It took me *months* of random xHC crashes to finally find a reliable repro and be able to do a deep dive debug session, which could all have been avoided had this unhandled, broken condition been actually reported with a warning, as it should have been as a bug intentionally left in unfixed (never mind that it shouldn't have been left in at all).

Quoted 2 lines

Another fix to solve clearing the caches of all stream rings with cancelled TDs is needed, but not as urgent.

3 years after that statement and 14 years after the original bug was introduced, I think it's finally time to fix it. And maybe next time let's not leave bugs unfixed (that are actually worse than the original bug), and let's actually get people to review kernel commits please.

Fixes xHC crashes and IOMMU faults with UAS devices when handling errors/faults. Easiest repro is to use hdparm to mark an early sector (e.g. 1024) on a disk as bad, then cat /dev/sdX > /dev/null in a loop. At least in the case of JMicron controllers, the read errors end up having to cancel two TDs (for two queued requests to different streams) and the one that didn't get cleared properly ends up faulting the xHC entirely when it tries to access DMA pages that have since been unmapped, referred to by the stale TDs. This normally happens quickly (after two or three loops). After this fix, I left the cat in a loop running overnight and experienced no xHC failures, with all read errors recovered properly. Repro'd and tested on an Apple M1 Mac Mini (dwc3 host).

On systems without an IOMMU, this bug would instead silently corrupt freed memory, making this a security bug (even on systems with IOMMUs this could silently corrupt memory belonging to other USB devices on the same controller, so it's still a security bug). Given that the kernel autoprobes partition tables, I'm pretty sure a malicious USB device pretending to be a UAS device and reporting an error with the right timing could deliberately trigger a UAF and write to freed memory, with no user action.

[Mathias: Commit message and code comment edit, original at:]
https://lore.kernel.org/linux-usb/[email protected]/

Fixes e9df17eb1408 ("USB: xhci: Correct assumptions about number of rings per endpoint.")
Fixes 94f339147fc3 ("xhci: Fix failure to give back some cached cancelled URBs.")
Fixes 674f8438c121 ("xhci: split handling halted endpoints into two steps")
---
 drivers/usb/host/xhci-ring.c |   54 ++++++++++++++++++++++++++++++++++---------
 drivers/usb/host/xhci.h      |    1 
 2 files changed, 44 insertions(+), 11 deletions(-)
drivers/usb/host/xhci-ring.c +43 -11
@@ -1034,13 +1034,27 @@ static int xhci_invalidate_cancelled_tds
 				break;
 			case TD_DIRTY: /* TD is cached, clear it */
 			case TD_HALTED:
+			case TD_CLEARING_CACHE_DEFERRED:
+				if (cached_td) {
+					if (cached_td->urb->stream_id != td->urb->stream_id) {
+						/* Multiple streams case, defer move dq */
+						xhci_dbg(xhci,
+							 "Move dq deferred: stream %u URB %p\n",
+							 td->urb->stream_id, td->urb);
+						td->cancel_status = TD_CLEARING_CACHE_DEFERRED;
+						break;
+					}
+
+					/* Should never happen, but clear the TD if it does */
+					xhci_warn(xhci,
+						  "Found multiple active URBs %p and %p in stream %u?\n",
+						  td->urb, cached_td->urb,
+						  td->urb->stream_id);
+					td_to_noop(xhci, ring, cached_td, false);
+					cached_td->cancel_status = TD_CLEARED;
+				}
+
 				td->cancel_status = TD_CLEARING_CACHE;
-				if (cached_td)
-					/* FIXME  stream case, several stopped rings */
-					xhci_dbg(xhci,
-						 "Move dq past stream %u URB %p instead of stream %u URB %p\n",
-						 td->urb->stream_id, td->urb,
-						 cached_td->urb->stream_id, cached_td->urb);
 				cached_td = td;
 				break;
 			}
@@ -1060,10 +1074,16 @@ static int xhci_invalidate_cancelled_tds
 	if (err) {
 		/* Failed to move past cached td, just set cached TDs to no-op */
 		list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) {
-			if (td->cancel_status != TD_CLEARING_CACHE)
+			/*
+			 * Deferred TDs need to have the deq pointer set after the above command
+			 * completes, so if that failed we just give up on all of them (and
+			 * complain loudly since this could cause issues due to caching).
+			 */
+			if (td->cancel_status != TD_CLEARING_CACHE &&
+			    td->cancel_status != TD_CLEARING_CACHE_DEFERRED)
 				continue;
-			xhci_dbg(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n",
-				 td->urb);
+			xhci_warn(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n",
+				  td->urb);
 			td_to_noop(xhci, ring, td, false);
 			td->cancel_status = TD_CLEARED;
 		}
@@ -1350,6 +1370,7 @@ static void xhci_handle_cmd_set_deq(stru
 	struct xhci_ep_ctx *ep_ctx;
 	struct xhci_slot_ctx *slot_ctx;
 	struct xhci_td *td, *tmp_td;
+	bool deferred = false;
 
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 	stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
@@ -1436,6 +1457,8 @@ static void xhci_handle_cmd_set_deq(stru
 			xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n",
 				 __func__, td->urb);
 			xhci_td_cleanup(ep->xhci, td, ep_ring, td->status);
+		} else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) {
+			deferred = true;
 		} else {
 			xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n",
 				 __func__, td->urb, td->cancel_status);
@@ -1445,8 +1468,17 @@ cleanup:
 	ep->ep_state &= ~SET_DEQ_PENDING;
 	ep->queued_deq_seg = NULL;
 	ep->queued_deq_ptr = NULL;
-	/* Restart any rings with pending URBs */
-	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+
+	if (deferred) {
+		/* We have more streams to clear */
+		xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n",
+			 __func__);
+		xhci_invalidate_cancelled_tds(ep);
+	} else {
+		/* Restart any rings with pending URBs */
+		xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__);
+		ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+	}
 }
 
 static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
drivers/usb/host/xhci.h +1 -0
@@ -1276,6 +1276,7 @@ enum xhci_cancelled_td_status {
 	TD_DIRTY = 0,
 	TD_HALTED,
 	TD_CLEARING_CACHE,
+	TD_CLEARING_CACHE_DEFERRED,
 	TD_CLEARED,
 };
 
author maintainer
#107 lore raw

PATCH 97/281 xhci: Apply broken streams quirk to Etron EJ188 xHCI host

In reply to Greg Kroah-Hartman

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

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

From: Kuangyi Chiang <[email protected]>

commit 91f7a1524a92c70ffe264db8bdfa075f15bbbeb9 upstream.

As described in commit 8f873c1ff4ca ("xhci: Blacklist using streams on the Etron EJ168 controller"), EJ188 have the same issue as EJ168, where Streams do not work reliable on EJ188. So apply XHCI_BROKEN_STREAMS quirk to EJ188 as well.

---
 drivers/usb/host/xhci-pci.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +3 -1
@@ -404,8 +404,10 @@ static void xhci_pci_quirks(struct devic
 		xhci->quirks |= XHCI_BROKEN_STREAMS;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
-			pdev->device == PCI_DEVICE_ID_EJ188)
+			pdev->device == PCI_DEVICE_ID_EJ188) {
 		xhci->quirks |= XHCI_RESET_ON_RESUME;
+		xhci->quirks |= XHCI_BROKEN_STREAMS;
+	}
 
 	if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
 	    pdev->device == 0x0014) {
author maintainer
#108 lore raw

PATCH 98/281 thunderbolt: debugfs: Fix margin debugfs node creation condition

In reply to Greg Kroah-Hartman

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

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

From: Aapo Vienamo <[email protected]>

commit 985cfe501b74f214905ab4817acee0df24627268 upstream.

The margin debugfs node controls the "Enable Margin Test" field of the lane margining operations. This field selects between either low or high voltage margin values for voltage margin test or left or right timing margin values for timing margin test.

According to the USB4 specification, whether or not the "Enable Margin Test" control applies, depends on the values of the "Independent High/Low Voltage Margin" or "Independent Left/Right Timing Margin" capability fields for voltage and timing margin tests respectively. The pre-existing condition enabled the debugfs node also in the case where both low/high or left/right margins are returned, which is incorrect. This change only enables the debugfs node in question, if the specific required capability values are met.

Fixes d0f1e0c2a699 ("thunderbolt: Add support for receiver lane margining")
---
 drivers/thunderbolt/debugfs.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/thunderbolt/debugfs.c +3 -2
@@ -943,8 +943,9 @@ static void margining_port_init(struct t
 	debugfs_create_file("run", 0600, dir, port, &margining_run_fops);
 	debugfs_create_file("results", 0600, dir, port, &margining_results_fops);
 	debugfs_create_file("test", 0600, dir, port, &margining_test_fops);
-	if (independent_voltage_margins(usb4) ||
-	    (supports_time(usb4) && independent_time_margins(usb4)))
+	if (independent_voltage_margins(usb4) == USB4_MARGIN_CAP_0_VOLTAGE_HL ||
+	    (supports_time(usb4) &&
+	     independent_time_margins(usb4) == USB4_MARGIN_CAP_1_TIME_LR))
 		debugfs_create_file("margin", 0600, dir, port, &margining_margin_fops);
 }
 
author maintainer
#109 lore raw

PATCH 99/281 ata: libata-scsi: Set the RMB bit only for removable media devices

In reply to Greg Kroah-Hartman

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

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

From: Damien Le Moal <[email protected]>

commit a6a75edc8669a4f030546c7390808ef0cc034742 upstream.

The SCSI Removable Media Bit (RMB) should only be set for removable media, where the device stays and the media changes, e.g. CD-ROM or floppy.

The ATA removable media device bit is obsoleted since ATA-8 ACS (2006), but before that it was used to indicate that the device can have its media removed (while the device stays).

Commit 8a3e33cf92c7 ("ata: ahci: find eSATA ports and flag them as removable") introduced a change to set the RMB bit if the port has either the eSATA bit or the hot-plug capable bit set. The reasoning was that the author wanted his eSATA ports to get treated like a USB stick.

This is however wrong. See "20-082r23SPC-6: Removable Medium Bit Expectations" which has since been integrated to SPC, which states that:

"""
Reports have been received that some USB Memory Stick device servers set the removable medium (RMB) bit to one. The rub comes when the medium is actually removed, because... The device server is removed concurrently with the medium removal. If there is no device server, then there is no device server that is waiting to have removable medium inserted.

Sufficient numbers of SCSI analysts see such a device:
- not as a device that supports removable medium; but
- as a removable, hot pluggable device.
"""

The definition of the RMB bit in the SPC specification has since been clarified to match this.

Thus, a USB stick should not have the RMB bit set (and neither shall an eSATA nor a hot-plug capable port).

Commit dc8b4afc4a04 ("ata: ahci: don't mark HotPlugCapable Ports as external/removable") then changed so that the RMB bit is only set for the eSATA bit (and not for the hot-plug capable bit), because of a lot of bug reports of SATA devices were being automounted by udisks. However, treating eSATA and hot-plug capable ports differently is not correct.

Quoted 1 line

From the AHCI 1.3.1 spec:

Hot Plug Capable Port (HPCP): When set to '1', indicates that this port's signal and power connectors are externally accessible via a joint signal and power connector for blindmate device hot plug.

So a hot-plug capable port is an external port, just like commit 45b96d65ec68 ("ata: ahci: a hotplug capable port is an external port") claims.

In order to not violate the SPC specification, modify the SCSI INQUIRY data to only set the RMB bit if the ATA device can have its media removed.

This fixes a reported problem where GNOME/udisks was automounting devices connected to hot-plug capable ports.

---
 drivers/ata/libata-scsi.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/ata/libata-scsi.c +4 -4
@@ -1828,11 +1828,11 @@ static unsigned int ata_scsiop_inq_std(s
 		2
 	};
 
-	/* set scsi removable (RMB) bit per ata bit, or if the
-	 * AHCI port says it's external (Hotplug-capable, eSATA).
+	/*
+	 * Set the SCSI Removable Media Bit (RMB) if the ATA removable media
+	 * device bit (obsolete since ATA-8 ACS) is set.
 	 */
-	if (ata_id_removable(args->id) ||
-	    (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
+	if (ata_id_removable(args->id))
 		hdr[1] |= (1 << 7);
 
 	if (args->dev->class == ATA_DEV_ZAC) {
author maintainer
#110 lore raw

PATCH 100/281 scsi: core: Disable CDL by default

In reply to Greg Kroah-Hartman

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

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

From: Damien Le Moal <[email protected]>

commit 52912ca87e2b810e5acdcdc452593d30c9187d8f upstream.

For SCSI devices supporting the Command Duration Limits feature set, the user can enable/disable this feature use through the sysfs device attribute "cdl_enable". This attribute modification triggers a call to scsi_cdl_enable() to enable and disable the feature for ATA devices and set the scsi device cdl_enable field to the user provided bool value. For SCSI devices supporting CDL, the feature set is always enabled and scsi_cdl_enable() is reduced to setting the cdl_enable field.

However, for ATA devices, a drive may spin-up with the CDL feature enabled by default. But the SCSI device cdl_enable field is always initialized to false (CDL disabled), regardless of the actual device CDL feature state. For ATA devices managed by libata (or libsas), libata-core always disables the CDL feature set when the device is attached, thus syncing the state of the CDL feature on the device and of the SCSI device cdl_enable field. However, for ATA devices connected to a SAS HBA, the CDL feature is not disabled on scan for ATA devices that have this feature enabled by default, leading to an inconsistent state of the feature on the device with the SCSI device cdl_enable field.

Avoid this inconsistency by adding a call to scsi_cdl_enable() in scsi_cdl_check() to make sure that the device-side state of the CDL feature set always matches the scsi device cdl_enable field state. This implies that CDL will always be disabled for ATA devices connected to SAS HBAs, which is consistent with libata/libsas initialization of the device.

---
 drivers/scsi/scsi.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/scsi/scsi.c +7 -0
@@ -673,6 +673,13 @@ void scsi_cdl_check(struct scsi_device *
 		sdev->use_10_for_rw = 0;
 
 		sdev->cdl_supported = 1;
+
+		/*
+		 * If the device supports CDL, make sure that the current drive
+		 * feature status is consistent with the user controlled
+		 * cdl_enable state.
+		 */
+		scsi_cdl_enable(sdev, sdev->cdl_enable);
 	} else {
 		sdev->cdl_supported = 0;
 	}
author maintainer
#111 lore raw

PATCH 101/281 scsi: mpi3mr: Fix ATA NCQ priority support

In reply to Greg Kroah-Hartman

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

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

From: Damien Le Moal <[email protected]>

commit 90e6f08915ec6efe46570420412a65050ec826b2 upstream.

The function mpi3mr_qcmd() of the mpi3mr driver is able to indicate to the HBA if a read or write command directed at an ATA device should be translated to an NCQ read/write command with the high prioiryt bit set when the request uses the RT priority class and the user has enabled NCQ priority through sysfs.

However, unlike the mpt3sas driver, the mpi3mr driver does not define the sas_ncq_prio_supported and sas_ncq_prio_enable sysfs attributes, so the ncq_prio_enable field of struct mpi3mr_sdev_priv_data is never actually set and NCQ Priority cannot ever be used.

Fix this by defining these missing atributes to allow a user to check if an ATA device supports NCQ priority and to enable/disable the use of NCQ priority. To do this, lift the function scsih_ncq_prio_supp() out of the mpt3sas driver and make it the generic SCSI SAS transport function sas_ata_ncq_prio_supported(). Nothing in that function is hardware specific, so this function can be used in both the mpt3sas driver and the mpi3mr driver.

---
 drivers/scsi/mpi3mr/mpi3mr_app.c     |   62 +++++++++++++++++++++++++++++++++++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |    3 -
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |    4 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   23 ------------
 drivers/scsi/scsi_transport_sas.c    |   23 ++++++++++++
 include/scsi/scsi_transport_sas.h    |    2 +
 6 files changed, 89 insertions(+), 28 deletions(-)
drivers/scsi/mpi3mr/mpi3mr_app.c +62 -0
@@ -2158,10 +2158,72 @@ persistent_id_show(struct device *dev, s
 }
 static DEVICE_ATTR_RO(persistent_id);
 
+/**
+ * sas_ncq_prio_supported_show - Indicate if device supports NCQ priority
+ * @dev: pointer to embedded device
+ * @attr: sas_ncq_prio_supported attribute descriptor
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' sdev attribute, only works with SATA devices
+ */
+static ssize_t
+sas_ncq_prio_supported_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+
+	return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
+}
+static DEVICE_ATTR_RO(sas_ncq_prio_supported);
+
+/**
+ * sas_ncq_prio_enable_show - send prioritized io commands to device
+ * @dev: pointer to embedded device
+ * @attr: sas_ncq_prio_enable attribute descriptor
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read/write' sdev attribute, only works with SATA devices
+ */
+static ssize_t
+sas_ncq_prio_enable_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct mpi3mr_sdev_priv_data *sdev_priv_data =  sdev->hostdata;
+
+	if (!sdev_priv_data)
+		return 0;
+
+	return sysfs_emit(buf, "%d\n", sdev_priv_data->ncq_prio_enable);
+}
+
+static ssize_t
+sas_ncq_prio_enable_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct mpi3mr_sdev_priv_data *sdev_priv_data =  sdev->hostdata;
+	bool ncq_prio_enable = 0;
+
+	if (kstrtobool(buf, &ncq_prio_enable))
+		return -EINVAL;
+
+	if (!sas_ata_ncq_prio_supported(sdev))
+		return -EINVAL;
+
+	sdev_priv_data->ncq_prio_enable = ncq_prio_enable;
+
+	return strlen(buf);
+}
+static DEVICE_ATTR_RW(sas_ncq_prio_enable);
+
 static struct attribute *mpi3mr_dev_attrs[] = {
 	&dev_attr_sas_address.attr,
 	&dev_attr_device_handle.attr,
 	&dev_attr_persistent_id.attr,
+	&dev_attr_sas_ncq_prio_supported.attr,
+	&dev_attr_sas_ncq_prio_enable.attr,
 	NULL,
 };
 
drivers/scsi/mpt3sas/mpt3sas_base.h +0 -3
@@ -2048,9 +2048,6 @@ void
 mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request);
 
-/* NCQ Prio Handling Check */
-bool scsih_ncq_prio_supp(struct scsi_device *sdev);
-
 void mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_init_debugfs(void);
drivers/scsi/mpt3sas/mpt3sas_ctl.c +2 -2
@@ -4088,7 +4088,7 @@ sas_ncq_prio_supported_show(struct devic
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 
-	return sysfs_emit(buf, "%d\n", scsih_ncq_prio_supp(sdev));
+	return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
 }
 static DEVICE_ATTR_RO(sas_ncq_prio_supported);
 
@@ -4123,7 +4123,7 @@ sas_ncq_prio_enable_store(struct device
 	if (kstrtobool(buf, &ncq_prio_enable))
 		return -EINVAL;
 
-	if (!scsih_ncq_prio_supp(sdev))
+	if (!sas_ata_ncq_prio_supported(sdev))
 		return -EINVAL;
 
 	sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;
drivers/scsi/mpt3sas/mpt3sas_scsih.c +0 -23
@@ -12573,29 +12573,6 @@ scsih_pci_mmio_enabled(struct pci_dev *p
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
-/**
- * scsih_ncq_prio_supp - Check for NCQ command priority support
- * @sdev: scsi device struct
- *
- * This is called when a user indicates they would like to enable
- * ncq command priorities. This works only on SATA devices.
- */
-bool scsih_ncq_prio_supp(struct scsi_device *sdev)
-{
-	struct scsi_vpd *vpd;
-	bool ncq_prio_supp = false;
-
-	rcu_read_lock();
-	vpd = rcu_dereference(sdev->vpd_pg89);
-	if (!vpd || vpd->len < 214)
-		goto out;
-
-	ncq_prio_supp = (vpd->data[213] >> 4) & 1;
-out:
-	rcu_read_unlock();
-
-	return ncq_prio_supp;
-}
 /*
  * The pci device ids are defined in mpi/mpi2_cnfg.h.
  */
drivers/scsi/scsi_transport_sas.c +23 -0
@@ -416,6 +416,29 @@ unsigned int sas_is_tlr_enabled(struct s
 }
 EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
 
+/**
+ * sas_ata_ncq_prio_supported - Check for ATA NCQ command priority support
+ * @sdev: SCSI device
+ *
+ * Check if an ATA device supports NCQ priority using VPD page 89h (ATA
+ * Information). Since this VPD page is implemented only for ATA devices,
+ * this function always returns false for SCSI devices.
+ */
+bool sas_ata_ncq_prio_supported(struct scsi_device *sdev)
+{
+	struct scsi_vpd *vpd;
+	bool ncq_prio_supported = false;
+
+	rcu_read_lock();
+	vpd = rcu_dereference(sdev->vpd_pg89);
+	if (vpd && vpd->len >= 214)
+		ncq_prio_supported = (vpd->data[213] >> 4) & 1;
+	rcu_read_unlock();
+
+	return ncq_prio_supported;
+}
+EXPORT_SYMBOL_GPL(sas_ata_ncq_prio_supported);
+
 /*
  * SAS Phy attributes
  */
include/scsi/scsi_transport_sas.h +2 -0
@@ -200,6 +200,8 @@ unsigned int sas_is_tlr_enabled(struct s
 void sas_disable_tlr(struct scsi_device *);
 void sas_enable_tlr(struct scsi_device *);
 
+bool sas_ata_ncq_prio_supported(struct scsi_device *sdev);
+
 extern struct sas_rphy *sas_end_device_alloc(struct sas_port *);
 extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type);
 void sas_rphy_free(struct sas_rphy *);
author maintainer
#112 lore raw

PATCH 102/281 scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory

In reply to Greg Kroah-Hartman

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

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

From: Breno Leitao <[email protected]>

commit 4254dfeda82f20844299dca6c38cbffcfd499f41 upstream.

There is a potential out-of-bounds access when using test_bit() on a single word. The test_bit() and set_bit() functions operate on long values, and when testing or setting a single word, they can exceed the word boundary. KASAN detects this issue and produces a dump:

	 BUG: KASAN: slab-out-of-bounds in _scsih_add_device.constprop.0 (./arch/x86/include/asm/bitops.h:60 ./include/asm-generic/bitops/instrumented-atomic.h:29 drivers/scsi/mpt3sas/mpt3sas_scsih.c:7331) mpt3sas

	 Write of size 8 at addr ffff8881d26e3c60 by task kworker/u1536:2/2965

For full log, please look at [1].

Make the allocation at least the size of sizeof(unsigned long) so that set_bit() and test_bit() have sufficient room for read/write operations without overwriting unallocated memory.

[1] Link: https://lore.kernel.org/all/[email protected]/

Fixes c696f7b83ede ("scsi: mpt3sas: Implement device_remove_in_progress check in IOCTL path")
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/scsi/mpt3sas/mpt3sas_base.c +19 -0
@@ -8512,6 +8512,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPT
 	ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
 	if (ioc->facts.MaxDevHandle % 8)
 		ioc->pd_handles_sz++;
+	/*
+	 * pd_handles_sz should have, at least, the minimal room for
+	 * set_bit()/test_bit(), otherwise out-of-memory touch may occur.
+	 */
+	ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long));
+
 	ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
 	    GFP_KERNEL);
 	if (!ioc->pd_handles) {
@@ -8529,6 +8535,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPT
 	ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
 	if (ioc->facts.MaxDevHandle % 8)
 		ioc->pend_os_device_add_sz++;
+
+	/*
+	 * pend_os_device_add_sz should have, at least, the minimal room for
+	 * set_bit()/test_bit(), otherwise out-of-memory may occur.
+	 */
+	ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz,
+					   sizeof(unsigned long));
 	ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
 	    GFP_KERNEL);
 	if (!ioc->pend_os_device_add) {
@@ -8820,6 +8833,12 @@ _base_check_ioc_facts_changes(struct MPT
 		if (ioc->facts.MaxDevHandle % 8)
 			pd_handles_sz++;
 
+		/*
+		 * pd_handles should have, at least, the minimal room for
+		 * set_bit()/test_bit(), otherwise out-of-memory touch may
+		 * occur.
+		 */
+		pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long));
 		pd_handles = krealloc(ioc->pd_handles, pd_handles_sz,
 		    GFP_KERNEL);
 		if (!pd_handles) {
author maintainer
#113 lore raw

PATCH 103/281 scsi: sd: Use READ(16) when reading block zero on large capacity disks

In reply to Greg Kroah-Hartman

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

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

From: Martin K. Petersen <[email protected]>

commit 7926d51f73e0434a6250c2fd1a0555f98d9a62da upstream.

Commit 321da3dc1f3c ("scsi: sd: usb_storage: uas: Access media prior to querying device properties") triggered a read to LBA 0 before attempting to inquire about device characteristics. This was done because some protocol bridge devices will return generic values until an attached storage device's media has been accessed.

Pierre Tomon reported that this change caused problems on a large capacity external drive connected via a bridge device. The bridge in question does not appear to implement the READ(10) command.

Issue a READ(16) instead of READ(10) when a device has been identified as preferring 16-byte commands (use_16_for_rw heuristic).

---
 drivers/scsi/sd.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/scsi/sd.c +12 -5
@@ -3572,16 +3572,23 @@ static bool sd_validate_opt_xfer_size(st
 
 static void sd_read_block_zero(struct scsi_disk *sdkp)
 {
-	unsigned int buf_len = sdkp->device->sector_size;
-	char *buffer, cmd[10] = { };
+	struct scsi_device *sdev = sdkp->device;
+	unsigned int buf_len = sdev->sector_size;
+	u8 *buffer, cmd[16] = { };
 
 	buffer = kmalloc(buf_len, GFP_KERNEL);
 	if (!buffer)
 		return;
 
-	cmd[0] = READ_10;
-	put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */
-	put_unaligned_be16(1, &cmd[7]);	/* Transfer 1 logical block */
+	if (sdev->use_16_for_rw) {
+		cmd[0] = READ_16;
+		put_unaligned_be64(0, &cmd[2]); /* Logical block address 0 */
+		put_unaligned_be32(1, &cmd[10]);/* Transfer 1 logical block */
+	} else {
+		cmd[0] = READ_10;
+		put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */
+		put_unaligned_be16(1, &cmd[7]);	/* Transfer 1 logical block */
+	}
 
 	scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len,
 			 SD_TIMEOUT, sdkp->max_retries, NULL);
author maintainer
#114 lore raw

PATCH 104/281 gve: Clear napi->skb before dev_kfree_skb_any()

In reply to Greg Kroah-Hartman

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

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

From: Ziwei Xiao <[email protected]>

commit 6f4d93b78ade0a4c2cafd587f7b429ce95abb02e upstream.

gve_rx_free_skb incorrectly leaves napi->skb referencing an skb after it is freed with dev_kfree_skb_any(). This can result in a subsequent call to napi_get_frags returning a dangling pointer.

Fix this by clearing napi->skb before the skb is freed.

---
 drivers/net/ethernet/google/gve/gve_rx_dqo.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/ethernet/google/gve/gve_rx_dqo.c +5 -3
@@ -581,11 +581,13 @@ static void gve_rx_skb_hash(struct sk_bu
 	skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type);
 }
 
-static void gve_rx_free_skb(struct gve_rx_ring *rx)
+static void gve_rx_free_skb(struct napi_struct *napi, struct gve_rx_ring *rx)
 {
 	if (!rx->ctx.skb_head)
 		return;
 
+	if (rx->ctx.skb_head == napi->skb)
+		napi->skb = NULL;
 	dev_kfree_skb_any(rx->ctx.skb_head);
 	rx->ctx.skb_head = NULL;
 	rx->ctx.skb_tail = NULL;
@@ -884,7 +886,7 @@ int gve_rx_poll_dqo(struct gve_notify_bl
 
 		err = gve_rx_dqo(napi, rx, compl_desc, complq->head, rx->q_num);
 		if (err < 0) {
-			gve_rx_free_skb(rx);
+			gve_rx_free_skb(napi, rx);
 			u64_stats_update_begin(&rx->statss);
 			if (err == -ENOMEM)
 				rx->rx_skb_alloc_fail++;
@@ -927,7 +929,7 @@ int gve_rx_poll_dqo(struct gve_notify_bl
 
 		/* gve_rx_complete_skb() will consume skb if successful */
 		if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) {
-			gve_rx_free_skb(rx);
+			gve_rx_free_skb(napi, rx);
 			u64_stats_update_begin(&rx->statss);
 			rx->rx_desc_err_dropped_pkt++;
 			u64_stats_update_end(&rx->statss);
author maintainer
#115 lore raw

PATCH 105/281 powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP

In reply to Greg Kroah-Hartman

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

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

From: Hari Bathini <[email protected]>

commit 7b090b6ff51b9a9f002139660672f662b95f0630 upstream.

Since commit 5c4233cc0920 ("powerpc/kdump: Split KEXEC_CORE and CRASH_DUMP dependency"), crashing_cpu is not available without CONFIG_CRASH_DUMP. Fix compile error on 64-BIT 85xx owing to this change.

---
 arch/powerpc/platforms/85xx/smp.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
arch/powerpc/platforms/85xx/smp.c +6 -3
@@ -398,6 +398,7 @@ static void mpc85xx_smp_kexec_cpu_down(i
 	hard_irq_disable();
 	mpic_teardown_this_cpu(secondary);
 
+#ifdef CONFIG_CRASH_DUMP
 	if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
 		/*
 		 * We enter the crash kernel on whatever cpu crashed,
@@ -406,9 +407,11 @@ static void mpc85xx_smp_kexec_cpu_down(i
 		 */
 		disable_threadbit = 1;
 		disable_cpu = cpu_first_thread_sibling(cpu);
-	} else if (sibling != crashing_cpu &&
-		   cpu_thread_in_core(cpu) == 0 &&
-		   cpu_thread_in_core(sibling) != 0) {
+	} else if (sibling == crashing_cpu) {
+		return;
+	}
+#endif
+	if (cpu_thread_in_core(cpu) == 0 && cpu_thread_in_core(sibling) != 0) {
 		disable_threadbit = 2;
 		disable_cpu = sibling;
 	}
author maintainer
#116 lore raw

PATCH 106/281 powerpc/uaccess: Fix build errors seen with GCC 13/14

In reply to Greg Kroah-Hartman

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

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

From: Michael Ellerman <[email protected]>

commit 2d43cc701b96f910f50915ac4c2a0cae5deb734c upstream.

Building ppc64le_defconfig with GCC 14 fails with assembler errors:

CC fs/readdir.o
/tmp/ccdQn0mD.s: Assembler messages:
/tmp/ccdQn0mD.s:212: Error: operand out of domain (18 is not a multiple of 4) /tmp/ccdQn0mD.s:226: Error: operand out of domain (18 is not a multiple of 4) ... [6 lines]
/tmp/ccdQn0mD.s:1699: Error: operand out of domain (18 is not a multiple of 4)

A snippet of the asm shows:

  # ../fs/readdir.c:210:         unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
         ld 9,0(29)       # MEM[(u64 *)name_38(D) + _88 * 1], MEM[(u64 *)name_38(D) + _88 * 1]
  # 210 "../fs/readdir.c" 1
         1:      std 9,18(8)     # put_user       # *__pus_addr_52, MEM[(u64 *)name_38(D) + _88 * 1]

The 'std' instruction requires a 4-byte aligned displacement because it is a DS-form instruction, and as the assembler says, 18 is not a multiple of 4.

A similar error is seen with GCC 13 and CONFIG_UBSAN_SIGNED_WRAP=y.

The fix is to change the constraint on the memory operand to put_user(), from "m" which is a general memory reference to "YZ".

The "Z" constraint is documented in the GCC manual PowerPC machine constraints, and specifies a "memory operand accessed with indexed or indirect addressing". "Y" is not documented in the manual but specifies a "memory operand for a DS-form instruction". Using both allows the compiler to generate a DS-form "std" or X-form "stdx" as appropriate.

The change has to be conditional on CONFIG_PPC_KERNEL_PREFIXED because the "Y" constraint does not guarantee 4-byte alignment when prefixed instructions are enabled.

Unfortunately clang doesn't support the "Y" constraint so that has to be behind an ifdef.

Although the build error is only seen with GCC 13/14, that appears to just be luck. The constraint has been incorrect since it was first added.

Fixes c20beffeec3c ("powerpc/uaccess: Use flexible addressing with __put_user()/__get_user()")
Cc [email protected] # v5.10+
---
 arch/powerpc/include/asm/uaccess.h |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
arch/powerpc/include/asm/uaccess.h +16 -0
@@ -92,9 +92,25 @@ __pu_failed:							\
 		: label)
 #endif
 
+#ifdef CONFIG_CC_IS_CLANG
+#define DS_FORM_CONSTRAINT "Z<>"
+#else
+#define DS_FORM_CONSTRAINT "YZ<>"
+#endif
+
 #ifdef __powerpc64__
+#ifdef CONFIG_PPC_KERNEL_PREFIXED
 #define __put_user_asm2_goto(x, ptr, label)			\
 	__put_user_asm_goto(x, ptr, label, "std")
+#else
+#define __put_user_asm2_goto(x, addr, label)			\
+	asm goto ("1: std%U1%X1 %0,%1	# put_user\n"		\
+		EX_TABLE(1b, %l2)				\
+		:						\
+		: "r" (x), DS_FORM_CONSTRAINT (*addr)		\
+		:						\
+		: label)
+#endif // CONFIG_PPC_KERNEL_PREFIXED
 #else /* __powerpc64__ */
 #define __put_user_asm2_goto(x, addr, label)			\
 	asm goto(					\
author maintainer
#117 lore raw

PATCH 107/281 HID: nvidia-shield: Add missing check for input_ff_create_memless

In reply to Greg Kroah-Hartman

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

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

From: Chen Ni <[email protected]>

[ Upstream commit 0a3f9f7fc59feb8a91a2793b8b60977895c72365 ]

Add check for the return value of input_ff_create_memless() and return the error if it fails in order to catch the error.

Fixes 09308562d4af ("HID: nvidia-shield: Initial driver implementation with Thunderstrike support")
---
 drivers/hid/hid-nvidia-shield.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hid/hid-nvidia-shield.c +3 -1
index 58b15750dbb0a..ff9078ad19611 100644
@@ -283,7 +283,9 @@ static struct input_dev *shield_haptics_create(
 		return haptics;
 
 	input_set_capability(haptics, EV_FF, FF_RUMBLE);
-	input_ff_create_memless(haptics, NULL, play_effect);
+	ret = input_ff_create_memless(haptics, NULL, play_effect);
+	if (ret)
+		goto err;
 
 	ret = input_register_device(haptics);
 	if (ret)
Signature · 1 line
2.43.0
author maintainer
#118 lore raw

PATCH 108/281 cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c

In reply to Greg Kroah-Hartman

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

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

From: Dave Jiang <[email protected]>

[ Upstream commit d55510527153d17a3af8cc2df69c04f95ae1350d ]

tools/testing/cxl/test/mem.c uses vmalloc() and vfree() but does not include linux/vmalloc.h. Kernel v6.10 made changes that causes the currently included headers not depend on vmalloc.h and therefore mem.c can no longer compile. Add linux/vmalloc.h to fix compile issue.

CC [M] tools/testing/cxl/test/mem.o
tools/testing/cxl/test/mem.c: In function ‘label_area_release’:
tools/testing/cxl/test/mem.c:1428:9: error: implicit declaration of function ‘vfree’; did you mean ‘kvfree’? [-Werror=implicit-function-declaration]

 1428 |         vfree(lsa);
      |         ^~~~~
      |         kvfree
tools/testing/cxl/test/mem.c: In function ‘cxl_mock_mem_probe’:
tools/testing/cxl/test/mem.c:1466:22: error: implicit declaration of function ‘vmalloc’; did you mean ‘kmalloc’? [-Werror=implicit-function-declaration]
 1466 |         mdata->lsa = vmalloc(LSA_SIZE);
      |                      ^~~~~~~
      |                      kmalloc
Fixes 7d3eb23c4ccf ("tools/testing/cxl: Introduce a mock memory device + driver")
---
 tools/testing/cxl/test/mem.c | 1 +
 1 file changed, 1 insertion(+)
tools/testing/cxl/test/mem.c +1 -0
index 35ee41e435ab3..0d0ca63de8629 100644
@@ -3,6 +3,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/sizes.h>
Signature · 1 line
2.43.0
author maintainer
#119 lore raw

PATCH 109/281 cxl/region: Fix memregion leaks in devm_cxl_add_region()

In reply to Greg Kroah-Hartman

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

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

From: Li Zhijian <[email protected]>

[ Upstream commit 49ba7b515c4c0719b866d16f068e62d16a8a3dd1 ]

Move the mode verification to __create_region() before allocating the memregion to avoid the memregion leaks.

Fixes 6e099264185d ("cxl/region: Add volatile region creation support")
---
 drivers/cxl/core/region.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/cxl/core/region.c +9 -9
index 812b2948b6c65..18b95149640b6 100644
@@ -2352,15 +2352,6 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
 	struct device *dev;
 	int rc;
 
-	switch (mode) {
-	case CXL_DECODER_RAM:
-	case CXL_DECODER_PMEM:
-		break;
-	default:
-		dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
-		return ERR_PTR(-EINVAL);
-	}
-
 	cxlr = cxl_region_alloc(cxlrd, id);
 	if (IS_ERR(cxlr))
 		return cxlr;
@@ -2415,6 +2406,15 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
 {
 	int rc;
 
+	switch (mode) {
+	case CXL_DECODER_RAM:
+	case CXL_DECODER_PMEM:
+		break;
+	default:
+		dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
+		return ERR_PTR(-EINVAL);
+	}
+
 	rc = memregion_alloc(GFP_KERNEL);
 	if (rc < 0)
 		return ERR_PTR(rc);
Signature · 1 line
2.43.0
author maintainer
#120 lore raw

PATCH 110/281 cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit cc5ac966f26193ab185cc43d64d9f1ae998ccb6e ]

This lets us see the correct trace output.

Fixes c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
---
 include/trace/events/cachefiles.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
include/trace/events/cachefiles.h +3 -1
index cf4b98b9a9edc..e3213af847cdf 100644
@@ -127,7 +127,9 @@ enum cachefiles_error_trace {
 	EM(cachefiles_obj_see_lookup_cookie,	"SEE lookup_cookie")	\
 	EM(cachefiles_obj_see_lookup_failed,	"SEE lookup_failed")	\
 	EM(cachefiles_obj_see_withdraw_cookie,	"SEE withdraw_cookie")	\
-	E_(cachefiles_obj_see_withdrawal,	"SEE withdrawal")
+	EM(cachefiles_obj_see_withdrawal,	"SEE withdrawal")	\
+	EM(cachefiles_obj_get_ondemand_fd,      "GET ondemand_fd")	\
+	E_(cachefiles_obj_put_ondemand_fd,      "PUT ondemand_fd")
 
 #define cachefiles_coherency_traces					\
 	EM(cachefiles_coherency_check_aux,	"BAD aux ")		\
Signature · 1 line
2.43.0
author maintainer
#121 lore raw

PATCH 111/281 cachefiles: remove requests from xarray during flushing requests

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 0fc75c5940fa634d84e64c93bfc388e1274ed013 ]

Even with CACHEFILES_DEAD set, we can still read the requests, so in the following concurrency the request may be used after it has been freed:

mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)

            cachefiles_daemon_read
             cachefiles_ondemand_daemon_read
                                  // close dev fd
                                  cachefiles_flush_reqs
                                   complete(&REQ_A->done)
   kfree(REQ_A)
              xa_lock(&cache->reqs);
              cachefiles_ondemand_select_req
                req->msg.opcode != CACHEFILES_OP_READ
                // req use-after-free !!!
              xa_unlock(&cache->reqs);
                                   xa_destroy(&cache->reqs)

Hence remove requests from cache->reqs when flushing them to avoid accessing freed requests.

---
 fs/cachefiles/daemon.c | 1 +
 1 file changed, 1 insertion(+)
fs/cachefiles/daemon.c +1 -0
index 6465e25742309..ccb7b707ea4b7 100644
@@ -159,6 +159,7 @@ static void cachefiles_flush_reqs(struct cachefiles_cache *cache)
 	xa_for_each(xa, index, req) {
 		req->error = -EIO;
 		complete(&req->done);
+		__xa_erase(xa, index);
 	}
 	xa_unlock(xa);
 
Signature · 1 line
2.43.0
author maintainer
#122 lore raw

PATCH 112/281 cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit de3e26f9e5b76fc628077578c001c4a51bf54d06 ]

We got the following issue in a fuzz test of randomly issuing the restore command:

==================================================================

BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962

CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
 kasan_report+0x94/0xc0
 cachefiles_ondemand_daemon_read+0x609/0xab0
 vfs_read+0x169/0xb50
 ksys_read+0xf5/0x1e0

Allocated by task 626:
 __kmalloc+0x1df/0x4b0
 cachefiles_ondemand_send_req+0x24d/0x690
 cachefiles_create_tmpfile+0x249/0xb30
 cachefiles_create_file+0x6f/0x140
 cachefiles_look_up_object+0x29c/0xa60
 cachefiles_lookup_cookie+0x37d/0xca0
 fscache_cookie_state_machine+0x43c/0x1230
 [...]

Freed by task 626:
 kfree+0xf1/0x2c0
 cachefiles_ondemand_send_req+0x568/0x690
 cachefiles_create_tmpfile+0x249/0xb30
 cachefiles_create_file+0x6f/0x140
 cachefiles_look_up_object+0x29c/0xa60
 cachefiles_lookup_cookie+0x37d/0xca0
 fscache_cookie_state_machine+0x43c/0x1230
 [...]
==================================================================

Following is the process that triggers the issue:

mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)

            cachefiles_daemon_read
             cachefiles_ondemand_daemon_read
              REQ_A = cachefiles_ondemand_select_req
              cachefiles_ondemand_get_fd
              copy_to_user(_buffer, msg, n)
            process_open_req(REQ_A)
                                  ------ restore ------
                                  cachefiles_ondemand_restore
                                  xas_for_each(&xas, req, ULONG_MAX)
                                   xas_set_mark(&xas, CACHEFILES_REQ_NEW);

                                  cachefiles_daemon_read
                                   cachefiles_ondemand_daemon_read
                                    REQ_A = cachefiles_ondemand_select_req

             write(devfd, ("copen %u,%llu", msg->msg_id, size));
             cachefiles_ondemand_copen
              xa_erase(&cache->reqs, id)
              complete(&REQ_A->done)
   kfree(REQ_A)
                                    cachefiles_ondemand_get_fd(REQ_A)
                                     fd = get_unused_fd_flags
                                     file = anon_inode_getfile
                                     fd_install(fd, file)
                                     load = (void *)REQ_A->msg.data;
                                     load->fd = fd;
                                     // load UAF !!!

This issue is caused by issuing a restore command when the daemon is still alive, which results in a request being processed multiple times thus triggering a UAF. So to avoid this problem, add an additional reference count to cachefiles_req, which is held while waiting and reading, and then released when the waiting and reading is over.

Note that since there is only one reference count for waiting, we need to avoid the same request being completed multiple times, so we can only complete the request if it is successfully removed from the xarray.

Fixes e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
---
 fs/cachefiles/internal.h |  1 +
 fs/cachefiles/ondemand.c | 23 +++++++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)
fs/cachefiles/internal.h +1 -0
index d33169f0018b1..7745b8abc3aa3 100644
@@ -138,6 +138,7 @@ static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)
 struct cachefiles_req {
 	struct cachefiles_object *object;
 	struct completion done;
+	refcount_t ref;
 	int error;
 	struct cachefiles_msg msg;
 };
fs/cachefiles/ondemand.c +19 -4
index 4ba42f1fa3b40..c011fb24d2382 100644
@@ -4,6 +4,12 @@
 #include <linux/uio.h>
 #include "internal.h"
 
+static inline void cachefiles_req_put(struct cachefiles_req *req)
+{
+	if (refcount_dec_and_test(&req->ref))
+		kfree(req);
+}
+
 static int cachefiles_ondemand_fd_release(struct inode *inode,
 					  struct file *file)
 {
@@ -330,6 +336,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 
 	xas_clear_mark(&xas, CACHEFILES_REQ_NEW);
 	cache->req_id_next = xas.xa_index + 1;
+	refcount_inc(&req->ref);
 	xa_unlock(&cache->reqs);
 
 	id = xas.xa_index;
@@ -356,15 +363,22 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 		complete(&req->done);
 	}
 
+	cachefiles_req_put(req);
 	return n;
 
 err_put_fd:
 	if (msg->opcode == CACHEFILES_OP_OPEN)
 		close_fd(((struct cachefiles_open *)msg->data)->fd);
 error:
-	xa_erase(&cache->reqs, id);
-	req->error = ret;
-	complete(&req->done);
+	xas_reset(&xas);
+	xas_lock(&xas);
+	if (xas_load(&xas) == req) {
+		req->error = ret;
+		complete(&req->done);
+		xas_store(&xas, NULL);
+	}
+	xas_unlock(&xas);
+	cachefiles_req_put(req);
 	return ret;
 }
 
@@ -395,6 +409,7 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object,
 		goto out;
 	}
 
+	refcount_set(&req->ref, 1);
 	req->object = object;
 	init_completion(&req->done);
 	req->msg.opcode = opcode;
@@ -456,7 +471,7 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object,
 	wake_up_all(&cache->daemon_pollwq);
 	wait_for_completion(&req->done);
 	ret = req->error;
-	kfree(req);
+	cachefiles_req_put(req);
 	return ret;
 out:
 	/* Reset the object to close state in error handling path.
Signature · 1 line
2.43.0
author maintainer
#123 lore raw

PATCH 113/281 cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit da4a827416066191aafeeccee50a8836a826ba10 ]

We got the following issue in a fuzz test of randomly issuing the restore command:

==================================================================

BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0xb41/0xb60
Read of size 8 at addr ffff888122e84088 by task ondemand-04-dae/963

CPU: 13 PID: 963 Comm: ondemand-04-dae Not tainted 6.8.0-dirty #564
Call Trace:
 kasan_report+0x93/0xc0
 cachefiles_ondemand_daemon_read+0xb41/0xb60
 vfs_read+0x169/0xb50
 ksys_read+0xf5/0x1e0

Allocated by task 116:
 kmem_cache_alloc+0x140/0x3a0
 cachefiles_lookup_cookie+0x140/0xcd0
 fscache_cookie_state_machine+0x43c/0x1230
 [...]

Freed by task 792:
 kmem_cache_free+0xfe/0x390
 cachefiles_put_object+0x241/0x480
 fscache_cookie_state_machine+0x5c8/0x1230
 [...]
==================================================================

Following is the process that triggers the issue:

mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_withdraw_cookie
cachefiles_ondemand_clean_object(object)
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)

            cachefiles_daemon_read
             cachefiles_ondemand_daemon_read
              REQ_A = cachefiles_ondemand_select_req
              msg->object_id = req->object->ondemand->ondemand_id
                                  ------ restore ------
                                  cachefiles_ondemand_restore
                                  xas_for_each(&xas, req, ULONG_MAX)
                                   xas_set_mark(&xas, CACHEFILES_REQ_NEW)

                                  cachefiles_daemon_read
                                   cachefiles_ondemand_daemon_read
                                    REQ_A = cachefiles_ondemand_select_req
              copy_to_user(_buffer, msg, n)
               xa_erase(&cache->reqs, id)
               complete(&REQ_A->done)
              ------ close(fd) ------
              cachefiles_ondemand_fd_release
               cachefiles_put_object
 cachefiles_put_object
  kmem_cache_free(cachefiles_object_jar, object)
                                    REQ_A->object->ondemand->ondemand_id
                                     // object UAF !!!

When we see the request within xa_lock, req->object must not have been freed yet, so grab the reference count of object before xa_unlock to avoid the above issue.

Fixes 0a7e54c1959c ("cachefiles: resend an open request if the read request's object is closed")
---
 fs/cachefiles/ondemand.c          | 3 +++
 include/trace/events/cachefiles.h | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)
fs/cachefiles/ondemand.c +3 -0
index c011fb24d2382..3dd002108a872 100644
@@ -337,6 +337,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	xas_clear_mark(&xas, CACHEFILES_REQ_NEW);
 	cache->req_id_next = xas.xa_index + 1;
 	refcount_inc(&req->ref);
+	cachefiles_grab_object(req->object, cachefiles_obj_get_read_req);
 	xa_unlock(&cache->reqs);
 
 	id = xas.xa_index;
@@ -357,6 +358,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 		goto err_put_fd;
 	}
 
+	cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
 	/* CLOSE request has no reply */
 	if (msg->opcode == CACHEFILES_OP_CLOSE) {
 		xa_erase(&cache->reqs, id);
@@ -370,6 +372,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	if (msg->opcode == CACHEFILES_OP_OPEN)
 		close_fd(((struct cachefiles_open *)msg->data)->fd);
 error:
+	cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
 	xas_reset(&xas);
 	xas_lock(&xas);
 	if (xas_load(&xas) == req) {
include/trace/events/cachefiles.h +5 -1
index e3213af847cdf..7d931db02b934 100644
@@ -33,6 +33,8 @@ enum cachefiles_obj_ref_trace {
 	cachefiles_obj_see_withdrawal,
 	cachefiles_obj_get_ondemand_fd,
 	cachefiles_obj_put_ondemand_fd,
+	cachefiles_obj_get_read_req,
+	cachefiles_obj_put_read_req,
 };
 
 enum fscache_why_object_killed {
@@ -129,7 +131,9 @@ enum cachefiles_error_trace {
 	EM(cachefiles_obj_see_withdraw_cookie,	"SEE withdraw_cookie")	\
 	EM(cachefiles_obj_see_withdrawal,	"SEE withdrawal")	\
 	EM(cachefiles_obj_get_ondemand_fd,      "GET ondemand_fd")	\
-	E_(cachefiles_obj_put_ondemand_fd,      "PUT ondemand_fd")
+	EM(cachefiles_obj_put_ondemand_fd,      "PUT ondemand_fd")	\
+	EM(cachefiles_obj_get_read_req,		"GET read_req")		\
+	E_(cachefiles_obj_put_read_req,		"PUT read_req")
 
 #define cachefiles_coherency_traces					\
 	EM(cachefiles_coherency_check_aux,	"BAD aux ")		\
Signature · 1 line
2.43.0
author maintainer
#124 lore raw

PATCH 114/281 cachefiles: add spin_lock for cachefiles_ondemand_info

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 0a790040838c736495d5afd6b2d636f159f817f1 ]

The following concurrency may cause a read request to fail to be completed and result in a hung:

t1 | t2
---------------------------------------------------------

                            cachefiles_ondemand_copen
                              req = xa_erase(&cache->reqs, id)

// Anon fd is maliciously closed.
cachefiles_ondemand_fd_release
xa_lock(&cache->reqs)
cachefiles_ondemand_set_object_close(object)
xa_unlock(&cache->reqs)

                              cachefiles_ondemand_set_object_open
                              // No one will ever close it again.

cachefiles_ondemand_daemon_read
cachefiles_ondemand_select_req
// Get a read req but its fd is already closed.
// The daemon can't issue a cread ioctl with an closed fd, then hung.

So add spin_lock for cachefiles_ondemand_info to protect ondemand_id and state, thus we can avoid the above problem in cachefiles_ondemand_copen() by using ondemand_id to determine if fd has been closed.

Fixes c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
---
 fs/cachefiles/internal.h |  1 +
 fs/cachefiles/ondemand.c | 35 ++++++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)
fs/cachefiles/internal.h +1 -0
index 7745b8abc3aa3..45c8bed605383 100644
@@ -55,6 +55,7 @@ struct cachefiles_ondemand_info {
 	int				ondemand_id;
 	enum cachefiles_object_state	state;
 	struct cachefiles_object	*object;
+	spinlock_t			lock;
 };
 
 /*
fs/cachefiles/ondemand.c +34 -1
index 3dd002108a872..7b667ddc84ca5 100644
@@ -16,13 +16,16 @@ static int cachefiles_ondemand_fd_release(struct inode *inode,
 	struct cachefiles_object *object = file->private_data;
 	struct cachefiles_cache *cache = object->volume->cache;
 	struct cachefiles_ondemand_info *info = object->ondemand;
-	int object_id = info->ondemand_id;
+	int object_id;
 	struct cachefiles_req *req;
 	XA_STATE(xas, &cache->reqs, 0);
 
 	xa_lock(&cache->reqs);
+	spin_lock(&info->lock);
+	object_id = info->ondemand_id;
 	info->ondemand_id = CACHEFILES_ONDEMAND_ID_CLOSED;
 	cachefiles_ondemand_set_object_close(object);
+	spin_unlock(&info->lock);
 
 	/* Only flush CACHEFILES_REQ_NEW marked req to avoid race with daemon_read */
 	xas_for_each_marked(&xas, req, ULONG_MAX, CACHEFILES_REQ_NEW) {
@@ -122,6 +125,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
 {
 	struct cachefiles_req *req;
 	struct fscache_cookie *cookie;
+	struct cachefiles_ondemand_info *info;
 	char *pid, *psize;
 	unsigned long id;
 	long size;
@@ -172,6 +176,33 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
 		goto out;
 	}
 
+	info = req->object->ondemand;
+	spin_lock(&info->lock);
+	/*
+	 * The anonymous fd was closed before copen ? Fail the request.
+	 *
+	 *             t1             |             t2
+	 * ---------------------------------------------------------
+	 *                             cachefiles_ondemand_copen
+	 *                             req = xa_erase(&cache->reqs, id)
+	 * // Anon fd is maliciously closed.
+	 * cachefiles_ondemand_fd_release
+	 * xa_lock(&cache->reqs)
+	 * cachefiles_ondemand_set_object_close(object)
+	 * xa_unlock(&cache->reqs)
+	 *                             cachefiles_ondemand_set_object_open
+	 *                             // No one will ever close it again.
+	 * cachefiles_ondemand_daemon_read
+	 * cachefiles_ondemand_select_req
+	 *
+	 * Get a read req but its fd is already closed. The daemon can't
+	 * issue a cread ioctl with an closed fd, then hung.
+	 */
+	if (info->ondemand_id == CACHEFILES_ONDEMAND_ID_CLOSED) {
+		spin_unlock(&info->lock);
+		req->error = -EBADFD;
+		goto out;
+	}
 	cookie = req->object->cookie;
 	cookie->object_size = size;
 	if (size)
@@ -181,6 +212,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
 	trace_cachefiles_ondemand_copen(req->object, id, size);
 
 	cachefiles_ondemand_set_object_open(req->object);
+	spin_unlock(&info->lock);
 	wake_up_all(&cache->daemon_pollwq);
 
 out:
@@ -596,6 +628,7 @@ int cachefiles_ondemand_init_obj_info(struct cachefiles_object *object,
 		return -ENOMEM;
 
 	object->ondemand->object = object;
+	spin_lock_init(&object->ondemand->lock);
 	INIT_WORK(&object->ondemand->ondemand_work, ondemand_object_worker);
 	return 0;
 }
Signature · 1 line
2.43.0
author maintainer
#125 lore raw

PATCH 115/281 cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 3e6d704f02aa4c50c7bc5fe91a4401df249a137b ]

The err_put_fd label is only used once, so remove it to make the code more readable. In addition, the logic for deleting error request and CLOSE request is merged to simplify the code.

Stable-dep-of: 4988e35e95fc ("cachefiles: never get a new anonymous fd if ondemand_id is valid")

---
 fs/cachefiles/ondemand.c | 45 ++++++++++++++--------------------------
 1 file changed, 16 insertions(+), 29 deletions(-)
fs/cachefiles/ondemand.c +16 -29
index 7b667ddc84ca5..c8389bb118f5b 100644
@@ -337,7 +337,6 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 {
 	struct cachefiles_req *req;
 	struct cachefiles_msg *msg;
-	unsigned long id = 0;
 	size_t n;
 	int ret = 0;
 	XA_STATE(xas, &cache->reqs, cache->req_id_next);
@@ -372,49 +371,37 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	cachefiles_grab_object(req->object, cachefiles_obj_get_read_req);
 	xa_unlock(&cache->reqs);
 
-	id = xas.xa_index;
-
 	if (msg->opcode == CACHEFILES_OP_OPEN) {
 		ret = cachefiles_ondemand_get_fd(req);
 		if (ret) {
 			cachefiles_ondemand_set_object_close(req->object);
-			goto error;
+			goto out;
 		}
 	}
 
-	msg->msg_id = id;
+	msg->msg_id = xas.xa_index;
 	msg->object_id = req->object->ondemand->ondemand_id;
 
 	if (copy_to_user(_buffer, msg, n) != 0) {
 		ret = -EFAULT;
-		goto err_put_fd;
-	}
-
-	cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
-	/* CLOSE request has no reply */
-	if (msg->opcode == CACHEFILES_OP_CLOSE) {
-		xa_erase(&cache->reqs, id);
-		complete(&req->done);
+		if (msg->opcode == CACHEFILES_OP_OPEN)
+			close_fd(((struct cachefiles_open *)msg->data)->fd);
 	}
-
-	cachefiles_req_put(req);
-	return n;
-
-err_put_fd:
-	if (msg->opcode == CACHEFILES_OP_OPEN)
-		close_fd(((struct cachefiles_open *)msg->data)->fd);
-error:
+out:
 	cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
-	xas_reset(&xas);
-	xas_lock(&xas);
-	if (xas_load(&xas) == req) {
-		req->error = ret;
-		complete(&req->done);
-		xas_store(&xas, NULL);
+	/* Remove error request and CLOSE request has no reply */
+	if (ret || msg->opcode == CACHEFILES_OP_CLOSE) {
+		xas_reset(&xas);
+		xas_lock(&xas);
+		if (xas_load(&xas) == req) {
+			req->error = ret;
+			complete(&req->done);
+			xas_store(&xas, NULL);
+		}
+		xas_unlock(&xas);
 	}
-	xas_unlock(&xas);
 	cachefiles_req_put(req);
-	return ret;
+	return ret ? ret : n;
 }
 
 typedef int (*init_req_fn)(struct cachefiles_req *req, void *private);
Signature · 1 line
2.43.0
author maintainer
#126 lore raw

PATCH 116/281 cachefiles: never get a new anonymous fd if ondemand_id is valid

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 4988e35e95fc938bdde0e15880fe72042fc86acf ]

Now every time the daemon reads an open request, it gets a new anonymous fd and ondemand_id. With the introduction of "restore", it is possible to read the same open request more than once, and therefore an object can have more than one anonymous fd.

If the anonymous fd is not unique, the following concurrencies will result in an fd leak:

t1 | t2 | t3
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)

            cachefiles_daemon_read
             cachefiles_ondemand_daemon_read
              REQ_A = cachefiles_ondemand_select_req
              cachefiles_ondemand_get_fd
                load->fd = fd0
                ondemand_id = object_id0
                                  ------ restore ------
                                  cachefiles_ondemand_restore
                                   // restore REQ_A
                                  cachefiles_daemon_read
                                   cachefiles_ondemand_daemon_read
                                    REQ_A = cachefiles_ondemand_select_req
                                      cachefiles_ondemand_get_fd
                                        load->fd = fd1
                                        ondemand_id = object_id1
             process_open_req(REQ_A)
             write(devfd, ("copen %u,%llu", msg->msg_id, size))
             cachefiles_ondemand_copen
              xa_erase(&cache->reqs, id)
              complete(&REQ_A->done)
   kfree(REQ_A)
                                  process_open_req(REQ_A)
                                  // copen fails due to no req
                                  // daemon close(fd1)
                                  cachefiles_ondemand_fd_release
                                   // set object closed
 -- umount --
 cachefiles_withdraw_cookie
  cachefiles_ondemand_clean_object
   cachefiles_ondemand_init_close_req
    if (!cachefiles_ondemand_object_is_open(object))
      return -ENOENT;
    // The fd0 is not closed until the daemon exits.

However, the anonymous fd holds the reference count of the object and the object holds the reference count of the cookie. So even though the cookie has been relinquished, it will not be unhashed and freed until the daemon exits.

In fscache_hash_cookie(), when the same cookie is found in the hash list, if the cookie is set with the FSCACHE_COOKIE_RELINQUISHED bit, then the new cookie waits for the old cookie to be unhashed, while the old cookie is waiting for the leaked fd to be closed, if the daemon does not exit in time it will trigger a hung task.

To avoid this, allocate a new anonymous fd only if no anonymous fd has been allocated (ondemand_id == 0) or if the previously allocated anonymous fd has been closed (ondemand_id == -1). Moreover, returns an error if ondemand_id is valid, letting the daemon know that the current userland restore logic is abnormal and needs to be checked.

Fixes c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
---
 fs/cachefiles/ondemand.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)
fs/cachefiles/ondemand.c +28 -6
index c8389bb118f5b..dbcd4161ea3a1 100644
@@ -14,11 +14,18 @@ static int cachefiles_ondemand_fd_release(struct inode *inode,
 					  struct file *file)
 {
 	struct cachefiles_object *object = file->private_data;
-	struct cachefiles_cache *cache = object->volume->cache;
-	struct cachefiles_ondemand_info *info = object->ondemand;
+	struct cachefiles_cache *cache;
+	struct cachefiles_ondemand_info *info;
 	int object_id;
 	struct cachefiles_req *req;
-	XA_STATE(xas, &cache->reqs, 0);
+	XA_STATE(xas, NULL, 0);
+
+	if (!object)
+		return 0;
+
+	info = object->ondemand;
+	cache = object->volume->cache;
+	xas.xa = &cache->reqs;
 
 	xa_lock(&cache->reqs);
 	spin_lock(&info->lock);
@@ -275,22 +282,39 @@ static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
 		goto err_put_fd;
 	}
 
+	spin_lock(&object->ondemand->lock);
+	if (object->ondemand->ondemand_id > 0) {
+		spin_unlock(&object->ondemand->lock);
+		/* Pair with check in cachefiles_ondemand_fd_release(). */
+		file->private_data = NULL;
+		ret = -EEXIST;
+		goto err_put_file;
+	}
+
 	file->f_mode |= FMODE_PWRITE | FMODE_LSEEK;
 	fd_install(fd, file);
 
 	load = (void *)req->msg.data;
 	load->fd = fd;
 	object->ondemand->ondemand_id = object_id;
+	spin_unlock(&object->ondemand->lock);
 
 	cachefiles_get_unbind_pincount(cache);
 	trace_cachefiles_ondemand_open(object, &req->msg, load);
 	return 0;
 
+err_put_file:
+	fput(file);
 err_put_fd:
 	put_unused_fd(fd);
 err_free_id:
 	xa_erase(&cache->ondemand_ids, object_id);
 err:
+	spin_lock(&object->ondemand->lock);
+	/* Avoid marking an opened object as closed. */
+	if (object->ondemand->ondemand_id <= 0)
+		cachefiles_ondemand_set_object_close(object);
+	spin_unlock(&object->ondemand->lock);
 	cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd);
 	return ret;
 }
@@ -373,10 +397,8 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 
 	if (msg->opcode == CACHEFILES_OP_OPEN) {
 		ret = cachefiles_ondemand_get_fd(req);
-		if (ret) {
-			cachefiles_ondemand_set_object_close(req->object);
+		if (ret)
 			goto out;
-		}
 	}
 
 	msg->msg_id = xas.xa_index;
Signature · 1 line
2.43.0
author maintainer
#127 lore raw

PATCH 117/281 cachefiles: defer exposing anon_fd until after copy_to_user() succeeds

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 4b4391e77a6bf24cba2ef1590e113d9b73b11039 ]

After installing the anonymous fd, we can now see it in userland and close it. However, at this point we may not have gotten the reference count of the cache, but we will put it during colse fd, so this may cause a cache UAF.

So grab the cache reference count before fd_install(). In addition, by kernel convention, fd is taken over by the user land after fd_install(), and the kernel should not call close_fd() after that, i.e., it should call fd_install() after everything is ready, thus fd_install() is called after copy_to_user() succeeds.

Fixes c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
---
 fs/cachefiles/ondemand.c | 53 +++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 20 deletions(-)
fs/cachefiles/ondemand.c +33 -20
index dbcd4161ea3a1..89f118d68d125 100644
@@ -4,6 +4,11 @@
 #include <linux/uio.h>
 #include "internal.h"
 
+struct ondemand_anon_file {
+	struct file *file;
+	int fd;
+};
+
 static inline void cachefiles_req_put(struct cachefiles_req *req)
 {
 	if (refcount_dec_and_test(&req->ref))
@@ -250,14 +255,14 @@ int cachefiles_ondemand_restore(struct cachefiles_cache *cache, char *args)
 	return 0;
 }
 
-static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
+static int cachefiles_ondemand_get_fd(struct cachefiles_req *req,
+				      struct ondemand_anon_file *anon_file)
 {
 	struct cachefiles_object *object;
 	struct cachefiles_cache *cache;
 	struct cachefiles_open *load;
-	struct file *file;
 	u32 object_id;
-	int ret, fd;
+	int ret;
 
 	object = cachefiles_grab_object(req->object,
 			cachefiles_obj_get_ondemand_fd);
@@ -269,16 +274,16 @@ static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
 	if (ret < 0)
 		goto err;
 
-	fd = get_unused_fd_flags(O_WRONLY);
-	if (fd < 0) {
-		ret = fd;
+	anon_file->fd = get_unused_fd_flags(O_WRONLY);
+	if (anon_file->fd < 0) {
+		ret = anon_file->fd;
 		goto err_free_id;
 	}
 
-	file = anon_inode_getfile("[cachefiles]", &cachefiles_ondemand_fd_fops,
-				  object, O_WRONLY);
-	if (IS_ERR(file)) {
-		ret = PTR_ERR(file);
+	anon_file->file = anon_inode_getfile("[cachefiles]",
+				&cachefiles_ondemand_fd_fops, object, O_WRONLY);
+	if (IS_ERR(anon_file->file)) {
+		ret = PTR_ERR(anon_file->file);
 		goto err_put_fd;
 	}
 
@@ -286,16 +291,15 @@ static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
 	if (object->ondemand->ondemand_id > 0) {
 		spin_unlock(&object->ondemand->lock);
 		/* Pair with check in cachefiles_ondemand_fd_release(). */
-		file->private_data = NULL;
+		anon_file->file->private_data = NULL;
 		ret = -EEXIST;
 		goto err_put_file;
 	}
 
-	file->f_mode |= FMODE_PWRITE | FMODE_LSEEK;
-	fd_install(fd, file);
+	anon_file->file->f_mode |= FMODE_PWRITE | FMODE_LSEEK;
 
 	load = (void *)req->msg.data;
-	load->fd = fd;
+	load->fd = anon_file->fd;
 	object->ondemand->ondemand_id = object_id;
 	spin_unlock(&object->ondemand->lock);
 
@@ -304,9 +308,11 @@ static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
 	return 0;
 
 err_put_file:
-	fput(file);
+	fput(anon_file->file);
+	anon_file->file = NULL;
 err_put_fd:
-	put_unused_fd(fd);
+	put_unused_fd(anon_file->fd);
+	anon_file->fd = ret;
 err_free_id:
 	xa_erase(&cache->ondemand_ids, object_id);
 err:
@@ -363,6 +369,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	struct cachefiles_msg *msg;
 	size_t n;
 	int ret = 0;
+	struct ondemand_anon_file anon_file;
 	XA_STATE(xas, &cache->reqs, cache->req_id_next);
 
 	xa_lock(&cache->reqs);
@@ -396,7 +403,7 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	xa_unlock(&cache->reqs);
 
 	if (msg->opcode == CACHEFILES_OP_OPEN) {
-		ret = cachefiles_ondemand_get_fd(req);
+		ret = cachefiles_ondemand_get_fd(req, &anon_file);
 		if (ret)
 			goto out;
 	}
@@ -404,10 +411,16 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
 	msg->msg_id = xas.xa_index;
 	msg->object_id = req->object->ondemand->ondemand_id;
 
-	if (copy_to_user(_buffer, msg, n) != 0) {
+	if (copy_to_user(_buffer, msg, n) != 0)
 		ret = -EFAULT;
-		if (msg->opcode == CACHEFILES_OP_OPEN)
-			close_fd(((struct cachefiles_open *)msg->data)->fd);
+
+	if (msg->opcode == CACHEFILES_OP_OPEN) {
+		if (ret < 0) {
+			fput(anon_file.file);
+			put_unused_fd(anon_file.fd);
+			goto out;
+		}
+		fd_install(anon_file.fd, anon_file.file);
 	}
 out:
 	cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
Signature · 1 line
2.43.0
author maintainer
#128 lore raw

PATCH 118/281 cachefiles: flush all requests after setting CACHEFILES_DEAD

In reply to Greg Kroah-Hartman

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

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

From: Baokun Li <[email protected]>

[ Upstream commit 85e833cd7243bda7285492b0653c3abb1e2e757b ]

In ondemand mode, when the daemon is processing an open request, if the kernel flags the cache as CACHEFILES_DEAD, the cachefiles_daemon_write() will always return -EIO, so the daemon can't pass the copen to the kernel. Then the kernel process that is waiting for the copen triggers a hung_task.

Since the DEAD state is irreversible, it can only be exited by closing /dev/cachefiles. Therefore, after calling cachefiles_io_error() to mark the cache as CACHEFILES_DEAD, if in ondemand mode, flush all requests to avoid the above hungtask. We may still be able to read some of the cached data before closing the fd of /dev/cachefiles.

Note that this relies on the patch that adds reference counting to the req, otherwise it may UAF.

Fixes c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
---
 fs/cachefiles/daemon.c   | 2 +-
 fs/cachefiles/internal.h | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)
fs/cachefiles/daemon.c +1 -1
index ccb7b707ea4b7..06cdf1a8a16f6 100644
@@ -133,7 +133,7 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static void cachefiles_flush_reqs(struct cachefiles_cache *cache)
+void cachefiles_flush_reqs(struct cachefiles_cache *cache)
 {
 	struct xarray *xa = &cache->reqs;
 	struct cachefiles_req *req;
fs/cachefiles/internal.h +3 -0
index 45c8bed605383..6845a90cdfcce 100644
@@ -188,6 +188,7 @@ extern int cachefiles_has_space(struct cachefiles_cache *cache,
  * daemon.c
  */
 extern const struct file_operations cachefiles_daemon_fops;
+extern void cachefiles_flush_reqs(struct cachefiles_cache *cache);
 extern void cachefiles_get_unbind_pincount(struct cachefiles_cache *cache);
 extern void cachefiles_put_unbind_pincount(struct cachefiles_cache *cache);
 
@@ -426,6 +427,8 @@ do {							\
 	pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__);	\
 	fscache_io_error((___cache)->cache);		\
 	set_bit(CACHEFILES_DEAD, &(___cache)->flags);	\
+	if (cachefiles_in_ondemand_mode(___cache))	\
+		cachefiles_flush_reqs(___cache);	\
 } while (0)
 
 #define cachefiles_io_error_obj(object, FMT, ...)			\
Signature · 1 line
2.43.0
author maintainer
#129 lore raw

PATCH 119/281 kselftest/alsa: Ensure _GNU_SOURCE is defined

In reply to Greg Kroah-Hartman

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

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

From: Mark Brown <[email protected]>

[ Upstream commit 2032e61e24fe9fe55d6c7a34fb5506c911b3e280 ]

The pcmtest driver tests use the kselftest harness which requires that _GNU_SOURCE is defined but nothing causes it to be defined. Since the KHDR_INCLUDES Makefile variable has had the required define added let's use that, this should provide some futureproofing.

Fixes daef47b89efd ("selftests: Compile kselftest headers with -D_GNU_SOURCE")
---
 tools/testing/selftests/alsa/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/alsa/Makefile +1 -1
index 5af9ba8a4645b..c1ce39874e2b5 100644
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 
-CFLAGS += $(shell pkg-config --cflags alsa)
+CFLAGS += $(shell pkg-config --cflags alsa) $(KHDR_INCLUDES)
 LDLIBS += $(shell pkg-config --libs alsa)
 ifeq ($(LDLIBS),)
 LDLIBS += -lasound
Signature · 1 line
2.43.0
author maintainer
#130 lore raw

PATCH 120/281 selftests/ftrace: Fix to check required event file

In reply to Greg Kroah-Hartman

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

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

From: Masami Hiramatsu (Google) <[email protected]>

[ Upstream commit f6c3c83db1d939ebdb8c8922748ae647d8126d91 ]

The dynevent/test_duplicates.tc test case uses syscalls/sys_enter_openat event for defining eprobe on it. Since this syscalls events depend on CONFIG_FTRACE_SYSCALLS=y, if it is not set, the test will fail.

Add the event file to required line so that the test will return unsupported result.

Fixes 297e1dcdca3d ("selftests/ftrace: Add selftest for testing duplicate eprobes and kprobes")
---
 .../testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc +1 -1
index d3a79da215c8b..5f72abe6fa79b 100644
@@ -1,7 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - check if duplicate events are caught
-# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README events/syscalls/sys_enter_openat
 
 echo 0 > events/enable
 
Signature · 1 line
2.43.0
author maintainer
#131 lore raw

PATCH 121/281 clk: sifive: Do not register clkdevs for PRCI clocks

In reply to Greg Kroah-Hartman

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

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

From: Samuel Holland <[email protected]>

[ Upstream commit 2607133196c35f31892ee199ce7ffa717bea4ad1 ]

These clkdevs were unnecessary, because systems using this driver always look up clocks using the devicetree. And as Russell King points out[1], since the provided device name was truncated, lookups via clkdev would never match.

Recently, commit 8d532528ff6a ("clkdev: report over-sized strings when creating clkdev entries") caused clkdev registration to fail due to the truncation, and this now prevents the driver from probing. Fix the driver by removing the clkdev registration.

Fixes 30b8e27e3b58 ("clk: sifive: add a driver for the SiFive FU540 PRCI IP block")
Fixes 8d532528ff6a ("clkdev: report over-sized strings when creating clkdev entries")
---
 drivers/clk/sifive/sifive-prci.c | 8 --------
 1 file changed, 8 deletions(-)
drivers/clk/sifive/sifive-prci.c +0 -8
index 25b8e1a80ddce..b32a59fe55e74 100644
@@ -4,7 +4,6 @@
  * Copyright (C) 2020 Zong Li
  */
 
-#include <linux/clkdev.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -537,13 +536,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
 			return r;
 		}
 
-		r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
-		if (r) {
-			dev_warn(dev, "Failed to register clkdev for %s: %d\n",
-				 init.name, r);
-			return r;
-		}
-
 		pd->hw_clks.hws[i] = &pic->hw;
 	}
 
Signature · 1 line
2.43.0
author maintainer
#132 lore raw

PATCH 122/281 NFSv4.1 enforce rootpath check in fs_location query

In reply to Greg Kroah-Hartman

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

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

From: Olga Kornievskaia <[email protected]>

[ Upstream commit 28568c906c1bb5f7560e18082ed7d6295860f1c2 ]

In commit 4ca9f31a2be66 ("NFSv4.1 test and add 4.1 trunking transport"), we introduce the ability to query the NFS server for possible trunking locations of the existing filesystem. However, we never checked the returned file system path for these alternative locations. According to the RFC, the server can say that the filesystem currently known under "fs_root" of fs_location also resides under these server locations under the following "rootpath" pathname. The client cannot handle trunking a filesystem that reside under different location under different paths other than what the main path is. This patch enforces the check that fs_root path and rootpath path in fs_location reply is the same.

Fixes 4ca9f31a2be6 ("NFSv4.1 test and add 4.1 trunking transport")
---
 fs/nfs/nfs4proc.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +22 -1
index c93c12063b3af..3a816c4a6d5e2 100644
@@ -4023,6 +4023,23 @@ static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
 	}
 }
 
+static bool _is_same_nfs4_pathname(struct nfs4_pathname *path1,
+				   struct nfs4_pathname *path2)
+{
+	int i;
+
+	if (path1->ncomponents != path2->ncomponents)
+		return false;
+	for (i = 0; i < path1->ncomponents; i++) {
+		if (path1->components[i].len != path2->components[i].len)
+			return false;
+		if (memcmp(path1->components[i].data, path2->components[i].data,
+				path1->components[i].len))
+			return false;
+	}
+	return true;
+}
+
 static int _nfs4_discover_trunking(struct nfs_server *server,
 				   struct nfs_fh *fhandle)
 {
@@ -4056,9 +4073,13 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
 	if (status)
 		goto out_free_3;
 
-	for (i = 0; i < locations->nlocations; i++)
+	for (i = 0; i < locations->nlocations; i++) {
+		if (!_is_same_nfs4_pathname(&locations->fs_path,
+					&locations->locations[i].rootpath))
+			continue;
 		test_fs_location_for_trunking(&locations->locations[i], clp,
 					      server);
+	}
 out_free_3:
 	kfree(locations->fattr);
 out_free_2:
Signature · 1 line
2.43.0
author maintainer
#133 lore raw

PATCH 123/281 SUNRPC: return proper error from gss_wrap_req_priv

In reply to Greg Kroah-Hartman

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

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

From: Chen Hanxiao <[email protected]>

[ Upstream commit 33c94d7e3cb84f6d130678d6d59ba475a6c489cf ]

don't return 0 if snd_buf->len really greater than snd_buf->buflen

Fixes 0c77668ddb4e ("SUNRPC: Introduce trace points in rpc_auth_gss.ko")
---
 net/sunrpc/auth_gss/auth_gss.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/sunrpc/auth_gss/auth_gss.c +3 -1
index c7af0220f82f4..369310909fc98 100644
@@ -1875,8 +1875,10 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 	offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
 	maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
 	/* slack space should prevent this ever happening: */
-	if (unlikely(snd_buf->len > snd_buf->buflen))
+	if (unlikely(snd_buf->len > snd_buf->buflen)) {
+		status = -EIO;
 		goto wrap_failed;
+	}
 	/* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
 	 * done anyway, so it's safe to put the request on the wire: */
 	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
Signature · 1 line
2.43.0