Skip to contentSkip to conversation

6.1.22-rc1 review

PATCH In review Greg Kroah-Hartman 14 participants 238 messages Mar 28, 2023 – Mar 29, 2023 Page 1 of 2

Subsystems (6)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.1.22-rc1 review

This is the start of the stable review cycle for the 6.1.22 release. There are 224 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 Thu, 30 Mar 2023 14:25:33 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.22-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 6.1.22-rc1

Ma Jun <[email protected]>
drm/amdkfd: Fix the memory overrun

Yifan Zhang <[email protected]>
drm/amdkfd: add GC 11.0.4 KFD support

Ma Jun <[email protected]>
drm/amdkfd: Fix the warning of array-index-out-of-bounds

Prike Liang <[email protected]>
drm/amdkfd: introduce dummy cache info for property asic

Vincent Guittot <[email protected]>
sched/fair: Sanitize vruntime of entity being migrated

Zhang Qiao <[email protected]>
sched/fair: sanitize vruntime of entity being placed

Mike Snitzer <[email protected]>
dm crypt: avoid accessing uninitialized tasklet

Mikulas Patocka <[email protected]>
dm crypt: add cond_resched() to dmcrypt_write()

Jiasheng Jiang <[email protected]>
dm stats: check for and propagate alloc_percpu failure

Wei Chen <[email protected]>
i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer()

Ivan Bornyakov <[email protected]>
bus: imx-weim: fix branch condition evaluates to a garbage value

Liam R. Howlett <[email protected]>
mm/ksm: fix race with VMA iteration and mm_struct teardown

Abel Vesa <[email protected]>
soc: qcom: llcc: Fix slice configuration values for SC8280XP

Manivannan Sadhasivam <[email protected]>
arm64: dts: qcom: sm8150: Fix the iommu mask used for PCIe controllers

Krishna chaitanya chundru <[email protected]>
arm64: dts: qcom: sc7280: Mark PCIe controller as cache coherent

Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix device node validation for mailbox transport

Rijo Thomas <[email protected]>
tee: amdtee: fix race condition in amdtee_open_session

Nathan Chancellor <[email protected]>
riscv: Handle zicsr/zifencei issues between clang and binutils

Dylan Jhong <[email protected]>
riscv: mm: Fix incorrect ASID argument when flushing TLB

Tim Huang <[email protected]>
drm/amdgpu: reposition the gpu reset checking for reuse

Tim Huang <[email protected]>
drm/amdgpu: skip ASIC reset for APUs when go to S4

Ville Syrjälä <[email protected]>

    drm/i915: Preserve crtc_state->inherited during state clearing

Nirmoy Das <[email protected]>
drm/i915/active: Fix missing debug object activation

Kai-Heng Feng <[email protected]>
drm/amdgpu/nv: Apply ASPM quirk on Intel ADL + AMD Navi

Johan Hovold <[email protected]>
drm/meson: fix missing component unbind on bind errors

Hersen Wu <[email protected]>
drm/amd/display: fix wrong index used in dccg32_set_dpstreamclk

Matheus Castello <[email protected]>
drm/bridge: lt8912b: return EPROBE_DEFER if bridge is not found

Ryusuke Konishi <[email protected]>
nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy()

Felix Fietkau <[email protected]>
wifi: mac80211: fix qos on mesh interfaces

Namjae Jeon <[email protected]>
ksmbd: return unsupported error on smb1 mount

Namjae Jeon <[email protected]>
ksmbd: return STATUS_NOT_SUPPORTED on unsupported smb2.0 dialect

Namjae Jeon <[email protected]>
ksmbd: don't terminate inactive sessions after a few seconds

Namjae Jeon <[email protected]>
ksmbd: set FILE_NAMED_STREAMS attribute in FS_ATTRIBUTE_INFORMATION

Namjae Jeon <[email protected]>
ksmbd: fix wrong signingkey creation when encryption is AES256

Liam R. Howlett <[email protected]>
maple_tree: fix mas_skip_node() end slot detection

Liam R. Howlett <[email protected]>
test_maple_tree: add more testing for mas_empty_area()

Peter Collingbourne <[email protected]>
Revert "kasan: drop skip_kasan_poison variable in free_pages_prepare"

Savino Dicanosa <[email protected]>
io_uring/rsrc: fix null-ptr-deref in io_file_bitmap_get()

Jens Axboe <[email protected]>
io_uring/net: avoid sending -ECONNABORTED on repeated connection requests

Marco Elver <[email protected]>
kfence: avoid passing -g for test

Muchun Song <[email protected]>
mm: kfence: fix using kfence_metadata without initialization in show_object()

Hans de Goede <[email protected]>
usb: ucsi_acpi: Increase the command completion timeout

Hans de Goede <[email protected]>
usb: ucsi: Fix NULL pointer deref in ucsi_connector_change()

Wesley Cheng <[email protected]>
usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC

Xu Yang <[email protected]>
usb: chipidea: core: fix possible concurrent when switch role

Xu Yang <[email protected]>
usb: chipdea: core: fix return -EINVAL if request role is the same with current role

Pawel Laszczak <[email protected]>
usb: cdnsp: changes PCI Device ID to fix conflict with CNDS3 driver

Pawel Laszczak <[email protected]>
usb: cdnsp: Fixes issue with redundant Status Stage

Pawel Laszczak <[email protected]>
usb: cdns3: Fix issue with using incorrect PCI device function

Xu Yang <[email protected]>
usb: typec: tcpm: fix warning when handle discover_identity message

Xu Yang <[email protected]>
usb: typec: tcpm: fix create duplicate source-capabilities file

Coly Li <[email protected]>
dm thin: fix deadlock when swapping to thin device

Lin Ma <[email protected]>
igb: revert rtnl_lock() that causes deadlock

Krzysztof Kozlowski <[email protected]>
arm64: dts: imx8mm-nitrogen-r2: fix WM8960 clock name

Jeff Layton <[email protected]>
lockd: set file_lock start and end when decoding nlm4 testargs

Nathan Huckleberry <[email protected]>
fsverity: Remove WQ_UNBOUND from fsverity read workqueue

Eric Biggers <[email protected]>
fscrypt: destroy keyring after security_sb_delete()

Geert Uytterhoeven <[email protected]>
mm/slab: Fix undefined init_cache_node_node() for NUMA and !SMP

Hans de Goede <[email protected]>
efi: sysfb_efi: Fix DMI quirks not working for simpledrm

Min Li <[email protected]>
Bluetooth: Fix race condition in hci_cmd_sync_clear

Naohiro Aota <[email protected]>
btrfs: zoned: fix btrfs_can_activate_zone() to support DUP profile

Alvin Šipraga <[email protected]>
usb: gadget: u_audio: don't let userspace block driver unbind

Fabrice Gasnier <[email protected]>
usb: dwc2: fix a devres leak in hw_enable upon suspend resume

Ziyang Huang <[email protected]>
usb: dwc2: drd: fix inconsistent mode if role-switch-default-mode="host"

Alexander Stein <[email protected]>
usb: misc: onboard-hub: add support for Microchip USB2517 USB 2.0 hub

Joel Selvaraj <[email protected]>
scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR

Chang S. Bae <[email protected]>
selftests/x86/amx: Add a ptrace test

Chang S. Bae <[email protected]>
x86/fpu/xstate: Prevent false-positive warning in __copy_xstate_uabi_buf()

Paulo Alcantara <[email protected]>
cifs: fix dentry lookups in directory handle cache

Shyam Prasad N <[email protected]>
cifs: print session id while listing open files

Shyam Prasad N <[email protected]>
cifs: dump pending mids for all channels in DebugData

Shyam Prasad N <[email protected]>
cifs: empty interface list when server doesn't support query interfaces

Shyam Prasad N <[email protected]>
cifs: do not poll server interfaces too regularly

Shyam Prasad N <[email protected]>
cifs: append path to open_enter trace event

Shyam Prasad N <[email protected]>
cifs: lock chan_lock outside match_session

Davide Caratti <[email protected]>
act_mirred: use the backlog for nested calls to mirred ingress

Davide Caratti <[email protected]>
net/sched: act_mirred: better wording on protection against excessive stack growth

Mario Limonciello <[email protected]>
drm/amd: Fix initialization mistake for NBIO 7.3.0

lyndonli <[email protected]>
drm/amdgpu: Fix call trace warning and hang when removing amdgpu device

Al Viro <[email protected]>
sh: sanitize the flags on sigreturn

Swapnil Patel <[email protected]>
drm/amd/display: Update clock table to include highest clock setting

Enrico Sau <[email protected]>

    net: usb: qmi_wwan: add Telit 0x1080 composition

Enrico Sau <[email protected]>
net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990

Daniel Scally <[email protected]>
platform/x86: int3472: Add GPIOs to Surface Go 3 Board data

Michael Kelley <[email protected]>
scsi: storvsc: Handle BlockSize change in Hyper-V VHD/VHDX file

Ranjan Kumar <[email protected]>
scsi: mpi3mr: Bad drive in topology results kernel crash

Ranjan Kumar <[email protected]>
scsi: mpi3mr: NVMe command size greater than 8K fails

Ranjan Kumar <[email protected]>
scsi: mpi3mr: Wait for diagnostic save during controller init

Ranjan Kumar <[email protected]>
scsi: mpi3mr: Driver unload crashes host when enhanced logging is enabled

Jakob Koschel <[email protected]>
scsi: lpfc: Avoid usage of list iterator variable after loop

Justin Tee <[email protected]>
scsi: lpfc: Check kzalloc() in lpfc_sli4_cgn_params_read()

Adrien Thierry <[email protected]>
scsi: ufs: core: Add soft dependency on governor_simpleondemand

Kang Chen <[email protected]>
scsi: hisi_sas: Check devm_add_action() return value

Daniel Wagner <[email protected]>
scsi: qla2xxx: Add option to disable FC2 Target support

Maurizio Lombardi <[email protected]>
scsi: target: iscsi: Fix an error message in iscsi_check_key()

Lorenz Bauer <[email protected]>
selftests/bpf: check that modifier resolves after pointer

Michael Schmitz <[email protected]>
m68k: Only force 030 bus error if PC not in exception table

Kars de Jong <[email protected]>
m68k: mm: Fix systems with memory at end of 32-bit address space

Reka Norman <[email protected]>
HID: intel-ish-hid: ipc: Fix potential use-after-free in work function

Rafał Szalecki <[email protected]>
HID: logitech-hidpp: Add support for Logitech MX Master 3S mouse

Alexander Aring <[email protected]>
ca8210: fix mac_len negative array access

Danny Kaehn <[email protected]>
HID: cp2112: Fix driver not registering GPIO IRQ chip as threaded

Alexandr Sapozhnikov <[email protected]>

    drm/cirrus: NULL-check pipe->plane.state->fb in cirrus_pipe_update()

Alexandre Ghiti <[email protected]>
riscv: Bump COMMAND_LINE_SIZE value to 1024

Mario Limonciello <[email protected]>
ACPI: x86: utils: Add Cezanne to the list for forcing StorageD3Enable

Mario Limonciello <[email protected]>
ACPI: x86: Drop quirk for HP Elitebook

Duc Anh Le <[email protected]>

    ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A43)

Adrien Thierry <[email protected]>
scsi: ufs: core: Initialize devfreq synchronously

Joseph Hunkeler <[email protected]>
ASoC: amd: yp: Add OMEN by HP Gaming Laptop 16z-n000 to quirks

Tom Rix <[email protected]>
thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit

Mario Limonciello <[email protected]>
thunderbolt: Use const qualifier for ring_interrupt_index

Gil Fine <[email protected]>
thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access

Mario Limonciello <[email protected]>
thunderbolt: Disable interrupt auto clear for rings

Mika Westerberg <[email protected]>
thunderbolt: Fix memory leak in margining

Sanjay R Mehta <[email protected]>
thunderbolt: Add quirk to disable CLx

Mika Westerberg <[email protected]>
thunderbolt: Call tb_check_quirks() after initializing adapters

Mika Westerberg <[email protected]>
thunderbolt: Use scale field when allocating USB3 bandwidth

Yaroslav Furman <[email protected]>
uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2

Steve French <[email protected]>
smb3: fix unusable share after force unmount failure

Steve French <[email protected]>
smb3: lower default deferred close timeout to address perf regression

Nilesh Javali <[email protected]>
scsi: qla2xxx: Perform lockless command completion in abort path

Quinn Tran <[email protected]>
scsi: qla2xxx: Synchronize the IOCB count to be in order

Frank Crawford <[email protected]>
hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs

Phinex Hung <[email protected]>
hwmon: fix potential sensor registration fail if of_node is missing

Frederic Weisbecker <[email protected]>
entry/rcu: Check TIF_RESCHED _after_ delayed RCU wake-up

Breno Leitao <[email protected]>
perf/x86/amd/core: Always clear status for idx

Josh Poimboeuf <[email protected]>
entry: Fix noinstr warning in __enter_from_user_mode()

Tzung-Bi Shih <[email protected]>
platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl

Sungwoo Kim <[email protected]>
Bluetooth: HCI: Fix global-out-of-bounds

Howard Chung <[email protected]>
Bluetooth: mgmt: Fix MGMT add advmon with RSSI command

Zheng Wang <[email protected]>
Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work

Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix responding with wrong PDU type

Stephan Gerhold <[email protected]>
Bluetooth: btqcomsmd: Fix command timeout after setting BD address

Hersen Wu <[email protected]>
drm/amd/display: Set dcn32 caps.seamless_odm

Liang He <[email protected]>
net: mdio: thunder: Add missing fwnode_handle_put()

Arınç ÜNAL <[email protected]>
net: dsa: mt7530: move setting ssc_delta to PHY_INTERFACE_MODE_TRGMII case

Arınç ÜNAL <[email protected]>
net: dsa: mt7530: move lowering TRGMII driving to mt7530_setup()

Arınç ÜNAL <[email protected]>
net: dsa: mt7530: move enabling disabling core clock to mt7530_pll_setup()

Grant Grundler <[email protected]>
net: asix: fix modprobe "sysfs: cannot create duplicate filename"

Joshua Washington <[email protected]>
gve: Cache link_speed value from device

Brian Gix <[email protected]>
Bluetooth: Remove "Power-on" check from Mesh feature

Pauli Virtanen <[email protected]>
Bluetooth: ISO: fix timestamped HCI ISO data packet parsing

Luiz Augusto von Dentz <[email protected]>
Bluetooth: btusb: Remove detection of ISO packets over bulk

Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_core: Detect if an ACL packet is in fact an ISO packet

Zhengping Jiang <[email protected]>
Bluetooth: hci_sync: Resume adv with no RPA when active scan

ChenXiaoSong <[email protected]>
ksmbd: fix possible refcount leak in smb2_open()

Namjae Jeon <[email protected]>
ksmbd: add low bound validation to FSCTL_QUERY_ALLOCATED_RANGES

Namjae Jeon <[email protected]>
ksmbd: add low bound validation to FSCTL_SET_ZERO_DATA

Roger Pau Monne <[email protected]>
hvc/xen: prevent concurrent accesses to the shared ring

Ido Schimmel <[email protected]>
mlxsw: spectrum_fid: Fix incorrect local port type

Caleb Sander <[email protected]>
nvme-tcp: fix nvme_tcp_term_pdu to match spec

Zhang Changzhong <[email protected]>
net/sonic: use dma_mapping_error() for error check

Eric Dumazet <[email protected]>
erspan: do not use skb_mac_header() in ndo_start_xmit()

Li Zetao <[email protected]>

    atm: idt77252: fix kmemleak when rmmod idt77252

Álvaro Fernández Rojas <[email protected]>
net: dsa: tag_brcm: legacy: fix daisy-chained switches

Dan Carpenter <[email protected]>
net/mlx5: E-Switch, Fix an Oops in error handling code

Maher Sanalla <[email protected]>
net/mlx5: Read the TC mapping of all priorities on ETS query

Emeel Hakim <[email protected]>
net/mlx5e: Overcome slow response for first macsec ASO WQE

Lama Kayal <[email protected]>
net/mlx5: Fix steering rules cleanup

Gavin Li <[email protected]>
net/mlx5e: Block entering switchdev mode with ns inconsistency

Gavin Li <[email protected]>
net/mlx5e: Set uplink rep as NETNS_LOCAL

Daniel Borkmann <[email protected]>
bpf: Adjust insufficient default bpf_jit_limit

Radoslaw Tyl <[email protected]>
i40e: fix flow director packet filter programming

Stefan Assmann <[email protected]>
iavf: fix hang on reboot with ice

Michal Swiatkowski <[email protected]>
ice: check if VF exists before mode check

David Howells <[email protected]>
keys: Do not cache key in task struct if key is requested from kernel thread

Masami Hiramatsu (Google) <[email protected]>
bootconfig: Fix testcase to increase max node

Jiasheng Jiang <[email protected]>
octeontx2-vf: Add missing free for alloc_percpu

Geoff Levand <[email protected]>
net/ps3_gelic_net: Use dma_mapping_error

Geoff Levand <[email protected]>
net/ps3_gelic_net: Fix RX sk_buff length

Szymon Heidrich <[email protected]>

    net: usb: lan78xx: Limit packet length to skb->len

Zheng Wang <[email protected]>
net: qcom/emac: Fix use after free bug in emac_remove due to race condition

Andrzej Hajda <[email protected]>
drm/i915/gt: perform uc late init after probe error injection

John Harrison <[email protected]>
drm/i915/guc: Fix missing ecodes

John Harrison <[email protected]>
drm/i915/guc: Rename GuC register state capture node to be more obvious

Tejas Upadhyay <[email protected]>
drm/i915/fbdev: lock the fbdev obj before vma pin

Nirmoy Das <[email protected]>
drm/i915: Print return value on error

Ido Schimmel <[email protected]>
mlxsw: core_thermal: Fix fan speed in maximum cooling state

Daniel Lezcano <[email protected]>
thermal/drivers/mellanox: Use generic thermal_zone_get_trip() function

Jochen Henneberg <[email protected]>
net: stmmac: Fix for mismatched host/device DMA address width

Florian Fainelli <[email protected]>
net: mdio: fix owner field for mdio buses registered using ACPI

Maxime Bizon <[email protected]>
net: mdio: fix owner field for mdio buses registered using device-tree

Florian Fainelli <[email protected]>
net: phy: Ensure state transitions are processed from phy_stop()

Zheng Wang <[email protected]>
xirc2ps_cs: Fix use after free bug in xirc2ps_detach

Daniil Tatianin <[email protected]>
qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info

Ard Biesheuvel <[email protected]>
efi/libstub: smbios: Use length member instead of record struct size

Szymon Heidrich <[email protected]>

    net: usb: smsc95xx: Limit packet length to skb->len

Álvaro Fernández Rojas <[email protected]>
net: dsa: b53: mmap: fix device tree support

Jeff Layton <[email protected]>
nfsd: don't replace page in rq_pages if it's a continuation of last page

Yu Kuai <[email protected]>
scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate()

Yicong Yang <[email protected]>
i2c: hisi: Only use the completion interrupt to finish the transfer

Matthias Schiffer <[email protected]>
i2c: mxs: ensure that DMA buffers are safe for DMA

Alexander Stein <[email protected]>
i2c: imx-lpi2c: check only for enabled interrupt flags

AKASHI Takahiro <[email protected]>
igc: fix the validation logic for taprio's gate list

Akihiko Odaki <[email protected]>
igbvf: Regard vf reset nack as success

Gaosheng Cui <[email protected]>
intel/igbvf: free irq on the error path in igbvf_request_msix()

Ahmed Zaki <[email protected]>
iavf: do not track VLAN 0 filters

Alexander Lobakin <[email protected]>
iavf: fix non-tunneled IPv6 UDP packet type and hashing

Alexander Lobakin <[email protected]>
iavf: fix inverted Rx hash condition leading to disabled hash

Kal Conley <[email protected]>
xsk: Add missing overflow check in xdp_umem_reg

Dave Wysochanski <[email protected]>
NFS: Fix /proc/PID/io read_bytes for buffered reads

Alexander Stein <[email protected]>
arm64: dts: imx93: add missing #address-cells and #size-cells to i2c nodes

Marek Vasut <[email protected]>
arm64: dts: imx8mn: specify #sound-dai-cells for SAI nodes

Peng Fan <[email protected]>
ARM: dts: imx6sl: tolino-shine2hd: fix usbotg1 pinctrl

Peng Fan <[email protected]>
ARM: dts: imx6sll: e60k02: fix usbotg1 pinctrl

Peng Fan <[email protected]>
ARM: dts: imx6sll: e70k02: fix usbotg1 pinctrl

Andrew Halaney <[email protected]>
arm64: dts: imx8dxl-evk: Fix eqos phy reset gpio

Wei Fang <[email protected]>
arm64: dts: imx8dxl-evk: Disable hibernation mode of AR8031 for EQOS

Zheng Wang <[email protected]>
power: supply: da9150: Fix use after free bug in da9150_charger_remove due to race condition

Zheng Wang <[email protected]>
power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition

Manivannan Sadhasivam <[email protected]>
arm64: dts: qcom: sm8450: Mark UFS controller as cache coherent

Cruise Hung <[email protected]>
drm/amd/display: Fix DP MST sinks removal issue

Paolo Abeni <[email protected]>
mptcp: fix UaF in listener shutdown

Paolo Abeni <[email protected]>
mptcp: use the workqueue to destroy unaccepted sockets

Paolo Abeni <[email protected]>
mptcp: refactor passive socket initialization

Saaem Rizvi <[email protected]>
drm/amd/display: Remove OTG DIV register write for Virtual signals.

Aurabindo Pillai <[email protected]>
drm/amd/display: fix k1 k2 divider programming for phantom streams

Eric Bernstein <[email protected]>
drm/amd/display: Include virtual signal to set k1 and k2 values

Costa Shulyupin <[email protected]>
tracing/hwlat: Replace sched_setaffinity with set_cpus_allowed_ptr

Song Liu <[email protected]>

    perf: fix perf_event_context->time

Yang Jihong <[email protected]>
perf/core: Fix perf_output_begin parameter is incorrectly invoked in perf_event_bpf_output

Konrad Dybcio <[email protected]>
interconnect: qcom: qcm2290: Fix MASTER_SNOC_BIMC_NRT

Dmitry Baryshkov <[email protected]>
interconnect: qcom: sm8450: switch to qcom_icc_rpmh_* function

Dmitry Baryshkov <[email protected]>
interconnect: qcom: osm-l3: fix icc_onecell_data allocation

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

Diffstat:

 Makefile                                           |   4 +-
 arch/arm/boot/dts/e60k02.dtsi                      |   1 +
 arch/arm/boot/dts/e70k02.dtsi                      |   1 +
 arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts       |   1 +
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts      |   6 +-
 .../boot/dts/freescale/imx8mm-nitrogen-r2.dts      |   2 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi          |   5 +
 arch/arm64/boot/dts/freescale/imx93.dtsi           |  16 +
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |   2 +
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |   4 +-
 arch/arm64/boot/dts/qcom/sm8450.dtsi               |   1 +
 arch/m68k/kernel/traps.c                           |   4 +-
 arch/m68k/mm/motorola.c                            |  10 +-
 arch/riscv/Kconfig                                 |  22 ++
 arch/riscv/Makefile                                |  10 +-
 arch/riscv/include/asm/tlbflush.h                  |   2 +
 arch/riscv/include/uapi/asm/setup.h                |   8 +
 arch/riscv/mm/context.c                            |   2 +-
 arch/riscv/mm/tlbflush.c                           |   2 +-
 arch/sh/include/asm/processor_32.h                 |   1 +
 arch/sh/kernel/signal_32.c                         |   3 +
 arch/x86/events/amd/core.c                         |   3 +-
 arch/x86/kernel/fpu/xstate.c                       |  30 +-
 drivers/acpi/x86/s2idle.c                          |  24 --
 drivers/acpi/x86/utils.c                           |  37 +--
 drivers/atm/idt77252.c                             |  11 +
 drivers/bluetooth/btqcomsmd.c                      |  17 +-
 drivers/bluetooth/btsdio.c                         |   1 +
 drivers/bluetooth/btusb.c                          |  10 -
 drivers/bus/imx-weim.c                             |   2 +-
 drivers/firmware/arm_scmi/mailbox.c                |  37 +++
 drivers/firmware/efi/libstub/smbios.c              |   2 +-
 drivers/firmware/efi/sysfb_efi.c                   |   5 +-
 drivers/firmware/sysfb.c                           |   4 +-
 drivers/firmware/sysfb_simplefb.c                  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h                |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c           |  41 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |  15 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c         |   2 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c             |  14 +-
 drivers/gpu/drm/amd/amdgpu/nv.c                    |   2 +-
 drivers/gpu/drm/amd/amdgpu/vi.c                    |  17 +-
 drivers/gpu/drm/amd/amdkfd/kfd_crat.c              | 364 +++++----------------
 drivers/gpu/drm/amd/amdkfd/kfd_crat.h              |  12 +
 drivers/gpu/drm/amd/amdkfd/kfd_device.c            |   2 +
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c          | 245 +++++++++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_topology.h          |   5 +-
 .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c |  19 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c      |   9 +
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c  |   3 +-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c |   4 +-
 .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c  |   1 +
 drivers/gpu/drm/bridge/lontium-lt8912b.c           |   4 +-
 drivers/gpu/drm/i915/display/intel_display.c       |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c         |  28 +-
 drivers/gpu/drm/i915/gt/intel_gt.c                 |   4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c     |  30 +-
 drivers/gpu/drm/i915/i915_active.c                 |   3 +-
 drivers/gpu/drm/i915/i915_gpu_error.h              |   2 +-
 drivers/gpu/drm/meson/meson_drv.c                  |  13 +-
 drivers/gpu/drm/tiny/cirrus.c                      |   2 +-
 drivers/hid/hid-cp2112.c                           |   1 +
 drivers/hid/hid-logitech-hidpp.c                   |   2 +
 drivers/hid/intel-ish-hid/ipc/ipc.c                |   9 +-
 drivers/hwmon/hwmon.c                              |   7 +-
 drivers/hwmon/it87.c                               |   4 +-
 drivers/i2c/busses/i2c-hisi.c                      |   6 +-
 drivers/i2c/busses/i2c-imx-lpi2c.c                 |   4 +
 drivers/i2c/busses/i2c-mxs.c                       |  18 +-
 drivers/i2c/busses/i2c-xgene-slimpro.c             |   3 +
 drivers/interconnect/qcom/osm-l3.c                 |   2 +-
 drivers/interconnect/qcom/qcm2290.c                |   4 +-
 drivers/interconnect/qcom/sm8450.c                 |  98 +-----
 drivers/md/dm-crypt.c                              |  16 +-
 drivers/md/dm-stats.c                              |   7 +-
 drivers/md/dm-stats.h                              |   2 +-
 drivers/md/dm-thin.c                               |   2 +
 drivers/md/dm.c                                    |   4 +-
 drivers/net/dsa/b53/b53_mmap.c                     |   2 +-
 drivers/net/dsa/mt7530.c                           |  49 +--
 drivers/net/ethernet/google/gve/gve_ethtool.c      |   5 +-
 drivers/net/ethernet/intel/i40e/i40e_txrx.c        |   8 +-
 drivers/net/ethernet/intel/iavf/iavf_common.c      |   2 +-
 drivers/net/ethernet/intel/iavf/iavf_main.c        |  13 +
 drivers/net/ethernet/intel/iavf/iavf_txrx.c        |   2 +-
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c    |   2 -
 drivers/net/ethernet/intel/ice/ice_sriov.c         |   8 +-
 drivers/net/ethernet/intel/igb/igb_main.c          |   2 -
 drivers/net/ethernet/intel/igbvf/netdev.c          |   8 +-
 drivers/net/ethernet/intel/igbvf/vf.c              |  13 +-
 drivers/net/ethernet/intel/igc/igc_main.c          |  20 +-
 .../net/ethernet/marvell/octeontx2/nic/otx2_vf.c   |   2 +
 .../ethernet/mellanox/mlx5/core/en_accel/macsec.c  |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c |   6 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   6 +-
 .../mellanox/mlx5/core/esw/acl/ingress_ofld.c      |   3 +-
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.c  |   1 +
 .../ethernet/mellanox/mlx5/core/eswitch_offloads.c |  19 ++
 drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 216 +++---------
 drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c |   4 +-
 drivers/net/ethernet/natsemi/sonic.c               |   4 +-
 drivers/net/ethernet/qlogic/qed/qed_sriov.c        |   5 +-
 drivers/net/ethernet/qualcomm/emac/emac.c          |   6 +
 drivers/net/ethernet/stmicro/stmmac/common.h       |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c  |   4 +-
 .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  30 +-
 drivers/net/ethernet/toshiba/ps3_gelic_net.c       |  41 +--
 drivers/net/ethernet/toshiba/ps3_gelic_net.h       |   5 +-
 drivers/net/ethernet/xircom/xirc2ps_cs.c           |   5 +
 drivers/net/ieee802154/ca8210.c                    |   2 +
 drivers/net/mdio/acpi_mdio.c                       |  10 +-
 drivers/net/mdio/mdio-thunder.c                    |   1 +
 drivers/net/mdio/of_mdio.c                         |  12 +-
 drivers/net/phy/mdio_devres.c                      |  11 +-
 drivers/net/phy/phy.c                              |  23 +-
 drivers/net/usb/asix_devices.c                     |  32 +-
 drivers/net/usb/cdc_mbim.c                         |   5 +
 drivers/net/usb/lan78xx.c                          |  18 +-
 drivers/net/usb/qmi_wwan.c                         |   1 +
 drivers/net/usb/smsc95xx.c                         |   6 +
 drivers/platform/chrome/cros_ec_chardev.c          |   2 +-
 .../x86/intel/int3472/tps68470_board_data.c        |   5 +-
 drivers/power/supply/bq24190_charger.c             |   1 +
 drivers/power/supply/da9150-charger.c              |   1 +
 drivers/scsi/device_handler/scsi_dh_alua.c         |   6 +-
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c             |   3 +-
 drivers/scsi/lpfc/lpfc_init.c                      |   2 +
 drivers/scsi/lpfc/lpfc_sli.c                       |  12 +-
 drivers/scsi/mpi3mr/mpi3mr_app.c                   |   4 +-
 drivers/scsi/mpi3mr/mpi3mr_fw.c                    |  19 +-
 drivers/scsi/mpi3mr/mpi3mr_transport.c             |  15 +-
 drivers/scsi/qla2xxx/qla_gbl.h                     |   1 +
 drivers/scsi/qla2xxx/qla_init.c                    |   3 +-
 drivers/scsi/qla2xxx/qla_isr.c                     |   3 +-
 drivers/scsi/qla2xxx/qla_os.c                      |  21 +-
 drivers/scsi/scsi_devinfo.c                        |   1 +
 drivers/scsi/storvsc_drv.c                         |  16 +
 drivers/soc/qcom/llcc-qcom.c                       |   6 +-
 drivers/target/iscsi/iscsi_target_parameters.c     |  12 +-
 drivers/tee/amdtee/core.c                          |  29 +-
 drivers/thunderbolt/debugfs.c                      |  12 +-
 drivers/thunderbolt/nhi.c                          |  49 +--
 drivers/thunderbolt/nhi_regs.h                     |   6 +-
 drivers/thunderbolt/quirks.c                       |  13 +
 drivers/thunderbolt/retimer.c                      |  23 +-
 drivers/thunderbolt/sb_regs.h                      |   1 +
 drivers/thunderbolt/switch.c                       |   4 +-
 drivers/thunderbolt/tb.h                           |  12 +-
 drivers/thunderbolt/usb4.c                         |  36 +-
 drivers/tty/hvc/hvc_xen.c                          |  19 +-
 drivers/ufs/core/ufshcd.c                          |  48 ++-
 drivers/usb/cdns3/cdns3-pci-wrap.c                 |   5 +
 drivers/usb/cdns3/cdnsp-ep0.c                      |  19 +-
 drivers/usb/cdns3/cdnsp-pci.c                      |  27 +-
 drivers/usb/chipidea/ci.h                          |   2 +
 drivers/usb/chipidea/core.c                        |  11 +-
 drivers/usb/chipidea/otg.c                         |   5 +-
 drivers/usb/dwc2/drd.c                             |   3 +-
 drivers/usb/dwc2/platform.c                        |  16 +-
 drivers/usb/dwc3/gadget.c                          |  14 +-
 drivers/usb/gadget/function/u_audio.c              |   2 +-
 drivers/usb/misc/onboard_usb_hub.c                 |   1 +
 drivers/usb/misc/onboard_usb_hub.h                 |   1 +
 drivers/usb/storage/unusual_uas.h                  |   7 +
 drivers/usb/typec/tcpm/tcpm.c                      |  28 +-
 drivers/usb/typec/ucsi/ucsi.c                      |  11 +-
 drivers/usb/typec/ucsi/ucsi_acpi.c                 |   2 +-
 fs/btrfs/zoned.c                                   |  14 +-
 fs/cifs/cached_dir.c                               |  37 ++-
 fs/cifs/cifs_debug.c                               |  46 ++-
 fs/cifs/cifsfs.c                                   |   9 +-
 fs/cifs/cifssmb.c                                  |   6 +-
 fs/cifs/connect.c                                  |  14 +-
 fs/cifs/fs_context.h                               |   2 +-
 fs/cifs/link.c                                     |   2 +
 fs/cifs/smb2inode.c                                |   1 +
 fs/cifs/smb2ops.c                                  |  27 +-
 fs/cifs/smb2pdu.c                                  |  12 +-
 fs/cifs/trace.h                                    |  12 +-
 fs/ksmbd/auth.c                                    |   5 +-
 fs/ksmbd/connection.c                              |  11 +-
 fs/ksmbd/connection.h                              |   3 +-
 fs/ksmbd/smb2pdu.c                                 |  20 +-
 fs/ksmbd/smb_common.c                              |  27 +-
 fs/ksmbd/smb_common.h                              |  30 +-
 fs/ksmbd/transport_rdma.c                          |   2 +-
 fs/ksmbd/transport_tcp.c                           |  35 +-
 fs/lockd/clnt4xdr.c                                |   9 +-
 fs/lockd/xdr4.c                                    |  13 +-
 fs/nfs/read.c                                      |   3 +
 fs/nfsd/vfs.c                                      |   9 +-
 fs/nilfs2/ioctl.c                                  |   2 +-
 fs/super.c                                         |  15 +-
 fs/verity/verify.c                                 |  12 +-
 include/linux/acpi_mdio.h                          |   9 +-
 include/linux/context_tracking.h                   |   1 +
 include/linux/context_tracking_state.h             |   2 +
 include/linux/lockd/xdr4.h                         |   1 +
 include/linux/nvme-tcp.h                           |   5 +-
 include/linux/of_mdio.h                            |  22 +-
 include/linux/stmmac.h                             |   2 +-
 include/linux/sysfb.h                              |   9 +-
 include/ufs/ufshcd.h                               |   1 +
 io_uring/filetable.c                               |   3 +
 io_uring/net.c                                     |  25 +-
 io_uring/rsrc.c                                    |   1 +
 kernel/bpf/core.c                                  |   2 +-
 kernel/entry/common.c                              |   5 +-
 kernel/events/core.c                               |   4 +-
 kernel/sched/core.c                                |   3 +
 kernel/sched/fair.c                                |  54 ++-
 kernel/trace/trace_hwlat.c                         |   4 +-
 lib/maple_tree.c                                   |  24 +-
 lib/test_maple_tree.c                              |  48 +++
 mm/kfence/Makefile                                 |   2 +-
 mm/kfence/core.c                                   |  10 +-
 mm/ksm.c                                           |  11 +-
 mm/page_alloc.c                                    |   3 +-
 mm/slab.c                                          |   2 +-
 net/bluetooth/hci_core.c                           |  23 +-
 net/bluetooth/hci_sync.c                           |  68 ++--
 net/bluetooth/iso.c                                |   9 +-
 net/bluetooth/l2cap_core.c                         | 117 ++++---
 net/bluetooth/mgmt.c                               |   9 +-
 net/dsa/tag_brcm.c                                 |  10 +-
 net/ipv4/ip_gre.c                                  |   4 +-
 net/ipv6/ip6_gre.c                                 |   4 +-
 net/mac80211/wme.c                                 |   6 +-
 net/mptcp/protocol.c                               |  63 ++--
 net/mptcp/protocol.h                               |   6 +-
 net/mptcp/subflow.c                                | 116 ++-----
 net/sched/act_mirred.c                             |  23 +-
 net/xdp/xdp_umem.c                                 |  13 +-
 security/keys/request_key.c                        |   9 +-
 sound/soc/amd/yc/acp6x-mach.c                      |  14 +
 tools/bootconfig/test-bootconfig.sh                |  12 +-
 tools/testing/selftests/bpf/prog_tests/btf.c       |  28 ++
 .../testing/selftests/net/forwarding/tc_actions.sh |  49 ++-
 tools/testing/selftests/x86/amx.c                  | 108 +++++-
 242 files changed, 2367 insertions(+), 1453 deletions(-)
author maintainer
#1 lore raw

PATCH 1/224 interconnect: qcom: osm-l3: fix icc_onecell_data allocation

From: Dmitry Baryshkov <[email protected]>

[ Upstream commit f77ebdda0ee652124061c2ac42399bb6c367e729 ]

This is a struct with a trailing zero-length array of icc_node pointers but it's allocated as if it were a single array of icc_nodes instead.

Fortunately this overallocates memory rather then allocating less memory than required.

Fix by replacing devm_kcalloc() with devm_kzalloc() and struct_size() macro.

Fixes 5bc9900addaf ("interconnect: qcom: Add OSM L3 interconnect provider support")
---
 drivers/interconnect/qcom/osm-l3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/interconnect/qcom/osm-l3.c +1 -1
index 333adb21e7176..46b538e6c07b6 100644
@@ -294,7 +294,7 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
 	qnodes = desc->nodes;
 	num_nodes = desc->num_nodes;
 
-	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
Signature · 1 line
2.39.2
author maintainer
#2 lore raw

PATCH 2/224 interconnect: qcom: sm8450: switch to qcom_icc_rpmh_* function

In reply to Greg Kroah-Hartman

From: Dmitry Baryshkov <[email protected]>

[ Upstream commit 87e8fab1917a2b3f6e3dedfd1cdf22a1416e6676 ]

Change sm8450 interconnect driver to use generic qcom_icc_rpmh_* functions rather than embedding a copy of thema. This also fixes an overallocation of memory for icc_onecell_data structure.

Fixes fafc114a468e ("interconnect: qcom: Add SM8450 interconnect provider driver")
---
 drivers/interconnect/qcom/sm8450.c | 98 +-----------------------------
 1 file changed, 2 insertions(+), 96 deletions(-)
drivers/interconnect/qcom/sm8450.c +2 -96
index e3a12e3d6e061..2d7a8e7b85ec2 100644
@@ -1844,100 +1844,6 @@ static const struct qcom_icc_desc sm8450_system_noc = {
 	.num_bcms = ARRAY_SIZE(system_noc_bcms),
 };
 
-static int qnoc_probe(struct platform_device *pdev)
-{
-	const struct qcom_icc_desc *desc;
-	struct icc_onecell_data *data;
-	struct icc_provider *provider;
-	struct qcom_icc_node * const *qnodes;
-	struct qcom_icc_provider *qp;
-	struct icc_node *node;
-	size_t num_nodes, i;
-	int ret;
-
-	desc = device_get_match_data(&pdev->dev);
-	if (!desc)
-		return -EINVAL;
-
-	qnodes = desc->nodes;
-	num_nodes = desc->num_nodes;
-
-	qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
-	if (!qp)
-		return -ENOMEM;
-
-	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	provider = &qp->provider;
-	provider->dev = &pdev->dev;
-	provider->set = qcom_icc_set;
-	provider->pre_aggregate = qcom_icc_pre_aggregate;
-	provider->aggregate = qcom_icc_aggregate;
-	provider->xlate_extended = qcom_icc_xlate_extended;
-	INIT_LIST_HEAD(&provider->nodes);
-	provider->data = data;
-
-	qp->dev = &pdev->dev;
-	qp->bcms = desc->bcms;
-	qp->num_bcms = desc->num_bcms;
-
-	qp->voter = of_bcm_voter_get(qp->dev, NULL);
-	if (IS_ERR(qp->voter))
-		return PTR_ERR(qp->voter);
-
-	ret = icc_provider_add(provider);
-	if (ret) {
-		dev_err(&pdev->dev, "error adding interconnect provider\n");
-		return ret;
-	}
-
-	for (i = 0; i < qp->num_bcms; i++)
-		qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
-
-	for (i = 0; i < num_nodes; i++) {
-		size_t j;
-
-		if (!qnodes[i])
-			continue;
-
-		node = icc_node_create(qnodes[i]->id);
-		if (IS_ERR(node)) {
-			ret = PTR_ERR(node);
-			goto err;
-		}
-
-		node->name = qnodes[i]->name;
-		node->data = qnodes[i];
-		icc_node_add(node, provider);
-
-		for (j = 0; j < qnodes[i]->num_links; j++)
-			icc_link_create(node, qnodes[i]->links[j]);
-
-		data->nodes[i] = node;
-	}
-	data->num_nodes = num_nodes;
-
-	platform_set_drvdata(pdev, qp);
-
-	return 0;
-err:
-	icc_nodes_remove(provider);
-	icc_provider_del(provider);
-	return ret;
-}
-
-static int qnoc_remove(struct platform_device *pdev)
-{
-	struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
-
-	icc_nodes_remove(&qp->provider);
-	icc_provider_del(&qp->provider);
-
-	return 0;
-}
-
 static const struct of_device_id qnoc_of_match[] = {
 	{ .compatible = "qcom,sm8450-aggre1-noc",
 	  .data = &sm8450_aggre1_noc},
@@ -1966,8 +1872,8 @@ static const struct of_device_id qnoc_of_match[] = {
 MODULE_DEVICE_TABLE(of, qnoc_of_match);
 
 static struct platform_driver qnoc_driver = {
-	.probe = qnoc_probe,
-	.remove = qnoc_remove,
+	.probe = qcom_icc_rpmh_probe,
+	.remove = qcom_icc_rpmh_remove,
 	.driver = {
 		.name = "qnoc-sm8450",
 		.of_match_table = qnoc_of_match,
Signature · 1 line
2.39.2
author maintainer
#3 lore raw

PATCH 3/224 interconnect: qcom: qcm2290: Fix MASTER_SNOC_BIMC_NRT

In reply to Greg Kroah-Hartman

From: Konrad Dybcio <[email protected]>

[ Upstream commit 633a12fda6536a1a17bcea29502e777e86a4547e ]

Due to what seems to be a copy-paste error, the _NRT master was identical to the _RT master, which should not be the case.. Fix it using the values available from the downstream kernel [1].

[1] https://android.googlesource.com/kernel/msm-extra/devicetree/+/refs/heads/android-msm-bramble-4.19-android11-qpr1/qcom/scuba-bus.dtsi#127

Fixes 1a14b1ac3935 ("interconnect: qcom: Add QCM2290 driver support")
---
 drivers/interconnect/qcom/qcm2290.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/interconnect/qcom/qcm2290.c +2 -2
index 0da612d6398c5..a29cdb4fac03f 100644
@@ -147,9 +147,9 @@ static struct qcom_icc_node mas_snoc_bimc_nrt = {
 	.name = "mas_snoc_bimc_nrt",
 	.buswidth = 16,
 	.qos.ap_owned = true,
-	.qos.qos_port = 2,
+	.qos.qos_port = 3,
 	.qos.qos_mode = NOC_QOS_MODE_BYPASS,
-	.mas_rpm_id = 163,
+	.mas_rpm_id = 164,
 	.slv_rpm_id = -1,
 	.num_links = ARRAY_SIZE(mas_snoc_bimc_nrt_links),
 	.links = mas_snoc_bimc_nrt_links,
Signature · 1 line
2.39.2
author maintainer
#4 lore raw

PATCH 4/224 perf/core: Fix perf_output_begin parameter is incorrectly invoked in perf_event_bpf_output

In reply to Greg Kroah-Hartman

From: Yang Jihong <[email protected]>

[ Upstream commit eb81a2ed4f52be831c9fb879752d89645a312c13 ]

syzkaller reportes a KASAN issue with stack-out-of-bounds. The call trace is as follows:

  dump_stack+0x9c/0xd3
  print_address_description.constprop.0+0x19/0x170
  __kasan_report.cold+0x6c/0x84
  kasan_report+0x3a/0x50
  __perf_event_header__init_id+0x34/0x290
  perf_event_header__init_id+0x48/0x60
  perf_output_begin+0x4a4/0x560
  perf_event_bpf_output+0x161/0x1e0
  perf_iterate_sb_cpu+0x29e/0x340
  perf_iterate_sb+0x4c/0xc0
  perf_event_bpf_event+0x194/0x2c0
  __bpf_prog_put.constprop.0+0x55/0xf0
  __cls_bpf_delete_prog+0xea/0x120 [cls_bpf]
  cls_bpf_delete_prog_work+0x1c/0x30 [cls_bpf]
  process_one_work+0x3c2/0x730
  worker_thread+0x93/0x650
  kthread+0x1b8/0x210
  ret_from_fork+0x1f/0x30

commit 267fb27352b6 ("perf: Reduce stack usage of perf_output_begin()") use on-stack struct perf_sample_data of the caller function.

However, perf_event_bpf_output uses incorrect parameter to convert small-sized data (struct perf_bpf_event) into large-sized data (struct perf_sample_data), which causes memory overwriting occurs in __perf_event_header__init_id.

Fixes 267fb27352b6 ("perf: Reduce stack usage of perf_output_begin()")
---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
index 227ada7240295..6c4e78cd7a8b5 100644
@@ -9009,7 +9009,7 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 
 	perf_event_header__init_id(&bpf_event->event_id.header,
 				   &sample, event);
-	ret = perf_output_begin(&handle, data, event,
+	ret = perf_output_begin(&handle, &sample, event,
 				bpf_event->event_id.header.size);
 	if (ret)
 		return;
Signature · 1 line
2.39.2
author maintainer
#5 lore raw

PATCH 5/224 perf: fix perf_event_context->time

In reply to Greg Kroah-Hartman

From: Song Liu <[email protected]>

[ Upstream commit baf1b12a67f5b24f395baca03e442ce27cab0c18 ]

Time readers rely on perf_event_context->[time|timestamp|timeoffset] to get accurate time_enabled and time_running for an event. The difference between ctx->timestamp and ctx->time is the among of time when the context is not enabled. __update_context_time(ctx, false) is used to increase timestamp, but not time. Therefore, it should only be called in ctx_sched_in() when EVENT_TIME was not enabled.

---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
index 6c4e78cd7a8b5..2aa286b4151b3 100644
@@ -3830,7 +3830,7 @@ ctx_sched_in(struct perf_event_context *ctx,
 	if (likely(!ctx->nr_events))
 		return;
 
-	if (is_active ^ EVENT_TIME) {
+	if (!(is_active & EVENT_TIME)) {
 		/* start ctx time */
 		__update_context_time(ctx, false);
 		perf_cgroup_set_timestamp(cpuctx);
Signature · 1 line
2.39.2
author maintainer
#6 lore raw

PATCH 6/224 tracing/hwlat: Replace sched_setaffinity with set_cpus_allowed_ptr

In reply to Greg Kroah-Hartman

From: Costa Shulyupin <[email protected]>

[ Upstream commit 71c7a30442b724717a30d5e7d1662ba4904eb3d4 ]

There is a problem with the behavior of hwlat in a container, resulting in incorrect output. A warning message is generated:
"cpumask changed while in round-robin mode, switching to mode none", and the tracing_cpumask is ignored. This issue arises because the kernel thread, hwlatd, is not a part of the container, and the function sched_setaffinity is unable to locate it using its PID. Additionally, the task_struct of hwlatd is already known. Ultimately, the function set_cpus_allowed_ptr achieves the same outcome as sched_setaffinity, but employs task_struct instead of PID.

Test case:

  # cd /sys/kernel/tracing
  # echo 0 > tracing_on
  # echo round-robin > hwlat_detector/mode
  # echo hwlat > current_tracer
  # unshare --fork --pid bash -c 'echo 1 > tracing_on'
  # dmesg -c

Actual behavior:

[573502.809060] hwlat_detector: cpumask changed while in round-robin mode, switching to mode none
Cc Masami Hiramatsu <[email protected]>
Fixes 0330f7aa8ee63 ("tracing: Have hwlat trace migrate across tracing_cpumask CPUs")
---
 kernel/trace/trace_hwlat.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace_hwlat.c +2 -2
index c4945f8adc119..2f37a6e68aa9f 100644
@@ -339,7 +339,7 @@ static void move_to_next_cpu(void)
 	cpumask_clear(current_mask);
 	cpumask_set_cpu(next_cpu, current_mask);
 
-	sched_setaffinity(0, current_mask);
+	set_cpus_allowed_ptr(current, current_mask);
 	return;
 
  change_mode:
@@ -446,7 +446,7 @@ static int start_single_kthread(struct trace_array *tr)
 
 	}
 
-	sched_setaffinity(kthread->pid, current_mask);
+	set_cpus_allowed_ptr(kthread, current_mask);
 
 	kdata->kthread = kthread;
 	wake_up_process(kthread);
Signature · 1 line
2.39.2
author maintainer
#7 lore raw

PATCH 7/224 drm/amd/display: Include virtual signal to set k1 and k2 values

In reply to Greg Kroah-Hartman

From: Eric Bernstein <[email protected]>

[ Upstream commit 368307cef69ccd9bf5511f25e58e3a103be169fb ]

Stable-dep-of: 709671ffb15d ("drm/amd/display: Remove OTG DIV register write for Virtual signals.")

---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +1 -1
index d0b46a3e01551..f31d8efadeb75 100644
@@ -1180,7 +1180,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
 			*k2_div = PIXEL_RATE_DIV_BY_2;
 		else
 			*k2_div = PIXEL_RATE_DIV_BY_4;
-	} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+	} else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
 		if (two_pix_per_container) {
 			*k1_div = PIXEL_RATE_DIV_BY_1;
 			*k2_div = PIXEL_RATE_DIV_BY_2;
Signature · 1 line
2.39.2
author maintainer
#8 lore raw

PATCH 8/224 drm/amd/display: fix k1 k2 divider programming for phantom streams

In reply to Greg Kroah-Hartman

From: Aurabindo Pillai <[email protected]>

[ Upstream commit 3b214bb7185d8284d7d4c53e15127f69a375abf6 ]

[Why & How]
When k1 and k2 divider programming logic is executed for a phantom stream, the corresponding master stream should be used for the calculation. Fix the if condition to use the master stream for checking signal type instead of the phantom stream.

Stable-dep-of: 709671ffb15d ("drm/amd/display: Remove OTG DIV register write for Virtual signals.")

---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +2 -2
index f31d8efadeb75..f108e82e70c8b 100644
@@ -1174,13 +1174,13 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
 	if (is_dp_128b_132b_signal(pipe_ctx)) {
 		*k1_div = PIXEL_RATE_DIV_BY_1;
 		*k2_div = PIXEL_RATE_DIV_BY_1;
-	} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+	} else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) {
 		*k1_div = PIXEL_RATE_DIV_BY_1;
 		if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
 			*k2_div = PIXEL_RATE_DIV_BY_2;
 		else
 			*k2_div = PIXEL_RATE_DIV_BY_4;
-	} else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
+	} else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
 		if (two_pix_per_container) {
 			*k1_div = PIXEL_RATE_DIV_BY_1;
 			*k2_div = PIXEL_RATE_DIV_BY_2;
Signature · 1 line
2.39.2
author maintainer
#9 lore raw

PATCH 9/224 drm/amd/display: Remove OTG DIV register write for Virtual signals.

In reply to Greg Kroah-Hartman

From: Saaem Rizvi <[email protected]>

[ Upstream commit 709671ffb15dcd1b4f6afe2a9d8c67c7c4ead4a1 ]

[WHY]
Hot plugging and then hot unplugging leads to k1 and k2 values to change, as signal is detected as a virtual signal on hot unplug. Writing these values to OTG_PIXEL_RATE_DIV register might cause primary display to blank (known hw bug).

[HOW]
No longer write k1 and k2 values to register if signal is virtual, we have safe guards in place in the case that k1 and k2 is unassigned so that an unknown value is not written to the register either.

---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +1 -1
index f108e82e70c8b..1a85509c12f23 100644
@@ -1180,7 +1180,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
 			*k2_div = PIXEL_RATE_DIV_BY_2;
 		else
 			*k2_div = PIXEL_RATE_DIV_BY_4;
-	} else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
+	} else if (dc_is_dp_signal(stream->signal)) {
 		if (two_pix_per_container) {
 			*k1_div = PIXEL_RATE_DIV_BY_1;
 			*k2_div = PIXEL_RATE_DIV_BY_2;
Signature · 1 line
2.39.2
author maintainer
#10 lore raw

PATCH 10/224 mptcp: refactor passive socket initialization

In reply to Greg Kroah-Hartman

From: Paolo Abeni <[email protected]>

[ Upstream commit 3a236aef280ed5122b2d47087eb514d0921ae033 ]

After commit 30e51b923e43 ("mptcp: fix unreleased socket in accept queue") unaccepted msk sockets go throu complete shutdown, we don't need anymore to delay inserting the first subflow into the subflow lists.

The reference counting deserve some extra care, as __mptcp_close() is unaware of the request socket linkage to the first subflow.

Please note that this is more a refactoring than a fix but because this modification is needed to include other corrections, see the following commits. Then a Fixes tag has been added here to help the stable team.

---
 net/mptcp/protocol.c | 17 -----------------
 net/mptcp/subflow.c  | 27 +++++++++++++++++++++------
 2 files changed, 21 insertions(+), 23 deletions(-)
net/mptcp/protocol.c +0 -17
index 938cccab331dd..777f795246ed2 100644
@@ -834,7 +834,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
 	if (sk->sk_socket && !ssk->sk_socket)
 		mptcp_sock_graft(ssk, sk->sk_socket);
 
-	mptcp_propagate_sndbuf((struct sock *)msk, ssk);
 	mptcp_sockopt_sync_locked(msk, ssk);
 	return true;
 }
@@ -3729,22 +3728,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
 
 		lock_sock(newsk);
 
-		/* PM/worker can now acquire the first subflow socket
-		 * lock without racing with listener queue cleanup,
-		 * we can notify it, if needed.
-		 *
-		 * Even if remote has reset the initial subflow by now
-		 * the refcnt is still at least one.
-		 */
-		subflow = mptcp_subflow_ctx(msk->first);
-		list_add(&subflow->node, &msk->conn_list);
-		sock_hold(msk->first);
-		if (mptcp_is_fully_established(newsk))
-			mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
-
-		mptcp_rcv_space_init(msk, msk->first);
-		mptcp_propagate_sndbuf(newsk, msk->first);
-
 		/* set ssk->sk_socket of accept()ed flows to mptcp socket.
 		 * This is needed so NOSPACE flag can be set from tcp stack.
 		 */
net/mptcp/subflow.c +21 -6
index 1e10a38ccf9d0..fe815103060c6 100644
@@ -355,6 +355,12 @@ void mptcp_subflow_reset(struct sock *ssk)
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
 	struct sock *sk = subflow->conn;
 
+	/* mptcp_mp_fail_no_response() can reach here on an already closed
+	 * socket
+	 */
+	if (ssk->sk_state == TCP_CLOSE)
+		return;
+
 	/* must hold: tcp_done() could drop last reference on parent */
 	sock_hold(sk);
 
@@ -685,6 +691,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 	struct mptcp_options_received mp_opt;
 	bool fallback, fallback_is_fatal;
 	struct sock *new_msk = NULL;
+	struct mptcp_sock *owner;
 	struct sock *child;
 
 	pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
@@ -759,6 +766,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 		ctx->setsockopt_seq = listener->setsockopt_seq;
 
 		if (ctx->mp_capable) {
+			owner = mptcp_sk(new_msk);
+
 			/* this can't race with mptcp_close(), as the msk is
 			 * not yet exposted to user-space
 			 */
@@ -767,14 +776,14 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 			/* record the newly created socket as the first msk
 			 * subflow, but don't link it yet into conn_list
 			 */
-			WRITE_ONCE(mptcp_sk(new_msk)->first, child);
+			WRITE_ONCE(owner->first, child);
 
 			/* new mpc subflow takes ownership of the newly
 			 * created mptcp socket
 			 */
 			mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq;
-			mptcp_pm_new_connection(mptcp_sk(new_msk), child, 1);
-			mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
+			mptcp_pm_new_connection(owner, child, 1);
+			mptcp_token_accept(subflow_req, owner);
 			ctx->conn = new_msk;
 			new_msk = NULL;
 
@@ -782,15 +791,21 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 			 * uses the correct data
 			 */
 			mptcp_copy_inaddrs(ctx->conn, child);
+			mptcp_propagate_sndbuf(ctx->conn, child);
+
+			mptcp_rcv_space_init(owner, child);
+			list_add(&ctx->node, &owner->conn_list);
+			sock_hold(child);
 
 			/* with OoO packets we can reach here without ingress
 			 * mpc option
 			 */
-			if (mp_opt.suboptions & OPTIONS_MPTCP_MPC)
+			if (mp_opt.suboptions & OPTIONS_MPTCP_MPC) {
 				mptcp_subflow_fully_established(ctx, &mp_opt);
+				mptcp_pm_fully_established(owner, child, GFP_ATOMIC);
+				ctx->pm_notified = 1;
+			}
 		} else if (ctx->mp_join) {
-			struct mptcp_sock *owner;
-
 			owner = subflow_req->msk;
 			if (!owner) {
 				subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
Signature · 1 line
2.39.2
author maintainer
#11 lore raw

PATCH 11/224 mptcp: use the workqueue to destroy unaccepted sockets

In reply to Greg Kroah-Hartman

From: Paolo Abeni <[email protected]>

[ Upstream commit b6985b9b82954caa53f862d6059d06c0526254f0 ]

Backports notes: one simple conflict in net/mptcp/protocol.c with:

commit a5ef058dc4d9 ("net: introduce and use custom sockopt socket flag")

Where the two commits add a new line for different actions in the same context in mptcp_stream_accept().

Christoph reported a UaF at token lookup time after having refactored the passive socket initialization part:

  BUG: KASAN: use-after-free in __token_bucket_busy+0x253/0x260
  Read of size 4 at addr ffff88810698d5b0 by task syz-executor653/3198

  CPU: 1 PID: 3198 Comm: syz-executor653 Not tainted 6.2.0-rc59af4eaa31c1f6c00c8f1e448ed99a45c66340dd5 #6
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
  Call Trace:
   <TASK>
   dump_stack_lvl+0x6e/0x91
   print_report+0x16a/0x46f
   kasan_report+0xad/0x130
   __token_bucket_busy+0x253/0x260
   mptcp_token_new_connect+0x13d/0x490
   mptcp_connect+0x4ed/0x860
   __inet_stream_connect+0x80e/0xd90
   tcp_sendmsg_fastopen+0x3ce/0x710
   mptcp_sendmsg+0xff1/0x1a20
   inet_sendmsg+0x11d/0x140
   __sys_sendto+0x405/0x490
   __x64_sys_sendto+0xdc/0x1b0
   do_syscall_64+0x3b/0x90
   entry_SYSCALL_64_after_hwframe+0x72/0xdc

We need to properly clean-up all the paired MPTCP-level resources and be sure to release the msk last, even when the unaccepted subflow is destroyed by the TCP internals via inet_child_forget().

We can re-use the existing MPTCP_WORK_CLOSE_SUBFLOW infra, explicitly checking that for the critical scenario: the closed subflow is the MPC one, the msk is not accepted and eventually going through full cleanup.

With such change, __mptcp_destroy_sock() is always called on msk sockets, even on accepted ones. We don't need anymore to transiently drop one sk reference at msk clone time.

Please note this commit depends on the parent one:

mptcp: refactor passive socket initialization

---
 net/mptcp/protocol.c | 41 +++++++++++++++++++++++++++++++----------
 net/mptcp/protocol.h |  5 ++++-
 net/mptcp/subflow.c  | 17 ++++++++++++-----
 3 files changed, 47 insertions(+), 16 deletions(-)
net/mptcp/protocol.c +31 -10
index 777f795246ed2..b679e8a430a83 100644
@@ -2357,7 +2357,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		goto out;
 	}
 
-	sock_orphan(ssk);
 	subflow->disposable = 1;
 
 	/* if ssk hit tcp_done(), tcp_cleanup_ulp() cleared the related ops
@@ -2365,7 +2364,20 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 	 * reference owned by msk;
 	 */
 	if (!inet_csk(ssk)->icsk_ulp_ops) {
+		WARN_ON_ONCE(!sock_flag(ssk, SOCK_DEAD));
 		kfree_rcu(subflow, rcu);
+	} else if (msk->in_accept_queue && msk->first == ssk) {
+		/* if the first subflow moved to a close state, e.g. due to
+		 * incoming reset and we reach here before inet_child_forget()
+		 * the TCP stack could later try to close it via
+		 * inet_csk_listen_stop(), or deliver it to the user space via
+		 * accept().
+		 * We can't delete the subflow - or risk a double free - nor let
+		 * the msk survive - or will be leaked in the non accept scenario:
+		 * fallback and let TCP cope with the subflow cleanup.
+		 */
+		WARN_ON_ONCE(sock_flag(ssk, SOCK_DEAD));
+		mptcp_subflow_drop_ctx(ssk);
 	} else {
 		/* otherwise tcp will dispose of the ssk and subflow ctx */
 		if (ssk->sk_state == TCP_LISTEN) {
@@ -2412,9 +2424,10 @@ static unsigned int mptcp_sync_mss(struct sock *sk, u32 pmtu)
 	return 0;
 }
 
-static void __mptcp_close_subflow(struct mptcp_sock *msk)
+static void __mptcp_close_subflow(struct sock *sk)
 {
 	struct mptcp_subflow_context *subflow, *tmp;
+	struct mptcp_sock *msk = mptcp_sk(sk);
 
 	might_sleep();
 
@@ -2428,7 +2441,15 @@ static void __mptcp_close_subflow(struct mptcp_sock *msk)
 		if (!skb_queue_empty_lockless(&ssk->sk_receive_queue))
 			continue;
 
-		mptcp_close_ssk((struct sock *)msk, ssk, subflow);
+		mptcp_close_ssk(sk, ssk, subflow);
+	}
+
+	/* if the MPC subflow has been closed before the msk is accepted,
+	 * msk will never be accept-ed, close it now
+	 */
+	if (!msk->first && msk->in_accept_queue) {
+		sock_set_flag(sk, SOCK_DEAD);
+		inet_sk_state_store(sk, TCP_CLOSE);
 	}
 }
 
@@ -2637,6 +2658,9 @@ static void mptcp_worker(struct work_struct *work)
 	__mptcp_check_send_data_fin(sk);
 	mptcp_check_data_fin(sk);
 
+	if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
+		__mptcp_close_subflow(sk);
+
 	/* There is no point in keeping around an orphaned sk timedout or
 	 * closed, but we need the msk around to reply to incoming DATA_FIN,
 	 * even if it is orphaned and in FIN_WAIT2 state
@@ -2652,9 +2676,6 @@ static void mptcp_worker(struct work_struct *work)
 		}
 	}
 
-	if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
-		__mptcp_close_subflow(msk);
-
 	if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
 		__mptcp_retrans(sk);
 
@@ -3084,6 +3105,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
 	msk->local_key = subflow_req->local_key;
 	msk->token = subflow_req->token;
 	msk->subflow = NULL;
+	msk->in_accept_queue = 1;
 	WRITE_ONCE(msk->fully_established, false);
 	if (mp_opt->suboptions & OPTION_MPTCP_CSUMREQD)
 		WRITE_ONCE(msk->csum_enabled, true);
@@ -3110,8 +3132,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
 	security_inet_csk_clone(nsk, req);
 	bh_unlock_sock(nsk);
 
-	/* keep a single reference */
-	__sock_put(nsk);
+	/* note: the newly allocated socket refcount is 2 now */
 	return nsk;
 }
 
@@ -3167,8 +3188,6 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 			goto out;
 		}
 
-		/* acquire the 2nd reference for the owning socket */
-		sock_hold(new_mptcp_sock);
 		newsk = new_mptcp_sock;
 		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVEACK);
 	} else {
@@ -3726,6 +3745,8 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
 		struct mptcp_subflow_context *subflow;
 		struct sock *newsk = newsock->sk;
 
+		msk->in_accept_queue = 0;
+
 		lock_sock(newsk);
 
 		/* set ssk->sk_socket of accept()ed flows to mptcp socket.
net/mptcp/protocol.h +4 -1
index 6f22ae13c9848..2cddd5b52e8fa 100644
@@ -286,7 +286,8 @@ struct mptcp_sock {
 	u8		recvmsg_inq:1,
 			cork:1,
 			nodelay:1,
-			fastopening:1;
+			fastopening:1,
+			in_accept_queue:1;
 	int		connect_flags;
 	struct work_struct work;
 	struct sk_buff  *ooo_last_skb;
@@ -651,6 +652,8 @@ void mptcp_subflow_set_active(struct mptcp_subflow_context *subflow);
 
 bool mptcp_subflow_active(struct mptcp_subflow_context *subflow);
 
+void mptcp_subflow_drop_ctx(struct sock *ssk);
+
 static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
 					      struct mptcp_subflow_context *ctx)
 {
net/mptcp/subflow.c +12 -5
index fe815103060c6..459621a0410cd 100644
@@ -636,9 +636,10 @@ static bool subflow_hmac_valid(const struct request_sock *req,
 
 static void mptcp_force_close(struct sock *sk)
 {
-	/* the msk is not yet exposed to user-space */
+	/* the msk is not yet exposed to user-space, and refcount is 2 */
 	inet_sk_state_store(sk, TCP_CLOSE);
 	sk_common_release(sk);
+	sock_put(sk);
 }
 
 static void subflow_ulp_fallback(struct sock *sk,
@@ -654,7 +655,7 @@ static void subflow_ulp_fallback(struct sock *sk,
 	mptcp_subflow_ops_undo_override(sk);
 }
 
-static void subflow_drop_ctx(struct sock *ssk)
+void mptcp_subflow_drop_ctx(struct sock *ssk)
 {
 	struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(ssk);
 
@@ -758,7 +759,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 
 			if (new_msk)
 				mptcp_copy_inaddrs(new_msk, child);
-			subflow_drop_ctx(child);
+			mptcp_subflow_drop_ctx(child);
 			goto out;
 		}
 
@@ -849,7 +850,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 	return child;
 
 dispose_child:
-	subflow_drop_ctx(child);
+	mptcp_subflow_drop_ctx(child);
 	tcp_rsk(req)->drop_req = true;
 	inet_csk_prepare_for_destroy_sock(child);
 	tcp_done(child);
@@ -1804,7 +1805,6 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
 		struct sock *sk = (struct sock *)msk;
 		bool do_cancel_work;
 
-		sock_hold(sk);
 		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
 		next = msk->dl_next;
 		msk->first = NULL;
@@ -1892,6 +1892,13 @@ static void subflow_ulp_release(struct sock *ssk)
 		 * when the subflow is still unaccepted
 		 */
 		release = ctx->disposable || list_empty(&ctx->node);
+
+		/* inet_child_forget() does not call sk_state_change(),
+		 * explicitly trigger the socket close machinery
+		 */
+		if (!release && !test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW,
+						  &mptcp_sk(sk)->flags))
+			mptcp_schedule_work(sk);
 		sock_put(sk);
 	}
 
Signature · 1 line
2.39.2
author maintainer
#12 lore raw

PATCH 12/224 mptcp: fix UaF in listener shutdown

In reply to Greg Kroah-Hartman

From: Paolo Abeni <[email protected]>

[ Upstream commit 0a3f4f1f9c27215e4ddcd312558342e57b93e518 ]

Backports notes: one simple conflict in net/mptcp/protocol.c with:

commit f8c9dfbd875b ("mptcp: add pm listener events")

Where one commit removes code in __mptcp_close_ssk() while the other one adds one line at the same place. We can simply remove the whole condition because this extra instruction is not present in v6.1.

As reported by Christoph after having refactored the passive socket initialization, the mptcp listener shutdown path is prone to an UaF issue.

  BUG: KASAN: use-after-free in _raw_spin_lock_bh+0x73/0xe0
  Write of size 4 at addr ffff88810cb23098 by task syz-executor731/1266

  CPU: 1 PID: 1266 Comm: syz-executor731 Not tainted 6.2.0-rc59af4eaa31c1f6c00c8f1e448ed99a45c66340dd5 #6
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
  Call Trace:
   <TASK>
   dump_stack_lvl+0x6e/0x91
   print_report+0x16a/0x46f
   kasan_report+0xad/0x130
   kasan_check_range+0x14a/0x1a0
   _raw_spin_lock_bh+0x73/0xe0
   subflow_error_report+0x6d/0x110
   sk_error_report+0x3b/0x190
   tcp_disconnect+0x138c/0x1aa0
   inet_child_forget+0x6f/0x2e0
   inet_csk_listen_stop+0x209/0x1060
   __mptcp_close_ssk+0x52d/0x610
   mptcp_destroy_common+0x165/0x640
   mptcp_destroy+0x13/0x80
   __mptcp_destroy_sock+0xe7/0x270
   __mptcp_close+0x70e/0x9b0
   mptcp_close+0x2b/0x150
   inet_release+0xe9/0x1f0
   __sock_release+0xd2/0x280
   sock_close+0x15/0x20
   __fput+0x252/0xa20
   task_work_run+0x169/0x250
   exit_to_user_mode_prepare+0x113/0x120
   syscall_exit_to_user_mode+0x1d/0x40
   do_syscall_64+0x48/0x90
   entry_SYSCALL_64_after_hwframe+0x72/0xdc

The msk grace period can legitly expire in between the last reference count dropped in mptcp_subflow_queue_clean() and the later eventual access in inet_csk_listen_stop()

After the previous patch we don't need anymore special-casing msk listener socket cleanup: the mptcp worker will process each of the unaccepted msk sockets.

Just drop the now unnecessary code.

Please note this commit depends on the two parent ones:

mptcp: refactor passive socket initialization
mptcp: use the workqueue to destroy unaccepted sockets

---
 net/mptcp/protocol.c |  5 ---
 net/mptcp/protocol.h |  1 -
 net/mptcp/subflow.c  | 72 --------------------------------------------
 3 files changed, 78 deletions(-)
net/mptcp/protocol.c +0 -5
index b679e8a430a83..f0cde2d7233dc 100644
@@ -2380,11 +2380,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		mptcp_subflow_drop_ctx(ssk);
 	} else {
 		/* otherwise tcp will dispose of the ssk and subflow ctx */
-		if (ssk->sk_state == TCP_LISTEN) {
-			tcp_set_state(ssk, TCP_CLOSE);
-			mptcp_subflow_queue_clean(sk, ssk);
-			inet_csk_listen_stop(ssk);
-		}
 		__tcp_close(ssk, 0);
 
 		/* close acquired an extra ref */
net/mptcp/protocol.h +0 -1
index 2cddd5b52e8fa..051e8022d6611 100644
@@ -615,7 +615,6 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		     struct mptcp_subflow_context *subflow);
 void __mptcp_subflow_send_ack(struct sock *ssk);
 void mptcp_subflow_reset(struct sock *ssk);
-void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
 void mptcp_sock_graft(struct sock *sk, struct socket *parent);
 struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
 bool __mptcp_close(struct sock *sk, long timeout);
net/mptcp/subflow.c +0 -72

78 lines not on this page · raw message

Signature · 1 line
2.39.2
author maintainer
#13 lore raw

PATCH 13/224 drm/amd/display: Fix DP MST sinks removal issue

In reply to Greg Kroah-Hartman

From: Cruise Hung <[email protected]>

[ Upstream commit cbd6c1b17d3b42b7935526a86ad5f66838767d03 ]

[Why]
In USB4 DP tunneling, it's possible to have this scenario that the path becomes unavailable and CM tears down the path a little bit late. So, in this case, the HPD is high but fails to read any DPCD register. That causes the link connection type to be set to sst.
And not all sinks are removed behind the MST branch.

[How]
Restore the link connection type if it fails to read DPCD register.

Cc Mario Limonciello <[email protected]>
(cherry picked from commit cbd6c1b17d3b42b7935526a86ad5f66838767d03)

Modified for stable backport as a lot of the code in this file was moved in 6.3 to drivers/gpu/drm/amd/display/dc/link/link_detection.c.

---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc_link.c +9 -0
index 328c5e33cc66b..bf7fcd268cb47 100644
@@ -1016,6 +1016,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 	struct dc_sink *prev_sink = NULL;
 	struct dpcd_caps prev_dpcd_caps;
 	enum dc_connection_type new_connection_type = dc_connection_none;
+	enum dc_connection_type pre_connection_type = link->type;
 	const uint32_t post_oui_delay = 30; // 30ms
 
 	DC_LOGGER_INIT(link->ctx->logger);
@@ -1118,6 +1119,8 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 			}
 
 			if (!detect_dp(link, &sink_caps, reason)) {
+				link->type = pre_connection_type;
+
 				if (prev_sink)
 					dc_sink_release(prev_sink);
 				return false;
@@ -1349,6 +1352,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 	bool is_delegated_to_mst_top_mgr = false;
 	enum dc_connection_type pre_link_type = link->type;
 
+	DC_LOGGER_INIT(link->ctx->logger);
+
 	is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
 
 	if (is_local_sink_detect_success && link->local_sink)
@@ -1359,6 +1364,10 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 			link->dpcd_caps.is_mst_capable)
 		is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
 
+	DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__,
+		 link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
+
+
 	if (is_local_sink_detect_success &&
 			pre_link_type == dc_connection_mst_branch &&
 			link->type != dc_connection_mst_branch)
Signature · 1 line
2.39.2
author maintainer
#14 lore raw

PATCH 14/224 arm64: dts: qcom: sm8450: Mark UFS controller as cache coherent

In reply to Greg Kroah-Hartman

From: Manivannan Sadhasivam <[email protected]>

[ Upstream commit 8ba961d4339c5db0e69ff6627606fe1f34c838e5 ]

The UFS controller on SM8450 supports cache coherency, hence add the "dma-coherent" property to mark it as such.

---
 arch/arm64/boot/dts/qcom/sm8450.dtsi | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/qcom/sm8450.dtsi +1 -0
index df0d888ffc008..4714d7bf03b9f 100644
@@ -3104,6 +3104,7 @@ ufs_mem_hc: ufshc@1d84000 {
 			power-domains = <&gcc UFS_PHY_GDSC>;
 
 			iommus = <&apps_smmu 0xe0 0x0>;
+			dma-coherent;
 
 			interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
 					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
Signature · 1 line
2.39.2
author maintainer
#15 lore raw

PATCH 15/224 power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition

In reply to Greg Kroah-Hartman

From: Zheng Wang <[email protected]>

[ Upstream commit 47c29d69212911f50bdcdd0564b5999a559010d4 ]

In bq24190_probe, &bdi->input_current_limit_work is bound with bq24190_input_current_limit_work. When external power changed, it will call bq24190_charger_external_power_changed
to start the work.

If we remove the module which will call bq24190_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows:

CPU0 CPUc1

                    |bq24190_input_current_limit_work

bq24190_remove |
power_supply_unregister |
device_unregister |
power_supply_dev_release|

kfree(psy)          |
                    |
                    | power_supply_get_property_from_supplier
                    |   //use

Fix it by finishing the work before cleanup in the bq24190_remove

Fixes 97774672573a ("power_supply: Initialize changed_work before calling device_add")
---
 drivers/power/supply/bq24190_charger.c | 1 +
 1 file changed, 1 insertion(+)
drivers/power/supply/bq24190_charger.c +1 -0
index 2274679c5ddd2..d7400b56820d6 100644
@@ -1906,6 +1906,7 @@ static void bq24190_remove(struct i2c_client *client)
 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
 	int error;
 
+	cancel_delayed_work_sync(&bdi->input_current_limit_work);
 	error = pm_runtime_resume_and_get(bdi->dev);
 	if (error < 0)
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
Signature · 1 line
2.39.2
author maintainer
#16 lore raw

PATCH 16/224 power: supply: da9150: Fix use after free bug in da9150_charger_remove due to race condition

In reply to Greg Kroah-Hartman

From: Zheng Wang <[email protected]>

[ Upstream commit 06615d11cc78162dfd5116efb71f29eb29502d37 ]

In da9150_charger_probe, &charger->otg_work is bound with da9150_charger_otg_work. da9150_charger_otg_ncb may be called to start the work.

If we remove the module which will call da9150_charger_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows:

Fix it by canceling the work before cleanup in the da9150_charger_remove

CPU0 CPUc1

                    |da9150_charger_otg_work

da9150_charger_remove |
power_supply_unregister |
device_unregister |
power_supply_dev_release|

kfree(psy)          |
                    |
                    | 	power_supply_changed(charger->usb);
                    |   //use
Fixes c1a281e34dae ("power: Add support for DA9150 Charger")
---
 drivers/power/supply/da9150-charger.c | 1 +
 1 file changed, 1 insertion(+)
drivers/power/supply/da9150-charger.c +1 -0
index f9314cc0cd75f..6b987da586556 100644
@@ -662,6 +662,7 @@ static int da9150_charger_remove(struct platform_device *pdev)
 
 	if (!IS_ERR_OR_NULL(charger->usb_phy))
 		usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
+	cancel_work_sync(&charger->otg_work);
 
 	power_supply_unregister(charger->battery);
 	power_supply_unregister(charger->usb);
Signature · 1 line
2.39.2
author maintainer
#17 lore raw

PATCH 17/224 arm64: dts: imx8dxl-evk: Disable hibernation mode of AR8031 for EQOS

In reply to Greg Kroah-Hartman

From: Wei Fang <[email protected]>

[ Upstream commit 0deefb5bd1382aae0aed7c8b266d5088a5308a26 ]

The hibernation mode of AR8031 PHY defaults to be enabled after hardware reset. When the cable is unplugged, the PHY will enter hibernation mode after about 10 senconds and the PHY clocks will be stopped to save power. However, due to the design of EQOS, the mac needs the RX_CLK of PHY for software reset to complete. Otherwise the software reset of EQOS will be failed and do not work correctly. The only way is to disable hibernation mode of AR8031 PHY for EQOS, the "qca,disable-hibernation-mode" property is used for this purpose and has already been submitted to the upstream, for more details please refer to the below link:
https://lore.kernel.org/netdev/[email protected]/

This issue is easy to reproduce, just unplug the cable and "ifconfig eth0 down", after about 10 senconds, then "ifconfig eth0 up", you will see failure log on the serial port. The log is shown as following:
root@imx8dxlevk:~#

[34.941970] imx-dwmac 5b050000.ethernet eth0: Link is Down
root@imx8dxlevk:~# ifconfig eth0 down
[35.437814] imx-dwmac 5b050000.ethernet eth0: FPE workqueue stop
[35.507913] imx-dwmac 5b050000.ethernet eth0: PHY [stmmac-1:00] driver [Qualcomm Atheros AR8031/AR8033] (irq=POLL)
[35.518613] imx-dwmac 5b050000.ethernet eth0: configuring for phy/rgmii-id link mode
root@imx8dxlevk:~# ifconfig eth0 up
[71.143044] imx-dwmac 5b050000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
[71.215855] imx-dwmac 5b050000.ethernet eth0: PHY [stmmac-1:00] driver [Qualcomm Atheros AR8031/AR8033] (irq=POLL)
[72.230417] imx-dwmac 5b050000.ethernet: Failed to reset the dma
[72.236512] imx-dwmac 5b050000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed
[72.245258] imx-dwmac 5b050000.ethernet eth0: __stmmac_open: Hw setup failed
SIOCSIFFLAGS: Connection timed out

After applying this patch, the software reset of EQOS will be successful. And the log is shown as below.

root@imx8dxlevk:~# ifconfig eth0 up
[96.114344] imx-dwmac 5b050000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
[96.171466] imx-dwmac 5b050000.ethernet eth0: PHY [stmmac-1:00] driver [Qualcomm Atheros AR8031/AR8033] (irq=POLL)
[96.188883] imx-dwmac 5b050000.ethernet eth0: No Safety Features support found
[96.196221] imx-dwmac 5b050000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
[96.204846] imx-dwmac 5b050000.ethernet eth0: registered PTP clock
[96.225558] imx-dwmac 5b050000.ethernet eth0: FPE workqueue start
[96.236858] imx-dwmac 5b050000.ethernet eth0: configuring for phy/rgmii-id link mode
[96.249358] 8021q: adding VLAN 0 to HW filter on device eth0

Stable-dep-of: feafeb53140a ("arm64: dts: imx8dxl-evk: Fix eqos phy reset gpio")

---
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts +1 -0
index ca2a43e0cbf61..96f5947ed5f41 100644
@@ -113,6 +113,7 @@ ethphy0: ethernet-phy@0 {
 			reg = <0>;
 			eee-broken-1000t;
 			qca,disable-smarteee;
+			qca,disable-hibernation-mode;
 			vddio-supply = <&vddio0>;
 
 			vddio0: vddio-regulator {
Signature · 1 line
2.39.2
author maintainer
#18 lore raw

PATCH 18/224 arm64: dts: imx8dxl-evk: Fix eqos phy reset gpio

In reply to Greg Kroah-Hartman

From: Andrew Halaney <[email protected]>

[ Upstream commit feafeb53140af3cde3fba46b292b15b3a0c0635c ]

The deprecated property is named snps,reset-gpio, but this devicetree used snps,reset-gpios instead which results in the reset not being used and the following make dtbs_check error:

./arch/arm64/boot/dts/freescale/imx8dxl-evk.dtb: ethernet@5b050000: 'snps,reset-gpio' is a dependency of 'snps,reset-delays-us'
From schema: ./Documentation/devicetree/bindings/net/snps,dwmac.yaml

Use the preferred method of defining the reset gpio in the phy node itself. Note that this drops the 10 us pre-delay, but prior this wasn't used at all and a pre-delay doesn't make much sense in this context so it should be fine.

Fixes 8dd495d12374 ("arm64: dts: freescale: add support for i.MX8DXL EVK board")
---
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts +3 -2
index 96f5947ed5f41..3af4c76369741 100644
@@ -99,8 +99,6 @@ &eqos {
 	phy-handle = <&ethphy0>;
 	nvmem-cells = <&fec_mac1>;
 	nvmem-cell-names = "mac-address";
-	snps,reset-gpios = <&pca6416_1 2 GPIO_ACTIVE_LOW>;
-	snps,reset-delays-us = <10 20 200000>;
 	status = "okay";
 
 	mdio {
@@ -114,6 +112,9 @@ ethphy0: ethernet-phy@0 {
 			eee-broken-1000t;
 			qca,disable-smarteee;
 			qca,disable-hibernation-mode;
+			reset-gpios = <&pca6416_1 2 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <20>;
+			reset-deassert-us = <200000>;
 			vddio-supply = <&vddio0>;
 
 			vddio0: vddio-regulator {
Signature · 1 line
2.39.2
author maintainer
#19 lore raw

PATCH 19/224 ARM: dts: imx6sll: e70k02: fix usbotg1 pinctrl

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 3d37f7685d525e58674c23d607020e66d501dcd1 ]

usb@2184000: 'pinctrl-0' is a dependency of 'pinctrl-names'

Fixes 3bb3fd856505 ("ARM: dts: add Netronix E70K02 board common file")
---
 arch/arm/boot/dts/e70k02.dtsi | 1 +
 1 file changed, 1 insertion(+)
arch/arm/boot/dts/e70k02.dtsi +1 -0
index 27ef9a62b23cf..a1f9fbd6004aa 100644
@@ -312,6 +312,7 @@ &usdhc3 {
 
 &usbotg1 {
 	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	disable-over-current;
 	srp-disable;
 	hnp-disable;
Signature · 1 line
2.39.2
author maintainer
#20 lore raw

PATCH 20/224 ARM: dts: imx6sll: e60k02: fix usbotg1 pinctrl

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 957c04e9784c7c757e8cc293d7fb2a60cdf461b6 ]

usb@2184000: 'pinctrl-0' is a dependency of 'pinctrl-names'

Fixes c100ea86e6ab ("ARM: dts: add Netronix E60K02 board common file")
---
 arch/arm/boot/dts/e60k02.dtsi | 1 +
 1 file changed, 1 insertion(+)
arch/arm/boot/dts/e60k02.dtsi +1 -0
index 935e2359f8dfa..07ae964863850 100644
@@ -302,6 +302,7 @@ &usdhc3 {
 
 &usbotg1 {
 	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	disable-over-current;
 	srp-disable;
 	hnp-disable;
Signature · 1 line
2.39.2
author maintainer
#21 lore raw

PATCH 21/224 ARM: dts: imx6sl: tolino-shine2hd: fix usbotg1 pinctrl

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 1cd489e1ada1cffa56bd06fd4609f5a60a985d43 ]

usb@2184000: 'pinctrl-0' is a dependency of 'pinctrl-names'

Fixes 9c7016f1ca6d ("ARM: dts: imx: add devicetree for Tolino Shine 2 HD")
---
 arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts +1 -0
index 663ee9df79e67..d6eee157c63b7 100644
@@ -597,6 +597,7 @@ &usdhc3 {
 
 &usbotg1 {
 	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	disable-over-current;
 	srp-disable;
 	hnp-disable;
Signature · 1 line
2.39.2
author maintainer
#22 lore raw

PATCH 22/224 arm64: dts: imx8mn: specify #sound-dai-cells for SAI nodes

In reply to Greg Kroah-Hartman

From: Marek Vasut <[email protected]>

[ Upstream commit 62fb54148cd6eb456ff031be8fb447c98cf0bd9b ]

Add #sound-dai-cells properties to SAI nodes.

Fixes 9e9860069725 ("arm64: dts: imx8mn: Add SAI nodes")
---
 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm64/boot/dts/freescale/imx8mn.dtsi +5 -0
index ba29b5b556ffa..37246ca9d9075 100644
@@ -295,6 +295,7 @@ spba2: spba-bus@30000000 {
 				sai2: sai@30020000 {
 					compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
 					reg = <0x30020000 0x10000>;
+					#sound-dai-cells = <0>;
 					interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clk IMX8MN_CLK_SAI2_IPG>,
 						<&clk IMX8MN_CLK_DUMMY>,
@@ -309,6 +310,7 @@ sai2: sai@30020000 {
 				sai3: sai@30030000 {
 					compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
 					reg = <0x30030000 0x10000>;
+					#sound-dai-cells = <0>;
 					interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clk IMX8MN_CLK_SAI3_IPG>,
 						 <&clk IMX8MN_CLK_DUMMY>,
@@ -323,6 +325,7 @@ sai3: sai@30030000 {
 				sai5: sai@30050000 {
 					compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
 					reg = <0x30050000 0x10000>;
+					#sound-dai-cells = <0>;
 					interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clk IMX8MN_CLK_SAI5_IPG>,
 						 <&clk IMX8MN_CLK_DUMMY>,
@@ -339,6 +342,7 @@ sai5: sai@30050000 {
 				sai6: sai@30060000 {
 					compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
 					reg = <0x30060000  0x10000>;
+					#sound-dai-cells = <0>;
 					interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clk IMX8MN_CLK_SAI6_IPG>,
 						 <&clk IMX8MN_CLK_DUMMY>,
@@ -396,6 +400,7 @@ spdif1: spdif@30090000 {
 				sai7: sai@300b0000 {
 					compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
 					reg = <0x300b0000 0x10000>;
+					#sound-dai-cells = <0>;
 					interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clk IMX8MN_CLK_SAI7_IPG>,
 						 <&clk IMX8MN_CLK_DUMMY>,
Signature · 1 line
2.39.2
author maintainer
#23 lore raw

PATCH 23/224 arm64: dts: imx93: add missing #address-cells and #size-cells to i2c nodes

In reply to Greg Kroah-Hartman

From: Alexander Stein <[email protected]>

[ Upstream commit b3cdf730486b048ca0bf23bef050550d9fd40422 ]

Add them to the SoC .dtsi, so that not every board has to specify them.

Fixes 1225396fefea ("arm64: dts: imx93: add lpi2c nodes")
---
 arch/arm64/boot/dts/freescale/imx93.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
arch/arm64/boot/dts/freescale/imx93.dtsi +16 -0
index 0247866fc86b0..8ab9f8194702e 100644
@@ -150,6 +150,8 @@ system_counter: timer@44290000 {
 			lpi2c1: i2c@44340000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x44340000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C1_GATE>,
 					 <&clk IMX93_CLK_BUS_AON>;
@@ -160,6 +162,8 @@ lpi2c1: i2c@44340000 {
 			lpi2c2: i2c@44350000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x44350000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C2_GATE>,
 					 <&clk IMX93_CLK_BUS_AON>;
@@ -277,6 +281,8 @@ mu2: mailbox@42440000 {
 			lpi2c3: i2c@42530000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x42530000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C3_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
@@ -287,6 +293,8 @@ lpi2c3: i2c@42530000 {
 			lpi2c4: i2c@42540000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x42540000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C4_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
@@ -351,6 +359,8 @@ lpuart8: serial@426a0000 {
 			lpi2c5: i2c@426b0000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x426b0000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C5_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
@@ -361,6 +371,8 @@ lpi2c5: i2c@426b0000 {
 			lpi2c6: i2c@426c0000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x426c0000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C6_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
@@ -371,6 +383,8 @@ lpi2c6: i2c@426c0000 {
 			lpi2c7: i2c@426d0000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x426d0000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C7_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
@@ -381,6 +395,8 @@ lpi2c7: i2c@426d0000 {
 			lpi2c8: i2c@426e0000 {
 				compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x426e0000 0x10000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_LPI2C8_GATE>,
 					 <&clk IMX93_CLK_BUS_WAKEUP>;
Signature · 1 line
2.39.2
author maintainer
#24 lore raw

PATCH 24/224 NFS: Fix /proc/PID/io read_bytes for buffered reads

In reply to Greg Kroah-Hartman

From: Dave Wysochanski <[email protected]>

[ Upstream commit 9c88ea00fef03031ce6554531e89be82f6a42835 ]

Prior to commit 8786fde8421c ("Convert NFS from readpages to readahead"), nfs_readpages() used the old mm interface read_cache_pages() which called task_io_account_read() for each NFS page read. After this commit, nfs_readpages() is converted to nfs_readahead(), which now uses the new mm interface readahead_page(). The new interface requires callers to call task_io_account_read() themselves. In addition, to nfs_readahead() task_io_account_read() should also be called from nfs_read_folio().

---
 fs/nfs/read.c | 3 +++
 1 file changed, 3 insertions(+)
fs/nfs/read.c +3 -0
index 8ae2c8d1219d8..cd970ce62786b 100644
@@ -15,6 +15,7 @@
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/task_io_accounting_ops.h>
 #include <linux/pagemap.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
@@ -338,6 +339,7 @@ int nfs_read_folio(struct file *file, struct folio *folio)
 
 	trace_nfs_aop_readpage(inode, page);
 	nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
+	task_io_account_read(folio_size(folio));
 
 	/*
 	 * Try to flush any pending writes to the file..
@@ -400,6 +402,7 @@ void nfs_readahead(struct readahead_control *ractl)
 
 	trace_nfs_aop_readahead(inode, readahead_pos(ractl), nr_pages);
 	nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
+	task_io_account_read(readahead_length(ractl));
 
 	ret = -ESTALE;
 	if (NFS_STALE(inode))
Signature · 1 line
2.39.2
author maintainer
#25 lore raw

PATCH 25/224 xsk: Add missing overflow check in xdp_umem_reg

In reply to Greg Kroah-Hartman

From: Kal Conley <[email protected]>

[ Upstream commit c7df4813b149362248d6ef7be41a311e27bf75fe ]

The number of chunks can overflow u32. Make sure to return -EINVAL on overflow. Also remove a redundant u32 cast assigning umem->npgs.

---
 net/xdp/xdp_umem.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
net/xdp/xdp_umem.c +7 -6
index 4681e8e8ad943..02207e852d796 100644
@@ -150,10 +150,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem)
 
 static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 {
-	u32 npgs_rem, chunk_size = mr->chunk_size, headroom = mr->headroom;
 	bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
-	u64 npgs, addr = mr->addr, size = mr->len;
-	unsigned int chunks, chunks_rem;
+	u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
+	u64 addr = mr->addr, size = mr->len;
+	u32 chunks_rem, npgs_rem;
+	u64 chunks, npgs;
 	int err;
 
 	if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
@@ -188,8 +189,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 	if (npgs > U32_MAX)
 		return -EINVAL;
 
-	chunks = (unsigned int)div_u64_rem(size, chunk_size, &chunks_rem);
-	if (chunks == 0)
+	chunks = div_u64_rem(size, chunk_size, &chunks_rem);
+	if (!chunks || chunks > U32_MAX)
 		return -EINVAL;
 
 	if (!unaligned_chunks && chunks_rem)
@@ -202,7 +203,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 	umem->headroom = headroom;
 	umem->chunk_size = chunk_size;
 	umem->chunks = chunks;
-	umem->npgs = (u32)npgs;
+	umem->npgs = npgs;
 	umem->pgs = NULL;
 	umem->user = NULL;
 	umem->flags = mr->flags;
Signature · 1 line
2.39.2
author maintainer
#26 lore raw

PATCH 26/224 iavf: fix inverted Rx hash condition leading to disabled hash

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

[ Upstream commit 32d57f667f871bc5a8babbe27ea4c5e668ee0ea8 ]

Condition, which checks whether the netdev has hashing enabled is inverted. Basically, the tagged commit effectively disabled passing flow hash from descriptor to skb, unless user *disables* it via Ethtool. Commit a876c3ba59a6 ("i40e/i40evf: properly report Rx packet hash") fixed this problem, but only for i40e.
Invert the condition now in iavf and unblock passing hash to skbs again.

Fixes 857942fd1aa1 ("i40e: Fix Rx hash reported to the stack by our driver")
---
 drivers/net/ethernet/intel/iavf/iavf_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_txrx.c +1 -1
index 18b6a702a1d6d..e989feda133c1 100644
@@ -1096,7 +1096,7 @@ static inline void iavf_rx_hash(struct iavf_ring *ring,
 		cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH <<
 			    IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT);
 
-	if (ring->netdev->features & NETIF_F_RXHASH)
+	if (!(ring->netdev->features & NETIF_F_RXHASH))
 		return;
 
 	if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
Signature · 1 line
2.39.2
author maintainer
#27 lore raw

PATCH 27/224 iavf: fix non-tunneled IPv6 UDP packet type and hashing

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

[ Upstream commit de58647b4301fe181f9c38e8b46f7021584ae427 ]

Currently, IAVF's decode_rx_desc_ptype() correctly reports payload type of L4 for IPv4 UDP packets and IPv{4,6} TCP, but only L3 for IPv6 UDP. Originally, i40e, ice and iavf were affected.
Commit 73df8c9e3e3d ("i40e: Correct UDP packet header for non_tunnel-ipv6") fixed that in i40e, then
commit 638a0c8c8861 ("ice: fix incorrect payload indicator on PTYPE") fixed that for ice.
IPv6 UDP is L4 obviously. Fix it and make iavf report correct L4 hash type for such packets, so that the stack won't calculate it on CPU when needs it.

---
 drivers/net/ethernet/intel/iavf/iavf_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_common.c +1 -1
index 34e46a23894f4..43148c07459f8 100644
@@ -661,7 +661,7 @@ struct iavf_rx_ptype_decoded iavf_ptype_lookup[BIT(8)] = {
 	/* Non Tunneled IPv6 */
 	IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
 	IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
-	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3),
+	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
 	IAVF_PTT_UNUSED_ENTRY(91),
 	IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
 	IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
Signature · 1 line
2.39.2
author maintainer
#28 lore raw

PATCH 28/224 iavf: do not track VLAN 0 filters

In reply to Greg Kroah-Hartman

From: Ahmed Zaki <[email protected]>

[ Upstream commit 964290ff32d132bf971d45b29f7de39756dab7c8 ]

When an interface with the maximum number of VLAN filters is brought up, a spurious error is logged:

    [257.483082] 8021q: adding VLAN 0 to HW filter on device enp0s3
    [257.483094] iavf 0000:00:03.0 enp0s3: Max allowed VLAN filters 8. Remove existing VLANs or disable filtering via Ethtool if supported.

The VF driver complains that it cannot add the VLAN 0 filter.

On the other hand, the PF driver always adds VLAN 0 filter on VF initialization. The VF does not need to ask the PF for that filter at all.

Fix the error by not tracking VLAN 0 filters altogether. With that, the check added by commit 0e710a3ffd0c ("iavf: Fix VF driver counting VLAN 0 filters") in iavf_virtchnl.c is useless and might be confusing if left as it suggests that we track VLAN 0.

Fixes 0e710a3ffd0c ("iavf: Fix VF driver counting VLAN 0 filters")
---
 drivers/net/ethernet/intel/iavf/iavf_main.c     | 8 ++++++++
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 2 --
 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +8 -0
index 3dad834b9b8e5..41edcf9e154a3 100644
@@ -893,6 +893,10 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
 {
 	struct iavf_adapter *adapter = netdev_priv(netdev);
 
+	/* Do not track VLAN 0 filter, always added by the PF on VF init */
+	if (!vid)
+		return 0;
+
 	if (!VLAN_FILTERING_ALLOWED(adapter))
 		return -EIO;
 
@@ -919,6 +923,10 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
 {
 	struct iavf_adapter *adapter = netdev_priv(netdev);
 
+	/* We do not track VLAN 0 filter */
+	if (!vid)
+		return 0;
+
 	iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));
 	if (proto == cpu_to_be16(ETH_P_8021Q))
 		clear_bit(vid, adapter->vsi.active_cvlans);
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +0 -2
index 0752fd67c96e5..2c03ca01fdd9c 100644
@@ -2438,8 +2438,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 		list_for_each_entry(f, &adapter->vlan_filter_list, list) {
 			if (f->is_new_vlan) {
 				f->is_new_vlan = false;
-				if (!f->vlan.vid)
-					continue;
 				if (f->vlan.tpid == ETH_P_8021Q)
 					set_bit(f->vlan.vid,
 						adapter->vsi.active_cvlans);
Signature · 1 line
2.39.2
author maintainer
#29 lore raw

PATCH 29/224 intel/igbvf: free irq on the error path in igbvf_request_msix()

In reply to Greg Kroah-Hartman

From: Gaosheng Cui <[email protected]>

[ Upstream commit 85eb39bb39cbb5c086df1e19ba67cc1366693a77 ]

In igbvf_request_msix(), irqs have not been freed on the err path, we need to free it. Fix it.

Fixes d4e0fe01a38a ("igbvf: add new driver to support 82576 virtual functions")
---
 drivers/net/ethernet/intel/igbvf/netdev.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igbvf/netdev.c +6 -2
index 3a32809510fc6..72cb1b56e9f24 100644
@@ -1074,7 +1074,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
 			  igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
 			  netdev);
 	if (err)
-		goto out;
+		goto free_irq_tx;
 
 	adapter->rx_ring->itr_register = E1000_EITR(vector);
 	adapter->rx_ring->itr_val = adapter->current_itr;
@@ -1083,10 +1083,14 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
 	err = request_irq(adapter->msix_entries[vector].vector,
 			  igbvf_msix_other, 0, netdev->name, netdev);
 	if (err)
-		goto out;
+		goto free_irq_rx;
 
 	igbvf_configure_msix(adapter);
 	return 0;
+free_irq_rx:
+	free_irq(adapter->msix_entries[--vector].vector, netdev);
+free_irq_tx:
+	free_irq(adapter->msix_entries[--vector].vector, netdev);
 out:
 	return err;
 }
Signature · 1 line
2.39.2
author maintainer
#30 lore raw

PATCH 30/224 igbvf: Regard vf reset nack as success

In reply to Greg Kroah-Hartman

From: Akihiko Odaki <[email protected]>

[ Upstream commit 02c83791ef969c6a8a150b4927193d0d0e50fb23 ]

vf reset nack actually represents the reset operation itself is performed but no address is assigned. Therefore, e1000_reset_hw_vf should fill the "perm_addr" with the zero address and return success on such an occasion. This prevents its callers in netdev.c from saying PF still resetting, and instead allows them to correctly report that no address is assigned.

Fixes 6ddbc4cf1f4d ("igb: Indicate failure on vf reset for empty mac address")
---
 drivers/net/ethernet/intel/igbvf/vf.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/igbvf/vf.c +10 -3
index b8ba3f94c3632..a47a2e3e548cf 100644
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright(c) 2009 - 2018 Intel Corporation. */
 
+#include <linux/etherdevice.h>
+
 #include "vf.h"
 
 static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
@@ -131,11 +133,16 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
 		/* set our "perm_addr" based on info provided by PF */
 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
 		if (!ret_val) {
-			if (msgbuf[0] == (E1000_VF_RESET |
-					  E1000_VT_MSGTYPE_ACK))
+			switch (msgbuf[0]) {
+			case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK:
 				memcpy(hw->mac.perm_addr, addr, ETH_ALEN);
-			else
+				break;
+			case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK:
+				eth_zero_addr(hw->mac.perm_addr);
+				break;
+			default:
 				ret_val = -E1000_ERR_MAC_INIT;
+			}
 		}
 	}
 
Signature · 1 line
2.39.2
author maintainer
#31 lore raw

PATCH 31/224 igc: fix the validation logic for taprios gate list

In reply to Greg Kroah-Hartman

From: AKASHI Takahiro <[email protected]>

[ Upstream commit 2b4cc3d3f4d8ec42961e98568a0afeee96a943ab ]

The check introduced in the commit a5fd39464a40 ("igc: Lift TAPRIO schedule restriction") can detect a false positive error in some corner case. For instance,

    tc qdisc replace ... taprio num_tc 4
	...
	sched-entry S 0x01 100000	# slot#1
	sched-entry S 0x03 100000	# slot#2
	sched-entry S 0x04 100000	# slot#3
	sched-entry S 0x08 200000	# slot#4
	flags 0x02			# hardware offload

Here the queue#0 (the first queue) is on at the slot#1 and #2, and off at the slot#3 and #4. Under the current logic, when the slot#4 is examined, validate_schedule() returns *false* since the enablement count for the queue#0 is two and it is already off at the previous slot (i.e. #3). But this definition is truely correct.

Let's fix the logic to enforce a strict validation for consecutively-opened slots.

---
 drivers/net/ethernet/intel/igc/igc_main.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/ethernet/intel/igc/igc_main.c +10 -10
index 3b5b36206c44b..1d9b70e0ff67f 100644
@@ -6000,18 +6000,18 @@ static bool validate_schedule(struct igc_adapter *adapter,
 		if (e->command != TC_TAPRIO_CMD_SET_GATES)
 			return false;
 
-		for (i = 0; i < adapter->num_tx_queues; i++) {
-			if (e->gate_mask & BIT(i))
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			if (e->gate_mask & BIT(i)) {
 				queue_uses[i]++;
 
-			/* There are limitations: A single queue cannot be
-			 * opened and closed multiple times per cycle unless the
-			 * gate stays open. Check for it.
-			 */
-			if (queue_uses[i] > 1 &&
-			    !(prev->gate_mask & BIT(i)))
-				return false;
-		}
+				/* There are limitations: A single queue cannot
+				 * be opened and closed multiple times per cycle
+				 * unless the gate stays open. Check for it.
+				 */
+				if (queue_uses[i] > 1 &&
+				    !(prev->gate_mask & BIT(i)))
+					return false;
+			}
 	}
 
 	return true;
Signature · 1 line
2.39.2
author maintainer
#32 lore raw

PATCH 32/224 i2c: imx-lpi2c: check only for enabled interrupt flags

In reply to Greg Kroah-Hartman

From: Alexander Stein <[email protected]>

[ Upstream commit 1c7885004567e8951d65a983be095f254dd20bef ]

When reading from I2C, the Tx watermark is set to 0. Unfortunately the TDF (transmit data flag) is enabled when Tx FIFO entries is equal or less than watermark. So it is set in every case, hence the reset default of 1. This results in the MSR_RDF _and_ MSR_TDF flags to be set thus trying to send Tx data on a read message.
Mask the IRQ status to filter for wanted flags only.

Fixes a55fa9d0e42e ("i2c: imx-lpi2c: add low power i2c bus driver")
---
 drivers/i2c/busses/i2c-imx-lpi2c.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/i2c/busses/i2c-imx-lpi2c.c +4 -0
index 188f2a36d2fd6..9b2f9544c5681 100644
@@ -503,10 +503,14 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
 static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
 {
 	struct lpi2c_imx_struct *lpi2c_imx = dev_id;
+	unsigned int enabled;
 	unsigned int temp;
 
+	enabled = readl(lpi2c_imx->base + LPI2C_MIER);
+
 	lpi2c_imx_intctrl(lpi2c_imx, 0);
 	temp = readl(lpi2c_imx->base + LPI2C_MSR);
+	temp &= enabled;
 
 	if (temp & MSR_RDF)
 		lpi2c_imx_read_rxfifo(lpi2c_imx);
Signature · 1 line
2.39.2
author maintainer
#33 lore raw

PATCH 33/224 i2c: mxs: ensure that DMA buffers are safe for DMA

In reply to Greg Kroah-Hartman

From: Matthias Schiffer <[email protected]>

[ Upstream commit 5190417bdf72c71b65bd9892103c6186816a6e8b ]

We found that after commit 9c46929e7989
("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems"), the PCF85063 RTC driver stopped working on i.MX28 due to regmap_bulk_read() reading bogus data into a stack buffer. This is caused by the i2c-mxs driver using DMA transfers even for messages without the I2C_M_DMA_SAFE flag, and the aforementioned commit enabling vmapped stacks.

As the MXS I2C controller requires DMA for reads of >4 bytes, DMA can't be disabled, so the issue is fixed by using i2c_get_dma_safe_msg_buf() to create a bounce buffer when needed.

Fixes 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems")
---
 drivers/i2c/busses/i2c-mxs.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/i2c/busses/i2c-mxs.c +13 -5
index d113bed795452..e0f3b3545cfe4 100644
@@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
 }
 
 static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
-			struct i2c_msg *msg, uint32_t flags)
+			struct i2c_msg *msg, u8 *buf, uint32_t flags)
 {
 	struct dma_async_tx_descriptor *desc;
 	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
@@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
 		}
 
 		/* Queue the DMA data transfer. */
-		sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+		sg_init_one(&i2c->sg_io[1], buf, msg->len);
 		dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
 		desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
 					DMA_DEV_TO_MEM,
@@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
 		/* Queue the DMA data transfer. */
 		sg_init_table(i2c->sg_io, 2);
 		sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
-		sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+		sg_set_buf(&i2c->sg_io[1], buf, msg->len);
 		dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
 		desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
 					DMA_MEM_TO_DEV,
@@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
 	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
 	int ret;
 	int flags;
+	u8 *dma_buf;
 	int use_pio = 0;
 	unsigned long time_left;
 
@@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
 		if (ret && (ret != -ENXIO))
 			mxs_i2c_reset(i2c);
 	} else {
+		dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
+		if (!dma_buf)
+			return -ENOMEM;
+
 		reinit_completion(&i2c->cmd_complete);
-		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
-		if (ret)
+		ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
+		if (ret) {
+			i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
 			return ret;
+		}
 
 		time_left = wait_for_completion_timeout(&i2c->cmd_complete,
 						msecs_to_jiffies(1000));
+		i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
 		if (!time_left)
 			goto timeout;
 
Signature · 1 line
2.39.2
author maintainer
#34 lore raw

PATCH 34/224 i2c: hisi: Only use the completion interrupt to finish the transfer

In reply to Greg Kroah-Hartman

From: Yicong Yang <[email protected]>

[ Upstream commit d98263512684a47e81bcb72a5408958ecd1e60b0 ]

The controller will always generate a completion interrupt when the transfer is finished normally or not. Currently we use either error or completion interrupt to finish, this may result the completion interrupt unhandled and corrupt the next transfer, especially at low speed mode. Since on error case, the error interrupt will come first then is the completion interrupt. So only use the completion interrupt to finish the whole transfer process.

Fixes d62fbdb99a85 ("i2c: add support for HiSilicon I2C controller")
---
 drivers/i2c/busses/i2c-hisi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-hisi.c +5 -1
index 76c3d8f6fc3c6..d30071f299879 100644
@@ -339,7 +339,11 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
 		hisi_i2c_read_rx_fifo(ctlr);
 
 out:
-	if (int_stat & HISI_I2C_INT_TRANS_CPLT || ctlr->xfer_err) {
+	/*
+	 * Only use TRANS_CPLT to indicate the completion. On error cases we'll
+	 * get two interrupts, INT_ERR first then TRANS_CPLT.
+	 */
+	if (int_stat & HISI_I2C_INT_TRANS_CPLT) {
 		hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL);
 		hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
 		complete(ctlr->completion);
Signature · 1 line
2.39.2
author maintainer
#35 lore raw

PATCH 35/224 scsi: scsi_dh_alua: Fix memleak for qdata in alua_activate()

In reply to Greg Kroah-Hartman

From: Yu Kuai <[email protected]>

[ Upstream commit a13faca032acbf2699293587085293bdfaafc8ae ]

If alua_rtpg_queue() failed from alua_activate(), then 'qdata' is not freed, which will cause following memleak:

unreferenced object 0xffff88810b2c6980 (size 32):
comm "kworker/u16:2", pid 635322, jiffies 4355801099 (age 1216426.076s) hex dump (first 32 bytes):

    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    40 39 24 c1 ff ff ff ff 00 f8 ea 0a 81 88 ff ff  @9$.............
  backtrace:
    [<0000000098f3a26d>] alua_activate+0xb0/0x320
    [<000000003b529641>] scsi_dh_activate+0xb2/0x140
    [<000000007b296db3>] activate_path_work+0xc6/0xe0 [dm_multipath]
    [<000000007adc9ace>] process_one_work+0x3c5/0x730
    [<00000000c457a985>] worker_thread+0x93/0x650
    [<00000000cb80e628>] kthread+0x1ba/0x210
    [<00000000a1e61077>] ret_from_fork+0x22/0x30

Fix the problem by freeing 'qdata' in error path.

Fixes 625fe857e4fa ("scsi: scsi_dh_alua: Check scsi_device_get() return value")
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +4 -2
index 610a51538f034..0781f991e7845 100644
@@ -1117,10 +1117,12 @@ static int alua_activate(struct scsi_device *sdev,
 	rcu_read_unlock();
 	mutex_unlock(&h->init_mutex);
 
-	if (alua_rtpg_queue(pg, sdev, qdata, true))
+	if (alua_rtpg_queue(pg, sdev, qdata, true)) {
 		fn = NULL;
-	else
+	} else {
+		kfree(qdata);
 		err = SCSI_DH_DEV_OFFLINED;
+	}
 	kref_put(&pg->kref, release_port_group);
 out:
 	if (fn)
Signature · 1 line
2.39.2
author maintainer
#36 lore raw

PATCH 36/224 nfsd: dont replace page in rq_pages if its a continuation of last page

In reply to Greg Kroah-Hartman

From: Jeff Layton <[email protected]>

[ Upstream commit 27c934dd8832dd40fd34776f916dc201e18b319b ]

The splice read calls nfsd_splice_actor to put the pages containing file data into the svc_rqst->rq_pages array. It's possible however to get a splice result that only has a partial page at the end, if (e.g.) the filesystem hands back a short read that doesn't cover the whole page.

nfsd_splice_actor will plop the partial page into its rq_pages array and return. Then later, when nfsd_splice_actor is called again, the remainder of the page may end up being filled out. At this point, nfsd_splice_actor will put the page into the array _again_ corrupting the reply. If this is done enough times, rq_next_page will overrun the array and corrupt the trailing fields -- the rq_respages and rq_next_page pointers themselves.

If we've already added the page to the array in the last pass, don't add it to the array a second time when dealing with a splice continuation. This was originally handled properly in nfsd_splice_actor, but commit 91e23b1c3982 ("NFSD: Clean up nfsd_splice_actor()") removed the check for it.

---
 fs/nfsd/vfs.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
fs/nfsd/vfs.c +8 -1
index 59f9a8cee012a..dc3ba13546dd6 100644
@@ -874,8 +874,15 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 	struct page *last_page;
 
 	last_page = page + (offset + sd->len - 1) / PAGE_SIZE;
-	for (page += offset / PAGE_SIZE; page <= last_page; page++)
+	for (page += offset / PAGE_SIZE; page <= last_page; page++) {
+		/*
+		 * Skip page replacement when extending the contents
+		 * of the current page.
+		 */
+		if (page == *(rqstp->rq_next_page - 1))
+			continue;
 		svc_rqst_replace_page(rqstp, page);
+	}
 	if (rqstp->rq_res.page_len == 0)	// first call
 		rqstp->rq_res.page_base = offset % PAGE_SIZE;
 	rqstp->rq_res.page_len += sd->len;
Signature · 1 line
2.39.2
author maintainer
#37 lore raw

PATCH 37/224 net: dsa: b53: mmap: fix device tree support

In reply to Greg Kroah-Hartman

From: Álvaro Fernández Rojas <[email protected]>

[ Upstream commit 30796d0dcb6e41c6558a07950f2ce60c209da867 ]

CPU port should also be enabled in order to get a working switch.

---
 drivers/net/dsa/b53/b53_mmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_mmap.c +1 -1
index e968322dfbf0b..70887e0aece33 100644
@@ -263,7 +263,7 @@ static int b53_mmap_probe_of(struct platform_device *pdev,
 		if (of_property_read_u32(of_port, "reg", &reg))
 			continue;
 
-		if (reg < B53_CPU_PORT)
+		if (reg < B53_N_PORTS)
 			pdata->enabled_ports |= BIT(reg);
 	}
 
Signature · 1 line
2.39.2
author maintainer
#38 lore raw

PATCH 38/224 net: usb: smsc95xx: Limit packet length to skb->len

In reply to Greg Kroah-Hartman

From: Szymon Heidrich <[email protected]>

[ Upstream commit ff821092cf02a70c2bccd2d19269f01e29aa52cf ]

Packet length retrieved from descriptor may be larger than the actual socket buffer length. In such case the cloned skb passed up the network stack will leak kernel memory contents.

Fixes 2f7ca802bdae ("net: Add SMSC LAN9500 USB2.0 10/100 ethernet adapter driver")
---
 drivers/net/usb/smsc95xx.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/usb/smsc95xx.c +6 -0
index 32d2c60d334dc..563ecd27b93ea 100644
@@ -1833,6 +1833,12 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 		size = (u16)((header & RX_STS_FL_) >> 16);
 		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
 
+		if (unlikely(size > skb->len)) {
+			netif_dbg(dev, rx_err, dev->net,
+				  "size err header=0x%08x\n", header);
+			return 0;
+		}
+
 		if (unlikely(header & RX_STS_ES_)) {
 			netif_dbg(dev, rx_err, dev->net,
 				  "Error header=0x%08x\n", header);
Signature · 1 line
2.39.2
author maintainer
#39 lore raw

PATCH 39/224 efi/libstub: smbios: Use length member instead of record struct size

In reply to Greg Kroah-Hartman

From: Ard Biesheuvel <[email protected]>

[ Upstream commit 34343eb06afc04af9178a9883d9354dc12beede0 ]

The type 1 SMBIOS record happens to always be the same size, but there are other record types which have been augmented over time, and so we should really use the length field in the header to decide where the string table starts.

Fixes 550b33cfd4452968 ("arm64: efi: Force the use of ...")
---
 drivers/firmware/efi/libstub/smbios.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/smbios.c +1 -1
index 460418b7f5f5e..aadb422b9637d 100644
@@ -36,7 +36,7 @@ const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
 	if (status != EFI_SUCCESS)
 		return NULL;
 
-	strtable = (u8 *)record + recsize;
+	strtable = (u8 *)record + record->length;
 	for (int i = 1; i < ((u8 *)record)[offset]; i++) {
 		int len = strlen(strtable);
 
Signature · 1 line
2.39.2
author maintainer
#40 lore raw

PATCH 40/224 qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info

In reply to Greg Kroah-Hartman

From: Daniil Tatianin <[email protected]>

[ Upstream commit 25143b6a01d0cc5319edd3de22ffa2578b045550 ]

We have to make sure that the info returned by the helper is valid before using it.

Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool.

Fixes f990c82c385b ("qed*: Add support for ndo_set_vf_trust")
Fixes 733def6a04bf ("qed*: IOV link control")
---
 drivers/net/ethernet/qlogic/qed/qed_sriov.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/qlogic/qed/qed_sriov.c +4 -1
index 0848b5529d48a..911509c2b17d5 100644
@@ -4404,6 +4404,9 @@ qed_iov_configure_min_tx_rate(struct qed_dev *cdev, int vfid, u32 rate)
 	}
 
 	vf = qed_iov_get_vf_info(QED_LEADING_HWFN(cdev), (u16)vfid, true);
+	if (!vf)
+		return -EINVAL;
+
 	vport_id = vf->vport_id;
 
 	return qed_configure_vport_wfq(cdev, vport_id, rate);
@@ -5152,7 +5155,7 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
 
 		/* Validate that the VF has a configured vport */
 		vf = qed_iov_get_vf_info(hwfn, i, true);
-		if (!vf->vport_instance)
+		if (!vf || !vf->vport_instance)
 			continue;
 
 		memset(&params, 0, sizeof(params));
Signature · 1 line
2.39.2
author maintainer
#41 lore raw

PATCH 41/224 xirc2ps_cs: Fix use after free bug in xirc2ps_detach

In reply to Greg Kroah-Hartman

From: Zheng Wang <[email protected]>

[ Upstream commit e8d20c3ded59a092532513c9bd030d1ea66f5f44 ]

In xirc2ps_probe, the local->tx_timeout_task was bounded with xirc2ps_tx_timeout_task. When timeout occurs, it will call xirc_tx_timeout->schedule_work to start the work.

When we call xirc2ps_detach to remove the driver, there may be a sequence as follows:

Stop responding to timeout tasks and complete scheduled tasks before cleanup in xirc2ps_detach, which will fix the problem.

CPU0 CPU1

                    |xirc2ps_tx_timeout_task
xirc2ps_detach      |
  free_netdev       |
    kfree(dev);     |
                    |
                    | do_reset
                    |   //use dev
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 drivers/net/ethernet/xircom/xirc2ps_cs.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/ethernet/xircom/xirc2ps_cs.c +5 -0
index 894e92ef415b9..9f505cf02d965 100644
@@ -503,6 +503,11 @@ static void
 xirc2ps_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
+    struct local_info *local = netdev_priv(dev);
+
+    netif_carrier_off(dev);
+    netif_tx_disable(dev);
+    cancel_work_sync(&local->tx_timeout_task);
 
     dev_dbg(&link->dev, "detach\n");
 
Signature · 1 line
2.39.2
author maintainer
#42 lore raw

PATCH 42/224 net: phy: Ensure state transitions are processed from phy_stop()

In reply to Greg Kroah-Hartman

From: Florian Fainelli <[email protected]>

[ Upstream commit 4203d84032e28f893594a453bd8bc9c3b15c7334 ]

In the phy_disconnect() -> phy_stop() path, we will be forcibly setting the PHY state machine to PHY_HALTED. This invalidates the old_state != phydev->state condition in phy_state_machine() such that we will neither display the state change for debugging, nor will we invoke the link_change_notify() callback.

Factor the code by introducing phy_process_state_change(), and ensure that we process the state change from phy_stop() as well.

Fixes 5c5f626bcace ("net: phy: improve handling link_change_notify callback")
---
 drivers/net/phy/phy.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
drivers/net/phy/phy.c +16 -7
index e741d8aebffe1..d1aea767ed09f 100644
@@ -57,6 +57,18 @@ static const char *phy_state_to_str(enum phy_state st)
 	return NULL;
 }
 
+static void phy_process_state_change(struct phy_device *phydev,
+				     enum phy_state old_state)
+{
+	if (old_state != phydev->state) {
+		phydev_dbg(phydev, "PHY state change %s -> %s\n",
+			   phy_state_to_str(old_state),
+			   phy_state_to_str(phydev->state));
+		if (phydev->drv && phydev->drv->link_change_notify)
+			phydev->drv->link_change_notify(phydev);
+	}
+}
+
 static void phy_link_up(struct phy_device *phydev)
 {
 	phydev->phy_link_change(phydev, true);
@@ -1093,6 +1105,7 @@ EXPORT_SYMBOL(phy_free_interrupt);
 void phy_stop(struct phy_device *phydev)
 {
 	struct net_device *dev = phydev->attached_dev;
+	enum phy_state old_state;
 
 	if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) {
 		WARN(1, "called from state %s\n",
@@ -1101,6 +1114,7 @@ void phy_stop(struct phy_device *phydev)
 	}
 
 	mutex_lock(&phydev->lock);
+	old_state = phydev->state;
 
 	if (phydev->state == PHY_CABLETEST) {
 		phy_abort_cable_test(phydev);
@@ -1111,6 +1125,7 @@ void phy_stop(struct phy_device *phydev)
 		sfp_upstream_stop(phydev->sfp_bus);
 
 	phydev->state = PHY_HALTED;
+	phy_process_state_change(phydev, old_state);
 
 	mutex_unlock(&phydev->lock);
 
@@ -1228,13 +1243,7 @@ void phy_state_machine(struct work_struct *work)
 	if (err < 0)
 		phy_error(phydev);
 
-	if (old_state != phydev->state) {
-		phydev_dbg(phydev, "PHY state change %s -> %s\n",
-			   phy_state_to_str(old_state),
-			   phy_state_to_str(phydev->state));
-		if (phydev->drv && phydev->drv->link_change_notify)
-			phydev->drv->link_change_notify(phydev);
-	}
+	phy_process_state_change(phydev, old_state);
 
 	/* Only re-schedule a PHY state machine change if we are polling the
 	 * PHY, if PHY_MAC_INTERRUPT is set, then we will be moving
Signature · 1 line
2.39.2
author maintainer
#43 lore raw

PATCH 43/224 net: mdio: fix owner field for mdio buses registered using device-tree

In reply to Greg Kroah-Hartman

From: Maxime Bizon <[email protected]>

[ Upstream commit 99669259f3361d759219811e670b7e0742668556 ]

Bus ownership is wrong when using of_mdiobus_register() to register an mdio bus. That function is not inline, so when it calls mdiobus_register() the wrong THIS_MODULE value is captured.

Fixes 90eff9096c01 ("net: phy: Allow splitting MDIO bus/device support from PHYs")
[florian: fix kdoc, added Fixes tag]
---
 drivers/net/mdio/of_mdio.c    | 12 +++++++-----
 drivers/net/phy/mdio_devres.c | 11 ++++++-----
 include/linux/of_mdio.h       | 22 +++++++++++++++++++---
 3 files changed, 32 insertions(+), 13 deletions(-)
drivers/net/mdio/of_mdio.c +7 -5
index 510822d6d0d90..1e46e39f5f46a 100644
@@ -139,21 +139,23 @@ bool of_mdiobus_child_is_phy(struct device_node *child)
 EXPORT_SYMBOL(of_mdiobus_child_is_phy);
 
 /**
- * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
+ * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree
  * @mdio: pointer to mii_bus structure
  * @np: pointer to device_node of MDIO bus.
+ * @owner: module owning the @mdio object.
  *
  * This function registers the mii_bus structure and registers a phy_device
  * for each child node of @np.
  */
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
+			  struct module *owner)
 {
 	struct device_node *child;
 	bool scanphys = false;
 	int addr, rc;
 
 	if (!np)
-		return mdiobus_register(mdio);
+		return __mdiobus_register(mdio, owner);
 
 	/* Do not continue if the node is disabled */
 	if (!of_device_is_available(np))
@@ -172,7 +174,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 	of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us);
 
 	/* Register the MDIO bus */
-	rc = mdiobus_register(mdio);
+	rc = __mdiobus_register(mdio, owner);
 	if (rc)
 		return rc;
 
@@ -236,7 +238,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 	mdiobus_unregister(mdio);
 	return rc;
 }
-EXPORT_SYMBOL(of_mdiobus_register);
+EXPORT_SYMBOL(__of_mdiobus_register);
 
 /**
  * of_mdio_find_device - Given a device tree node, find the mdio_device
drivers/net/phy/mdio_devres.c +6 -5
index b560e99695dfd..69b829e6ab35b 100644
@@ -98,13 +98,14 @@ EXPORT_SYMBOL(__devm_mdiobus_register);
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
 /**
- * devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
+ * __devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
  * @dev:	Device to register mii_bus for
  * @mdio:	MII bus structure to register
  * @np:		Device node to parse
+ * @owner:	Owning module
  */
-int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
-			     struct device_node *np)
+int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
+			       struct device_node *np, struct module *owner)
 {
 	struct mdiobus_devres *dr;
 	int ret;
@@ -117,7 +118,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
 	if (!dr)
 		return -ENOMEM;
 
-	ret = of_mdiobus_register(mdio, np);
+	ret = __of_mdiobus_register(mdio, np, owner);
 	if (ret) {
 		devres_free(dr);
 		return ret;
@@ -127,7 +128,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
 	devres_add(dev, dr);
 	return 0;
 }
-EXPORT_SYMBOL(devm_of_mdiobus_register);
+EXPORT_SYMBOL(__devm_of_mdiobus_register);
 #endif /* CONFIG_OF_MDIO */
 
 MODULE_LICENSE("GPL");
include/linux/of_mdio.h +19 -3
index da633d34ab866..8a52ef2e6fa6b 100644
@@ -14,9 +14,25 @@
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
 bool of_mdiobus_child_is_phy(struct device_node *child);
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
-int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
-			     struct device_node *np);
+int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
+			  struct module *owner);
+
+static inline int of_mdiobus_register(struct mii_bus *mdio,
+				      struct device_node *np)
+{
+	return __of_mdiobus_register(mdio, np, THIS_MODULE);
+}
+
+int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
+			       struct device_node *np, struct module *owner);
+
+static inline int devm_of_mdiobus_register(struct device *dev,
+					   struct mii_bus *mdio,
+					   struct device_node *np)
+{
+	return __devm_of_mdiobus_register(dev, mdio, np, THIS_MODULE);
+}
+
 struct mdio_device *of_mdio_find_device(struct device_node *np);
 struct phy_device *of_phy_find_device(struct device_node *phy_np);
 struct phy_device *
Signature · 1 line
2.39.2
author maintainer
#44 lore raw

PATCH 44/224 net: mdio: fix owner field for mdio buses registered using ACPI

In reply to Greg Kroah-Hartman

From: Florian Fainelli <[email protected]>

[ Upstream commit 30b605b8501e321f79e19c3238aa6ca31da6087c ]

Bus ownership is wrong when using acpi_mdiobus_register() to register an mdio bus. That function is not inline, so when it calls mdiobus_register() the wrong THIS_MODULE value is captured.

CC Maxime Bizon <[email protected]>
Fixes 803ca24d2f92 ("net: mdio: Add ACPI support code for mdio")
---
 drivers/net/mdio/acpi_mdio.c | 10 ++++++----
 include/linux/acpi_mdio.h    |  9 ++++++++-
 2 files changed, 14 insertions(+), 5 deletions(-)
drivers/net/mdio/acpi_mdio.c +6 -4
index d77c987fda9cd..4630dde019749 100644
@@ -18,16 +18,18 @@ MODULE_AUTHOR("Calvin Johnson <[email protected]>");
 MODULE_LICENSE("GPL");
 
 /**
- * acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
+ * __acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
  * @mdio: pointer to mii_bus structure
  * @fwnode: pointer to fwnode of MDIO bus. This fwnode is expected to represent
+ * @owner: module owning this @mdio object.
  * an ACPI device object corresponding to the MDIO bus and its children are
  * expected to correspond to the PHY devices on that bus.
  *
  * This function registers the mii_bus structure and registers a phy_device
  * for each child node of @fwnode.
  */
-int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode,
+			    struct module *owner)
 {
 	struct fwnode_handle *child;
 	u32 addr;
@@ -35,7 +37,7 @@ int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
 
 	/* Mask out all PHYs from auto probing. */
 	mdio->phy_mask = GENMASK(31, 0);
-	ret = mdiobus_register(mdio);
+	ret = __mdiobus_register(mdio, owner);
 	if (ret)
 		return ret;
 
@@ -55,4 +57,4 @@ int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
 	}
 	return 0;
 }
-EXPORT_SYMBOL(acpi_mdiobus_register);
+EXPORT_SYMBOL(__acpi_mdiobus_register);
include/linux/acpi_mdio.h +8 -1
index 0a24ab7cb66fa..8e2eefa9fbc0f 100644
@@ -9,7 +9,14 @@
 #include <linux/phy.h>
 
 #if IS_ENABLED(CONFIG_ACPI_MDIO)
-int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode);
+int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode,
+			    struct module *owner);
+
+static inline int
+acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *handle)
+{
+	return __acpi_mdiobus_register(mdio, handle, THIS_MODULE);
+}
 #else /* CONFIG_ACPI_MDIO */
 static inline int
 acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
Signature · 1 line
2.39.2
author maintainer
#45 lore raw

PATCH 45/224 net: stmmac: Fix for mismatched host/device DMA address width

In reply to Greg Kroah-Hartman

From: Jochen Henneberg <[email protected]>

[ Upstream commit 070246e4674b125860d311c18ce2623e73e2bd51 ]

Currently DMA address width is either read from a RO device register or force set from the platform data. This breaks DMA when the host DMA address width is <=32it but the device is >32bit.

Right now the driver may decide to use a 2nd DMA descriptor for another buffer (happens in case of TSO xmit) assuming that 32bit addressing is used due to platform configuration but the device will still use both descriptor addresses as one address.

This can be observed with the Intel EHL platform driver that sets 32bit for addr64 but the MAC reports 40bit. The TX queue gets stuck in case of TCP with iptables NAT configuration on TSO packets.

The logic should be like this: Whatever we do on the host side (memory allocation GFP flags) should happen with the host DMA width, whenever we decide how to set addresses on the device registers we must use the device DMA address width.

This patch renames the platform address width field from addr64 (term used in device datasheet) to host_addr and uses this value exclusively for host side operations while all chip operations consider the device DMA width as read from the device register.

Fixes 7cfc4486e7ea ("stmmac: intel: Configure EHL PSE0 GbE and PSE1 GbE to 32 bits DMA addressing")
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
 .../net/ethernet/stmicro/stmmac/dwmac-imx.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c |  4 +--
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 30 ++++++++++---------
 include/linux/stmmac.h                        |  2 +-
 6 files changed, 22 insertions(+), 19 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +1 -0
index 6b5d96bced475..ec9c130276d89 100644
@@ -418,6 +418,7 @@ struct dma_features {
 	unsigned int frpbs;
 	unsigned int frpes;
 	unsigned int addr64;
+	unsigned int host_dma_width;
 	unsigned int rssen;
 	unsigned int vlhash;
 	unsigned int sphen;
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c +1 -1
index bd52fb7cf4860..0d6a84199fd8a 100644
@@ -251,7 +251,7 @@ static int imx_dwmac_probe(struct platform_device *pdev)
 		goto err_parse_dt;
 	}
 
-	plat_dat->addr64 = dwmac->ops->addr_width;
+	plat_dat->host_dma_width = dwmac->ops->addr_width;
 	plat_dat->init = imx_dwmac_init;
 	plat_dat->exit = imx_dwmac_exit;
 	plat_dat->clks_config = imx_dwmac_clks_config;
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +2 -2
index 7deb1f817dacc..13aa919633b47 100644
@@ -684,7 +684,7 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
 
 	intel_priv->is_pse = true;
 	plat->bus_id = 2;
-	plat->addr64 = 32;
+	plat->host_dma_width = 32;
 
 	plat->clk_ptp_rate = 200000000;
 
@@ -725,7 +725,7 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
 
 	intel_priv->is_pse = true;
 	plat->bus_id = 3;
-	plat->addr64 = 32;
+	plat->host_dma_width = 32;
 
 	plat->clk_ptp_rate = 200000000;
 
drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c +1 -1
index 2f7d8e4561d92..9ae31e3dc8218 100644
@@ -591,7 +591,7 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
 	plat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
 	plat->riwt_off = 1;
 	plat->maxmtu = ETH_DATA_LEN;
-	plat->addr64 = priv_plat->variant->dma_bit_mask;
+	plat->host_dma_width = priv_plat->variant->dma_bit_mask;
 	plat->bsp_priv = priv_plat;
 	plat->init = mediatek_dwmac_init;
 	plat->clks_config = mediatek_dwmac_clks_config;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +16 -14
index 3c1d4b27668fe..93321437f0933 100644
@@ -1429,7 +1429,7 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv,
 	struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
 	gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
 
-	if (priv->dma_cap.addr64 <= 32)
+	if (priv->dma_cap.host_dma_width <= 32)
 		gfp |= GFP_DMA32;
 
 	if (!buf->page) {
@@ -4585,7 +4585,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
 	unsigned int entry = rx_q->dirty_rx;
 	gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
 
-	if (priv->dma_cap.addr64 <= 32)
+	if (priv->dma_cap.host_dma_width <= 32)
 		gfp |= GFP_DMA32;
 
 	while (dirty-- > 0) {
@@ -6201,7 +6201,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "\tFlexible RX Parser: %s\n",
 		   priv->dma_cap.frpsel ? "Y" : "N");
 	seq_printf(seq, "\tEnhanced Addressing: %d\n",
-		   priv->dma_cap.addr64);
+		   priv->dma_cap.host_dma_width);
 	seq_printf(seq, "\tReceive Side Scaling: %s\n",
 		   priv->dma_cap.rssen ? "Y" : "N");
 	seq_printf(seq, "\tVLAN Hash Filtering: %s\n",
@@ -7171,20 +7171,22 @@ int stmmac_dvr_probe(struct device *device,
 		dev_info(priv->device, "SPH feature enabled\n");
 	}
 
-	/* The current IP register MAC_HW_Feature1[ADDR64] only define
-	 * 32/40/64 bit width, but some SOC support others like i.MX8MP
-	 * support 34 bits but it map to 40 bits width in MAC_HW_Feature1[ADDR64].
-	 * So overwrite dma_cap.addr64 according to HW real design.
+	/* Ideally our host DMA address width is the same as for the
+	 * device. However, it may differ and then we have to use our
+	 * host DMA width for allocation and the device DMA width for
+	 * register handling.
 	 */
-	if (priv->plat->addr64)
-		priv->dma_cap.addr64 = priv->plat->addr64;
+	if (priv->plat->host_dma_width)
+		priv->dma_cap.host_dma_width = priv->plat->host_dma_width;
+	else
+		priv->dma_cap.host_dma_width = priv->dma_cap.addr64;
 
-	if (priv->dma_cap.addr64) {
+	if (priv->dma_cap.host_dma_width) {
 		ret = dma_set_mask_and_coherent(device,
-				DMA_BIT_MASK(priv->dma_cap.addr64));
+				DMA_BIT_MASK(priv->dma_cap.host_dma_width));
 		if (!ret) {
-			dev_info(priv->device, "Using %d bits DMA width\n",
-				 priv->dma_cap.addr64);
+			dev_info(priv->device, "Using %d/%d bits DMA host/device width\n",
+				 priv->dma_cap.host_dma_width, priv->dma_cap.addr64);
 
 			/*
 			 * If more than 32 bits can be addressed, make sure to
@@ -7199,7 +7201,7 @@ int stmmac_dvr_probe(struct device *device,
 				goto error_hw_init;
 			}
 
-			priv->dma_cap.addr64 = 32;
+			priv->dma_cap.host_dma_width = 32;
 		}
 	}
 
include/linux/stmmac.h +1 -1
index 313edd19bf545..d82ff9fa1a6e8 100644
@@ -215,7 +215,7 @@ struct plat_stmmacenet_data {
 	int unicast_filter_entries;
 	int tx_fifo_size;
 	int rx_fifo_size;
-	u32 addr64;
+	u32 host_dma_width;
 	u32 rx_queues_to_use;
 	u32 tx_queues_to_use;
 	u8 rx_sched_algorithm;
Signature · 1 line
2.39.2
author maintainer
#46 lore raw

PATCH 46/224 thermal/drivers/mellanox: Use generic thermal_zone_get_trip() function

In reply to Greg Kroah-Hartman

From: Daniel Lezcano <[email protected]>

[ Upstream commit 44a29a4dab73411671e0b84817a5f07e291b1501 ]

The thermal framework gives the possibility to register the trip points with the thermal zone. When that is done, no get_trip_* ops are needed and they can be removed.

Convert ops content logic into generic trip points and register them with the thermal zone.

Stable-dep-of: 6d206b1ea9f4 ("mlxsw: core_thermal: Fix fan speed in maximum cooling state")

---
 .../ethernet/mellanox/mlxsw/core_thermal.c    | 209 ++++--------------
 1 file changed, 48 insertions(+), 161 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +48 -161
index 987fe5c9d5a36..c5240d38c9dbd 100644
@@ -36,33 +36,39 @@ enum mlxsw_thermal_trips {
 	MLXSW_THERMAL_TEMP_TRIP_HOT,
 };
 
-struct mlxsw_thermal_trip {
-	int	type;
-	int	temp;
-	int	hyst;
+struct mlxsw_cooling_states {
 	int	min_state;
 	int	max_state;
 };
 
-static const struct mlxsw_thermal_trip default_thermal_trips[] = {
+static const struct thermal_trip default_thermal_trips[] = {
 	{	/* In range - 0-40% PWM */
 		.type		= THERMAL_TRIP_ACTIVE,
-		.temp		= MLXSW_THERMAL_ASIC_TEMP_NORM,
-		.hyst		= MLXSW_THERMAL_HYSTERESIS_TEMP,
-		.min_state	= 0,
-		.max_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
+		.temperature	= MLXSW_THERMAL_ASIC_TEMP_NORM,
+		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
 	},
 	{
 		/* In range - 40-100% PWM */
 		.type		= THERMAL_TRIP_ACTIVE,
-		.temp		= MLXSW_THERMAL_ASIC_TEMP_HIGH,
-		.hyst		= MLXSW_THERMAL_HYSTERESIS_TEMP,
-		.min_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
-		.max_state	= MLXSW_THERMAL_MAX_STATE,
+		.temperature	= MLXSW_THERMAL_ASIC_TEMP_HIGH,
+		.hysteresis	= MLXSW_THERMAL_HYSTERESIS_TEMP,
 	},
 	{	/* Warning */
 		.type		= THERMAL_TRIP_HOT,
-		.temp		= MLXSW_THERMAL_ASIC_TEMP_HOT,
+		.temperature	= MLXSW_THERMAL_ASIC_TEMP_HOT,
+	},
+};
+
+static const struct mlxsw_cooling_states default_cooling_states[] = {
+	{
+		.min_state	= 0,
+		.max_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
+	},
+	{
+		.min_state	= (4 * MLXSW_THERMAL_MAX_STATE) / 10,
+		.max_state	= MLXSW_THERMAL_MAX_STATE,
+	},
+	{
 		.min_state	= MLXSW_THERMAL_MAX_STATE,
 		.max_state	= MLXSW_THERMAL_MAX_STATE,
 	},
@@ -78,7 +84,8 @@ struct mlxsw_thermal;
 struct mlxsw_thermal_module {
 	struct mlxsw_thermal *parent;
 	struct thermal_zone_device *tzdev;
-	struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
+	struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
+	struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
 	int module; /* Module or gearbox number */
 	u8 slot_index;
 };
@@ -99,7 +106,8 @@ struct mlxsw_thermal {
 	int polling_delay;
 	struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
 	u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
-	struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
+	struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
+	struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
 	struct mlxsw_thermal_area line_cards[];
 };
 
@@ -136,9 +144,9 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
 static void
 mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz)
 {
-	tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = 0;
-	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = 0;
-	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = 0;
+	tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = 0;
+	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = 0;
+	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = 0;
 }
 
 static int
@@ -180,12 +188,12 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
 	 * by subtracting double hysteresis value.
 	 */
 	if (crit_temp >= MLXSW_THERMAL_MODULE_TEMP_SHIFT)
-		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp -
+		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp -
 					MLXSW_THERMAL_MODULE_TEMP_SHIFT;
 	else
-		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp;
-	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp;
-	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp;
+		tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp;
+	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = crit_temp;
+	tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = emerg_temp;
 
 	return 0;
 }
@@ -202,11 +210,11 @@ static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
 		return 0;
 
 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
-		const struct mlxsw_thermal_trip *trip = &thermal->trips[i];
+		const struct mlxsw_cooling_states *state = &thermal->cooling_states[i];
 
 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
-						       trip->max_state,
-						       trip->min_state,
+						       state->max_state,
+						       state->min_state,
 						       THERMAL_WEIGHT_DEFAULT);
 		if (err < 0) {
 			dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
@@ -260,61 +268,6 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
 	return 0;
 }
 
-static int mlxsw_thermal_get_trip_type(struct thermal_zone_device *tzdev,
-				       int trip,
-				       enum thermal_trip_type *p_type)
-{
-	struct mlxsw_thermal *thermal = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	*p_type = thermal->trips[trip].type;
-	return 0;
-}
-
-static int mlxsw_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
-				       int trip, int *p_temp)
-{
-	struct mlxsw_thermal *thermal = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	*p_temp = thermal->trips[trip].temp;
-	return 0;
-}
-
-static int mlxsw_thermal_set_trip_temp(struct thermal_zone_device *tzdev,
-				       int trip, int temp)
-{
-	struct mlxsw_thermal *thermal = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	thermal->trips[trip].temp = temp;
-	return 0;
-}
-
-static int mlxsw_thermal_get_trip_hyst(struct thermal_zone_device *tzdev,
-				       int trip, int *p_hyst)
-{
-	struct mlxsw_thermal *thermal = tzdev->devdata;
-
-	*p_hyst = thermal->trips[trip].hyst;
-	return 0;
-}
-
-static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
-				       int trip, int hyst)
-{
-	struct mlxsw_thermal *thermal = tzdev->devdata;
-
-	thermal->trips[trip].hyst = hyst;
-	return 0;
-}
-
 static struct thermal_zone_params mlxsw_thermal_params = {
 	.no_hwmon = true,
 };
@@ -323,11 +276,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = {
 	.bind = mlxsw_thermal_bind,
 	.unbind = mlxsw_thermal_unbind,
 	.get_temp = mlxsw_thermal_get_temp,
-	.get_trip_type	= mlxsw_thermal_get_trip_type,
-	.get_trip_temp	= mlxsw_thermal_get_trip_temp,
-	.set_trip_temp	= mlxsw_thermal_set_trip_temp,
-	.get_trip_hyst	= mlxsw_thermal_get_trip_hyst,
-	.set_trip_hyst	= mlxsw_thermal_set_trip_hyst,
 };
 
 static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
@@ -342,11 +290,11 @@ static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
 		return 0;
 
 	for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
-		const struct mlxsw_thermal_trip *trip = &tz->trips[i];
+		const struct mlxsw_cooling_states *state = &tz->cooling_states[i];
 
 		err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
-						       trip->max_state,
-						       trip->min_state,
+						       state->max_state,
+						       state->min_state,
 						       THERMAL_WEIGHT_DEFAULT);
 		if (err < 0)
 			goto err_thermal_zone_bind_cooling_device;
@@ -434,74 +382,10 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
 	return 0;
 }
 
-static int
-mlxsw_thermal_module_trip_type_get(struct thermal_zone_device *tzdev, int trip,
-				   enum thermal_trip_type *p_type)
-{
-	struct mlxsw_thermal_module *tz = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	*p_type = tz->trips[trip].type;
-	return 0;
-}
-
-static int
-mlxsw_thermal_module_trip_temp_get(struct thermal_zone_device *tzdev,
-				   int trip, int *p_temp)
-{
-	struct mlxsw_thermal_module *tz = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	*p_temp = tz->trips[trip].temp;
-	return 0;
-}
-
-static int
-mlxsw_thermal_module_trip_temp_set(struct thermal_zone_device *tzdev,
-				   int trip, int temp)
-{
-	struct mlxsw_thermal_module *tz = tzdev->devdata;
-
-	if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
-		return -EINVAL;
-
-	tz->trips[trip].temp = temp;
-	return 0;
-}
-
-static int
-mlxsw_thermal_module_trip_hyst_get(struct thermal_zone_device *tzdev, int trip,
-				   int *p_hyst)
-{
-	struct mlxsw_thermal_module *tz = tzdev->devdata;
-
-	*p_hyst = tz->trips[trip].hyst;
-	return 0;
-}
-
-static int
-mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
-				   int hyst)
-{
-	struct mlxsw_thermal_module *tz = tzdev->devdata;
-
-	tz->trips[trip].hyst = hyst;
-	return 0;
-}
-
 static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
 	.bind		= mlxsw_thermal_module_bind,
 	.unbind		= mlxsw_thermal_module_unbind,
 	.get_temp	= mlxsw_thermal_module_temp_get,
-	.get_trip_type	= mlxsw_thermal_module_trip_type_get,
-	.get_trip_temp	= mlxsw_thermal_module_trip_temp_get,
-	.set_trip_temp	= mlxsw_thermal_module_trip_temp_set,
-	.get_trip_hyst	= mlxsw_thermal_module_trip_hyst_get,
-	.set_trip_hyst	= mlxsw_thermal_module_trip_hyst_set,
 };
 
 static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
@@ -531,11 +415,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
 	.bind		= mlxsw_thermal_module_bind,
 	.unbind		= mlxsw_thermal_module_unbind,
 	.get_temp	= mlxsw_thermal_gearbox_temp_get,
-	.get_trip_type	= mlxsw_thermal_module_trip_type_get,
-	.get_trip_temp	= mlxsw_thermal_module_trip_temp_get,
-	.set_trip_temp	= mlxsw_thermal_module_trip_temp_set,
-	.get_trip_hyst	= mlxsw_thermal_module_trip_hyst_get,
-	.set_trip_hyst	= mlxsw_thermal_module_trip_hyst_set,
 };
 
 static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
@@ -617,7 +496,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
 	else
 		snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
 			 module_tz->module + 1);
-	module_tz->tzdev = thermal_zone_device_register(tz_name,
+	module_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
+							module_tz->trips,
 							MLXSW_THERMAL_NUM_TRIPS,
 							MLXSW_THERMAL_TRIP_MASK,
 							module_tz,
@@ -661,6 +541,8 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
 	module_tz->parent = thermal;
 	memcpy(module_tz->trips, default_thermal_trips,
 	       sizeof(thermal->trips));
+	memcpy(module_tz->cooling_states, default_cooling_states,
+	       sizeof(thermal->cooling_states));
 	/* Initialize all trip point. */
 	mlxsw_thermal_module_trips_reset(module_tz);
 	/* Read module temperature and thresholds. */
@@ -756,7 +638,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
 	else
 		snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
 			 gearbox_tz->module + 1);
-	gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
+	gearbox_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
+						gearbox_tz->trips,
 						MLXSW_THERMAL_NUM_TRIPS,
 						MLXSW_THERMAL_TRIP_MASK,
 						gearbox_tz,
@@ -813,6 +696,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
 		gearbox_tz = &area->tz_gearbox_arr[i];
 		memcpy(gearbox_tz->trips, default_thermal_trips,
 		       sizeof(thermal->trips));
+		memcpy(gearbox_tz->cooling_states, default_cooling_states,
+		       sizeof(thermal->cooling_states));
 		gearbox_tz->module = i;
 		gearbox_tz->parent = thermal;
 		gearbox_tz->slot_index = area->slot_index;
@@ -928,6 +813,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
 	thermal->core = core;
 	thermal->bus_info = bus_info;
 	memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
+	memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states));
 	thermal->line_cards[0].slot_index = 0;
 
 	err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
@@ -981,7 +867,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
 				 MLXSW_THERMAL_SLOW_POLL_INT :
 				 MLXSW_THERMAL_POLL_INT;
 
-	thermal->tzdev = thermal_zone_device_register("mlxsw",
+	thermal->tzdev = thermal_zone_device_register_with_trips("mlxsw",
+						      thermal->trips,
 						      MLXSW_THERMAL_NUM_TRIPS,
 						      MLXSW_THERMAL_TRIP_MASK,
 						      thermal,
Signature · 1 line
2.39.2
author maintainer
#47 lore raw

PATCH 47/224 mlxsw: core_thermal: Fix fan speed in maximum cooling state

In reply to Greg Kroah-Hartman

From: Ido Schimmel <[email protected]>

[ Upstream commit 6d206b1ea9f48433a96edec7028586db1d947911 ]

The cooling levels array is supposed to prevent the system fans from being configured below a 20% duty cycle as otherwise some of them get stuck at 0 RPM.

Due to an off-by-one error, the last element in the array was not initialized, causing it to be set to zero, which in turn lead to fans being configured with a 0% duty cycle in maximum cooling state.

Since commit 332fdf951df8 ("mlxsw: thermal: Fix out-of-bounds memory accesses") the contents of the array are static. Therefore, instead of fixing the initialization of the array, simply remove it and adjust thermal_cooling_device_ops::set_cur_state() so that the configured duty cycle is never set below 20%.

Before:

 # cat /sys/class/thermal/thermal_zone0/cdev0/type
 mlxsw_fan
 # echo 10 > /sys/class/thermal/thermal_zone0/cdev0/cur_state
 # cat /sys/class/hwmon/hwmon0/name
 mlxsw
 # cat /sys/class/hwmon/hwmon0/pwm1
 0

After:

 # cat /sys/class/thermal/thermal_zone0/cdev0/type
 mlxsw_fan
 # echo 10 > /sys/class/thermal/thermal_zone0/cdev0/cur_state
 # cat /sys/class/hwmon/hwmon0/name
 mlxsw
 # cat /sys/class/hwmon/hwmon0/pwm1
 255

This bug was uncovered when the thermal subsystem repeatedly tried to configure the cooling devices to their maximum state due to another issue [1]. This resulted in the fans being stuck at 0 RPM, which eventually lead to the system undergoing thermal shutdown.

[1] https://lore.kernel.org/netdev/ZA3CFNhU4AbtsP4G@shredder/

Fixes a421ce088ac8 ("mlxsw: core: Extend cooling device with cooling levels")
---
 drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +1 -6
index c5240d38c9dbd..09ed6e5fa6c34 100644
@@ -105,7 +105,6 @@ struct mlxsw_thermal {
 	struct thermal_zone_device *tzdev;
 	int polling_delay;
 	struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
-	u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
 	struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
 	struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
 	struct mlxsw_thermal_area line_cards[];
@@ -468,7 +467,7 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
 		return idx;
 
 	/* Normalize the state to the valid speed range. */
-	state = thermal->cooling_levels[state];
+	state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state);
 	mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
 	err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
 	if (err) {
@@ -859,10 +858,6 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
 		}
 	}
 
-	/* Initialize cooling levels per PWM state. */
-	for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
-		thermal->cooling_levels[i] = max(MLXSW_THERMAL_MIN_STATE, i);
-
 	thermal->polling_delay = bus_info->low_frequency ?
 				 MLXSW_THERMAL_SLOW_POLL_INT :
 				 MLXSW_THERMAL_POLL_INT;
Signature · 1 line
2.39.2
author maintainer
#48 lore raw

PATCH 48/224 drm/i915: Print return value on error

In reply to Greg Kroah-Hartman

From: Nirmoy Das <[email protected]>

[ Upstream commit 20c68127e8e9d7899001c47465d0b79581f5fdc1 ]

Print returned error code for better debuggability.

Stable-dep-of: ed00eba03474 ("drm/i915/fbdev: lock the fbdev obj before vma pin")

---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/display/intel_fbdev.c +3 -3
index 9899b5dcd291d..d9b42905bad84 100644
@@ -175,7 +175,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
 	}
 
 	if (IS_ERR(obj)) {
-		drm_err(&dev_priv->drm, "failed to allocate framebuffer\n");
+		drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj);
 		return PTR_ERR(obj);
 	}
 
@@ -256,7 +256,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
 	info = drm_fb_helper_alloc_fbi(helper);
 	if (IS_ERR(info)) {
-		drm_err(&dev_priv->drm, "Failed to allocate fb_info\n");
+		drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info);
 		ret = PTR_ERR(info);
 		goto out_unpin;
 	}
@@ -291,7 +291,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
 	vaddr = i915_vma_pin_iomap(vma);
 	if (IS_ERR(vaddr)) {
 		drm_err(&dev_priv->drm,
-			"Failed to remap framebuffer into virtual memory\n");
+			"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
 		ret = PTR_ERR(vaddr);
 		goto out_unpin;
 	}
Signature · 1 line
2.39.2
author maintainer
#49 lore raw

PATCH 49/224 drm/i915/fbdev: lock the fbdev obj before vma pin

In reply to Greg Kroah-Hartman

From: Tejas Upadhyay <[email protected]>

[ Upstream commit ed00eba03474adbf525ff03d69705d8c78b76456 ]

lock the fbdev obj before calling into
i915_vma_pin_iomap(). This helps to solve below :

<7>[   93.563308] i915 0000:00:02.0: [drm:intelfb_create [i915]] no BIOS fb, allocating a new one
<4>[   93.581844] ------------[ cut here ]------------
<4>[   93.581855] WARNING: CPU: 12 PID: 625 at drivers/gpu/drm/i915/gem/i915_gem_pages.c:424 i915_gem_object_pin_map+0x152/0x1c0 [i915]
Fixes f0b6b01b3efe ("drm/i915: Add ww context to intel_dpt_pin, v2.")
Cc Chris Wilson <[email protected]>
Cc Matthew Auld <[email protected]>
Cc Maarten Lankhorst <[email protected]>
(cherry picked from commit 561b31acfd65502a2cda2067513240fc57ccdbdc)
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 24 ++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/display/intel_fbdev.c +18 -6
index d9b42905bad84..968915000519f 100644
@@ -208,6 +208,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
 	bool prealloc = false;
 	void __iomem *vaddr;
 	struct drm_i915_gem_object *obj;
+	struct i915_gem_ww_ctx ww;
 	int ret;
 
 	mutex_lock(&ifbdev->hpd_lock);
@@ -288,13 +289,24 @@ static int intelfb_create(struct drm_fb_helper *helper,
 		info->fix.smem_len = vma->size;
 	}
 
-	vaddr = i915_vma_pin_iomap(vma);
-	if (IS_ERR(vaddr)) {
-		drm_err(&dev_priv->drm,
-			"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
-		ret = PTR_ERR(vaddr);
-		goto out_unpin;
+	for_i915_gem_ww(&ww, ret, false) {
+		ret = i915_gem_object_lock(vma->obj, &ww);
+
+		if (ret)
+			continue;
+
+		vaddr = i915_vma_pin_iomap(vma);
+		if (IS_ERR(vaddr)) {
+			drm_err(&dev_priv->drm,
+				"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
+			ret = PTR_ERR(vaddr);
+			continue;
+		}
 	}
+
+	if (ret)
+		goto out_unpin;
+
 	info->screen_base = vaddr;
 	info->screen_size = vma->size;
 
Signature · 1 line
2.39.2
author maintainer
#50 lore raw

PATCH 50/224 drm/i915/guc: Rename GuC register state capture node to be more obvious

In reply to Greg Kroah-Hartman

From: John Harrison <[email protected]>

[ Upstream commit 583ebae783b8241a30581c084ad6226051b594c5 ]

The GuC specific register state entry in the error capture object was just called 'capture'. Although the companion 'node' entry was called 'guc_capture_node'. Rename the base entry to be 'guc_capture' instead so that it is a) more consistent and b) more obvious what it is.

Stable-dep-of: 8df23e4c4f72 ("drm/i915/guc: Fix missing ecodes")

---
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 8 ++++----
 drivers/gpu/drm/i915/i915_gpu_error.h          | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +4 -4
index 685ddccc0f26a..13118609339ac 100644
@@ -1491,7 +1491,7 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *ebuf,
 
 	if (!ebuf || !ee)
 		return -EINVAL;
-	cap = ee->capture;
+	cap = ee->guc_capture;
 	if (!cap || !ee->engine)
 		return -ENODEV;
 
@@ -1561,8 +1561,8 @@ void intel_guc_capture_free_node(struct intel_engine_coredump *ee)
 	if (!ee || !ee->guc_capture_node)
 		return;
 
-	guc_capture_add_node_to_cachelist(ee->capture, ee->guc_capture_node);
-	ee->capture = NULL;
+	guc_capture_add_node_to_cachelist(ee->guc_capture, ee->guc_capture_node);
+	ee->guc_capture = NULL;
 	ee->guc_capture_node = NULL;
 }
 
@@ -1596,7 +1596,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt,
 		    (ce->lrc.lrca & CTX_GTT_ADDRESS_MASK)) {
 			list_del(&n->link);
 			ee->guc_capture_node = n;
-			ee->capture = guc->capture;
+			ee->guc_capture = guc->capture;
 			return;
 		}
 	}
drivers/gpu/drm/i915/i915_gpu_error.h +1 -1
index efc75cc2ffdb9..56027ffbce51f 100644
@@ -94,7 +94,7 @@ struct intel_engine_coredump {
 	struct intel_instdone instdone;
 
 	/* GuC matched capture-lists info */
-	struct intel_guc_state_capture *capture;
+	struct intel_guc_state_capture *guc_capture;
 	struct __guc_capture_parsed_output *guc_capture_node;
 
 	struct i915_gem_context_coredump {
Signature · 1 line
2.39.2
author maintainer
#51 lore raw

PATCH 51/224 drm/i915/guc: Fix missing ecodes

In reply to Greg Kroah-Hartman

From: John Harrison <[email protected]>

[ Upstream commit 8df23e4c4f72f4e201c28e6fb0a67e2dbf30628a ]

Error captures are tagged with an 'ecode'. This is a pseduo-unique magic number that is meant to distinguish similar seeming bugs with different underlying signatures. It is a combination of two ring state registers. Unfortunately, the register state being used is only valid in execlist mode. In GuC mode, the register state exists in a separate list of arbitrary register address/value pairs rather than the named entry structure. So, search through that list to find the two exciting registers and copy them over to the structure's named members.

v2: if else if instead of if if (Alan)

Fixes a6f0f9cf330a ("drm/i915/guc: Plumb GuC-capture into gpu_coredump")
Cc Alan Previn <[email protected]>
Cc Umesh Nerlige Ramappa <[email protected]>
Cc Lucas De Marchi <[email protected]>
Cc Jani Nikula <[email protected]>
Cc Joonas Lahtinen <[email protected]>
Cc Rodrigo Vivi <[email protected]>
Cc Tvrtko Ursulin <[email protected]>
Cc Matt Roper <[email protected]>
Cc Aravind Iddamsetty <[email protected]>
Cc Michael Cheng <[email protected]>
Cc Matthew Brost <[email protected]>
Cc Bruce Chang <[email protected]>
Cc Daniele Ceraolo Spurio <[email protected]>
Cc Matthew Auld <[email protected]>
(cherry picked from commit 9724ecdbb9ddd6da3260e4a442574b90fc75188a)
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c    | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)
drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +22 -0
index 13118609339ac..1e1fa20fb41c9 100644
@@ -1556,6 +1556,27 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *ebuf,
 
 #endif //CONFIG_DRM_I915_CAPTURE_ERROR
 
+static void guc_capture_find_ecode(struct intel_engine_coredump *ee)
+{
+	struct gcap_reg_list_info *reginfo;
+	struct guc_mmio_reg *regs;
+	i915_reg_t reg_ipehr = RING_IPEHR(0);
+	i915_reg_t reg_instdone = RING_INSTDONE(0);
+	int i;
+
+	if (!ee->guc_capture_node)
+		return;
+
+	reginfo = ee->guc_capture_node->reginfo + GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE;
+	regs = reginfo->regs;
+	for (i = 0; i < reginfo->num_regs; i++) {
+		if (regs[i].offset == reg_ipehr.reg)
+			ee->ipehr = regs[i].value;
+		else if (regs[i].offset == reg_instdone.reg)
+			ee->instdone.instdone = regs[i].value;
+	}
+}
+
 void intel_guc_capture_free_node(struct intel_engine_coredump *ee)
 {
 	if (!ee || !ee->guc_capture_node)
@@ -1597,6 +1618,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt,
 			list_del(&n->link);
 			ee->guc_capture_node = n;
 			ee->guc_capture = guc->capture;
+			guc_capture_find_ecode(ee);
 			return;
 		}
 	}
Signature · 1 line
2.39.2
author maintainer
#52 lore raw

PATCH 52/224 drm/i915/gt: perform uc late init after probe error injection

In reply to Greg Kroah-Hartman

From: Andrzej Hajda <[email protected]>

[ Upstream commit 150784f9285e656373cf3953ef4a7663f1e1a0f2 ]

Probe pseudo errors should be injected only in places where real errors can be encountered, otherwise unwinding code can be broken. Placing intel_uc_init_late before i915_inject_probe_error violated this rule, resulting in following bug:
__intel_gt_disable:655 GEM_BUG_ON(intel_gt_pm_is_awake(gt))

Fixes 481d458caede ("drm/i915/guc: Add golden context to GuC ADS")
(cherry picked from commit c4252a11131c7f27a158294241466e2a4e7ff94e)
---
 drivers/gpu/drm/i915/gt/intel_gt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/gt/intel_gt.c +2 -2
index c7db49749a636..d12ec092e62df 100644
@@ -691,12 +691,12 @@ int intel_gt_init(struct intel_gt *gt)
 	if (err)
 		goto err_gt;
 
-	intel_uc_init_late(&gt->uc);
-
 	err = i915_inject_probe_error(gt->i915, -EIO);
 	if (err)
 		goto err_gt;
 
+	intel_uc_init_late(&gt->uc);
+
 	intel_migrate_init(&gt->migrate, gt);
 
 	intel_pxp_init(&gt->pxp);
Signature · 1 line
2.39.2
author maintainer
#53 lore raw

PATCH 53/224 net: qcom/emac: Fix use after free bug in emac_remove due to race condition

In reply to Greg Kroah-Hartman

From: Zheng Wang <[email protected]>

[ Upstream commit 6b6bc5b8bd2d4ca9e1efa9ae0f98a0b0687ace75 ]

In emac_probe, &adpt->work_thread is bound with emac_work_thread. Then it will be started by timeout handler emac_tx_timeout or a IRQ handler emac_isr.

If we remove the driver which will call emac_remove
to make cleanup, there may be a unfinished work.

The possible sequence is as follows:

Fix it by finishing the work before cleanup in the emac_remove and disable timeout response.

CPU0 CPU1

                    |emac_work_thread
emac_remove         |
free_netdev         |
kfree(netdev);      |
                    |emac_reinit_locked
                    |emac_mac_down
                    |//use netdev
Fixes b9b17debc69d ("net: emac: emac gigabit ethernet controller driver")
---
 drivers/net/ethernet/qualcomm/emac/emac.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/ethernet/qualcomm/emac/emac.c +6 -0
index 3115b2c128980..eaa50050aa0b7 100644
@@ -724,9 +724,15 @@ static int emac_remove(struct platform_device *pdev)
 	struct net_device *netdev = dev_get_drvdata(&pdev->dev);
 	struct emac_adapter *adpt = netdev_priv(netdev);
 
+	netif_carrier_off(netdev);
+	netif_tx_disable(netdev);
+
 	unregister_netdev(netdev);
 	netif_napi_del(&adpt->rx_q.napi);
 
+	free_irq(adpt->irq.irq, &adpt->irq);
+	cancel_work_sync(&adpt->work_thread);
+
 	emac_clks_teardown(adpt);
 
 	put_device(&adpt->phydev->mdio.dev);
Signature · 1 line
2.39.2
author maintainer
#54 lore raw

PATCH 54/224 net: usb: lan78xx: Limit packet length to skb->len

In reply to Greg Kroah-Hartman

From: Szymon Heidrich <[email protected]>

[ Upstream commit 7f247f5a2c18b3f21206cdd51193df4f38e1b9f5 ]

Packet length retrieved from descriptor may be larger than the actual socket buffer length. In such case the cloned skb passed up the network stack will leak kernel memory contents.

Additionally prevent integer underflow when size is less than ETH_FCS_LEN.

Fixes 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
---
 drivers/net/usb/lan78xx.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
drivers/net/usb/lan78xx.c +17 -1
index 068488890d57b..c458c030fadf6 100644
@@ -3579,13 +3579,29 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb,
 		size = (rx_cmd_a & RX_CMD_A_LEN_MASK_);
 		align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
+		if (unlikely(size > skb->len)) {
+			netif_dbg(dev, rx_err, dev->net,
+				  "size err rx_cmd_a=0x%08x\n",
+				  rx_cmd_a);
+			return 0;
+		}
+
 		if (unlikely(rx_cmd_a & RX_CMD_A_RED_)) {
 			netif_dbg(dev, rx_err, dev->net,
 				  "Error rx_cmd_a=0x%08x", rx_cmd_a);
 		} else {
-			u32 frame_len = size - ETH_FCS_LEN;
+			u32 frame_len;
 			struct sk_buff *skb2;
 
+			if (unlikely(size < ETH_FCS_LEN)) {
+				netif_dbg(dev, rx_err, dev->net,
+					  "size err rx_cmd_a=0x%08x\n",
+					  rx_cmd_a);
+				return 0;
+			}
+
+			frame_len = size - ETH_FCS_LEN;
+
 			skb2 = napi_alloc_skb(&dev->napi, frame_len);
 			if (!skb2)
 				return 0;
Signature · 1 line
2.39.2
author maintainer
#55 lore raw

PATCH 55/224 net/ps3_gelic_net: Fix RX sk_buff length

In reply to Greg Kroah-Hartman

From: Geoff Levand <[email protected]>

[ Upstream commit 19b3bb51c3bc288b3f2c6f8c4450b0f548320625 ]

The Gelic Ethernet device needs to have the RX sk_buffs aligned to GELIC_NET_RXBUF_ALIGN, and also the length of the RX sk_buffs must be a multiple of GELIC_NET_RXBUF_ALIGN.

The current Gelic Ethernet driver was not allocating sk_buffs large enough to allow for this alignment.

Also, correct the maximum and minimum MTU sizes, and add a new preprocessor macro for the maximum frame size, GELIC_NET_MAX_FRAME.

Fixes various randomly occurring runtime network errors.

Fixes 02c1889166b4 ("ps3: gigabit ethernet driver for PS3, take3")
---
 drivers/net/ethernet/toshiba/ps3_gelic_net.c | 19 ++++++++++---------
 drivers/net/ethernet/toshiba/ps3_gelic_net.h |  5 +++--
 2 files changed, 13 insertions(+), 11 deletions(-)
drivers/net/ethernet/toshiba/ps3_gelic_net.c +10 -9
index cf8de8a7a8a1e..dffd664e65f4e 100644
@@ -365,26 +365,27 @@ static int gelic_card_init_chain(struct gelic_card *card,
  *
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
+ *
+ * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length
+ * must be a multiple of GELIC_NET_RXBUF_ALIGN.
  */
 static int gelic_descr_prepare_rx(struct gelic_card *card,
 				  struct gelic_descr *descr)
 {
+	static const unsigned int rx_skb_size =
+		ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) +
+		GELIC_NET_RXBUF_ALIGN - 1;
 	int offset;
-	unsigned int bufsize;
 
 	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
 		dev_info(ctodev(card), "%s: ERROR status\n", __func__);
-	/* we need to round up the buffer size to a multiple of 128 */
-	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
 
-	/* and we need to have it 128 byte aligned, therefore we allocate a
-	 * bit more */
-	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size);
 	if (!descr->skb) {
 		descr->buf_addr = 0; /* tell DMAC don't touch memory */
 		return -ENOMEM;
 	}
-	descr->buf_size = cpu_to_be32(bufsize);
+	descr->buf_size = cpu_to_be32(rx_skb_size);
 	descr->dmac_cmd_status = 0;
 	descr->result_size = 0;
 	descr->valid_size = 0;
@@ -397,7 +398,7 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
 	/* io-mmu-map the skb */
 	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
 						     descr->skb->data,
-						     GELIC_NET_MAX_MTU,
+						     GELIC_NET_MAX_FRAME,
 						     DMA_FROM_DEVICE));
 	if (!descr->buf_addr) {
 		dev_kfree_skb_any(descr->skb);
@@ -915,7 +916,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
 	data_error = be32_to_cpu(descr->data_error);
 	/* unmap skb buffer */
 	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
-			 GELIC_NET_MAX_MTU,
+			 GELIC_NET_MAX_FRAME,
 			 DMA_FROM_DEVICE);
 
 	skb_put(skb, be32_to_cpu(descr->valid_size)?
drivers/net/ethernet/toshiba/ps3_gelic_net.h +3 -2
index 68f324ed4eaf0..0d98defb011ed 100644
@@ -19,8 +19,9 @@
 #define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
 #define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
 
-#define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
-#define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
+#define GELIC_NET_MAX_FRAME             2312
+#define GELIC_NET_MAX_MTU               2294
+#define GELIC_NET_MIN_MTU               64
 #define GELIC_NET_RXBUF_ALIGN           128
 #define GELIC_CARD_RX_CSUM_DEFAULT      1 /* hw chksum */
 #define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
Signature · 1 line
2.39.2
author maintainer
#56 lore raw

PATCH 56/224 net/ps3_gelic_net: Use dma_mapping_error

In reply to Greg Kroah-Hartman

From: Geoff Levand <[email protected]>

[ Upstream commit bebe933d35a63d4f042fbf4dce4f22e689ba0fcd ]

The current Gelic Etherenet driver was checking the return value of its dma_map_single call, and not using the dma_mapping_error() routine.

Fixes runtime problems like these:

DMA-API: ps3_gelic_driver sb_05: device driver failed to check map error

  WARNING: CPU: 0 PID: 0 at kernel/dma/debug.c:1027 .check_unmap+0x888/0x8dc
Fixes 02c1889166b4 ("ps3: gigabit ethernet driver for PS3, take3")
---
 drivers/net/ethernet/toshiba/ps3_gelic_net.c | 24 +++++++++++---------
 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/net/ethernet/toshiba/ps3_gelic_net.c +13 -11
index dffd664e65f4e..9d535ae596266 100644
@@ -317,15 +317,17 @@ static int gelic_card_init_chain(struct gelic_card *card,
 
 	/* set up the hardware pointers in each descriptor */
 	for (i = 0; i < no; i++, descr++) {
+		dma_addr_t cpu_addr;
+
 		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
-		descr->bus_addr =
-			dma_map_single(ctodev(card), descr,
-				       GELIC_DESCR_SIZE,
-				       DMA_BIDIRECTIONAL);
 
-		if (!descr->bus_addr)
+		cpu_addr = dma_map_single(ctodev(card), descr,
+					  GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
+
+		if (dma_mapping_error(ctodev(card), cpu_addr))
 			goto iommu_error;
 
+		descr->bus_addr = cpu_to_be32(cpu_addr);
 		descr->next = descr + 1;
 		descr->prev = descr - 1;
 	}
@@ -375,6 +377,7 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
 	static const unsigned int rx_skb_size =
 		ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) +
 		GELIC_NET_RXBUF_ALIGN - 1;
+	dma_addr_t cpu_addr;
 	int offset;
 
 	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
@@ -396,11 +399,10 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
 	if (offset)
 		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
 	/* io-mmu-map the skb */
-	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
-						     descr->skb->data,
-						     GELIC_NET_MAX_FRAME,
-						     DMA_FROM_DEVICE));
-	if (!descr->buf_addr) {
+	cpu_addr = dma_map_single(ctodev(card), descr->skb->data,
+				  GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE);
+	descr->buf_addr = cpu_to_be32(cpu_addr);
+	if (dma_mapping_error(ctodev(card), cpu_addr)) {
 		dev_kfree_skb_any(descr->skb);
 		descr->skb = NULL;
 		dev_info(ctodev(card),
@@ -780,7 +782,7 @@ static int gelic_descr_prepare_tx(struct gelic_card *card,
 
 	buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE);
 
-	if (!buf) {
+	if (dma_mapping_error(ctodev(card), buf)) {
 		dev_err(ctodev(card),
 			"dma map 2 failed (%p, %i). Dropping packet\n",
 			skb->data, skb->len);
Signature · 1 line
2.39.2
author maintainer
#57 lore raw

PATCH 57/224 octeontx2-vf: Add missing free for alloc_percpu

In reply to Greg Kroah-Hartman

From: Jiasheng Jiang <[email protected]>

[ Upstream commit f038f3917baf04835ba2b7bcf2a04ac93fbf8a9c ]

Add the free_percpu for the allocated "vf->hw.lmt_info" in order to avoid memory leak, same as the "pf->hw.lmt_info" in drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c.

---
 drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +2 -0
index 7f8ffbf79cf74..ab126f8706c74 100644
@@ -709,6 +709,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 err_ptp_destroy:
 	otx2_ptp_destroy(vf);
 err_detach_rsrc:
+	free_percpu(vf->hw.lmt_info);
 	if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
 		qmem_free(vf->dev, vf->dync_lmt);
 	otx2_detach_resources(&vf->mbox);
@@ -762,6 +763,7 @@ static void otx2vf_remove(struct pci_dev *pdev)
 	otx2_shutdown_tc(vf);
 	otx2vf_disable_mbox_intr(vf);
 	otx2_detach_resources(&vf->mbox);
+	free_percpu(vf->hw.lmt_info);
 	if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
 		qmem_free(vf->dev, vf->dync_lmt);
 	otx2vf_vfaf_mbox_destroy(vf);
Signature · 1 line
2.39.2
author maintainer
#58 lore raw

PATCH 58/224 bootconfig: Fix testcase to increase max node

In reply to Greg Kroah-Hartman

From: Masami Hiramatsu (Google) <[email protected]>

[ Upstream commit b69245126a48e50882021180fa5d264dc7149ccc ]

Since commit 6c40624930c5 ("bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support") increased the max number of bootconfig node to 8192, the bootconfig testcase of the max number of nodes fails. To fix this issue, we can not simply increase the number in the test script because the test bootconfig file becomes too big (>32KB). To fix that, we can use a combination of three alphabets (26^3 = 17576). But with that, we can not express the 8193 (just one exceed from the limitation) because it also exceeds the max size of bootconfig. So, the first 26 nodes will just use one alphabet.

With this fix, test-bootconfig.sh passes all tests.

Fixes 6c40624930c5 ("bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support")
---
 tools/bootconfig/test-bootconfig.sh | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
tools/bootconfig/test-bootconfig.sh +8 -4
index f68e2e9eef8b2..a2c484c243f5d 100755
@@ -87,10 +87,14 @@ xfail grep -i "error" $OUTFILE
 
 echo "Max node number check"
 
-echo -n > $TEMPCONF
-for i in `seq 1 1024` ; do
-   echo "node$i" >> $TEMPCONF
-done
+awk '
+BEGIN {
+  for (i = 0; i < 26; i += 1)
+      printf("%c\n", 65 + i % 26)
+  for (i = 26; i < 8192; i += 1)
+      printf("%c%c%c\n", 65 + i % 26, 65 + (i / 26) % 26, 65 + (i / 26 / 26))
+}
+' > $TEMPCONF
 xpass $BOOTCONF -a $TEMPCONF $INITRD
 
 echo "badnode" >> $TEMPCONF
Signature · 1 line
2.39.2
author maintainer
#59 lore raw

PATCH 59/224 keys: Do not cache key in task struct if key is requested from kernel thread

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit 47f9e4c924025c5be87959d3335e66fcbb7f6b5c ]

The key which gets cached in task structure from a kernel thread does not get invalidated even after expiry. Due to which, a new key request from kernel thread will be served with the cached key if it's present in task struct irrespective of the key validity. The change is to not cache key in task_struct when key requested from kernel thread so that kernel thread gets a valid key on every key request.

The problem has been seen with the cifs module doing DNS lookups from a kernel thread and the results getting pinned by being attached to that kernel thread's cache - and thus not something that can be easily got rid of. The cache would ordinarily be cleared by notify-resume, but kernel threads don't do that.

This isn't seen with AFS because AFS is doing request_key() within the kernel half of a user thread - which will do notify-resume.

---
 security/keys/request_key.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
security/keys/request_key.c +6 -3
index 2da4404276f0f..07a0ef2baacd8 100644
@@ -38,9 +38,12 @@ static void cache_requested_key(struct key *key)
 #ifdef CONFIG_KEYS_REQUEST_CACHE
 	struct task_struct *t = current;
 
-	key_put(t->cached_requested_key);
-	t->cached_requested_key = key_get(key);
-	set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+	/* Do not cache key if it is a kernel thread */
+	if (!(t->flags & PF_KTHREAD)) {
+		key_put(t->cached_requested_key);
+		t->cached_requested_key = key_get(key);
+		set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+	}
 #endif
 }
 
Signature · 1 line
2.39.2
author maintainer
#60 lore raw

PATCH 60/224 ice: check if VF exists before mode check

In reply to Greg Kroah-Hartman

From: Michal Swiatkowski <[email protected]>

[ Upstream commit 83b49e7f63da88a1544cba2b2e40bfabb24bd203 ]

Setting trust on VF should return EINVAL when there is no VF. Move checking for switchdev mode after checking if VF exists.

Fixes c54d209c78b8 ("ice: Wait for VF to be reset/ready before configuration")
---
 drivers/net/ethernet/intel/ice/ice_sriov.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/intel/ice/ice_sriov.c +4 -4
index 3ba1408c56a9a..b3849bc3d4fc6 100644
@@ -1384,15 +1384,15 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
 	struct ice_vf *vf;
 	int ret;
 
+	vf = ice_get_vf_by_id(pf, vf_id);
+	if (!vf)
+		return -EINVAL;
+
 	if (ice_is_eswitch_mode_switchdev(pf)) {
 		dev_info(ice_pf_to_dev(pf), "Trusted VF is forbidden in switchdev mode\n");
 		return -EOPNOTSUPP;
 	}
 
-	vf = ice_get_vf_by_id(pf, vf_id);
-	if (!vf)
-		return -EINVAL;
-
 	ret = ice_check_vf_ready_for_cfg(vf);
 	if (ret)
 		goto out_put_vf;
Signature · 1 line
2.39.2
author maintainer
#61 lore raw

PATCH 61/224 iavf: fix hang on reboot with ice

In reply to Greg Kroah-Hartman

From: Stefan Assmann <[email protected]>

[ Upstream commit 4e264be98b88a6d6f476c11087fe865696e8bef5 ]

When a system with E810 with existing VFs gets rebooted the following hang may be observed.

Pid 1 is hung in iavf_remove(), part of a network driver:
PID: 1 TASK: ffff965400e5a340 CPU: 24 COMMAND: "systemd-shutdow"
#0 [ffffaad04005fa50] __schedule at ffffffff8b3239cb
#1 [ffffaad04005fae8] schedule at ffffffff8b323e2d
#2 [ffffaad04005fb00] schedule_hrtimeout_range_clock at ffffffff8b32cebc #3 [ffffaad04005fb80] usleep_range_state at ffffffff8b32c930 #4 [ffffaad04005fbb0] iavf_remove at ffffffffc12b9b4c [iavf] #5 [ffffaad04005fbf0] pci_device_remove at ffffffff8add7513 #6 [ffffaad04005fc10] device_release_driver_internal at ffffffff8af08baa #7 [ffffaad04005fc40] pci_stop_bus_device at ffffffff8adcc5fc #8 [ffffaad04005fc60] pci_stop_and_remove_bus_device at ffffffff8adcc81e #9 [ffffaad04005fc70] pci_iov_remove_virtfn at ffffffff8adf9429
#10 [ffffaad04005fca8] sriov_disable at ffffffff8adf98e4
#11 [ffffaad04005fcc8] ice_free_vfs at ffffffffc04bb2c8 [ice] #12 [ffffaad04005fd10] ice_remove at ffffffffc04778fe [ice] #13 [ffffaad04005fd38] ice_shutdown at ffffffffc0477946 [ice] #14 [ffffaad04005fd50] pci_device_shutdown at ffffffff8add58f1 #15 [ffffaad04005fd70] device_shutdown at ffffffff8af05386 #16 [ffffaad04005fd98] kernel_restart at ffffffff8a92a870
#17 [ffffaad04005fda8] __do_sys_reboot at ffffffff8a92abd6 #18 [ffffaad04005fee0] do_syscall_64 at ffffffff8b317159
#19 [ffffaad04005ff08] __context_tracking_enter at ffffffff8b31b6fc #20 [ffffaad04005ff18] syscall_exit_to_user_mode at ffffffff8b31b50d #21 [ffffaad04005ff28] do_syscall_64 at ffffffff8b317169
#22 [ffffaad04005ff50] entry_SYSCALL_64_after_hwframe at ffffffff8b40009b

     RIP: 00007f1baa5c13d7  RSP: 00007fffbcc55a98  RFLAGS: 00000202
     RAX: ffffffffffffffda  RBX: 0000000000000000  RCX: 00007f1baa5c13d7
     RDX: 0000000001234567  RSI: 0000000028121969  RDI: 00000000fee1dead
     RBP: 00007fffbcc55ca0   R8: 0000000000000000   R9: 00007fffbcc54e90
     R10: 00007fffbcc55050  R11: 0000000000000202  R12: 0000000000000005
     R13: 0000000000000000  R14: 00007fffbcc55af0  R15: 0000000000000000
     ORIG_RAX: 00000000000000a9  CS: 0033  SS: 002b

During reboot all drivers PM shutdown callbacks are invoked. In iavf_shutdown() the adapter state is changed to __IAVF_REMOVE. In ice_shutdown() the call chain above is executed, which at some point calls iavf_remove(). However iavf_remove() expects the VF to be in one of the states __IAVF_RUNNING, __IAVF_DOWN or __IAVF_INIT_FAILED. If that's not the case it sleeps forever.
So if iavf_shutdown() gets invoked before iavf_remove() the system will hang indefinitely because the adapter is already in state __IAVF_REMOVE.

Fix this by returning from iavf_remove() if the state is __IAVF_REMOVE, as we already went through iavf_shutdown().

Fixes 974578017fc1 ("iavf: Add waiting so the port is initialized in remove")
Fixes a8417330f8a5 ("iavf: Fix race condition between iavf_shutdown and iavf_remove")
---
 drivers/net/ethernet/intel/iavf/iavf_main.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/ethernet/intel/iavf/iavf_main.c +5 -0
index 41edcf9e154a3..5f8fff6c701fc 100644
@@ -5086,6 +5086,11 @@ static void iavf_remove(struct pci_dev *pdev)
 			mutex_unlock(&adapter->crit_lock);
 			break;
 		}
+		/* Simply return if we already went through iavf_shutdown */
+		if (adapter->state == __IAVF_REMOVE) {
+			mutex_unlock(&adapter->crit_lock);
+			return;
+		}
 
 		mutex_unlock(&adapter->crit_lock);
 		usleep_range(500, 1000);
Signature · 1 line
2.39.2
author maintainer
#62 lore raw

PATCH 62/224 i40e: fix flow director packet filter programming

In reply to Greg Kroah-Hartman

From: Radoslaw Tyl <[email protected]>

[ Upstream commit c672297bbc0e86dbf88396b8053e2fbb173f16ff ]

Initialize to zero structures to build a valid
Tx Packet used for the filter programming.

---
 drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_txrx.c +4 -4
index b97c95f89fa02..494775d65bf28 100644
@@ -171,10 +171,10 @@ static char *i40e_create_dummy_packet(u8 *dummy_packet, bool ipv4, u8 l4proto,
 				      struct i40e_fdir_filter *data)
 {
 	bool is_vlan = !!data->vlan_tag;
-	struct vlan_hdr vlan;
-	struct ipv6hdr ipv6;
-	struct ethhdr eth;
-	struct iphdr ip;
+	struct vlan_hdr vlan = {};
+	struct ipv6hdr ipv6 = {};
+	struct ethhdr eth = {};
+	struct iphdr ip = {};
 	u8 *tmp;
 
 	if (ipv4) {
Signature · 1 line
2.39.2
author maintainer
#63 lore raw

PATCH 63/224 bpf: Adjust insufficient default bpf_jit_limit

In reply to Greg Kroah-Hartman

From: Daniel Borkmann <[email protected]>

[ Upstream commit 10ec8ca8ec1a2f04c4ed90897225231c58c124a7 ]

We've seen recent AWS EKS (Kubernetes) user reports like the following:

After upgrading EKS nodes from v20230203 to v20230217 on our 1.24 EKS clusters after a few days a number of the nodes have containers stuck in ContainerCreating state or liveness/readiness probes reporting the following error:

Readiness probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "4a11039f730203ffc003b7[...]":
OCI runtime exec failed: exec failed: unable to start container process:
unable to init seccomp: error loading seccomp filter into kernel:
error loading seccomp filter: errno 524: unknown

However, we had not been seeing this issue on previous AMIs and it only started to occur on v20230217 (following the upgrade from kernel 5.4 to 5.10) with no other changes to the underlying cluster or workloads.

We tried the suggestions from that issue (sysctl net.core.bpf_jit_limit=452534528) which helped to immediately allow containers to be created and probes to execute but after approximately a day the issue returned and the value returned by cat /proc/vmallocinfo | grep bpf_jit | awk '{s+=$2} END {print s}' was steadily increasing.

I tested bpf tree to observe bpf_jit_charge_modmem, bpf_jit_uncharge_modmem their sizes passed in as well as bpf_jit_current under tcpdump BPF filter, seccomp BPF and native (e)BPF programs, and the behavior all looks sane and expected, that is nothing "leaking" from an upstream perspective.

The bpf_jit_limit knob was originally added in order to avoid a situation where unprivileged applications loading BPF programs (e.g. seccomp BPF policies) consuming all the module memory space via BPF JIT such that loading of kernel modules would be prevented. The default limit was defined back in 2018 and while good enough back then, we are generally seeing far more BPF consumers today.

Adjust the limit for the BPF JIT pool from originally 1/4 to now 1/2 of the module memory space to better reflect today's needs and avoid more users running into potentially hard to debug issues.

---
 kernel/bpf/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/core.c +1 -1
index 211f63e87c637..64706723624b9 100644
@@ -969,7 +969,7 @@ static int __init bpf_jit_charge_init(void)
 {
 	/* Only used as heuristic here to derive limit. */
 	bpf_jit_limit_max = bpf_jit_alloc_exec_limit();
-	bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 2,
+	bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 1,
 					    PAGE_SIZE), LONG_MAX);
 	return 0;
 }
Signature · 1 line
2.39.2
author maintainer
#64 lore raw

PATCH 64/224 net/mlx5e: Set uplink rep as NETNS_LOCAL

In reply to Greg Kroah-Hartman

From: Gavin Li <[email protected]>

[ Upstream commit c83172b0639c8a005c0dd3b36252dc22ddd9f19c ]

Previously, NETNS_LOCAL was not set for uplink representors, inconsistent with VF representors, and allowed the uplink representor to be moved between net namespaces and separated from the VF representors it shares the core device with. Such usage would break the isolation model of namespaces, as devices in different namespaces would have access to shared memory.

To solve this issue, set NETNS_LOCAL for uplink representors if eswitch is in switchdev mode.

Fixes 7a9fb35e8c3a ("net/mlx5e: Do not reload ethernet ports when changing eswitch mode")
---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +5 -1
index 609a49c1e09e6..3b5c5064cfafc 100644
@@ -4081,8 +4081,12 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
 		}
 	}
 
-	if (mlx5e_is_uplink_rep(priv))
+	if (mlx5e_is_uplink_rep(priv)) {
 		features = mlx5e_fix_uplink_rep_features(netdev, features);
+		features |= NETIF_F_NETNS_LOCAL;
+	} else {
+		features &= ~NETIF_F_NETNS_LOCAL;
+	}
 
 	mutex_unlock(&priv->state_lock);
 
Signature · 1 line
2.39.2
author maintainer
#65 lore raw

PATCH 65/224 net/mlx5e: Block entering switchdev mode with ns inconsistency

In reply to Greg Kroah-Hartman

From: Gavin Li <[email protected]>

[ Upstream commit 662404b24a4c4d839839ed25e3097571f5938b9b ]

Upon entering switchdev mode, VF/SF representors are spawned in the devlink instance's net namespace, whereas the PF net device transforms into the uplink representor, remaining in the net namespace the PF net device was in. Therefore, if a PF net device's namespace is different from its parent devlink net namespace, entering switchdev mode can create an illegal situation where all representors sharing the same core device are NOT in the same net namespace.

To avoid this issue, block entering switchdev mode for devices whose child netdev net namespace has diverged from the parent devlink's.

Fixes 7768d1971de6 ("net/mlx5: E-Switch, Add control for encapsulation")
---
 .../mellanox/mlx5/core/eswitch_offloads.c     | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +19 -0
index 34790a82a0976..64e5b9f29206e 100644
@@ -3488,6 +3488,18 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
 	return 0;
 }
 
+static bool esw_offloads_devlink_ns_eq_netdev_ns(struct devlink *devlink)
+{
+	struct net *devl_net, *netdev_net;
+	struct mlx5_eswitch *esw;
+
+	esw = mlx5_devlink_eswitch_get(devlink);
+	netdev_net = dev_net(esw->dev->mlx5e_res.uplink_netdev);
+	devl_net = devlink_net(devlink);
+
+	return net_eq(devl_net, netdev_net);
+}
+
 int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 				  struct netlink_ext_ack *extack)
 {
@@ -3502,6 +3514,13 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 	if (esw_mode_from_devlink(mode, &mlx5_mode))
 		return -EINVAL;
 
+	if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV &&
+	    !esw_offloads_devlink_ns_eq_netdev_ns(devlink)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Can't change E-Switch mode to switchdev when netdev net namespace has diverged from the devlink's.");
+		return -EPERM;
+	}
+
 	mlx5_lag_disable_change(esw->dev);
 	err = mlx5_esw_try_lock(esw);
 	if (err < 0) {
Signature · 1 line
2.39.2
author maintainer
#66 lore raw

PATCH 66/224 net/mlx5: Fix steering rules cleanup

In reply to Greg Kroah-Hartman

From: Lama Kayal <[email protected]>

[ Upstream commit 922f56e9a795d6f3dd72d3428ebdd7ee040fa855 ]

vport's mc, uc and multicast rules are not deleted in teardown path when EEH happens. Since the vport's promisc settings(uc, mc and all) in firmware are reset after EEH, mlx5 driver will try to delete the above rules in the initialization path. This cause kernel crash because these software rules are no longer valid.

Fix by nullifying these rules right after delete to avoid accessing any dangling pointers.

Call Trace:
__list_del_entry_valid+0xcc/0x100 (unreliable)
tree_put_node+0xf4/0x1b0 [mlx5_core]
tree_remove_node+0x30/0x70 [mlx5_core]
mlx5_del_flow_rules+0x14c/0x1f0 [mlx5_core]
esw_apply_vport_rx_mode+0x10c/0x200 [mlx5_core]
esw_update_vport_rx_mode+0xb4/0x180 [mlx5_core]
esw_vport_change_handle_locked+0x1ec/0x230 [mlx5_core]
esw_enable_vport+0x130/0x260 [mlx5_core]
mlx5_eswitch_enable_sriov+0x2a0/0x2f0 [mlx5_core]
mlx5_device_enable_sriov+0x74/0x440 [mlx5_core]
mlx5_load_one+0x114c/0x1550 [mlx5_core]
mlx5_pci_resume+0x68/0xf0 [mlx5_core]
eeh_report_resume+0x1a4/0x230
eeh_pe_dev_traverse+0x98/0x170
eeh_handle_normal_event+0x3e4/0x640
eeh_handle_event+0x4c/0x370
eeh_event_handler+0x14c/0x210
kthread+0x168/0x1b0
ret_from_kernel_thread+0x5c/0x84
Fixes a35f71f27a61 ("net/mlx5: E-Switch, Implement promiscuous rx modes vf request handling")
---
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +1 -0
index 43ba00d5e36ec..4b9d567c8f473 100644
@@ -916,6 +916,7 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num)
 	 */
 	esw_vport_change_handle_locked(vport);
 	vport->enabled_events = 0;
+	esw_apply_vport_rx_mode(esw, vport, false, false);
 	esw_vport_cleanup(esw, vport);
 	esw->enabled_vports--;
 
Signature · 1 line
2.39.2
author maintainer
#67 lore raw

PATCH 67/224 net/mlx5e: Overcome slow response for first macsec ASO WQE

In reply to Greg Kroah-Hartman

From: Emeel Hakim <[email protected]>

[ Upstream commit 7e3fce82d945cf6e7f99034b113ff2d250d7524d ]

First ASO WQE poll causes a cache miss in hardware hence the resut is delayed. It causes to the situation where such WQE is polled earlier than it is needed.

Add logic to retry ASO CQ polling operation.

Fixes 739cfa34518e ("net/mlx5: Make ASO poll CQ usable in atomic context")
---
 .../net/ethernet/mellanox/mlx5/core/en_accel/macsec.c    | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +8 -1
index 0c23340bfcc75..0f8f3ce35537d 100644
@@ -1412,6 +1412,7 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
 	struct mlx5e_macsec_aso *aso;
 	struct mlx5_aso_wqe *aso_wqe;
 	struct mlx5_aso *maso;
+	unsigned long expires;
 	int err;
 
 	aso = &macsec->aso;
@@ -1425,7 +1426,13 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
 	macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL);
 
 	mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl);
-	err = mlx5_aso_poll_cq(maso, false);
+	expires = jiffies + msecs_to_jiffies(10);
+	do {
+		err = mlx5_aso_poll_cq(maso, false);
+		if (err)
+			usleep_range(2, 10);
+	} while (err && time_is_after_jiffies(expires));
+
 	if (err)
 		goto err_out;
 
Signature · 1 line
2.39.2
author maintainer
#68 lore raw

PATCH 68/224 net/mlx5: Read the TC mapping of all priorities on ETS query

In reply to Greg Kroah-Hartman

From: Maher Sanalla <[email protected]>

[ Upstream commit 44d553188c38ac74b799dfdcebafef2f7bb70942 ]

When ETS configurations are queried by the user to get the mapping assignment between packet priority and traffic class, only priorities up to maximum TCs are queried from QTCT register in FW to retrieve their assigned TC, leaving the rest of the priorities mapped to the default TC #0 which might be misleading.

Fix by querying the TC mapping of all priorities on each ETS query, regardless of the maximum number of TCs configured in FW.

Fixes 820c2c5e773d ("net/mlx5e: Read ETS settings directly from firmware")
---
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +4 -2
index 2449731b7d79a..89de92d064836 100644
@@ -117,12 +117,14 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 	if (!MLX5_CAP_GEN(priv->mdev, ets))
 		return -EOPNOTSUPP;
 
-	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
-	for (i = 0; i < ets->ets_cap; i++) {
+	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 		err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
 		if (err)
 			return err;
+	}
 
+	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
+	for (i = 0; i < ets->ets_cap; i++) {
 		err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]);
 		if (err)
 			return err;
Signature · 1 line
2.39.2
author maintainer
#69 lore raw

PATCH 69/224 net/mlx5: E-Switch, Fix an Oops in error handling code

In reply to Greg Kroah-Hartman

From: Dan Carpenter <[email protected]>

[ Upstream commit 640fcdbcf27fc62de9223f958ceb4e897a00e791 ]

The error handling dereferences "vport". There is nothing we can do if it is an error pointer except returning the error code.

Fixes 133dcfc577ea ("net/mlx5: E-Switch, Alloc and free unique metadata for match")
---
 drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c +1 -2
index a994e71e05c11..db578a7e7008a 100644
@@ -364,8 +364,7 @@ int mlx5_esw_acl_ingress_vport_bond_update(struct mlx5_eswitch *esw, u16 vport_n
 
 	if (WARN_ON_ONCE(IS_ERR(vport))) {
 		esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
-		err = PTR_ERR(vport);
-		goto out;
+		return PTR_ERR(vport);
 	}
 
 	esw_acl_ingress_ofld_rules_destroy(esw, vport);
Signature · 1 line
2.39.2
author maintainer
#70 lore raw

PATCH 70/224 net: dsa: tag_brcm: legacy: fix daisy-chained switches

In reply to Greg Kroah-Hartman

From: Álvaro Fernández Rojas <[email protected]>

[ Upstream commit 032a954061afd4b7426c3eb6bfd2952ef1e9a384 ]

When BCM63xx internal switches are connected to switches with a 4-byte Broadcom tag, it does not identify the packet as VLAN tagged, so it adds one based on its PVID (which is likely 0).
Right now, the packet is received by the BCM63xx internal switch and the 6-byte tag is properly processed. The next step would to decode the corresponding 4-byte tag. However, the internal switch adds an invalid VLAN tag after the 6-byte tag and the 4-byte tag handling fails.
In order to fix this we need to remove the invalid VLAN tag after the 6-byte tag before passing it to the 4-byte tag decoding.

---
 net/dsa/tag_brcm.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
net/dsa/tag_brcm.c +8 -2
index 16889ea3e0a79..a65d62fb90094 100644
@@ -7,6 +7,7 @@
 
 #include <linux/dsa/brcm.h>
 #include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 
@@ -248,6 +249,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
 static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
 					struct net_device *dev)
 {
+	int len = BRCM_LEG_TAG_LEN;
 	int source_port;
 	u8 *brcm_tag;
 
@@ -262,12 +264,16 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
 	if (!skb->dev)
 		return NULL;
 
+	/* VLAN tag is added by BCM63xx internal switch */
+	if (netdev_uses_dsa(skb->dev))
+		len += VLAN_HLEN;
+
 	/* Remove Broadcom tag and update checksum */
-	skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
+	skb_pull_rcsum(skb, len);
 
 	dsa_default_offload_fwd_mark(skb);
 
-	dsa_strip_etype_header(skb, BRCM_LEG_TAG_LEN);
+	dsa_strip_etype_header(skb, len);
 
 	return skb;
 }
Signature · 1 line
2.39.2
author maintainer
#71 lore raw

PATCH 71/224 atm: idt77252: fix kmemleak when rmmod idt77252

In reply to Greg Kroah-Hartman

From: Li Zetao <[email protected]>

[ Upstream commit 4fe3c88552a3fbe1944426a4506a18cdeb457b5a ]

There are memory leaks reported by kmemleak:

unreferenced object 0xffff888106500800 (size 128):

    comm "modprobe", pid 1017, jiffies 4297787785 (age 67.152s)
    hex dump (first 32 bytes):
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    backtrace:
      [<00000000970ce626>] __kmem_cache_alloc_node+0x20c/0x380
      [<00000000fb5f78d9>] kmalloc_trace+0x2f/0xb0
      [<000000000e947e2a>] idt77252_init_one+0x2847/0x3c90 [idt77252]
      [<000000006efb048e>] local_pci_probe+0xeb/0x1a0
    ...

unreferenced object 0xffff888106500b00 (size 128):

    comm "modprobe", pid 1017, jiffies 4297787785 (age 67.152s)
    hex dump (first 32 bytes):
      00 20 3d 01 80 88 ff ff 00 20 3d 01 80 88 ff ff  . =...... =.....
      f0 23 3d 01 80 88 ff ff 00 20 3d 01 00 00 00 00  .#=...... =.....
    backtrace:
      [<00000000970ce626>] __kmem_cache_alloc_node+0x20c/0x380
      [<00000000fb5f78d9>] kmalloc_trace+0x2f/0xb0
      [<00000000f451c5be>] alloc_scq.constprop.0+0x4a/0x400 [idt77252]
      [<00000000e6313849>] idt77252_init_one+0x28cf/0x3c90 [idt77252]

The root cause is traced to the vc_maps which alloced in open_card_oam() are not freed in close_card_oam(). The vc_maps are used to record open connections, so when close a vc_map in close_card_oam(), the memory should be freed. Moreover, the ubr0 is not closed when close a idt77252 device, leading to the memory leak of vc_map and scq_info.

Fix them by adding kfree in close_card_oam() and implementing new close_card_ubr0() to close ubr0.

---
 drivers/atm/idt77252.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/atm/idt77252.c +11 -0
index 681cb3786794d..49cb4537344aa 100644
@@ -2909,6 +2909,7 @@ close_card_oam(struct idt77252_dev *card)
 
 				recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
 			}
+			kfree(vc);
 		}
 	}
 }
@@ -2952,6 +2953,15 @@ open_card_ubr0(struct idt77252_dev *card)
 	return 0;
 }
 
+static void
+close_card_ubr0(struct idt77252_dev *card)
+{
+	struct vc_map *vc = card->vcs[0];
+
+	free_scq(card, vc->scq);
+	kfree(vc);
+}
+
 static int
 idt77252_dev_open(struct idt77252_dev *card)
 {
@@ -3001,6 +3011,7 @@ static void idt77252_dev_close(struct atm_dev *dev)
 	struct idt77252_dev *card = dev->dev_data;
 	u32 conf;
 
+	close_card_ubr0(card);
 	close_card_oam(card);
 
 	conf = SAR_CFG_RXPTH |	/* enable receive path           */
Signature · 1 line
2.39.2
author maintainer
#72 lore raw

PATCH 72/224 erspan: do not use skb_mac_header() in ndo_start_xmit()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 8e50ed774554f93d55426039b27b1e38d7fa64d8 ]

Drivers should not assume skb_mac_header(skb) == skb->data in their ndo_start_xmit().

Use skb_network_offset() and skb_transport_offset() which better describe what is needed in erspan_fb_xmit() and ip6erspan_tunnel_xmit()

syzbot reported:

WARNING: CPU: 0 PID: 5083 at include/linux/skbuff.h:2873 skb_mac_header include/linux/skbuff.h:2873 [inline]
WARNING: CPU: 0 PID: 5083 at include/linux/skbuff.h:2873 ip6erspan_tunnel_xmit+0x1d9c/0x2d90 net/ipv6/ip6_gre.c:962
Modules linked in:
CPU: 0 PID: 5083 Comm: syz-executor406 Not tainted 6.3.0-rc2-syzkaller-00866-gd4671cb96fa3 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023
RIP: 0010:skb_mac_header include/linux/skbuff.h:2873 [inline]
RIP: 0010:ip6erspan_tunnel_xmit+0x1d9c/0x2d90 net/ipv6/ip6_gre.c:962
Code: 04 02 41 01 de 84 c0 74 08 3c 03 0f 8e 1c 0a 00 00 45 89 b4 24 c8 00 00 00 c6 85 77 fe ff ff 01 e9 33 e7 ff ff e8 b4 27 a1 f8 <0f> 0b e9 b6 e7 ff ff e8 a8 27 a1 f8 49 8d bf f0 0c 00 00 48 b8 00
RSP: 0018:ffffc90003b2f830 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 000000000000ffff RCX: 0000000000000000
RDX: ffff888021273a80 RSI: ffffffff88e1bd4c RDI: 0000000000000003
RBP: ffffc90003b2f9d8 R08: 0000000000000003 R09: 000000000000ffff
R10: 000000000000ffff R11: 0000000000000000 R12: ffff88802b28da00
R13: 00000000000000d0 R14: ffff88807e25b6d0 R15: ffff888023408000
FS: 0000555556a61300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055e5b11eb6e8 CR3: 0000000027c1b000 CR4: 00000000003506f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
__netdev_start_xmit include/linux/netdevice.h:4900 [inline]
netdev_start_xmit include/linux/netdevice.h:4914 [inline]
__dev_direct_xmit+0x504/0x730 net/core/dev.c:4300
dev_direct_xmit include/linux/netdevice.h:3088 [inline]
packet_xmit+0x20a/0x390 net/packet/af_packet.c:285
packet_snd net/packet/af_packet.c:3075 [inline]
packet_sendmsg+0x31a0/0x5150 net/packet/af_packet.c:3107
sock_sendmsg_nosec net/socket.c:724 [inline]
sock_sendmsg+0xde/0x190 net/socket.c:747
__sys_sendto+0x23a/0x340 net/socket.c:2142
__do_sys_sendto net/socket.c:2154 [inline]
__se_sys_sendto net/socket.c:2150 [inline]
__x64_sys_sendto+0xe1/0x1b0 net/socket.c:2150
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f123aaa1039
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 b1 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffc15d12058 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f123aaa1039
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000020000040 R09: 0000000000000014
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f123aa648c0
R13: 431bde82d7b634db R14: 0000000000000000 R15: 0000000000000000
---
 net/ipv4/ip_gre.c  | 4 ++--
 net/ipv6/ip6_gre.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
net/ipv4/ip_gre.c +2 -2
index cae9f1a4e059f..5b8242265617d 100644
@@ -552,7 +552,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 		truncate = true;
 	}
 
-	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	nhoff = skb_network_offset(skb);
 	if (skb->protocol == htons(ETH_P_IP) &&
 	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
 		truncate = true;
@@ -561,7 +561,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 		int thoff;
 
 		if (skb_transport_header_was_set(skb))
-			thoff = skb_transport_header(skb) - skb_mac_header(skb);
+			thoff = skb_transport_offset(skb);
 		else
 			thoff = nhoff + sizeof(struct ipv6hdr);
 		if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
net/ipv6/ip6_gre.c +2 -2
index c035a96fba3a4..4d5937af08ee9 100644
@@ -981,7 +981,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 		truncate = true;
 	}
 
-	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	nhoff = skb_network_offset(skb);
 	if (skb->protocol == htons(ETH_P_IP) &&
 	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
 		truncate = true;
@@ -990,7 +990,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 		int thoff;
 
 		if (skb_transport_header_was_set(skb))
-			thoff = skb_transport_header(skb) - skb_mac_header(skb);
+			thoff = skb_transport_offset(skb);
 		else
 			thoff = nhoff + sizeof(struct ipv6hdr);
 		if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
Signature · 1 line
2.39.2
author maintainer
#73 lore raw

PATCH 73/224 net/sonic: use dma_mapping_error() for error check

In reply to Greg Kroah-Hartman

From: Zhang Changzhong <[email protected]>

[ Upstream commit 4107b8746d93ace135b8c4da4f19bbae81db785f ]

The DMA address returned by dma_map_single() should be checked with dma_mapping_error(). Fix it accordingly.

---
 drivers/net/ethernet/natsemi/sonic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/natsemi/sonic.c +2 -2
index d17d1b4f2585f..825356ee3492e 100644
@@ -292,7 +292,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
 	 */
 
 	laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE);
-	if (!laddr) {
+	if (dma_mapping_error(lp->device, laddr)) {
 		pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name);
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -509,7 +509,7 @@ static bool sonic_alloc_rb(struct net_device *dev, struct sonic_local *lp,
 
 	*new_addr = dma_map_single(lp->device, skb_put(*new_skb, SONIC_RBSIZE),
 				   SONIC_RBSIZE, DMA_FROM_DEVICE);
-	if (!*new_addr) {
+	if (dma_mapping_error(lp->device, *new_addr)) {
 		dev_kfree_skb(*new_skb);
 		*new_skb = NULL;
 		return false;
Signature · 1 line
2.39.2
author maintainer
#74 lore raw

PATCH 74/224 nvme-tcp: fix nvme_tcp_term_pdu to match spec

In reply to Greg Kroah-Hartman

From: Caleb Sander <[email protected]>

[ Upstream commit aa01c67de5926fdb276793180564f172c55fb0d7 ]

The FEI field of C2HTermReq/H2CTermReq is 4 bytes but not 4-byte-aligned in the NVMe/TCP specification (it is located at offset 10 in the PDU). Split it into two 16-bit integers in struct nvme_tcp_term_pdu so no padding is inserted. There should also be 10 reserved bytes after. There are currently no users of this type.

Fixes fc221d05447aa6db ("nvme-tcp: Add protocol header")
---
 include/linux/nvme-tcp.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
include/linux/nvme-tcp.h +3 -2
index 75470159a194d..57ebe1267f7fb 100644
@@ -115,8 +115,9 @@ struct nvme_tcp_icresp_pdu {
 struct nvme_tcp_term_pdu {
 	struct nvme_tcp_hdr	hdr;
 	__le16			fes;
-	__le32			fei;
-	__u8			rsvd[8];
+	__le16			feil;
+	__le16			feiu;
+	__u8			rsvd[10];
 };
 
 /**
Signature · 1 line
2.39.2
author maintainer
#75 lore raw

PATCH 75/224 mlxsw: spectrum_fid: Fix incorrect local port type

In reply to Greg Kroah-Hartman

From: Ido Schimmel <[email protected]>

[ Upstream commit bb765a743377d46d8da8e7f7e5128022504741b9 ]

Local port is a 10-bit number, but it was mistakenly stored in a u8, resulting in firmware errors when using a netdev corresponding to a local port higher than 255.

Fix by storing the local port in u16, as is done in the rest of the code.

---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +2 -2
index 045a24cacfa51..b6ee2d658b0c4 100644
@@ -1354,7 +1354,7 @@ static int mlxsw_sp_fid_8021q_port_vid_map(struct mlxsw_sp_fid *fid,
 					   u16 vid)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-	u8 local_port = mlxsw_sp_port->local_port;
+	u16 local_port = mlxsw_sp_port->local_port;
 	int err;
 
 	/* In case there are no {Port, VID} => FID mappings on the port,
@@ -1391,7 +1391,7 @@ mlxsw_sp_fid_8021q_port_vid_unmap(struct mlxsw_sp_fid *fid,
 				  struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-	u8 local_port = mlxsw_sp_port->local_port;
+	u16 local_port = mlxsw_sp_port->local_port;
 
 	mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
 	mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
Signature · 1 line
2.39.2
author maintainer
#76 lore raw

PATCH 76/224 hvc/xen: prevent concurrent accesses to the shared ring

In reply to Greg Kroah-Hartman

From: Roger Pau Monne <[email protected]>

[ Upstream commit 6214894f49a967c749ee6c07cb00f9cede748df4 ]

The hvc machinery registers both a console and a tty device based on the hv ops provided by the specific implementation. Those two interfaces however have different locks, and there's no single locks that's shared between the tty and the console implementations, hence the driver needs to protect itself against concurrent accesses. Otherwise concurrent calls using the split interfaces are likely to corrupt the ring indexes, leaving the console unusable.

Introduce a lock to xencons_info to serialize accesses to the shared ring. This is only required when using the shared memory console, concurrent accesses to the hypercall based console implementation are not an issue.

Note the conditional logic in domU_read_console() is slightly modified so the notify_daemon() call can be done outside of the locked region:
it's an hypercall and there's no need for it to be done with the lock held.

Fixes b536b4b96230 ('xen: use the hvc console infrastructure for Xen console')
---
 drivers/tty/hvc/hvc_xen.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
drivers/tty/hvc/hvc_xen.c +17 -2
index 37809c6c027fc..d9d0232753286 100644
@@ -43,6 +43,7 @@ struct xencons_info {
 	int irq;
 	int vtermno;
 	grant_ref_t gntref;
+	spinlock_t ring_lock;
 };
 
 static LIST_HEAD(xenconsoles);
@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons,
 	XENCONS_RING_IDX cons, prod;
 	struct xencons_interface *intf = xencons->intf;
 	int sent = 0;
+	unsigned long flags;
 
+	spin_lock_irqsave(&xencons->ring_lock, flags);
 	cons = intf->out_cons;
 	prod = intf->out_prod;
 	mb();			/* update queue values before going on */
 
 	if ((prod - cons) > sizeof(intf->out)) {
+		spin_unlock_irqrestore(&xencons->ring_lock, flags);
 		pr_err_once("xencons: Illegal ring page indices");
 		return -EINVAL;
 	}
@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons,
 
 	wmb();			/* write ring before updating pointer */
 	intf->out_prod = prod;
+	spin_unlock_irqrestore(&xencons->ring_lock, flags);
 
 	if (sent)
 		notify_daemon(xencons);
@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
 	int recv = 0;
 	struct xencons_info *xencons = vtermno_to_xencons(vtermno);
 	unsigned int eoiflag = 0;
+	unsigned long flags;
 
 	if (xencons == NULL)
 		return -EINVAL;
 	intf = xencons->intf;
 
+	spin_lock_irqsave(&xencons->ring_lock, flags);
 	cons = intf->in_cons;
 	prod = intf->in_prod;
 	mb();			/* get pointers before reading ring */
 
 	if ((prod - cons) > sizeof(intf->in)) {
+		spin_unlock_irqrestore(&xencons->ring_lock, flags);
 		pr_err_once("xencons: Illegal ring page indices");
 		return -EINVAL;
 	}
@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
 		xencons->out_cons = intf->out_cons;
 		xencons->out_cons_same = 0;
 	}
+	if (!recv && xencons->out_cons_same++ > 1) {
+		eoiflag = XEN_EOI_FLAG_SPURIOUS;
+	}
+	spin_unlock_irqrestore(&xencons->ring_lock, flags);
+
 	if (recv) {
 		notify_daemon(xencons);
-	} else if (xencons->out_cons_same++ > 1) {
-		eoiflag = XEN_EOI_FLAG_SPURIOUS;
 	}
 
 	xen_irq_lateeoi(xencons->irq, eoiflag);
@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void)
 		info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
 		if (!info)
 			return -ENOMEM;
+		spin_lock_init(&info->ring_lock);
 	} else if (info->intf != NULL) {
 		/* already configured */
 		return 0;
@@ -275,6 +287,7 @@ static int xen_hvm_console_init(void)
 
 static int xencons_info_pv_init(struct xencons_info *info, int vtermno)
 {
+	spin_lock_init(&info->ring_lock);
 	info->evtchn = xen_start_info->console.domU.evtchn;
 	/* GFN == MFN for PV guest */
 	info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void)
 		info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
 		if (!info)
 			return -ENOMEM;
+		spin_lock_init(&info->ring_lock);
 	}
 
 	info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
@@ -482,6 +496,7 @@ static int xencons_probe(struct xenbus_device *dev,
 	info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
+	spin_lock_init(&info->ring_lock);
 	dev_set_drvdata(&dev->dev, info);
 	info->xbdev = dev;
 	info->vtermno = xenbus_devid_to_vtermno(devid);
Signature · 1 line
2.39.2
author maintainer
#77 lore raw

PATCH 77/224 ksmbd: add low bound validation to FSCTL_SET_ZERO_DATA

In reply to Greg Kroah-Hartman

From: Namjae Jeon <[email protected]>

[ Upstream commit 2d74ec97131b1179a373b6d521f195c84e894eb6 ]

Smatch static checker warning:
fs/ksmbd/smb2pdu.c:7759 smb2_ioctl()
warn: no lower bound on 'off'

Fix unexpected result that could caused from negative off and bfz.

Fixes b5e5f9dfc915 ("ksmbd: check invalid FileOffset and BeyondFinalZero in FSCTL_ZERO_DATA")
---
 fs/ksmbd/smb2pdu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ksmbd/smb2pdu.c +1 -1
index 0f0f1243a9cbf..3bb971831e7ce 100644
@@ -7764,7 +7764,7 @@ int smb2_ioctl(struct ksmbd_work *work)
 
 		off = le64_to_cpu(zero_data->FileOffset);
 		bfz = le64_to_cpu(zero_data->BeyondFinalZero);
-		if (off > bfz) {
+		if (off < 0 || bfz < 0 || off > bfz) {
 			ret = -EINVAL;
 			goto out;
 		}
Signature · 1 line
2.39.2
author maintainer
#78 lore raw

PATCH 78/224 ksmbd: add low bound validation to FSCTL_QUERY_ALLOCATED_RANGES

In reply to Greg Kroah-Hartman

From: Namjae Jeon <[email protected]>

[ Upstream commit 342edb60dcda7a409430359b0cac2864bb9dfe44 ]

Smatch static checker warning:
fs/ksmbd/vfs.c:1040 ksmbd_vfs_fqar_lseek() warn: no lower bound on 'length' fs/ksmbd/vfs.c:1041 ksmbd_vfs_fqar_lseek() warn: no lower bound on 'start'

Fix unexpected result that could caused from negative start and length.

Fixes f44158485826 ("cifsd: add file operations")
---
 fs/ksmbd/smb2pdu.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
fs/ksmbd/smb2pdu.c +6 -3
index 3bb971831e7ce..61d12eab0be15 100644
@@ -7457,13 +7457,16 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
 	if (in_count == 0)
 		return -EINVAL;
 
+	start = le64_to_cpu(qar_req->file_offset);
+	length = le64_to_cpu(qar_req->length);
+
+	if (start < 0 || length < 0)
+		return -EINVAL;
+
 	fp = ksmbd_lookup_fd_fast(work, id);
 	if (!fp)
 		return -ENOENT;
 
-	start = le64_to_cpu(qar_req->file_offset);
-	length = le64_to_cpu(qar_req->length);
-
 	ret = ksmbd_vfs_fqar_lseek(fp, start, length,
 				   qar_rsp, in_count, out_count);
 	if (ret && ret != -E2BIG)
Signature · 1 line
2.39.2
author maintainer
#79 lore raw

PATCH 79/224 ksmbd: fix possible refcount leak in smb2_open()

In reply to Greg Kroah-Hartman

From: ChenXiaoSong <[email protected]>

[ Upstream commit 2624b445544ffc1472ccabfb6ec867c199d4c95c ]

Reference count of acls will leak when memory allocation fails. Fix this by adding the missing posix_acl_release().

Fixes e2f34481b24d ("cifsd: add server-side procedures for SMB3")
---
 fs/ksmbd/smb2pdu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/ksmbd/smb2pdu.c +4 -1
index 61d12eab0be15..e8c051a3329ec 100644
@@ -2994,8 +2994,11 @@ int smb2_open(struct ksmbd_work *work)
 							sizeof(struct smb_acl) +
 							sizeof(struct smb_ace) * ace_num * 2,
 							GFP_KERNEL);
-					if (!pntsd)
+					if (!pntsd) {
+						posix_acl_release(fattr.cf_acls);
+						posix_acl_release(fattr.cf_dacls);
 						goto err_out;
+					}
 
 					rc = build_sec_desc(user_ns,
 							    pntsd, NULL, 0,
Signature · 1 line
2.39.2
author maintainer
#80 lore raw

PATCH 80/224 Bluetooth: hci_sync: Resume adv with no RPA when active scan

In reply to Greg Kroah-Hartman

From: Zhengping Jiang <[email protected]>

[ Upstream commit 3c44a431d62bf4a20d7b901f98266ae3f4676d48 ]

The address resolution should be disabled during the active scan, so all the advertisements can reach the host. The advertising has to be paused before disabling the address resolution, because the advertising will prevent any changes to the resolving list and the address resolution status. Skipping this will cause the hci error and the discovery failure.

According to the bluetooth specification:
"7.8.44 LE Set Address Resolution Enable command

This command shall not be used when:
- Advertising (other than periodic advertising) is enabled,
- Scanning is enabled, or
- an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding."

If the host is using RPA, the controller needs to generate RPA for the advertising, so the advertising must remain paused during the active scan.

If the host is not using RPA, the advertising can be resumed after disabling the address resolution.

Fixes 9afc675edeeb ("Bluetooth: hci_sync: allow advertise when scan without RPA")
---
 net/bluetooth/hci_sync.c | 64 +++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 20 deletions(-)
net/bluetooth/hci_sync.c +44 -20
index 3eec688a88a92..13ec3c86a0dcf 100644
@@ -2367,6 +2367,45 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
 	return err;
 }
 
+static int hci_pause_addr_resolution(struct hci_dev *hdev)
+{
+	int err;
+
+	if (!use_ll_privacy(hdev))
+		return 0;
+
+	if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+		return 0;
+
+	/* Cannot disable addr resolution if scanning is enabled or
+	 * when initiating an LE connection.
+	 */
+	if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+	    hci_lookup_le_connect(hdev)) {
+		bt_dev_err(hdev, "Command not allowed when scan/LE connect");
+		return -EPERM;
+	}
+
+	/* Cannot disable addr resolution if advertising is enabled. */
+	err = hci_pause_advertising_sync(hdev);
+	if (err) {
+		bt_dev_err(hdev, "Pause advertising failed: %d", err);
+		return err;
+	}
+
+	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
+	if (err)
+		bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
+			   err);
+
+	/* Return if address resolution is disabled and RPA is not used. */
+	if (!err && scan_use_rpa(hdev))
+		return err;
+
+	hci_resume_advertising_sync(hdev);
+	return err;
+}
+
 struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev,
 					     bool extended, struct sock *sk)
 {
@@ -2402,7 +2441,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
 	u8 filter_policy;
 	int err;
 
-	/* Pause advertising if resolving list can be used as controllers are
+	/* Pause advertising if resolving list can be used as controllers
 	 * cannot accept resolving list modifications while advertising.
 	 */
 	if (use_ll_privacy(hdev)) {
@@ -5376,27 +5415,12 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
 
 	cancel_interleave_scan(hdev);
 
-	/* Pause advertising since active scanning disables address resolution
-	 * which advertising depend on in order to generate its RPAs.
-	 */
-	if (use_ll_privacy(hdev) && hci_dev_test_flag(hdev, HCI_PRIVACY)) {
-		err = hci_pause_advertising_sync(hdev);
-		if (err) {
-			bt_dev_err(hdev, "pause advertising failed: %d", err);
-			goto failed;
-		}
-	}
-
-	/* Disable address resolution while doing active scanning since the
-	 * accept list shall not be used and all reports shall reach the host
-	 * anyway.
+	/* Pause address resolution for active scan and stop advertising if
+	 * privacy is enabled.
 	 */
-	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
-	if (err) {
-		bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
-			   err);
+	err = hci_pause_addr_resolution(hdev);
+	if (err)
 		goto failed;
-	}
 
 	/* All active scans will be done with either a resolvable private
 	 * address (when privacy feature has been enabled) or non-resolvable
Signature · 1 line
2.39.2
author maintainer
#81 lore raw

PATCH 81/224 Bluetooth: hci_core: Detect if an ACL packet is in fact an ISO packet

In reply to Greg Kroah-Hartman

From: Luiz Augusto von Dentz <[email protected]>

[ Upstream commit 876e78104f23ce9267822757a63562a609b126c3 ]

Because some transports don't have a dedicated type for ISO packets (see 14202eff214e1e941fefa0366d4c3bc4b1a0d500) they may use ACL type when in fact they are ISO packets.

In the past this was left for the driver to detect such thing but it creates a problem when using the likes of btproxy when used by a VM as the host would not be aware of the connection the guest is doing it won't be able to detect such behavior, so this make bt_recv_frame detect when it happens as it is the common interface to all drivers including guest VMs.

Fixes 14202eff214e ("Bluetooth: btusb: Detect if an ACL packet is in fact an ISO packet")
---
 net/bluetooth/hci_core.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
net/bluetooth/hci_core.c +19 -4
index b65c3aabcd536..334e308451f53 100644
@@ -2871,10 +2871,25 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
 		return -ENXIO;
 	}
 
-	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
-	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
-	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
-	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
+	switch (hci_skb_pkt_type(skb)) {
+	case HCI_EVENT_PKT:
+		break;
+	case HCI_ACLDATA_PKT:
+		/* Detect if ISO packet has been sent as ACL */
+		if (hci_conn_num(hdev, ISO_LINK)) {
+			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
+			__u8 type;
+
+			type = hci_conn_lookup_type(hdev, hci_handle(handle));
+			if (type == ISO_LINK)
+				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
+		}
+		break;
+	case HCI_SCODATA_PKT:
+		break;
+	case HCI_ISODATA_PKT:
+		break;
+	default:
 		kfree_skb(skb);
 		return -EINVAL;
 	}
Signature · 1 line
2.39.2
author maintainer
#82 lore raw

PATCH 82/224 Bluetooth: btusb: Remove detection of ISO packets over bulk

In reply to Greg Kroah-Hartman

From: Luiz Augusto von Dentz <[email protected]>

[ Upstream commit efe375b716c1c1c9b52a816f5b933a95421020a2 ]

This removes the code introduced by 14202eff214e1e941fefa0366d4c3bc4b1a0d500 as hci_recv_frame is now able to detect ACL packets that are in fact ISO packets.

Fixes 14202eff214e ("Bluetooth: btusb: Detect if an ACL packet is in fact an ISO packet")
---
 drivers/bluetooth/btusb.c | 10 ----------
 1 file changed, 10 deletions(-)
drivers/bluetooth/btusb.c +0 -10
index 952dc9d2404ed..90b85dcb138df 100644
@@ -1020,21 +1020,11 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
 		hci_skb_expect(skb) -= len;
 
 		if (skb->len == HCI_ACL_HDR_SIZE) {
-			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
 			__le16 dlen = hci_acl_hdr(skb)->dlen;
-			__u8 type;
 
 			/* Complete ACL header */
 			hci_skb_expect(skb) = __le16_to_cpu(dlen);
 
-			/* Detect if ISO packet has been sent over bulk */
-			if (hci_conn_num(data->hdev, ISO_LINK)) {
-				type = hci_conn_lookup_type(data->hdev,
-							    hci_handle(handle));
-				if (type == ISO_LINK)
-					hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
-			}
-
 			if (skb_tailroom(skb) < hci_skb_expect(skb)) {
 				kfree_skb(skb);
 				skb = NULL;
Signature · 1 line
2.39.2
author maintainer
#83 lore raw

PATCH 83/224 Bluetooth: ISO: fix timestamped HCI ISO data packet parsing

In reply to Greg Kroah-Hartman

From: Pauli Virtanen <[email protected]>

[ Upstream commit 2f10e40a948e8a2abe7f983df3959a333ca8955f ]

Use correct HCI ISO data packet header struct when the packet has timestamp. The timestamp, when present, goes before the other fields (Core v5.3 4E 5.4.5), so the structs are not compatible.

Fixes ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
---
 net/bluetooth/iso.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
net/bluetooth/iso.c +7 -2
index 2dabef488eaae..cb959e8eac185 100644
@@ -1621,7 +1621,6 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
 void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 {
 	struct iso_conn *conn = hcon->iso_data;
-	struct hci_iso_data_hdr *hdr;
 	__u16 pb, ts, len;
 
 	if (!conn)
@@ -1643,6 +1642,8 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 		}
 
 		if (ts) {
+			struct hci_iso_ts_data_hdr *hdr;
+
 			/* TODO: add timestamp to the packet? */
 			hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
 			if (!hdr) {
@@ -1650,15 +1651,19 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 				goto drop;
 			}
 
+			len = __le16_to_cpu(hdr->slen);
 		} else {
+			struct hci_iso_data_hdr *hdr;
+
 			hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
 			if (!hdr) {
 				BT_ERR("Frame is too short (len %d)", skb->len);
 				goto drop;
 			}
+
+			len = __le16_to_cpu(hdr->slen);
 		}
 
-		len    = __le16_to_cpu(hdr->slen);
 		flags  = hci_iso_data_flags(len);
 		len    = hci_iso_data_len(len);
 
Signature · 1 line
2.39.2
author maintainer
#84 lore raw

PATCH 84/224 Bluetooth: Remove "Power-on" check from Mesh feature

In reply to Greg Kroah-Hartman

From: Brian Gix <[email protected]>

[ Upstream commit 52dd5e964a55c98c1b0bcf5fc737a5ddd00e7d4d ]

The Bluetooth mesh experimental feature enable was requiring the controller to be powered off in order for the Enable to work. Mesh is supposed to be enablable regardless of the controller state, and created an unintended requirement that the mesh daemon be started before the classic bluetoothd daemon.

Fixes af6bcc1921ff ("Bluetooth: Add experimental wrapper for MGMT based mesh")
---
 net/bluetooth/mgmt.c | 6 ------
 1 file changed, 6 deletions(-)
net/bluetooth/mgmt.c +0 -6
index 0dd30a3beb776..7576db8eb83e2 100644
@@ -4627,12 +4627,6 @@ static int set_mgmt_mesh_func(struct sock *sk, struct hci_dev *hdev,
 				       MGMT_OP_SET_EXP_FEATURE,
 				       MGMT_STATUS_INVALID_INDEX);
 
-	/* Changes can only be made when controller is powered down */
-	if (hdev_is_powered(hdev))
-		return mgmt_cmd_status(sk, hdev->id,
-				       MGMT_OP_SET_EXP_FEATURE,
-				       MGMT_STATUS_REJECTED);
-
 	/* Parameters are limited to a single octet */
 	if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
 		return mgmt_cmd_status(sk, hdev->id,
Signature · 1 line
2.39.2
author maintainer
#85 lore raw

PATCH 85/224 gve: Cache link_speed value from device

In reply to Greg Kroah-Hartman

From: Joshua Washington <[email protected]>

[ Upstream commit 68c3e4fc8628b1487c965aabb29207249657eb5f ]

The link speed is never changed for the uptime of a VM, and the current implementation sends an admin queue command for each call. Admin queue command invocations have nontrivial overhead (e.g., VM exits), which can be disruptive to users if triggered frequently. Our telemetry data shows that there are VMs that make frequent calls to this admin queue command. Caching the result of the original admin queue command would eliminate the need to send multiple admin queue commands on subsequent calls to retrieve link speed.

Fixes 7e074d5a76ca ("gve: Enable Link Speed Reporting in the driver.")
---
 drivers/net/ethernet/google/gve/gve_ethtool.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/google/gve/gve_ethtool.c +4 -1
index 7b9a2d9d96243..38df602f2869c 100644
@@ -535,7 +535,10 @@ static int gve_get_link_ksettings(struct net_device *netdev,
 				  struct ethtool_link_ksettings *cmd)
 {
 	struct gve_priv *priv = netdev_priv(netdev);
-	int err = gve_adminq_report_link_speed(priv);
+	int err = 0;
+
+	if (priv->link_speed == 0)
+		err = gve_adminq_report_link_speed(priv);
 
 	cmd->base.speed = priv->link_speed;
 	return err;
Signature · 1 line
2.39.2
author maintainer
#86 lore raw

PATCH 86/224 net: asix: fix modprobe "sysfs: cannot create duplicate filename"

In reply to Greg Kroah-Hartman

From: Grant Grundler <[email protected]>

[ Upstream commit 8eac0095de355ee31e1b014f79f83d2cd62a2d04 ]

"modprobe asix ; rmmod asix ; modprobe asix" fails with:
sysfs: cannot create duplicate filename \
'/devices/virtual/mdio_bus/usb-003:004'

Issue was originally reported by Anton Lundin on 2022-06-22 (link below).

Chrome OS team hit the same issue in Feb, 2023 when trying to find work arounds for other issues with AX88172 devices.

The use of devm_mdiobus_register() with usbnet devices results in the MDIO data being associated with the USB device. When the asix driver is unloaded, the USB device continues to exist and the corresponding "mdiobus_unregister()" is NOT called until the USB device is unplugged or unauthorized. So the next "modprobe asix" will fail because the MDIO phy sysfs attributes still exist.

The 'easy' (from a design PoV) fix is to use the non-devm variants of mdiobus_* functions and explicitly manage this use in the asix_bind and asix_unbind function calls. I've not explored trying to fix usbnet initialization so devm_* stuff will work.

---
 drivers/net/usb/asix_devices.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)
drivers/net/usb/asix_devices.c +27 -5
index 11f60d32be82e..6eacbf17f1c0c 100644
@@ -666,8 +666,9 @@ static int asix_resume(struct usb_interface *intf)
 static int ax88772_init_mdio(struct usbnet *dev)
 {
 	struct asix_common_private *priv = dev->driver_priv;
+	int ret;
 
-	priv->mdio = devm_mdiobus_alloc(&dev->udev->dev);
+	priv->mdio = mdiobus_alloc();
 	if (!priv->mdio)
 		return -ENOMEM;
 
@@ -679,7 +680,20 @@ static int ax88772_init_mdio(struct usbnet *dev)
 	snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
 		 dev->udev->bus->busnum, dev->udev->devnum);
 
-	return devm_mdiobus_register(&dev->udev->dev, priv->mdio);
+	ret = mdiobus_register(priv->mdio);
+	if (ret) {
+		netdev_err(dev->net, "Could not register MDIO bus (err %d)\n", ret);
+		mdiobus_free(priv->mdio);
+		priv->mdio = NULL;
+	}
+
+	return ret;
+}
+
+static void ax88772_mdio_unregister(struct asix_common_private *priv)
+{
+	mdiobus_unregister(priv->mdio);
+	mdiobus_free(priv->mdio);
 }
 
 static int ax88772_init_phy(struct usbnet *dev)
@@ -897,16 +911,23 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
 
 	ret = ax88772_init_mdio(dev);
 	if (ret)
-		return ret;
+		goto mdio_err;
 
 	ret = ax88772_phylink_setup(dev);
 	if (ret)
-		return ret;
+		goto phylink_err;
 
 	ret = ax88772_init_phy(dev);
 	if (ret)
-		phylink_destroy(priv->phylink);
+		goto initphy_err;
 
+	return 0;
+
+initphy_err:
+	phylink_destroy(priv->phylink);
+phylink_err:
+	ax88772_mdio_unregister(priv);
+mdio_err:
 	return ret;
 }
 
@@ -927,6 +948,7 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
 	phylink_disconnect_phy(priv->phylink);
 	rtnl_unlock();
 	phylink_destroy(priv->phylink);
+	ax88772_mdio_unregister(priv);
 	asix_rx_fixup_common_free(dev->driver_priv);
 }
 
Signature · 1 line
2.39.2
author maintainer
#87 lore raw

PATCH 87/224 net: dsa: mt7530: move enabling disabling core clock to mt7530_pll_setup()

In reply to Greg Kroah-Hartman

From: Arınç ÜNAL <[email protected]>

[ Upstream commit 8f058a6ef99f0b88a177b58cc46a44ff5112e40a ]

Split the code that enables and disables TRGMII clocks and core clock. Move enabling and disabling core clock to mt7530_pll_setup() as it's supposed to be run there.

Add 20 ms delay before enabling the core clock as seen on the U-Boot MediaTek ethernet driver.

Change the comment for enabling and disabling TRGMII clocks as the code seems to affect both TXC and RXC.

Tested rgmii and trgmii modes of port 6 and rgmii mode of port 5 on MCM MT7530 on MT7621AT Unielec U7621-06 and standalone MT7530 on MT7623NI Bananapi BPI-R2.

---
 drivers/net/dsa/mt7530.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/net/dsa/mt7530.c +12 -6
index 1757d6a2c72ae..2c0387dd3f359 100644
@@ -396,6 +396,9 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
 /* Set up switch core clock for MT7530 */
 static void mt7530_pll_setup(struct mt7530_priv *priv)
 {
+	/* Disable core clock */
+	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+
 	/* Disable PLL */
 	core_write(priv, CORE_GSWPLL_GRP1, 0);
 
@@ -409,6 +412,11 @@ static void mt7530_pll_setup(struct mt7530_priv *priv)
 		   RG_GSWPLL_EN_PRE |
 		   RG_GSWPLL_POSDIV_200M(2) |
 		   RG_GSWPLL_FBKDIV_200M(32));
+
+	udelay(20);
+
+	/* Enable core clock */
+	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 }
 
 /* Setup TX circuit including relevant PAD and driving */
@@ -466,9 +474,8 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 			mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
 				     TD_DM_DRVP(8) | TD_DM_DRVN(8));
 
-		/* Disable MT7530 core and TRGMII Tx clocks */
-		core_clear(priv, CORE_TRGMII_GSW_CLK_CG,
-			   REG_GSWCK_EN | REG_TRGMIICK_EN);
+		/* Disable the MT7530 TRGMII clocks */
+		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
 		/* Setup the MT7530 TRGMII Tx Clock */
 		core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
@@ -485,9 +492,8 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 			   RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
 			   RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
 
-		/* Enable MT7530 core and TRGMII Tx clocks */
-		core_set(priv, CORE_TRGMII_GSW_CLK_CG,
-			 REG_GSWCK_EN | REG_TRGMIICK_EN);
+		/* Enable the MT7530 TRGMII clocks */
+		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 	} else {
 		for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
 			mt7530_rmw(priv, MT7530_TRGMII_RD(i),
Signature · 1 line
2.39.2
author maintainer
#88 lore raw

PATCH 88/224 net: dsa: mt7530: move lowering TRGMII driving to mt7530_setup()

In reply to Greg Kroah-Hartman

From: Arınç ÜNAL <[email protected]>

[ Upstream commit fdcc8ccd823740c18e803b886cec461bc0e64201 ]

Move lowering the TRGMII Tx clock driving to mt7530_setup(), after setting the core clock, as seen on the U-Boot MediaTek ethernet driver.

Move the code which looks like it lowers the TRGMII Rx clock driving to after the TRGMII Tx clock driving is lowered. This is run after lowering the Tx clock driving on the U-Boot MediaTek ethernet driver as well.

This way, the switch should consume less power regardless of port 6 being used.

Update the comment explaining mt7530_pad_clk_setup().

Tested rgmii and trgmii modes of port 6 and rgmii mode of port 5 on MCM MT7530 on MT7621AT Unielec U7621-06 and standalone MT7530 on MT7623NI Bananapi BPI-R2.

---
 drivers/net/dsa/mt7530.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/net/dsa/mt7530.c +11 -11
index 2c0387dd3f359..b4a679cbc95cf 100644
@@ -419,12 +419,12 @@ static void mt7530_pll_setup(struct mt7530_priv *priv)
 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 }
 
-/* Setup TX circuit including relevant PAD and driving */
+/* Setup port 6 interface mode and TRGMII TX circuit */
 static int
 mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 ncpo1, ssc_delta, trgint, i, xtal;
+	u32 ncpo1, ssc_delta, trgint, xtal;
 
 	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
@@ -469,11 +469,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 		   P6_INTF_MODE(trgint));
 
 	if (trgint) {
-		/* Lower Tx Driving for TRGMII path */
-		for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
-			mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
-				     TD_DM_DRVP(8) | TD_DM_DRVN(8));
-
 		/* Disable the MT7530 TRGMII clocks */
 		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
@@ -494,10 +489,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 
 		/* Enable the MT7530 TRGMII clocks */
 		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-	} else {
-		for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-			mt7530_rmw(priv, MT7530_TRGMII_RD(i),
-				   RD_TAP_MASK, RD_TAP(16));
 	}
 
 	return 0;
@@ -2212,6 +2203,15 @@ mt7530_setup(struct dsa_switch *ds)
 
 	mt7530_pll_setup(priv);
 
+	/* Lower Tx driving for TRGMII path */
+	for (i = 0; i < NUM_TRGMII_CTRL; i++)
+		mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
+			     TD_DM_DRVP(8) | TD_DM_DRVN(8));
+
+	for (i = 0; i < NUM_TRGMII_CTRL; i++)
+		mt7530_rmw(priv, MT7530_TRGMII_RD(i),
+			   RD_TAP_MASK, RD_TAP(16));
+
 	/* Enable port 6 */
 	val = mt7530_read(priv, MT7530_MHWTRAP);
 	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
Signature · 1 line
2.39.2
author maintainer
#89 lore raw

PATCH 89/224 net: dsa: mt7530: move setting ssc_delta to PHY_INTERFACE_MODE_TRGMII case

In reply to Greg Kroah-Hartman

From: Arınç ÜNAL <[email protected]>

[ Upstream commit 407b508bdd70b6848993843d96ed49ac4108fb52 ]

Move setting the ssc_delta variable to under the PHY_INTERFACE_MODE_TRGMII case as it's only needed when trgmii is used.

Fixes b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
---
 drivers/net/dsa/mt7530.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/net/dsa/mt7530.c +4 -5
index b4a679cbc95cf..38bf760b5b5ee 100644
@@ -441,6 +441,10 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 		break;
 	case PHY_INTERFACE_MODE_TRGMII:
 		trgint = 1;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ssc_delta = 0x57;
+		else
+			ssc_delta = 0x87;
 		if (priv->id == ID_MT7621) {
 			/* PLL frequency: 150MHz: 1.2GBit */
 			if (xtal == HWTRAP_XTAL_40MHZ)
@@ -460,11 +464,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 		return -EINVAL;
 	}
 
-	if (xtal == HWTRAP_XTAL_25MHZ)
-		ssc_delta = 0x57;
-	else
-		ssc_delta = 0x87;
-
 	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
 		   P6_INTF_MODE(trgint));
 
Signature · 1 line
2.39.2
author maintainer
#90 lore raw

PATCH 90/224 net: mdio: thunder: Add missing fwnode_handle_put()

In reply to Greg Kroah-Hartman

From: Liang He <[email protected]>

[ Upstream commit b1de5c78ebe9858ccec9d49af2f76724f1d47e3e ]

In device_for_each_child_node(), we should add fwnode_handle_put() when break out of the iteration device_for_each_child_node() as it will automatically increase and decrease the refcounter.

Fixes 379d7ac7ca31 ("phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.")
---
 drivers/net/mdio/mdio-thunder.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/mdio/mdio-thunder.c +1 -0
index 822d2cdd2f359..394b864aaa372 100644
@@ -104,6 +104,7 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,
 		if (i >= ARRAY_SIZE(nexus->buses))
 			break;
 	}
+	fwnode_handle_put(fwn);
 	return 0;
 
 err_release_regions:
Signature · 1 line
2.39.2
author maintainer
#91 lore raw

PATCH 91/224 drm/amd/display: Set dcn32 caps.seamless_odm

In reply to Greg Kroah-Hartman

From: Hersen Wu <[email protected]>

[ Upstream commit f9537b1fa7fb51c2162bc15ce469cbbf1ca0fbfe ]

[Why & How]
seamless_odm set was not picked up while
merging commit 2d017189e2b3 ("drm/amd/display:
Blank eDP on enable drv if odm enabled")

Fixes 2d017189e2b3 ("drm/amd/display: Blank eDP on enable drv if odm enabled")
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +1 -0
index 26fc5cad7a770..a942e2812183a 100644
@@ -2142,6 +2142,7 @@ static bool dcn32_resource_construct(
 	dc->caps.edp_dsc_support = true;
 	dc->caps.extended_aux_timeout_support = true;
 	dc->caps.dmcub_support = true;
+	dc->caps.seamless_odm = true;
 
 	/* Color pipeline capabilities */
 	dc->caps.color.dpp.dcn_arch = 1;
Signature · 1 line
2.39.2
author maintainer
#92 lore raw

PATCH 92/224 Bluetooth: btqcomsmd: Fix command timeout after setting BD address

In reply to Greg Kroah-Hartman

From: Stephan Gerhold <[email protected]>

[ Upstream commit 5d44ab9e204200a78ad55cdf185aa2bb109b5950 ]

On most devices using the btqcomsmd driver (e.g. the DragonBoard 410c and other devices based on the Qualcomm MSM8916/MSM8909/... SoCs) the Bluetooth firmware seems to become unresponsive for a while after setting the BD address. On recent kernel versions (at least 5.17+) this often causes timeouts for subsequent commands, e.g. the HCI reset sent by the Bluetooth core during initialization:

    Bluetooth: hci0: Opcode 0x c03 failed: -110

Unfortunately this behavior does not seem to be documented anywhere. Experimentation suggests that the minimum necessary delay to avoid the problem is ~150us. However, to be sure add a sleep for > 1ms in case it is a bit longer on other firmware versions.

Older kernel versions are likely also affected, although perhaps with slightly different errors or less probability. Side effects can easily hide the issue in most cases, e.g. unrelated incoming interrupts that cause the necessary delay.

Fixes 1511cc750c3d ("Bluetooth: Introduce Qualcomm WCNSS SMD based HCI driver")
---
 drivers/bluetooth/btqcomsmd.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/bluetooth/btqcomsmd.c +16 -1
index 2acb719e596f5..11c7e04bf3947 100644
@@ -122,6 +122,21 @@ static int btqcomsmd_setup(struct hci_dev *hdev)
 	return 0;
 }
 
+static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	int ret;
+
+	ret = qca_set_bdaddr_rome(hdev, bdaddr);
+	if (ret)
+		return ret;
+
+	/* The firmware stops responding for a while after setting the bdaddr,
+	 * causing timeouts for subsequent commands. Sleep a bit to avoid this.
+	 */
+	usleep_range(1000, 10000);
+	return 0;
+}
+
 static int btqcomsmd_probe(struct platform_device *pdev)
 {
 	struct btqcomsmd *btq;
@@ -162,7 +177,7 @@ static int btqcomsmd_probe(struct platform_device *pdev)
 	hdev->close = btqcomsmd_close;
 	hdev->send = btqcomsmd_send;
 	hdev->setup = btqcomsmd_setup;
-	hdev->set_bdaddr = qca_set_bdaddr_rome;
+	hdev->set_bdaddr = btqcomsmd_set_bdaddr;
 
 	ret = hci_register_dev(hdev);
 	if (ret < 0)
Signature · 1 line
2.39.2
author maintainer
#93 lore raw

PATCH 93/224 Bluetooth: L2CAP: Fix responding with wrong PDU type

In reply to Greg Kroah-Hartman

From: Luiz Augusto von Dentz <[email protected]>

[ Upstream commit 9aa9d9473f1550d1936c31259720b3f1f4690576 ]

L2CAP_ECRED_CONN_REQ shall be responded with L2CAP_ECRED_CONN_RSP not L2CAP_LE_CONN_RSP:

L2CAP LE EATT Server - Reject - run
Listening for connections
New client connection with handle 0x002a
Sending L2CAP Request from client
Client received response code 0x15
Unexpected L2CAP response code (expected 0x18)
L2CAP LE EATT Server - Reject - test failed

Quoted 1 line

ACL Data RX: Handle 42 flags 0x02 dlen 26

LE L2CAP: Enhanced Credit Connection Request (0x17) ident 1 len 18
PSM: 39 (0x0027)
MTU: 64
MPS: 64
Credits: 5
Source CID: 65
Source CID: 66
Source CID: 67
Source CID: 68
Source CID: 69
< ACL Data TX: Handle 42 flags 0x00 dlen 16

      LE L2CAP: LE Connection Response (0x15) ident 1 len 8
        invalid size
        00 00 00 00 00 00 06 00

L2CAP LE EATT Server - Reject - run
Listening for connections
New client connection with handle 0x002a
Sending L2CAP Request from client
Client received response code 0x18
L2CAP LE EATT Server - Reject - test passed

Fixes 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
---
 net/bluetooth/l2cap_core.c | 117 +++++++++++++++++++++++++------------
 1 file changed, 79 insertions(+), 38 deletions(-)
net/bluetooth/l2cap_core.c +79 -38
index da85768b04b76..b6f69d1feeeec 100644
@@ -708,6 +708,17 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 }
 EXPORT_SYMBOL_GPL(l2cap_chan_del);
 
+static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
+				 l2cap_chan_func_t func, void *data)
+{
+	struct l2cap_chan *chan, *l;
+
+	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+		if (chan->ident == id)
+			func(chan, data);
+	}
+}
+
 static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
 			      void *data)
 {
@@ -775,23 +786,9 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
 
 static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
 {
-	struct l2cap_conn *conn = chan->conn;
-	struct l2cap_ecred_conn_rsp rsp;
-	u16 result;
-
-	if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
-		result = L2CAP_CR_LE_AUTHORIZATION;
-	else
-		result = L2CAP_CR_LE_BAD_PSM;
-
 	l2cap_state_change(chan, BT_DISCONN);
 
-	memset(&rsp, 0, sizeof(rsp));
-
-	rsp.result  = cpu_to_le16(result);
-
-	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
-		       &rsp);
+	__l2cap_ecred_conn_rsp_defer(chan);
 }
 
 static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
@@ -846,7 +843,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 					break;
 				case L2CAP_MODE_EXT_FLOWCTL:
 					l2cap_chan_ecred_connect_reject(chan);
-					break;
+					return;
 				}
 			}
 		}
@@ -3938,43 +3935,86 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
 		       &rsp);
 }
 
-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
 {
+	int *result = data;
+
+	if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+		return;
+
+	switch (chan->state) {
+	case BT_CONNECT2:
+		/* If channel still pending accept add to result */
+		(*result)++;
+		return;
+	case BT_CONNECTED:
+		return;
+	default:
+		/* If not connected or pending accept it has been refused */
+		*result = -ECONNREFUSED;
+		return;
+	}
+}
+
+struct l2cap_ecred_rsp_data {
 	struct {
 		struct l2cap_ecred_conn_rsp rsp;
-		__le16 dcid[5];
+		__le16 scid[L2CAP_ECRED_MAX_CID];
 	} __packed pdu;
+	int count;
+};
+
+static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
+{
+	struct l2cap_ecred_rsp_data *rsp = data;
+
+	if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+		return;
+
+	/* Reset ident so only one response is sent */
+	chan->ident = 0;
+
+	/* Include all channels pending with the same ident */
+	if (!rsp->pdu.rsp.result)
+		rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
+	else
+		l2cap_chan_del(chan, ECONNRESET);
+}
+
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+{
 	struct l2cap_conn *conn = chan->conn;
-	u16 ident = chan->ident;
-	int i = 0;
+	struct l2cap_ecred_rsp_data data;
+	u16 id = chan->ident;
+	int result = 0;
 
-	if (!ident)
+	if (!id)
 		return;
 
-	BT_DBG("chan %p ident %d", chan, ident);
+	BT_DBG("chan %p id %d", chan, id);
 
-	pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
-	pdu.rsp.mps     = cpu_to_le16(chan->mps);
-	pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
-	pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
+	memset(&data, 0, sizeof(data));
 
-	mutex_lock(&conn->chan_lock);
+	data.pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
+	data.pdu.rsp.mps     = cpu_to_le16(chan->mps);
+	data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
+	data.pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
 
-	list_for_each_entry(chan, &conn->chan_l, list) {
-		if (chan->ident != ident)
-			continue;
+	/* Verify that all channels are ready */
+	__l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result);
 
-		/* Reset ident so only one response is sent */
-		chan->ident = 0;
+	if (result > 0)
+		return;
 
-		/* Include all channels pending with the same ident */
-		pdu.dcid[i++] = cpu_to_le16(chan->scid);
-	}
+	if (result < 0)
+		data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION);
 
-	mutex_unlock(&conn->chan_lock);
+	/* Build response */
+	__l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data);
 
-	l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP,
-			sizeof(pdu.rsp) + i * sizeof(__le16), &pdu);
+	l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP,
+		       sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)),
+		       &data.pdu);
 }
 
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
@@ -6078,6 +6118,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
 		__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
 
 		chan->ident = cmd->ident;
+		chan->mode = L2CAP_MODE_EXT_FLOWCTL;
 
 		if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
 			l2cap_state_change(chan, BT_CONNECT2);
Signature · 1 line
2.39.2
author maintainer
#94 lore raw

PATCH 94/224 Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work

In reply to Greg Kroah-Hartman

From: Zheng Wang <[email protected]>

[ Upstream commit 1e9ac114c4428fdb7ff4635b45d4f46017e8916f ]

In btsdio_probe, &data->work was bound with btsdio_work.In btsdio_send_frame, it was started by schedule_work.

If we call btsdio_remove with an unfinished job, there may be a race condition and cause UAF bug on hdev.

Fixes ddbaf13e3609 ("[Bluetooth] Add generic driver for Bluetooth SDIO devices")
---
 drivers/bluetooth/btsdio.c | 1 +
 1 file changed, 1 insertion(+)
drivers/bluetooth/btsdio.c +1 -0
index 795be33f2892d..02893600db390 100644
@@ -354,6 +354,7 @@ static void btsdio_remove(struct sdio_func *func)
 
 	BT_DBG("func %p", func);
 
+	cancel_work_sync(&data->work);
 	if (!data)
 		return;
 
Signature · 1 line
2.39.2
author maintainer
#95 lore raw

PATCH 95/224 Bluetooth: mgmt: Fix MGMT add advmon with RSSI command

In reply to Greg Kroah-Hartman

From: Howard Chung <[email protected]>

[ Upstream commit 1a0291f81529e8044fb29845a0196ba47af894ce ]

The MGMT command: MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI uses variable length argument. This causes host not able to register advmon with rssi.

This patch has been locally tested by adding monitor with rssi via btmgmt on a kernel 6.1 machine.

Fixes b338d91703fa ("Bluetooth: Implement support for Mesh")
---
 net/bluetooth/mgmt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/mgmt.c +2 -1
index 7576db8eb83e2..fc4ba0884da96 100644
@@ -9346,7 +9346,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ add_ext_adv_data,        MGMT_ADD_EXT_ADV_DATA_SIZE,
 						HCI_MGMT_VAR_LEN },
 	{ add_adv_patterns_monitor_rssi,
-				   MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE },
+				   MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE,
+						HCI_MGMT_VAR_LEN },
 	{ set_mesh,                MGMT_SET_MESH_RECEIVER_SIZE,
 						HCI_MGMT_VAR_LEN },
 	{ mesh_features,           MGMT_MESH_READ_FEATURES_SIZE },
Signature · 1 line
2.39.2
author maintainer
#96 lore raw

PATCH 96/224 Bluetooth: HCI: Fix global-out-of-bounds

In reply to Greg Kroah-Hartman

From: Sungwoo Kim <[email protected]>

[ Upstream commit bce56405201111807cc8e4f47c6de3e10b17c1ac ]

To loop a variable-length array, hci_init_stage_sync(stage) considers that stage[i] is valid as long as stage[i-1].func is valid. Thus, the last element of stage[].func should be intentionally invalid as hci_init0[], le_init2[], and others did.
However, amp_init1[] and amp_init2[] have no invalid element, letting hci_init_stage_sync() keep accessing amp_init1[] over its valid range. This patch fixes this by adding {} in the last of amp_init1[] and amp_init2[].

==================================================================

BUG: KASAN: global-out-of-bounds in hci_dev_open_sync (

/v6.2-bzimage/net/bluetooth/hci_sync.c:3154
/v6.2-bzimage/net/bluetooth/hci_sync.c:3343
/v6.2-bzimage/net/bluetooth/hci_sync.c:4418
/v6.2-bzimage/net/bluetooth/hci_sync.c:4609
/v6.2-bzimage/net/bluetooth/hci_sync.c:4689)

Read of size 8 at addr ffffffffaed1ab70 by task kworker/u5:0/1032
CPU: 0 PID: 1032 Comm: kworker/u5:0 Not tainted 6.2.0 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04
Workqueue: hci1 hci_power_on
Call Trace:
 <TASK>
dump_stack_lvl (/v6.2-bzimage/lib/dump_stack.c:107 (discriminator 1))
print_report (/v6.2-bzimage/mm/kasan/report.c:307
  /v6.2-bzimage/mm/kasan/report.c:417)
? hci_dev_open_sync (/v6.2-bzimage/net/bluetooth/hci_sync.c:3154
  /v6.2-bzimage/net/bluetooth/hci_sync.c:3343
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4418
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4609
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4689)
kasan_report (/v6.2-bzimage/mm/kasan/report.c:184
  /v6.2-bzimage/mm/kasan/report.c:519)
? hci_dev_open_sync (/v6.2-bzimage/net/bluetooth/hci_sync.c:3154
  /v6.2-bzimage/net/bluetooth/hci_sync.c:3343
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4418
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4609
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4689)
hci_dev_open_sync (/v6.2-bzimage/net/bluetooth/hci_sync.c:3154
  /v6.2-bzimage/net/bluetooth/hci_sync.c:3343
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4418
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4609
  /v6.2-bzimage/net/bluetooth/hci_sync.c:4689)
? __pfx_hci_dev_open_sync (/v6.2-bzimage/net/bluetooth/hci_sync.c:4635)
? mutex_lock (/v6.2-bzimage/./arch/x86/include/asm/atomic64_64.h:190
  /v6.2-bzimage/./include/linux/atomic/atomic-long.h:443
  /v6.2-bzimage/./include/linux/atomic/atomic-instrumented.h:1781
  /v6.2-bzimage/kernel/locking/mutex.c:171
  /v6.2-bzimage/kernel/locking/mutex.c:285)
? __pfx_mutex_lock (/v6.2-bzimage/kernel/locking/mutex.c:282)
hci_power_on (/v6.2-bzimage/net/bluetooth/hci_core.c:485
  /v6.2-bzimage/net/bluetooth/hci_core.c:984)
? __pfx_hci_power_on (/v6.2-bzimage/net/bluetooth/hci_core.c:969)
? read_word_at_a_time (/v6.2-bzimage/./include/asm-generic/rwonce.h:85)
? strscpy (/v6.2-bzimage/./arch/x86/include/asm/word-at-a-time.h:62
  /v6.2-bzimage/lib/string.c:161)
process_one_work (/v6.2-bzimage/kernel/workqueue.c:2294)
worker_thread (/v6.2-bzimage/./include/linux/list.h:292
  /v6.2-bzimage/kernel/workqueue.c:2437)

? __pfx_worker_thread (/v6.2-bzimage/kernel/workqueue.c:2379) kthread (/v6.2-bzimage/kernel/kthread.c:376)
? __pfx_kthread (/v6.2-bzimage/kernel/kthread.c:331) ret_from_fork (/v6.2-bzimage/arch/x86/entry/entry_64.S:314)

 </TASK>
The buggy address belongs to the variable:
amp_init1+0x30/0x60
The buggy address belongs to the physical page:
page:000000003a157ec6 refcount:1 mapcount:0 mapping:0000000000000000 ia
flags: 0x200000000001000(reserved|node=0|zone=2)
raw: 0200000000001000 ffffea0005054688 ffffea0005054688 000000000000000
raw: 0000000000000000 0000000000000000 00000001ffffffff 000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
 ffffffffaed1aa00: f9 f9 f9 f9 00 00 00 00 f9 f9 f9 f9 00 00 00 00
 ffffffffaed1aa80: 00 00 00 00 f9 f9 f9 f9 00 00 00 00 00 00 00 00
>ffffffffaed1ab00: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 f9 f9
                                                             ^
 ffffffffaed1ab80: f9 f9 f9 f9 00 00 00 00 f9 f9 f9 f9 00 00 00 f9
 ffffffffaed1ac00: f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9 00 00 02 f9

This bug is found by FuzzBT, a modified version of Syzkaller. Other contributors for this bug are Ruoyu Wu and Peng Hui.

Fixes d0b137062b2d ("Bluetooth: hci_sync: Rework init stages")
---
 net/bluetooth/hci_sync.c | 2 ++
 1 file changed, 2 insertions(+)
net/bluetooth/hci_sync.c +2 -0
index 13ec3c86a0dcf..f886c1d05c882 100644
@@ -3340,6 +3340,7 @@ static const struct hci_init_stage amp_init1[] = {
 	HCI_INIT(hci_read_flow_control_mode_sync),
 	/* HCI_OP_READ_LOCATION_DATA */
 	HCI_INIT(hci_read_location_data_sync),
+	{}
 };
 
 static int hci_init1_sync(struct hci_dev *hdev)
@@ -3374,6 +3375,7 @@ static int hci_init1_sync(struct hci_dev *hdev)
 static const struct hci_init_stage amp_init2[] = {
 	/* HCI_OP_READ_LOCAL_FEATURES */
 	HCI_INIT(hci_read_local_features_sync),
+	{}
 };
 
 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
Signature · 1 line
2.39.2
author maintainer
#97 lore raw

PATCH 97/224 platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl

In reply to Greg Kroah-Hartman

From: Tzung-Bi Shih <[email protected]>

[ Upstream commit b20cf3f89c56b5f6a38b7f76a8128bf9f291bbd3 ]

It is possible to peep kernel page's data by providing larger insize in struct cros_ec_command[1] when invoking EC host commands.

Fix it by using zeroed memory.

[1]: https://elixir.bootlin.com/linux/v6.2/source/include/linux/platform_data/cros_ec_proto.h#L74

Fixes eda2e30c6684 ("mfd / platform: cros_ec: Miscellaneous character device to talk with the EC")
---
 drivers/platform/chrome/cros_ec_chardev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/chrome/cros_ec_chardev.c +1 -1
index 0de7c255254e0..d6de5a2941282 100644
@@ -284,7 +284,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
 	    u_cmd.insize > EC_MAX_MSG_BYTES)
 		return -EINVAL;
 
-	s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
+	s_cmd = kzalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
 			GFP_KERNEL);
 	if (!s_cmd)
 		return -ENOMEM;
Signature · 1 line
2.39.2
author maintainer
#98 lore raw

PATCH 98/224 entry: Fix noinstr warning in __enter_from_user_mode()

In reply to Greg Kroah-Hartman

From: Josh Poimboeuf <[email protected]>

[ Upstream commit f87d28673b71b35b248231a2086f9404afbb7f28 ]

__enter_from_user_mode() is triggering noinstr warnings with CONFIG_DEBUG_PREEMPT due to its call of preempt_count_add() via ct_state().

The preemption disable isn't needed as interrupts are already disabled. And the context_tracking_enabled() check in ct_state() also isn't needed as that's already being done by the CT_WARN_ON().

Just use __ct_state() instead.

Fixes the following warnings:

vmlinux.o: warning: objtool: enter_from_user_mode+0xba: call to preempt_count_add() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0xf9: call to preempt_count_add() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0xc7: call to preempt_count_add() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0xba: call to preempt_count_add() leaves .noinstr.text section

---
 include/linux/context_tracking.h       | 1 +
 include/linux/context_tracking_state.h | 2 ++
 kernel/entry/common.c                  | 2 +-
 3 files changed, 4 insertions(+), 1 deletion(-)
include/linux/context_tracking.h +1 -0
index d4afa8508a806..3a7909ed54980 100644
@@ -96,6 +96,7 @@ static inline void user_exit_irqoff(void) { }
 static inline int exception_enter(void) { return 0; }
 static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline int ct_state(void) { return -1; }
+static inline int __ct_state(void) { return -1; }
 static __always_inline bool context_tracking_guest_enter(void) { return false; }
 static inline void context_tracking_guest_exit(void) { }
 #define CT_WARN_ON(cond) do { } while (0)
include/linux/context_tracking_state.h +2 -0
index 4a4d56f771802..fdd537ea513ff 100644
@@ -46,7 +46,9 @@ struct context_tracking {
 
 #ifdef CONFIG_CONTEXT_TRACKING
 DECLARE_PER_CPU(struct context_tracking, context_tracking);
+#endif
 
+#ifdef CONFIG_CONTEXT_TRACKING_USER
 static __always_inline int __ct_state(void)
 {
 	return arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK;
kernel/entry/common.c +1 -1
index 846add8394c41..1314894d2efad 100644
@@ -21,7 +21,7 @@ static __always_inline void __enter_from_user_mode(struct pt_regs *regs)
 	arch_enter_from_user_mode(regs);
 	lockdep_hardirqs_off(CALLER_ADDR0);
 
-	CT_WARN_ON(ct_state() != CONTEXT_USER);
+	CT_WARN_ON(__ct_state() != CONTEXT_USER);
 	user_exit_irqoff();
 
 	instrumentation_begin();
Signature · 1 line
2.39.2
author maintainer
#99 lore raw

PATCH 99/224 perf/x86/amd/core: Always clear status for idx

In reply to Greg Kroah-Hartman

From: Breno Leitao <[email protected]>

[ Upstream commit 263f5ecaf7080513efc248ec739b6d9e00f4129f ]

The variable 'status' (which contains the unhandled overflow bits) is not being properly masked in some cases, displaying the following warning:

  WARNING: CPU: 156 PID: 475601 at arch/x86/events/amd/core.c:972 amd_pmu_v2_handle_irq+0x216/0x270

This seems to be happening because the loop is being continued before the status bit being unset, in case x86_perf_event_set_period() returns 0. This is also causing an inconsistency because the "handled" counter is incremented, but the status bit is not cleaned.

Move the bit cleaning together above, together when the "handled" counter is incremented.

Fixes 7685665c390d ("perf/x86/amd/core: Add PerfMonV2 overflow handling")
---
 arch/x86/events/amd/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/events/amd/core.c +1 -2
index 4386b10682ce4..8ca5e827f30b2 100644
@@ -923,6 +923,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
 
 		/* Event overflow */
 		handled++;
+		status &= ~mask;
 		perf_sample_data_init(&data, 0, hwc->last_period);
 
 		if (!x86_perf_event_set_period(event))
@@ -935,8 +936,6 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
 
 		if (perf_event_overflow(event, &data, regs))
 			x86_pmu_stop(event, 0);
-
-		status &= ~mask;
 	}
 
 	/*
Signature · 1 line
2.39.2
author maintainer
#100 lore raw

PATCH 100/224 entry/rcu: Check TIF_RESCHED _after_ delayed RCU wake-up

In reply to Greg Kroah-Hartman

From: Frederic Weisbecker <[email protected]>

[ Upstream commit b416514054810cf2d2cc348ae477cea619b64da7 ]

RCU sometimes needs to perform a delayed wake up for specific kthreads handling offloaded callbacks (RCU_NOCB). These wakeups are performed by timers and upon entry to idle (also to guest and to user on nohz_full).

However the delayed wake-up on kernel exit is actually performed after the thread flags are fetched towards the fast path check for work to do on exit to user. As a result, and if there is no other pending work to do upon that kernel exit, the current task will resume to userspace with TIF_RESCHED set and the pending wake up ignored.

Fix this with fetching the thread flags _after_ the delayed RCU-nocb kthread wake-up.

Fixes 47b8ff194c1f ("entry: Explicitly flush pending rcuog wakeup before last rescheduling point")
---
 kernel/entry/common.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/entry/common.c +2 -1
index 1314894d2efad..be61332c66b54 100644
@@ -192,13 +192,14 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 
 static void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
-	unsigned long ti_work = read_thread_flags();
+	unsigned long ti_work;
 
 	lockdep_assert_irqs_disabled();
 
 	/* Flush pending rcuog wakeup before the last need_resched() check */
 	tick_nohz_user_enter_prepare();
 
+	ti_work = read_thread_flags();
 	if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK))
 		ti_work = exit_to_user_mode_loop(regs, ti_work);
 
Signature · 1 line
2.39.2
author maintainer
#101 lore raw

PATCH 101/224 hwmon: fix potential sensor registration fail if of_node is missing

In reply to Greg Kroah-Hartman

From: Phinex Hung <[email protected]>

[ Upstream commit 2315332efcbe7124252f080e03b57d3d2f1f4771 ]

It is not sufficient to check of_node in current device. In some cases, this would cause the sensor registration to fail.

This patch looks for device's ancestors to find a valid of_node if any.

Fixes d560168b5d0f ("hwmon: (core) New hwmon registration API")
---
 drivers/hwmon/hwmon.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/hwmon/hwmon.c +5 -2
index 4218750d5a66b..9ed34b2e1f499 100644
@@ -756,6 +756,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 	struct hwmon_device *hwdev;
 	const char *label;
 	struct device *hdev;
+	struct device *tdev = dev;
 	int i, err, id;
 
 	/* Complain about invalid characters in hwmon name attribute */
@@ -825,7 +826,9 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 	hwdev->name = name;
 	hdev->class = &hwmon_class;
 	hdev->parent = dev;
-	hdev->of_node = dev ? dev->of_node : NULL;
+	while (tdev && !tdev->of_node)
+		tdev = tdev->parent;
+	hdev->of_node = tdev ? tdev->of_node : NULL;
 	hwdev->chip = chip;
 	dev_set_drvdata(hdev, drvdata);
 	dev_set_name(hdev, HWMON_ID_FORMAT, id);
@@ -837,7 +840,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 
 	INIT_LIST_HEAD(&hwdev->tzdata);
 
-	if (dev && dev->of_node && chip && chip->ops->read &&
+	if (hdev->of_node && chip && chip->ops->read &&
 	    chip->info[0]->type == hwmon_chip &&
 	    (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) {
 		err = hwmon_thermal_register_sensors(hdev);
Signature · 1 line
2.39.2
author maintainer
#102 lore raw

PATCH 102/224 hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs

In reply to Greg Kroah-Hartman

From: Frank Crawford <[email protected]>

[ Upstream commit 968b66ffeb7956acc72836a7797aeb7b2444ec51 ]

Fix voltage scaling for chips that have 10.9mV ADCs, where scaling was not performed.

Fixes ead8080351c9 ("hwmon: (it87) Add support for IT8732F")
[groeck: Update subject and description to focus on bug fix]
---
 drivers/hwmon/it87.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hwmon/it87.c +3 -1
index 7bd154ba351b9..b45bd3aa5a653 100644
@@ -486,6 +486,8 @@ static const struct it87_devices it87_devices[] = {
 #define has_pwm_freq2(data)	((data)->features & FEAT_PWM_FREQ2)
 #define has_six_temp(data)	((data)->features & FEAT_SIX_TEMP)
 #define has_vin3_5v(data)	((data)->features & FEAT_VIN3_5V)
+#define has_scaling(data)	((data)->features & (FEAT_12MV_ADC | \
+						     FEAT_10_9MV_ADC))
 
 struct it87_sio_data {
 	int sioaddr;
@@ -3098,7 +3100,7 @@ static int it87_probe(struct platform_device *pdev)
 			 "Detected broken BIOS defaults, disabling PWM interface\n");
 
 	/* Starting with IT8721F, we handle scaling of internal voltages */
-	if (has_12mv_adc(data)) {
+	if (has_scaling(data)) {
 		if (sio_data->internal & BIT(0))
 			data->in_scaled |= BIT(3);	/* in3 is AVCC */
 		if (sio_data->internal & BIT(1))
Signature · 1 line
2.39.2
author maintainer
#103 lore raw

PATCH 103/224 scsi: qla2xxx: Synchronize the IOCB count to be in order

In reply to Greg Kroah-Hartman

From: Quinn Tran <[email protected]>

commit d3affdeb400f3adc925bd996f3839481f5291839 upstream.

A system hang was observed with the following call trace:

BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
CPU: 15 PID: 86747 Comm: nvme Kdump: loaded Not tainted 6.2.0+ #1
Hardware name: Dell Inc. PowerEdge R6515/04F3CJ, BIOS 2.7.3 03/31/2022
RIP: 0010:__wake_up_common+0x55/0x190
Code: 41 f6 01 04 0f 85 b2 00 00 00 48 8b 43 08 4c 8d
      40 e8 48 8d 43 08 48 89 04 24 48 89 c6\
      49 8d 40 18 48 39 c6 0f 84 e9 00 00 00 <49> 8b 40 18 89 6c 24 14 31
      ed 4c 8d 60 e8 41 8b 18 f6 c3 04 75 5d
RSP: 0018:ffffb05a82afbba0 EFLAGS: 00010082
RAX: 0000000000000000 RBX: ffff8f9b83a00018 RCX: 0000000000000000
RDX: 0000000000000001 RSI: ffff8f9b83a00020 RDI: ffff8f9b83a00018
RBP: 0000000000000001 R08: ffffffffffffffe8 R09: ffffb05a82afbbf8
R10: 70735f7472617473 R11: 5f30307832616c71 R12: 0000000000000001
R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000
FS:  00007f815cf4c740(0000) GS:ffff8f9eeed80000(0000)
	knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000010633a000 CR4: 0000000000350ee0
Call Trace:
    <TASK>
    __wake_up_common_lock+0x83/0xd0
    qla_nvme_ls_req+0x21b/0x2b0 [qla2xxx]
    __nvme_fc_send_ls_req+0x1b5/0x350 [nvme_fc]
    nvme_fc_xmt_disconnect_assoc+0xca/0x110 [nvme_fc]
    nvme_fc_delete_association+0x1bf/0x220 [nvme_fc]
    ? nvme_remove_namespaces+0x9f/0x140 [nvme_core]
    nvme_do_delete_ctrl+0x5b/0xa0 [nvme_core]
    nvme_sysfs_delete+0x5f/0x70 [nvme_core]
    kernfs_fop_write_iter+0x12b/0x1c0
    vfs_write+0x2a3/0x3b0
    ksys_write+0x5f/0xe0
    do_syscall_64+0x5c/0x90
    ? syscall_exit_work+0x103/0x130
    ? syscall_exit_to_user_mode+0x12/0x30
    ? do_syscall_64+0x69/0x90
    ? exit_to_user_mode_loop+0xd0/0x130
    ? exit_to_user_mode_prepare+0xec/0x100
    ? syscall_exit_to_user_mode+0x12/0x30
    ? do_syscall_64+0x69/0x90
    ? syscall_exit_to_user_mode+0x12/0x30
    ? do_syscall_64+0x69/0x90
    entry_SYSCALL_64_after_hwframe+0x72/0xdc
    RIP: 0033:0x7f815cd3eb97

The IOCB counts are out of order and that would block any commands from going out and subsequently hang the system. Synchronize the IOCB count to be in correct order.

---
 drivers/scsi/qla2xxx/qla_isr.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_isr.c +2 -1
@@ -1900,6 +1900,8 @@ qla2x00_get_sp_from_handle(scsi_qla_host
 	}
 
 	req->outstanding_cmds[index] = NULL;
+
+	qla_put_fw_resources(sp->qpair, &sp->iores);
 	return sp;
 }
 
@@ -3112,7 +3114,6 @@ qla25xx_process_bidir_status_iocb(scsi_q
 	}
 	bsg_reply->reply_payload_rcv_len = 0;
 
-	qla_put_fw_resources(sp->qpair, &sp->iores);
 done:
 	/* Return the vendor specific reply to API */
 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
author maintainer
#104 lore raw

PATCH 104/224 scsi: qla2xxx: Perform lockless command completion in abort path

In reply to Greg Kroah-Hartman

From: Nilesh Javali <[email protected]>

commit 0367076b0817d5c75dfb83001ce7ce5c64d803a9 upstream.

While adding and removing the controller, the following call trace was observed:

WARNING: CPU: 3 PID: 623596 at kernel/dma/mapping.c:532 dma_free_attrs+0x33/0x50
CPU: 3 PID: 623596 Comm: sh Kdump: loaded Not tainted 5.14.0-96.el9.x86_64 #1
RIP: 0010:dma_free_attrs+0x33/0x50

Call Trace:
   qla2x00_async_sns_sp_done+0x107/0x1b0 [qla2xxx]
   qla2x00_abort_srb+0x8e/0x250 [qla2xxx]
   ? ql_dbg+0x70/0x100 [qla2xxx]
   __qla2x00_abort_all_cmds+0x108/0x190 [qla2xxx]
   qla2x00_abort_all_cmds+0x24/0x70 [qla2xxx]
   qla2x00_abort_isp_cleanup+0x305/0x3e0 [qla2xxx]
   qla2x00_remove_one+0x364/0x400 [qla2xxx]
   pci_device_remove+0x36/0xa0
   __device_release_driver+0x17a/0x230
   device_release_driver+0x24/0x30
   pci_stop_bus_device+0x68/0x90
   pci_stop_and_remove_bus_device_locked+0x16/0x30
   remove_store+0x75/0x90
   kernfs_fop_write_iter+0x11c/0x1b0
   new_sync_write+0x11f/0x1b0
   vfs_write+0x1eb/0x280
   ksys_write+0x5f/0xe0
   do_syscall_64+0x5c/0x80
   ? do_user_addr_fault+0x1d8/0x680
   ? do_syscall_64+0x69/0x80
   ? exc_page_fault+0x62/0x140
   ? asm_exc_page_fault+0x8/0x30
   entry_SYSCALL_64_after_hwframe+0x44/0xae

The command was completed in the abort path during driver unload with a lock held, causing the warning in abort path. Hence complete the command without any lock held.

---
 drivers/scsi/qla2xxx/qla_os.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/scsi/qla2xxx/qla_os.c +11 -0
@@ -1848,6 +1848,17 @@ __qla2x00_abort_all_cmds(struct qla_qpai
 	for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
 		sp = req->outstanding_cmds[cnt];
 		if (sp) {
+			/*
+			 * perform lockless completion during driver unload
+			 */
+			if (qla2x00_chip_is_down(vha)) {
+				req->outstanding_cmds[cnt] = NULL;
+				spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
+				sp->done(sp, res);
+				spin_lock_irqsave(qp->qp_lock_ptr, flags);
+				continue;
+			}
+
 			switch (sp->cmd_type) {
 			case TYPE_SRB:
 				qla2x00_abort_srb(qp, sp, res, &flags);
author maintainer
#105 lore raw

PATCH 105/224 smb3: lower default deferred close timeout to address perf regression

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

commit 7e0e76d99079be13c9961dde7c93b2d1ee665af4 upstream.

Performance tests with large number of threads noted that the change of the default closetimeo (deferred close timeout between when close is done by application and when client has to send the close to the server), to 5 seconds from 1 second, significantly degraded perf in some cases like this (in the filebench example reported, the stats show close requests on the wire taking twice as long, and 50% regression in filebench perf). This is stil configurable via mount parm closetimeo, but to be safe, decrease default back to its previous value of 1 second.

---
 fs/cifs/fs_context.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/fs_context.h +1 -1
index 1b8d4e27f831..3de00e7127ec 100644
@@ -286,5 +286,5 @@ extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
  * max deferred close timeout (jiffies) - 2^30
  */
 #define SMB3_MAX_DCLOSETIMEO (1 << 30)
-#define SMB3_DEF_DCLOSETIMEO (5 * HZ) /* Can increase later, other clients use larger */
+#define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
 #endif
Signature · 1 line
2.40.0
author maintainer
#106 lore raw

PATCH 106/224 smb3: fix unusable share after force unmount failure

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

commit 491eafce1a51c457701351a4bf40733799745314 upstream.

If user does forced unmount ("umount -f") while files are still open on the share (as was seen in a Kubernetes example running on SMB3.1.1 mount) then we were marking the share as "TID_EXITING" in umount_begin() which caused all subsequent operations (except write) to fail ... but unfortunately when umount_begin() is called we do not know yet that there are open files or active references on the share that would prevent unmount from succeeding. Kubernetes had example when they were doing umount -f when files were open which caused the share to become unusable until the files were closed (and the umount retried).

Fix this so that TID_EXITING is not set until we are about to send the tree disconnect (not at the beginning of forced umounts in umount_begin) so that if "umount -f" fails (due to open files or references) the mount is still usable.

---
 fs/cifs/cifsfs.c  |    9 ++++++---
 fs/cifs/cifssmb.c |    6 ++----
 fs/cifs/connect.c |    1 +
 fs/cifs/smb2pdu.c |    8 ++------
 4 files changed, 11 insertions(+), 13 deletions(-)
fs/cifs/cifsfs.c +6 -3
@@ -730,13 +730,16 @@ static void cifs_umount_begin(struct sup
 	spin_lock(&tcon->tc_lock);
 	if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
 		/* we have other mounts to same share or we have
-		   already tried to force umount this and woken up
+		   already tried to umount this and woken up
 		   all waiting network requests, nothing to do */
 		spin_unlock(&tcon->tc_lock);
 		spin_unlock(&cifs_tcp_ses_lock);
 		return;
-	} else if (tcon->tc_count == 1)
-		tcon->status = TID_EXITING;
+	}
+	/*
+	 * can not set tcon->status to TID_EXITING yet since we don't know if umount -f will
+	 * fail later (e.g. due to open files).  TID_EXITING will be set just before tdis req sent
+	 */
 	spin_unlock(&tcon->tc_lock);
 	spin_unlock(&cifs_tcp_ses_lock);
 
fs/cifs/cifssmb.c +2 -4
@@ -85,13 +85,11 @@ cifs_reconnect_tcon(struct cifs_tcon *tc
 
 	/*
 	 * only tree disconnect, open, and write, (and ulogoff which does not
-	 * have tcon) are allowed as we start force umount
+	 * have tcon) are allowed as we start umount
 	 */
 	spin_lock(&tcon->tc_lock);
 	if (tcon->status == TID_EXITING) {
-		if (smb_command != SMB_COM_WRITE_ANDX &&
-		    smb_command != SMB_COM_OPEN_ANDX &&
-		    smb_command != SMB_COM_TREE_DISCONNECT) {
+		if (smb_command != SMB_COM_TREE_DISCONNECT) {
 			spin_unlock(&tcon->tc_lock);
 			cifs_dbg(FYI, "can not send cmd %d while umounting\n",
 				 smb_command);
fs/cifs/connect.c +1 -0
@@ -2365,6 +2365,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
 	WARN_ON(tcon->tc_count < 0);
 
 	list_del_init(&tcon->tcon_list);
+	tcon->status = TID_EXITING;
 	spin_unlock(&tcon->tc_lock);
 	spin_unlock(&cifs_tcp_ses_lock);
 
fs/cifs/smb2pdu.c +2 -6
@@ -225,13 +225,9 @@ smb2_reconnect(__le16 smb2_command, stru
 	spin_lock(&tcon->tc_lock);
 	if (tcon->status == TID_EXITING) {
 		/*
-		 * only tree disconnect, open, and write,
-		 * (and ulogoff which does not have tcon)
-		 * are allowed as we start force umount.
+		 * only tree disconnect allowed when disconnecting ...
 		 */
-		if ((smb2_command != SMB2_WRITE) &&
-		   (smb2_command != SMB2_CREATE) &&
-		   (smb2_command != SMB2_TREE_DISCONNECT)) {
+		if (smb2_command != SMB2_TREE_DISCONNECT) {
 			spin_unlock(&tcon->tc_lock);
 			cifs_dbg(FYI, "can not send cmd %d while umounting\n",
 				 smb2_command);
author maintainer
#107 lore raw

PATCH 107/224 uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2

In reply to Greg Kroah-Hartman

From: Yaroslav Furman <[email protected]>

commit a37eb61b6ec064ac794b8a1e89fd33eb582fe51d upstream.

Just like other JMicron JMS5xx enclosures, it chokes on report-opcodes, let's avoid them.

---
 drivers/usb/storage/unusual_uas.h |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_uas.h +7 -0
@@ -111,6 +111,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x99
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BROKEN_FUA),
 
+/* Reported by: Yaroslav Furman <[email protected]> */
+UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999,
+		"JMicron",
+		"JMS583Gen 2",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_NO_REPORT_OPCODES),
+
 /* Reported-by: Thinh Nguyen <[email protected]> */
 UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
 		"PNY",
author maintainer
#108 lore raw

PATCH 108/224 thunderbolt: Use scale field when allocating USB3 bandwidth

In reply to Greg Kroah-Hartman

From: Mika Westerberg <[email protected]>

commit c82510b1d87bdebfe916048857d2ef46f1778aa5 upstream.

When tunneling aggregated USB3 (20 Gb/s) the bandwidth values that are programmed to the ADP_USB3_CS_2 go higher than 4096 and that does not fit anymore to the 12-bit field. Fix this by scaling the value using the scale field accordingly.

Fixes 3b1d8d577ca8 ("thunderbolt: Implement USB3 bandwidth negotiation routines")
---
 drivers/thunderbolt/usb4.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)
drivers/thunderbolt/usb4.c +17 -5
@@ -2050,18 +2050,30 @@ static int usb4_usb3_port_write_allocate
 						    int downstream_bw)
 {
 	u32 val, ubw, dbw, scale;
-	int ret;
+	int ret, max_bw;
 
-	/* Read the used scale, hardware default is 0 */
-	ret = tb_port_read(port, &scale, TB_CFG_PORT,
-			   port->cap_adap + ADP_USB3_CS_3, 1);
+	/* Figure out suitable scale */
+	scale = 0;
+	max_bw = max(upstream_bw, downstream_bw);
+	while (scale < 64) {
+		if (mbps_to_usb3_bw(max_bw, scale) < 4096)
+			break;
+		scale++;
+	}
+
+	if (WARN_ON(scale >= 64))
+		return -EINVAL;
+
+	ret = tb_port_write(port, &scale, TB_CFG_PORT,
+			    port->cap_adap + ADP_USB3_CS_3, 1);
 	if (ret)
 		return ret;
 
-	scale &= ADP_USB3_CS_3_SCALE_MASK;
 	ubw = mbps_to_usb3_bw(upstream_bw, scale);
 	dbw = mbps_to_usb3_bw(downstream_bw, scale);
 
+	tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);
+
 	ret = tb_port_read(port, &val, TB_CFG_PORT,
 			   port->cap_adap + ADP_USB3_CS_2, 1);
 	if (ret)
author maintainer
#109 lore raw

PATCH 109/224 thunderbolt: Call tb_check_quirks() after initializing adapters

In reply to Greg Kroah-Hartman

From: Mika Westerberg <[email protected]>

commit d2d6ddf188f609861489d5d188d545856a3ed399 upstream.

In order to apply quirks based on certain adapter types move call to tb_check_quirks() happen after the adapters are initialized. This should not affect the existing quirks.

---
 drivers/thunderbolt/switch.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/thunderbolt/switch.c +2 -2
@@ -2959,8 +2959,6 @@ int tb_switch_add(struct tb_switch *sw)
 			dev_warn(&sw->dev, "reading DROM failed: %d\n", ret);
 		tb_sw_dbg(sw, "uid: %#llx\n", sw->uid);
 
-		tb_check_quirks(sw);
-
 		ret = tb_switch_set_uuid(sw);
 		if (ret) {
 			dev_err(&sw->dev, "failed to set UUID\n");
@@ -2979,6 +2977,8 @@ int tb_switch_add(struct tb_switch *sw)
 			}
 		}
 
+		tb_check_quirks(sw);
+
 		tb_switch_default_link_ports(sw);
 
 		ret = tb_switch_update_link_attributes(sw);
author maintainer
#110 lore raw

PATCH 110/224 thunderbolt: Add quirk to disable CLx

In reply to Greg Kroah-Hartman

From: Sanjay R Mehta <[email protected]>

commit 7af9da8ce8f9a16221ecd8ba4280582f5bd452fc upstream.

Add QUIRK_NO_CLX to disable the CLx state for hardware which doesn't supports it.

AMD Yellow Carp and Pink Sardine don't support CLx state, hence disabling it using QUIRK_NO_CLX.

---
 drivers/thunderbolt/quirks.c |   13 +++++++++++++
 drivers/thunderbolt/tb.h     |   11 ++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
drivers/thunderbolt/quirks.c +13 -0
@@ -20,6 +20,12 @@ static void quirk_dp_credit_allocation(s
 	}
 }
 
+static void quirk_clx_disable(struct tb_switch *sw)
+{
+	sw->quirks |= QUIRK_NO_CLX;
+	tb_sw_dbg(sw, "disabling CL states\n");
+}
+
 struct tb_quirk {
 	u16 hw_vendor_id;
 	u16 hw_device_id;
@@ -37,6 +43,13 @@ static const struct tb_quirk tb_quirks[]
 	 * DP buffers.
 	 */
 	{ 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
+	/*
+	 * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
+	 */
+	{ 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable },
+	{ 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable },
+	{ 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable },
+	{ 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable },
 };
 
 /**
drivers/thunderbolt/tb.h +8 -3
@@ -23,6 +23,11 @@
 #define NVM_MAX_SIZE		SZ_512K
 #define NVM_DATA_DWORDS		16
 
+/* Keep link controller awake during update */
+#define QUIRK_FORCE_POWER_LINK_CONTROLLER		BIT(0)
+/* Disable CLx if not supported */
+#define QUIRK_NO_CLX					BIT(1)
+
 /**
  * struct tb_nvm - Structure holding NVM information
  * @dev: Owner of the NVM
@@ -997,6 +1002,9 @@ static inline bool tb_switch_is_clx_enab
  */
 static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw)
 {
+	if (sw->quirks & QUIRK_NO_CLX)
+		return false;
+
 	return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
 }
 
@@ -1254,9 +1262,6 @@ struct usb4_port *usb4_port_device_add(s
 void usb4_port_device_remove(struct usb4_port *usb4);
 int usb4_port_device_resume(struct usb4_port *usb4);
 
-/* Keep link controller awake during update */
-#define QUIRK_FORCE_POWER_LINK_CONTROLLER		BIT(0)
-
 void tb_check_quirks(struct tb_switch *sw);
 
 #ifdef CONFIG_ACPI
author maintainer
#111 lore raw

PATCH 111/224 thunderbolt: Fix memory leak in margining

In reply to Greg Kroah-Hartman

From: Mika Westerberg <[email protected]>

commit acec726473822bc6b585961f4ca2a11fa7f28341 upstream.

Memory for the usb4->margining needs to be relased for the upstream port of the router as well, even though the debugfs directory gets released with the router device removal. Fix this.

Fixes d0f1e0c2a699 ("thunderbolt: Add support for receiver lane margining")
---
 drivers/thunderbolt/debugfs.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/thunderbolt/debugfs.c +6 -6
index 4339e706cc3a..f92ad71ef983 100644
@@ -942,7 +942,8 @@ static void margining_port_remove(struct tb_port *port)
 
 	snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
 	parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
-	debugfs_remove_recursive(debugfs_lookup("margining", parent));
+	if (parent)
+		debugfs_remove_recursive(debugfs_lookup("margining", parent));
 
 	kfree(port->usb4->margining);
 	port->usb4->margining = NULL;
@@ -967,19 +968,18 @@ static void margining_switch_init(struct tb_switch *sw)
 
 static void margining_switch_remove(struct tb_switch *sw)
 {
+	struct tb_port *upstream, *downstream;
 	struct tb_switch *parent_sw;
-	struct tb_port *downstream;
 	u64 route = tb_route(sw);
 
 	if (!route)
 		return;
 
-	/*
-	 * Upstream is removed with the router itself but we need to
-	 * remove the downstream port margining directory.
-	 */
+	upstream = tb_upstream_port(sw);
 	parent_sw = tb_switch_parent(sw);
 	downstream = tb_port_at(route, parent_sw);
+
+	margining_port_remove(upstream);
 	margining_port_remove(downstream);
 }
 
Signature · 1 line
2.40.0
author maintainer
#112 lore raw

PATCH 112/224 thunderbolt: Disable interrupt auto clear for rings

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

commit 468c49f44759720a312e52d44a71c3949ed63d7c upstream.

When interrupt auto clear is programmed, any read to the interrupt status register will clear all interrupts. If two interrupts have come in before one can be serviced then this will cause lost interrupts.

On AMD USB4 routers this has manifested in odd problems particularly with long strings of control tranfers such as reading the DROM via bit banging.

Instead of clearing interrupts automatically, clear the bit corresponding to the given ring's interrupt in the ISR.

Fixes 7a1808f82a37 ("thunderbolt: Handle ring interrupt by reading interrupt status register")
Cc Sanju Mehta <[email protected]>
---
 drivers/thunderbolt/nhi.c      |   40 +++++++++++++++++++++++++---------------
 drivers/thunderbolt/nhi_regs.h |    6 ++++--
 2 files changed, 29 insertions(+), 17 deletions(-)
drivers/thunderbolt/nhi.c +25 -15
@@ -71,24 +71,31 @@ static void ring_interrupt_active(struct
 		u32 step, shift, ivr, misc;
 		void __iomem *ivr_base;
 		int index;
+		int bit;
 
 		if (ring->is_tx)
 			index = ring->hop;
 		else
 			index = ring->hop + ring->nhi->hop_count;
 
-		if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) {
-			/*
-			 * Ask the hardware to clear interrupt status
-			 * bits automatically since we already know
-			 * which interrupt was triggered.
-			 */
-			misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
-			if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) {
-				misc |= REG_DMA_MISC_INT_AUTO_CLEAR;
-				iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC);
-			}
-		}
+		/*
+		 * Intel routers support a bit that isn't part of
+		 * the USB4 spec to ask the hardware to clear
+		 * interrupt status bits automatically since
+		 * we already know which interrupt was triggered.
+		 *
+		 * Other routers explicitly disable auto-clear
+		 * to prevent conditions that may occur where two
+		 * MSIX interrupts are simultaneously active and
+		 * reading the register clears both of them.
+		 */
+		misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
+		if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
+			bit = REG_DMA_MISC_INT_AUTO_CLEAR;
+		else
+			bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
+		if (!(misc & bit))
+			iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC);
 
 		ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
 		step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
@@ -393,14 +400,17 @@ EXPORT_SYMBOL_GPL(tb_ring_poll_complete)
 
 static void ring_clear_msix(const struct tb_ring *ring)
 {
+	int bit;
+
 	if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
 		return;
 
+	bit = ring_interrupt_index(ring) & 31;
 	if (ring->is_tx)
-		ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE);
+		iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR);
 	else
-		ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE +
-			 4 * (ring->nhi->hop_count / 32));
+		iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR +
+			  4 * (ring->nhi->hop_count / 32));
 }
 
 static irqreturn_t ring_msix(int irq, void *data)
drivers/thunderbolt/nhi_regs.h +4 -2
@@ -77,12 +77,13 @@ struct ring_desc {
 
 /*
  * three bitfields: tx, rx, rx overflow
- * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are
- * cleared on read. New interrupts are fired only after ALL registers have been
+ * Every bitfield contains one bit for every hop (REG_HOP_COUNT).
+ * New interrupts are fired only after ALL registers have been
  * read (even those containing only disabled rings).
  */
 #define REG_RING_NOTIFY_BASE	0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_INT_CLEAR	0x37808
 
 /*
  * two bitfields: rx, tx
@@ -105,6 +106,7 @@ struct ring_desc {
 
 #define REG_DMA_MISC			0x39864
 #define REG_DMA_MISC_INT_AUTO_CLEAR     BIT(2)
+#define REG_DMA_MISC_DISABLE_AUTO_CLEAR	BIT(17)
 
 #define REG_INMAIL_DATA			0x39900
 
author maintainer
#113 lore raw

PATCH 113/224 thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access

In reply to Greg Kroah-Hartman

From: Gil Fine <[email protected]>

commit cd0c1e582b055dea615001b8bd8eccaf6f69f7ce upstream.

According to USB4 retimer specification, the process of firmware update sequence requires issuing a SET_INBOUND_SBTX port operation that later shall be followed by UNSET_INBOUND_SBTX port operation. This last step is not currently issued by the driver but it is necessary to make sure the retimers are put back to passthrough mode even during enumeration.

If this step is missing the link may not come up properly after soft-reboot for example.

For this reason issue UNSET_INBOUND_SBTX after SET_INBOUND_SBTX for enumeration and also when the NVM upgrade is run.

---
 drivers/thunderbolt/retimer.c |   23 +++++++++++++++++++++--
 drivers/thunderbolt/sb_regs.h |    1 +
 drivers/thunderbolt/tb.h      |    1 +
 drivers/thunderbolt/usb4.c    |   14 ++++++++++++++
 4 files changed, 37 insertions(+), 2 deletions(-)
drivers/thunderbolt/retimer.c +21 -2
@@ -187,6 +187,22 @@ static ssize_t nvm_authenticate_show(str
 	return ret;
 }
 
+static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
+{
+	int i;
+
+	for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
+		usb4_port_retimer_set_inbound_sbtx(port, i);
+}
+
+static void tb_retimer_unset_inbound_sbtx(struct tb_port *port)
+{
+	int i;
+
+	for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--)
+		usb4_port_retimer_unset_inbound_sbtx(port, i);
+}
+
 static ssize_t nvm_authenticate_store(struct device *dev,
 	struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -213,6 +229,7 @@ static ssize_t nvm_authenticate_store(st
 	rt->auth_status = 0;
 
 	if (val) {
+		tb_retimer_set_inbound_sbtx(rt->port);
 		if (val == AUTHENTICATE_ONLY) {
 			ret = tb_retimer_nvm_authenticate(rt, true);
 		} else {
@@ -232,6 +249,7 @@ static ssize_t nvm_authenticate_store(st
 	}
 
 exit_unlock:
+	tb_retimer_unset_inbound_sbtx(rt->port);
 	mutex_unlock(&rt->tb->lock);
 exit_rpm:
 	pm_runtime_mark_last_busy(&rt->dev);
@@ -440,8 +458,7 @@ int tb_retimer_scan(struct tb_port *port
 	 * Enable sideband channel for each retimer. We can do this
 	 * regardless whether there is device connected or not.
 	 */
-	for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
-		usb4_port_retimer_set_inbound_sbtx(port, i);
+	tb_retimer_set_inbound_sbtx(port);
 
 	/*
 	 * Before doing anything else, read the authentication status.
@@ -464,6 +481,8 @@ int tb_retimer_scan(struct tb_port *port
 			break;
 	}
 
+	tb_retimer_unset_inbound_sbtx(port);
+
 	if (!last_idx)
 		return 0;
 
drivers/thunderbolt/sb_regs.h +1 -0
@@ -20,6 +20,7 @@ enum usb4_sb_opcode {
 	USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c,		/* "LSEN" */
 	USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45,		/* "ENUM" */
 	USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c,		/* "LSUP" */
+	USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355,		/* "USUP" */
 	USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c,		/* "LAST" */
 	USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47,	/* "GNSS" */
 	USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42,		/* "BOPS" */
drivers/thunderbolt/tb.h +1 -0
@@ -1220,6 +1220,7 @@ int usb4_port_sw_margin(struct tb_port *
 int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors);
 
 int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index);
+int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index);
 int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf,
 			   u8 size);
 int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg,
drivers/thunderbolt/usb4.c +14 -0
@@ -1562,6 +1562,20 @@ int usb4_port_retimer_set_inbound_sbtx(s
 }
 
 /**
+ * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions
+ * @port: USB4 port
+ * @index: Retimer index
+ *
+ * Disables sideband channel transations on SBTX. The reverse of
+ * usb4_port_retimer_set_inbound_sbtx().
+ */
+int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index)
+{
+	return usb4_port_retimer_op(port, index,
+				    USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500);
+}
+
+/**
  * usb4_port_retimer_read() - Read from retimer sideband registers
  * @port: USB4 port
  * @index: Retimer index
author maintainer
#114 lore raw

PATCH 114/224 thunderbolt: Use const qualifier for `ring_interrupt_index`

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

commit 1716efdb07938bd6510e1127d02012799112c433 upstream.

ring_interrupt_index doesn't change the data for ring so mark it as const. This is needed by the following patch that disables interrupt auto clear for rings.

---
 drivers/thunderbolt/nhi.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thunderbolt/nhi.c +1 -1
@@ -46,7 +46,7 @@
 #define QUIRK_AUTO_CLEAR_INT	BIT(0)
 #define QUIRK_E2E		BIT(1)
 
-static int ring_interrupt_index(struct tb_ring *ring)
+static int ring_interrupt_index(const struct tb_ring *ring)
 {
 	int bit = ring->hop;
 	if (!ring->is_tx)
author maintainer
#115 lore raw

PATCH 115/224 thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit

In reply to Greg Kroah-Hartman

From: Tom Rix <[email protected]>

commit 58cdfe6f58b35f17f56386f5fcf937168a423ad1 upstream.

cppcheck reports
drivers/thunderbolt/nhi.c:74:7: style: Local variable 'bit' shadows outer variable [shadowVariable]

  int bit;
      ^
drivers/thunderbolt/nhi.c:66:6: note: Shadowed declaration
 int bit = ring_interrupt_index(ring) & 31;
     ^
drivers/thunderbolt/nhi.c:74:7: note: Shadow variable
  int bit;
      ^

For readablity rename the outer to interrupt_bit and the innner to auto_clear_bit.

Fixes 468c49f44759 ("thunderbolt: Disable interrupt auto clear for ring")
---
 drivers/thunderbolt/nhi.c |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/thunderbolt/nhi.c +9 -8
@@ -63,15 +63,15 @@ static void ring_interrupt_active(struct
 {
 	int reg = REG_RING_INTERRUPT_BASE +
 		  ring_interrupt_index(ring) / 32 * 4;
-	int bit = ring_interrupt_index(ring) & 31;
-	int mask = 1 << bit;
+	int interrupt_bit = ring_interrupt_index(ring) & 31;
+	int mask = 1 << interrupt_bit;
 	u32 old, new;
 
 	if (ring->irq > 0) {
 		u32 step, shift, ivr, misc;
 		void __iomem *ivr_base;
+		int auto_clear_bit;
 		int index;
-		int bit;
 
 		if (ring->is_tx)
 			index = ring->hop;
@@ -91,11 +91,12 @@ static void ring_interrupt_active(struct
 		 */
 		misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
 		if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
-			bit = REG_DMA_MISC_INT_AUTO_CLEAR;
+			auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR;
 		else
-			bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
-		if (!(misc & bit))
-			iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC);
+			auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
+		if (!(misc & auto_clear_bit))
+			iowrite32(misc | auto_clear_bit,
+				  ring->nhi->iobase + REG_DMA_MISC);
 
 		ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
 		step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
@@ -115,7 +116,7 @@ static void ring_interrupt_active(struct
 
 	dev_dbg(&ring->nhi->pdev->dev,
 		"%s interrupt at register %#x bit %d (%#x -> %#x)\n",
-		active ? "enabling" : "disabling", reg, bit, old, new);
+		active ? "enabling" : "disabling", reg, interrupt_bit, old, new);
 
 	if (new == old)
 		dev_WARN(&ring->nhi->pdev->dev,
author maintainer
#116 lore raw

PATCH 116/224 ASoC: amd: yp: Add OMEN by HP Gaming Laptop 16z-n000 to quirks

In reply to Greg Kroah-Hartman

From: Joseph Hunkeler <[email protected]>

[ Upstream commit 22ce6843abec19270bf69b176d7ee0a4ef781da5 ]

Enables display microphone on the HP OMEN 16z-n000 (8A42) laptop

---
 sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
index 36314753923b8..4e681e9c08fe5 100644
@@ -255,6 +255,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
 		}
 	},
+	{
+		.driver_data = &acp6x_card,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
+		}
+	},
 	{}
 };
 
Signature · 1 line
2.39.2
author maintainer
#117 lore raw

PATCH 117/224 scsi: ufs: core: Initialize devfreq synchronously

In reply to Greg Kroah-Hartman

From: Adrien Thierry <[email protected]>

[ Upstream commit 7dafc3e007918384c8693ff8d70381b5c1e9c247 ]

During UFS initialization, devfreq initialization is asynchronous:
ufshcd_async_scan() calls ufshcd_add_lus(), which in turn initializes devfreq for UFS. The simple ondemand governor is then loaded. If it is built as a module, request_module() is called and throws a warning:

  WARNING: CPU: 7 PID: 167 at kernel/kmod.c:136 __request_module+0x1e0/0x460
  Modules linked in: crct10dif_ce llcc_qcom phy_qcom_qmp_usb ufs_qcom phy_qcom_snps_femto_v2 ufshcd_pltfrm phy_qcom_qmp_combo ufshcd_core phy_qcom_qmp_ufs qcom_wdt socinfo fuse ipv6
  CPU: 7 PID: 167 Comm: kworker/u16:3 Not tainted 6.2.0-rc6-00009-g58706f7fb045 #1
  Hardware name: Qualcomm SA8540P Ride (DT)
  Workqueue: events_unbound async_run_entry_fn
  pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : __request_module+0x1e0/0x460
  lr : __request_module+0x1d8/0x460
  sp : ffff800009323b90
  x29: ffff800009323b90 x28: 0000000000000000 x27: 0000000000000000
  x26: ffff800009323d50 x25: ffff7b9045f57810 x24: ffff7b9045f57830
  x23: ffffdc5a83e426e8 x22: ffffdc5ae80a9818 x21: 0000000000000001
  x20: ffffdc5ae7502f98 x19: ffff7b9045f57800 x18: ffffffffffffffff
  x17: 312f716572667665 x16: 642f7366752e3030 x15: 0000000000000000
  x14: 000000000000021c x13: 0000000000005400 x12: ffff7b9042ed7614
  x11: ffff7b9042ed7600 x10: 00000000636c0890 x9 : 0000000000000038
  x8 : ffff7b9045f2c880 x7 : ffff7b9045f57c68 x6 : 0000000000000080
  x5 : 0000000000000000 x4 : 8000000000000000 x3 : 0000000000000000
  x2 : 0000000000000000 x1 : ffffdc5ae5d382f0 x0 : 0000000000000001
  Call trace:
   __request_module+0x1e0/0x460
   try_then_request_governor+0x7c/0x100
   devfreq_add_device+0x4b0/0x5fc
   ufshcd_async_scan+0x1d4/0x310 [ufshcd_core]
   async_run_entry_fn+0x34/0xe0
   process_one_work+0x1d0/0x320
   worker_thread+0x14c/0x444
   kthread+0x10c/0x110
   ret_from_fork+0x10/0x20

This occurs because synchronous module loading from async is not allowed. According to __request_module():

/*
* We don't allow synchronous module loading from async. Module
* init may invoke async_synchronize_full() which will end up
* waiting for this task which already is waiting for the module
* loading to complete, leading to a deadlock.
*/

Such a deadlock was experienced on the Qualcomm QDrive3/sa8540p-ride. With DEVFREQ_GOV_SIMPLE_ONDEMAND=m, the boot hangs after the warning.

Fix both the warning and the deadlock by moving devfreq initialization out of the async routine.

Tested on the sa8540p-ride by using fio to put the UFS under load, and printing the trace generated by /sys/kernel/tracing/events/ufs/ufshcd_clk_scaling events. The trace looks similar with and without the change.

---
 drivers/ufs/core/ufshcd.c | 47 ++++++++++++++++++++++++++-------------
 include/ufs/ufshcd.h      |  1 +
 2 files changed, 32 insertions(+), 16 deletions(-)
drivers/ufs/core/ufshcd.c +31 -16
index edd34dac91b1d..e652624c449a9 100644
@@ -1354,6 +1354,13 @@ static int ufshcd_devfreq_target(struct device *dev,
 	struct ufs_clk_info *clki;
 	unsigned long irq_flags;
 
+	/*
+	 * Skip devfreq if UFS initialization is not finished.
+	 * Otherwise ufs could be in a inconsistent state.
+	 */
+	if (!smp_load_acquire(&hba->logical_unit_scan_finished))
+		return 0;
+
 	if (!ufshcd_is_clkscaling_supported(hba))
 		return -EINVAL;
 
@@ -8184,22 +8191,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
 	if (ret)
 		goto out;
 
-	/* Initialize devfreq after UFS device is detected */
-	if (ufshcd_is_clkscaling_supported(hba)) {
-		memcpy(&hba->clk_scaling.saved_pwr_info.info,
-			&hba->pwr_info,
-			sizeof(struct ufs_pa_layer_attr));
-		hba->clk_scaling.saved_pwr_info.is_valid = true;
-		hba->clk_scaling.is_allowed = true;
-
-		ret = ufshcd_devfreq_init(hba);
-		if (ret)
-			goto out;
-
-		hba->clk_scaling.is_enabled = true;
-		ufshcd_init_clk_scaling_sysfs(hba);
-	}
-
 	ufs_bsg_probe(hba);
 	ufshpb_init(hba);
 	scsi_scan_host(hba->host);
@@ -8338,6 +8329,12 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
 	if (ret) {
 		pm_runtime_put_sync(hba->dev);
 		ufshcd_hba_exit(hba);
+	} else {
+		/*
+		 * Make sure that when reader code sees UFS initialization has finished,
+		 * all initialization steps have really been executed.
+		 */
+		smp_store_release(&hba->logical_unit_scan_finished, true);
 	}
 }
 
@@ -9892,12 +9889,30 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	 */
 	ufshcd_set_ufs_dev_active(hba);
 
+	/* Initialize devfreq */
+	if (ufshcd_is_clkscaling_supported(hba)) {
+		memcpy(&hba->clk_scaling.saved_pwr_info.info,
+			&hba->pwr_info,
+			sizeof(struct ufs_pa_layer_attr));
+		hba->clk_scaling.saved_pwr_info.is_valid = true;
+		hba->clk_scaling.is_allowed = true;
+
+		err = ufshcd_devfreq_init(hba);
+		if (err)
+			goto rpm_put_sync;
+
+		hba->clk_scaling.is_enabled = true;
+		ufshcd_init_clk_scaling_sysfs(hba);
+	}
+
 	async_schedule(ufshcd_async_scan, hba);
 	ufs_sysfs_add_nodes(hba->dev);
 
 	device_enable_async_suspend(dev);
 	return 0;
 
+rpm_put_sync:
+	pm_runtime_put_sync(dev);
 free_tmf_queue:
 	blk_mq_destroy_queue(hba->tmf_queue);
 free_tmf_tag_set:
include/ufs/ufshcd.h +1 -0
index b54f22840dabf..0ef1ec6a3b4d1 100644
@@ -894,6 +894,7 @@ struct ufs_hba {
 	struct completion *uic_async_done;
 
 	enum ufshcd_state ufshcd_state;
+	bool logical_unit_scan_finished;
 	u32 eh_flags;
 	u32 intr_mask;
 	u16 ee_ctrl_mask;
Signature · 1 line
2.39.2
author maintainer
#119 lore raw

PATCH 118/224 ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A43)

In reply to Greg Kroah-Hartman

From: Duc Anh Le <[email protected]>

[ Upstream commit d52279d5c9204a041e9ba02a66a353573b2f96e4 ]

This model requires an additional detection quirk to enable the internal microphone.

---
 sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
index 4e681e9c08fe5..4a69ce702360c 100644
@@ -262,6 +262,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
 		}
 	},
+	{
+		.driver_data = &acp6x_card,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+			DMI_MATCH(DMI_BOARD_NAME, "8A43"),
+		}
+	},
 	{}
 };
 
Signature · 1 line
2.39.2
author maintainer
#120 lore raw

PATCH 119/224 ACPI: x86: Drop quirk for HP Elitebook

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

[ Upstream commit e32d546c483a2a0f607687f5b521c2a2f942ffbe ]

There was a quirk in acpi/x86/s2idle.c for an HP Elitebook G9 platforms to force AMD GUID codepath instead of Microsoft codepath.

This was due to a bug with WCN6855 WLAN firmware interaction with the system.

This bug is fixed by WCN6855 firmware:
WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23

Remove the quirk as it's no longer necessary with this firmware.

---
 drivers/acpi/x86/s2idle.c | 24 ------------------------
 1 file changed, 24 deletions(-)
drivers/acpi/x86/s2idle.c +0 -24
index c7afce465a071..e499c60c45791 100644
@@ -384,29 +384,6 @@ static const struct acpi_device_id amd_hid_ids[] = {
 	{}
 };
 
-static int lps0_prefer_amd(const struct dmi_system_id *id)
-{
-	pr_debug("Using AMD GUID w/ _REV 2.\n");
-	rev_id = 2;
-	return 0;
-}
-static const struct dmi_system_id s2idle_dmi_table[] __initconst = {
-	{
-		/*
-		 * AMD Rembrandt based HP EliteBook 835/845/865 G9
-		 * Contains specialized AML in AMD/_REV 2 path to avoid
-		 * triggering a bug in Qualcomm WLAN firmware. This may be
-		 * removed in the future if that firmware is fixed.
-		 */
-		.callback = lps0_prefer_amd,
-		.matches = {
-			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
-			DMI_MATCH(DMI_BOARD_NAME, "8990"),
-		},
-	},
-	{}
-};
-
 static int lps0_device_attach(struct acpi_device *adev,
 			      const struct acpi_device_id *not_used)
 {
@@ -586,7 +563,6 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
 
 void __init acpi_s2idle_setup(void)
 {
-	dmi_check_system(s2idle_dmi_table);
 	acpi_scan_add_handler(&lps0_handler);
 	s2idle_set_ops(&acpi_s2idle_ops_lps0);
 }
Signature · 1 line
2.39.2
author maintainer
#121 lore raw

PATCH 120/224 ACPI: x86: utils: Add Cezanne to the list for forcing StorageD3Enable

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

[ Upstream commit e2a56364485e7789e7b8f342637c7f3a219f7ede ]

commit 018d6711c26e4 ("ACPI: x86: Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable") introduced a quirk to allow a system with ambiguous use of _ADR 0 to force StorageD3Enable.

It was reported that several more Dell systems suffered the same symptoms. As the list is continuing to grow but these are all Cezanne systems, instead add Cezanne to the CPU list to apply the StorageD3Enable property and remove the whole list.

It was also reported that an HP system only has StorageD3Enable on the ACPI device for the first NVME disk, not the second.

---
 drivers/acpi/x86/utils.c | 37 +++++++++++++------------------------
 1 file changed, 13 insertions(+), 24 deletions(-)
drivers/acpi/x86/utils.c +13 -24
index 4e816bb402f68..e45285d4e62a4 100644
@@ -200,39 +200,28 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
  * a hardcoded allowlist for D3 support, which was used for these platforms.
  *
  * This allows quirking on Linux in a similar fashion.
+ *
+ * Cezanne systems shouldn't *normally* need this as the BIOS includes
+ * StorageD3Enable.  But for two reasons we have added it.
+ * 1) The BIOS on a number of Dell systems have ambiguity
+ *    between the same value used for _ADR on ACPI nodes GPP1.DEV0 and GPP1.NVME.
+ *    GPP1.NVME is needed to get StorageD3Enable node set properly.
+ *    https://bugzilla.kernel.org/show_bug.cgi?id=216440
+ *    https://bugzilla.kernel.org/show_bug.cgi?id=216773
+ *    https://bugzilla.kernel.org/show_bug.cgi?id=217003
+ * 2) On at least one HP system StorageD3Enable is missing on the second NVME
+      disk in the system.
  */
 static const struct x86_cpu_id storage_d3_cpu_ids[] = {
 	X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL),	/* Renoir */
 	X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL),	/* Lucienne */
-	{}
-};
-
-static const struct dmi_system_id force_storage_d3_dmi[] = {
-	{
-		/*
-		 * _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME
-		 * but .NVME is needed to get StorageD3Enable node
-		 * https://bugzilla.kernel.org/show_bug.cgi?id=216440
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
-		}
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5625"),
-		}
-	},
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL),	/* Cezanne */
 	{}
 };
 
 bool force_storage_d3(void)
 {
-	const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi);
-
-	return dmi_id || x86_match_cpu(storage_d3_cpu_ids);
+	return x86_match_cpu(storage_d3_cpu_ids);
 }
 
 /*
Signature · 1 line
2.39.2
author maintainer
#122 lore raw

PATCH 121/224 riscv: Bump COMMAND_LINE_SIZE value to 1024

In reply to Greg Kroah-Hartman

From: Alexandre Ghiti <[email protected]>

[ Upstream commit 61fc1ee8be26bc192d691932b0a67eabee45d12f ]

Increase COMMAND_LINE_SIZE as the current default value is too low for syzbot kernel command line.

There has been considerable discussion on this patch that has led to a larger patch set removing COMMAND_LINE_SIZE from the uapi headers on all ports. That's not quite done yet, but it's gotten far enough we're confident this is not a uABI change so this is safe.

---
 arch/riscv/include/uapi/asm/setup.h | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 arch/riscv/include/uapi/asm/setup.h
arch/riscv/include/uapi/asm/setup.h new file +8 -0
new file mode 100644
index 0000000000000..66b13a5228808
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+
+#ifndef _UAPI_ASM_RISCV_SETUP_H
+#define _UAPI_ASM_RISCV_SETUP_H
+
+#define COMMAND_LINE_SIZE	1024
+
+#endif /* _UAPI_ASM_RISCV_SETUP_H */
Signature · 1 line
2.39.2
author maintainer
#123 lore raw

PATCH 122/224 drm/cirrus: NULL-check pipe->plane.state->fb in cirrus_pipe_update()

In reply to Greg Kroah-Hartman

From: Alexandr Sapozhnikov <[email protected]>

[ Upstream commit 7245e629dcaaf308f1868aeffa218e9849c77893 ]

After having been compared to NULL value at cirrus.c:455, pointer 'pipe->plane.state->fb' is passed as 1st parameter in call to function 'cirrus_fb_blit_rect' at cirrus.c:461, where it is dereferenced at cirrus.c:316.

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

v2:
* aligned commit message to line-length limits

---
 drivers/gpu/drm/tiny/cirrus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tiny/cirrus.c +1 -1
index 354d5e854a6f0..b27e469e90217 100644
@@ -455,7 +455,7 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
 	if (state->fb && cirrus->cpp != cirrus_cpp(state->fb))
 		cirrus_mode_set(cirrus, &crtc->mode, state->fb);
 
-	if (drm_atomic_helper_damage_merged(old_state, state, &rect))
+	if (state->fb && drm_atomic_helper_damage_merged(old_state, state, &rect))
 		cirrus_fb_blit_rect(state->fb, &shadow_plane_state->data[0], &rect);
 }
 
Signature · 1 line
2.39.2
author maintainer
#124 lore raw

PATCH 123/224 HID: cp2112: Fix driver not registering GPIO IRQ chip as threaded

In reply to Greg Kroah-Hartman

From: Danny Kaehn <[email protected]>

[ Upstream commit 37f5b858a66543b2b67c0288280af623985abc29 ]

The CP2112 generates interrupts from a polling routine on a thread, and can only support threaded interrupts. This patch configures the gpiochip irq chip with this flag, disallowing consumers to request a hard IRQ from this driver, which resulted in a segfault previously.

---
 drivers/hid/hid-cp2112.c | 1 +
 1 file changed, 1 insertion(+)
drivers/hid/hid-cp2112.c +1 -0
index 1e16b0fa310d1..27cadadda7c9d 100644
@@ -1354,6 +1354,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	girq->parents = NULL;
 	girq->default_type = IRQ_TYPE_NONE;
 	girq->handler = handle_simple_irq;
+	girq->threaded = true;
 
 	ret = gpiochip_add_data(&dev->gc, dev);
 	if (ret < 0) {
Signature · 1 line
2.39.2
author maintainer
#125 lore raw

PATCH 124/224 ca8210: fix mac_len negative array access

In reply to Greg Kroah-Hartman

From: Alexander Aring <[email protected]>

[ Upstream commit 6c993779ea1d0cccdb3a5d7d45446dd229e610a3 ]

This patch fixes a buffer overflow access of skb->data if ieee802154_hdr_peek_addrs() fails.

---
 drivers/net/ieee802154/ca8210.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ieee802154/ca8210.c +2 -0
index e1a569b99e4a6..0b0c6c0764fe9 100644
@@ -1913,6 +1913,8 @@ static int ca8210_skb_tx(
 	 * packet
 	 */
 	mac_len = ieee802154_hdr_peek_addrs(skb, &header);
+	if (mac_len < 0)
+		return mac_len;
 
 	secspec.security_level = header.sec.level;
 	secspec.key_id_mode = header.sec.key_id_mode;
Signature · 1 line
2.39.2
author maintainer
#126 lore raw

PATCH 125/224 HID: logitech-hidpp: Add support for Logitech MX Master 3S mouse

In reply to Greg Kroah-Hartman

From: Rafał Szalecki <[email protected]>

[ Upstream commit db50f7a3983f0154e730f1147ef729e0c5c2f90c ]

Add signature for the Logitech MX Master 3S mouse over Bluetooth.

---
 drivers/hid/hid-logitech-hidpp.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/hid/hid-logitech-hidpp.c +2 -0
index fdb66dc065822..e906ee375298a 100644
@@ -4378,6 +4378,8 @@ static const struct hid_device_id hidpp_devices[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e) },
 	{ /* MX Master 3 mouse over Bluetooth */
 	  HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023) },
+	{ /* MX Master 3S mouse over Bluetooth */
+	  HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb034) },
 	{}
 };
 
Signature · 1 line
2.39.2
author maintainer
#127 lore raw

PATCH 126/224 HID: intel-ish-hid: ipc: Fix potential use-after-free in work function

In reply to Greg Kroah-Hartman

From: Reka Norman <[email protected]>

[ Upstream commit 8ae2f2b0a28416ed2f6d8478ac8b9f7862f36785 ]

When a reset notify IPC message is received, the ISR schedules a work function and passes the ISHTP device to it via a global pointer ishtp_dev. If ish_probe() fails, the devm-managed device resources including ishtp_dev are freed, but the work is not cancelled, causing a use-after-free when the work function tries to access ishtp_dev. Use devm_work_autocancel() instead, so that the work is automatically cancelled if probe fails.

---
 drivers/hid/intel-ish-hid/ipc/ipc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/hid/intel-ish-hid/ipc/ipc.c +8 -1
index 15e14239af829..a49c6affd7c4c 100644
@@ -5,6 +5,7 @@
  * Copyright (c) 2014-2016, Intel Corporation.
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
@@ -621,7 +622,6 @@ static void	recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
 	case MNG_RESET_NOTIFY:
 		if (!ishtp_dev) {
 			ishtp_dev = dev;
-			INIT_WORK(&fw_reset_work, fw_reset_work_fn);
 		}
 		schedule_work(&fw_reset_work);
 		break;
@@ -940,6 +940,7 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
 {
 	struct ishtp_device *dev;
 	int	i;
+	int	ret;
 
 	dev = devm_kzalloc(&pdev->dev,
 			   sizeof(struct ishtp_device) + sizeof(struct ish_hw),
@@ -975,6 +976,12 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
 		list_add_tail(&tx_buf->link, &dev->wr_free_list);
 	}
 
+	ret = devm_work_autocancel(&pdev->dev, &fw_reset_work, fw_reset_work_fn);
+	if (ret) {
+		dev_err(dev->devc, "Failed to initialise FW reset work\n");
+		return NULL;
+	}
+
 	dev->ops = &ish_hw_ops;
 	dev->devc = &pdev->dev;
 	dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
Signature · 1 line
2.39.2
author maintainer
#128 lore raw

PATCH 127/224 m68k: mm: Fix systems with memory at end of 32-bit address space

In reply to Greg Kroah-Hartman

From: Kars de Jong <[email protected]>

[ Upstream commit 0d9fad91abfd723ea5070a46d98a9f4496c93ba9 ]

The calculation of end addresses of memory chunks overflowed to 0 when a memory chunk is located at the end of 32-bit address space. This is the case for the HP300 architecture.

---
 arch/m68k/mm/motorola.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/m68k/mm/motorola.c +5 -5
index 2a375637e0077..9113012240789 100644
@@ -437,7 +437,7 @@ void __init paging_init(void)
 	}
 
 	min_addr = m68k_memory[0].addr;
-	max_addr = min_addr + m68k_memory[0].size;
+	max_addr = min_addr + m68k_memory[0].size - 1;
 	memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0,
 			  MEMBLOCK_NONE);
 	for (i = 1; i < m68k_num_memory;) {
@@ -452,21 +452,21 @@ void __init paging_init(void)
 		}
 		memblock_add_node(m68k_memory[i].addr, m68k_memory[i].size, i,
 				  MEMBLOCK_NONE);
-		addr = m68k_memory[i].addr + m68k_memory[i].size;
+		addr = m68k_memory[i].addr + m68k_memory[i].size - 1;
 		if (addr > max_addr)
 			max_addr = addr;
 		i++;
 	}
 	m68k_memoffset = min_addr - PAGE_OFFSET;
-	m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
+	m68k_virt_to_node_shift = fls(max_addr - min_addr) - 6;
 
 	module_fixup(NULL, __start_fixup, __stop_fixup);
 	flush_icache();
 
-	high_memory = phys_to_virt(max_addr);
+	high_memory = phys_to_virt(max_addr) + 1;
 
 	min_low_pfn = availmem >> PAGE_SHIFT;
-	max_pfn = max_low_pfn = max_addr >> PAGE_SHIFT;
+	max_pfn = max_low_pfn = (max_addr >> PAGE_SHIFT) + 1;
 
 	/* Reserve kernel text/data/bss and the memory allocated in head.S */
 	memblock_reserve(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
Signature · 1 line
2.39.2
author maintainer
#129 lore raw

PATCH 128/224 m68k: Only force 030 bus error if PC not in exception table

In reply to Greg Kroah-Hartman

From: Michael Schmitz <[email protected]>

[ Upstream commit e36a82bebbf7da814530d5a179bef9df5934b717 ]

__get_kernel_nofault() does copy data in supervisor mode when forcing a task backtrace log through /proc/sysrq_trigger. This is expected cause a bus error exception on e.g. NULL pointer dereferencing when logging a kernel task has no workqueue associated. This bus error ought to be ignored.

Our 030 bus error handler is ill equipped to deal with this:

Whenever ssw indicates a kernel mode access on a data fault, we don't even attempt to handle the fault and instead always send a SEGV signal (or panic). As a result, the check for exception handling at the fault PC (buried in send_sig_fault() which gets called from do_page_fault() eventually) is never used.

In contrast, both 040 and 060 access error handlers do not care whether a fault happened on supervisor mode access, and will call do_page_fault() on those, ultimately honoring the exception table.

Add a check in bus_error030 to call do_page_fault() in case we do have an entry for the fault PC in our exception table.

I had attempted a fix for this earlier in 2019 that did rely on testing pagefault_disabled() (see link below) to achieve the same thing, but this patch should be more generic.

Tested on 030 Atari Falcon.

---
 arch/m68k/kernel/traps.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/m68k/kernel/traps.c +3 -1
index 5c8cba0efc63e..a700807c9b6d9 100644
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/ptrace.h>
 #include <linux/kallsyms.h>
+#include <linux/extable.h>
 
 #include <asm/setup.h>
 #include <asm/fpu.h>
@@ -545,7 +546,8 @@ static inline void bus_error030 (struct frame *fp)
 			errorcode |= 2;
 
 		if (mmusr & (MMU_I | MMU_WP)) {
-			if (ssw & 4) {
+			/* We might have an exception table for this PC */
+			if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) {
 				pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
 				       ssw & RW ? "read" : "write",
 				       fp->un.fmtb.daddr,
Signature · 1 line
2.39.2
author maintainer
#130 lore raw

PATCH 129/224 selftests/bpf: check that modifier resolves after pointer

In reply to Greg Kroah-Hartman

From: Lorenz Bauer <[email protected]>

[ Upstream commit dfdd608c3b365f0fd49d7e13911ebcde06b9865b ]

Add a regression test that ensures that a VAR pointing at a modifier which follows a PTR (or STRUCT or ARRAY) is resolved correctly by the datasec validator.

---
 tools/testing/selftests/bpf/prog_tests/btf.c | 28 ++++++++++++++++++++
 1 file changed, 28 insertions(+)
tools/testing/selftests/bpf/prog_tests/btf.c +28 -0
index 24dd6214394e0..d711f4bea98ea 100644
@@ -879,6 +879,34 @@ static struct btf_raw_test raw_tests[] = {
 	.btf_load_err = true,
 	.err_str = "Invalid elem",
 },
+{
+	.descr = "var after datasec, ptr followed by modifier",
+	.raw_types = {
+		/* .bss section */				/* [1] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2),
+			sizeof(void*)+4),
+		BTF_VAR_SECINFO_ENC(4, 0, sizeof(void*)),
+		BTF_VAR_SECINFO_ENC(6, sizeof(void*), 4),
+		/* int */					/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int* */					/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
+		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [4] */
+		/* const int */					/* [5] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0c\0",
+	.str_sec_size = sizeof("\0a\0b\0c\0"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void*)+4,
+	.key_type_id = 0,
+	.value_type_id = 1,
+	.max_entries = 1,
+},
 /* Test member exceeds the size of struct.
  *
  * struct A {
Signature · 1 line
2.39.2
author maintainer
#131 lore raw

PATCH 130/224 scsi: target: iscsi: Fix an error message in iscsi_check_key()

In reply to Greg Kroah-Hartman

From: Maurizio Lombardi <[email protected]>

[ Upstream commit 6cc55c969b7ce8d85e09a636693d4126c3676c11 ]

The first half of the error message is printed by pr_err(), the second half is printed by pr_debug(). The user will therefore see only the first part of the message and will miss some useful information.

---
 drivers/target/iscsi/iscsi_target_parameters.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/target/iscsi/iscsi_target_parameters.c +7 -5
index 2317fb077db0e..557516c642c3b 100644
@@ -1262,18 +1262,20 @@ static struct iscsi_param *iscsi_check_key(
 		return param;
 
 	if (!(param->phase & phase)) {
-		pr_err("Key \"%s\" may not be negotiated during ",
-				param->name);
+		char *phase_name;
+
 		switch (phase) {
 		case PHASE_SECURITY:
-			pr_debug("Security phase.\n");
+			phase_name = "Security";
 			break;
 		case PHASE_OPERATIONAL:
-			pr_debug("Operational phase.\n");
+			phase_name = "Operational";
 			break;
 		default:
-			pr_debug("Unknown phase.\n");
+			phase_name = "Unknown";
 		}
+		pr_err("Key \"%s\" may not be negotiated during %s phase.\n",
+				param->name, phase_name);
 		return NULL;
 	}
 
Signature · 1 line
2.39.2
author maintainer
#132 lore raw

PATCH 131/224 scsi: qla2xxx: Add option to disable FC2 Target support

In reply to Greg Kroah-Hartman

From: Daniel Wagner <[email protected]>

[ Upstream commit 877b03795fcf29ff2e2351f7e574ecc9b9c51732 ]

Commit 44c57f205876 ("scsi: qla2xxx: Changes to support FCP2 Target") added support for FC2 Targets. Unfortunately, there are older setups which break with this new feature enabled.

Allow to disable it via module option.

---
 drivers/scsi/qla2xxx/qla_gbl.h  |  1 +
 drivers/scsi/qla2xxx/qla_init.c |  3 ++-
 drivers/scsi/qla2xxx/qla_os.c   | 10 +++++++++-
 3 files changed, 12 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_gbl.h +1 -0
index e3256e721be14..ee54207fc5319 100644
@@ -192,6 +192,7 @@ extern int ql2xsecenable;
 extern int ql2xenforce_iocb_limit;
 extern int ql2xabts_wait_nvme;
 extern u32 ql2xnvme_queues;
+extern int ql2xfc2target;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
drivers/scsi/qla2xxx/qla_init.c +2 -1
index a8d822c4e3bac..93f7f3dd5d82b 100644
@@ -1841,7 +1841,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
 	case RSCN_PORT_ADDR:
 		fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
 		if (fcport) {
-			if (fcport->flags & FCF_FCP2_DEVICE &&
+			if (ql2xfc2target &&
+			    fcport->flags & FCF_FCP2_DEVICE &&
 			    atomic_read(&fcport->state) == FCS_ONLINE) {
 				ql_dbg(ql_dbg_disc, vha, 0x2115,
 				       "Delaying session delete for FCP2 portid=%06x %8phC ",
drivers/scsi/qla2xxx/qla_os.c +9 -1
index e010812015b14..7d2d872bae3c5 100644
@@ -360,6 +360,13 @@ MODULE_PARM_DESC(ql2xnvme_queues,
 	"1 - Minimum number of queues supported\n"
 	"8 - Default value");
 
+int ql2xfc2target = 1;
+module_param(ql2xfc2target, int, 0444);
+MODULE_PARM_DESC(qla2xfc2target,
+		  "Enables FC2 Target support. "
+		  "0 - FC2 Target support is disabled. "
+		  "1 - FC2 Target support is enabled (default).");
+
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;
 struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
 
@@ -4087,7 +4094,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
 	    "Mark all dev lost\n");
 
 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
-		if (fcport->loop_id != FC_NO_LOOP_ID &&
+		if (ql2xfc2target &&
+		    fcport->loop_id != FC_NO_LOOP_ID &&
 		    (fcport->flags & FCF_FCP2_DEVICE) &&
 		    fcport->port_type == FCT_TARGET &&
 		    !qla2x00_reset_active(vha)) {
Signature · 1 line
2.39.2
author maintainer
#133 lore raw

PATCH 132/224 scsi: hisi_sas: Check devm_add_action() return value

In reply to Greg Kroah-Hartman

From: Kang Chen <[email protected]>

[ Upstream commit 06d1a90de60208054cca15ef200138cfdbb642a9 ]

In case devm_add_action() fails, check it in the caller of interrupt_preinit_v3_hw().

---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +1 -2
index d56b4bfd27678..620dcefe7b6f4 100644
@@ -2448,8 +2448,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
 	hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
 	shost->nr_hw_queues = hisi_hba->cq_nvecs;
 
-	devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
-	return 0;
+	return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
 }
 
 static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
Signature · 1 line
2.39.2
author maintainer
#134 lore raw

PATCH 133/224 scsi: ufs: core: Add soft dependency on governor_simpleondemand

In reply to Greg Kroah-Hartman

From: Adrien Thierry <[email protected]>

[ Upstream commit 2ebe16155dc8bd4e602cad5b5f65458d2eaa1a75 ]

The ufshcd driver uses simpleondemand governor for devfreq. Add it to the list of ufshcd softdeps to allow userspace initramfs tools like dracut to automatically pull the governor module into the initramfs together with UFS drivers.

---
 drivers/ufs/core/ufshcd.c | 1 +
 1 file changed, 1 insertion(+)
drivers/ufs/core/ufshcd.c +1 -0
index e652624c449a9..82ecf776f9054 100644
@@ -10089,4 +10089,5 @@ module_exit(ufshcd_core_exit);
 MODULE_AUTHOR("Santosh Yaragnavi <[email protected]>");
 MODULE_AUTHOR("Vinayak Holikatti <[email protected]>");
 MODULE_DESCRIPTION("Generic UFS host controller driver Core");
+MODULE_SOFTDEP("pre: governor_simpleondemand");
 MODULE_LICENSE("GPL");
Signature · 1 line
2.39.2
author maintainer
#135 lore raw

PATCH 134/224 scsi: lpfc: Check kzalloc() in lpfc_sli4_cgn_params_read()

In reply to Greg Kroah-Hartman

From: Justin Tee <[email protected]>

[ Upstream commit 312320b0e0ec21249a17645683fe5304d796aec1 ]

If kzalloc() fails in lpfc_sli4_cgn_params_read(), then we rely on lpfc_read_object()'s routine to NULL check pdata.

Currently, an early return error is thrown from lpfc_read_object() to protect us from NULL ptr dereference, but the errno code is -ENODEV.

Change the errno code to a more appropriate -ENOMEM.

---
 drivers/scsi/lpfc/lpfc_init.c | 2 ++
 drivers/scsi/lpfc/lpfc_sli.c  | 4 ----
 2 files changed, 2 insertions(+), 4 deletions(-)
drivers/scsi/lpfc/lpfc_init.c +2 -0
index b535f1fd30100..2f38c8d5a48a9 100644
@@ -7234,6 +7234,8 @@ lpfc_sli4_cgn_params_read(struct lpfc_hba *phba)
 	/* Find out if the FW has a new set of congestion parameters. */
 	len = sizeof(struct lpfc_cgn_param);
 	pdata = kzalloc(len, GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
 	ret = lpfc_read_object(phba, (char *)LPFC_PORT_CFG_NAME,
 			       pdata, len);
 
drivers/scsi/lpfc/lpfc_sli.c +0 -4
index b93c948c4fcc4..43e06bb917e77 100644
@@ -22096,10 +22096,6 @@ lpfc_read_object(struct lpfc_hba *phba, char *rdobject, uint32_t *datap,
 	struct lpfc_dmabuf *pcmd;
 	u32 rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW] = {0};
 
-	/* sanity check on queue memory */
-	if (!datap)
-		return -ENODEV;
-
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox)
 		return -ENOMEM;
Signature · 1 line
2.39.2
author maintainer
#136 lore raw

PATCH 135/224 scsi: lpfc: Avoid usage of list iterator variable after loop

In reply to Greg Kroah-Hartman

From: Jakob Koschel <[email protected]>

[ Upstream commit 2850b23e9f9ae3696e472d2883ea1b43aafa884e ]

If the &epd_pool->list is empty when executing lpfc_get_io_buf_from_expedite_pool() the function would return an invalid pointer. Even in the case if the list is guaranteed to be populated, the iterator variable should not be used after the loop to be more robust for future changes.

Linus proposed to avoid any use of the list iterator variable after the loop, in the attempt to move the list iterator variable declaration into the macro to avoid any potential misuse after the loop [1].

---
 drivers/scsi/lpfc/lpfc_sli.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/lpfc/lpfc_sli.c +4 -4
index 43e06bb917e77..b44bb3ae22ad9 100644
@@ -21886,20 +21886,20 @@ lpfc_get_io_buf_from_private_pool(struct lpfc_hba *phba,
 static struct lpfc_io_buf *
 lpfc_get_io_buf_from_expedite_pool(struct lpfc_hba *phba)
 {
-	struct lpfc_io_buf *lpfc_ncmd;
+	struct lpfc_io_buf *lpfc_ncmd = NULL, *iter;
 	struct lpfc_io_buf *lpfc_ncmd_next;
 	unsigned long iflag;
 	struct lpfc_epd_pool *epd_pool;
 
 	epd_pool = &phba->epd_pool;
-	lpfc_ncmd = NULL;
 
 	spin_lock_irqsave(&epd_pool->lock, iflag);
 	if (epd_pool->count > 0) {
-		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
+		list_for_each_entry_safe(iter, lpfc_ncmd_next,
 					 &epd_pool->list, list) {
-			list_del(&lpfc_ncmd->list);
+			list_del(&iter->list);
 			epd_pool->count--;
+			lpfc_ncmd = iter;
 			break;
 		}
 	}
Signature · 1 line
2.39.2
author maintainer
#137 lore raw

PATCH 136/224 scsi: mpi3mr: Driver unload crashes host when enhanced logging is enabled

In reply to Greg Kroah-Hartman

From: Ranjan Kumar <[email protected]>

[ Upstream commit 5b06a7169c59ce0c77ef8b9c82aa07c478f82aac ]

Prevent driver from trying to dereference a NULL pointer in a debug print while removing a device during driver unload.

---
 drivers/scsi/mpi3mr/mpi3mr_transport.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/mpi3mr/mpi3mr_transport.c +2 -1
index 50263ba4f8428..90f61a0a8f4ef 100644
@@ -1549,7 +1549,8 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
 
 	list_for_each_entry_safe(mr_sas_phy, next_phy,
 	    &mr_sas_port->phy_list, port_siblings) {
-		if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
+		if ((!mrioc->stop_drv_processing) &&
+		    (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
 			dev_info(&mr_sas_port->port->dev,
 			    "remove: sas_address(0x%016llx), phy(%d)\n",
 			    (unsigned long long)
Signature · 1 line
2.39.2
author maintainer
#138 lore raw

PATCH 137/224 scsi: mpi3mr: Wait for diagnostic save during controller init

In reply to Greg Kroah-Hartman

From: Ranjan Kumar <[email protected]>

[ Upstream commit 0a319f1629495d27879b7ebf6eee62b8cf6e4c37 ]

If a controller reset operation is triggered to recover the controller from a fault state, then wait for the snapdump to be saved in the firmware region before proceeding to reset the controller.

---
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
drivers/scsi/mpi3mr/mpi3mr_fw.c +18 -1
index 74fa7f90399e3..ea9e69fb62826 100644
@@ -1198,7 +1198,7 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
  */
 static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
 {
-	u32 ioc_config, ioc_status, timeout;
+	u32 ioc_config, ioc_status, timeout, host_diagnostic;
 	int retval = 0;
 	enum mpi3mr_iocstate ioc_state;
 	u64 base_info;
@@ -1252,6 +1252,23 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
 			    retval, mpi3mr_iocstate_name(ioc_state));
 	}
 	if (ioc_state != MRIOC_STATE_RESET) {
+		if (ioc_state == MRIOC_STATE_FAULT) {
+			timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
+			mpi3mr_print_fault_info(mrioc);
+			do {
+				host_diagnostic =
+					readl(&mrioc->sysif_regs->host_diagnostic);
+				if (!(host_diagnostic &
+				      MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS))
+					break;
+				if (!pci_device_is_present(mrioc->pdev)) {
+					mrioc->unrecoverable = 1;
+					ioc_err(mrioc, "controller is not present at the bringup\n");
+					goto out_device_not_present;
+				}
+				msleep(100);
+			} while (--timeout);
+		}
 		mpi3mr_print_fault_info(mrioc);
 		ioc_info(mrioc, "issuing soft reset to bring to reset state\n");
 		retval = mpi3mr_issue_reset(mrioc,
Signature · 1 line
2.39.2
author maintainer
#139 lore raw

PATCH 138/224 scsi: mpi3mr: NVMe command size greater than 8K fails

In reply to Greg Kroah-Hartman

From: Ranjan Kumar <[email protected]>

[ Upstream commit 4f297e856a7b5da2f2c66a12e739666e23943560 ]

A wrong variable is checked while populating PRP entries in the PRP page and this results in failure. No PRP entries in the PRP page were successfully created and any NVMe Encapsulated commands with PRP of size greater than 8K failed.

---
 drivers/scsi/mpi3mr/mpi3mr_app.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/mpi3mr/mpi3mr_app.c +2 -2
index bff6377023979..d10c6afb7f9cd 100644
@@ -886,7 +886,7 @@ static int mpi3mr_build_nvme_prp(struct mpi3mr_ioc *mrioc,
 			 * each time through the loop.
 			 */
 			*prp_entry = cpu_to_le64(dma_addr);
-			if (*prp1_entry & sgemod_mask) {
+			if (*prp_entry & sgemod_mask) {
 				dprint_bsg_err(mrioc,
 				    "%s: PRP address collides with SGE modifier\n",
 				    __func__);
@@ -895,7 +895,7 @@ static int mpi3mr_build_nvme_prp(struct mpi3mr_ioc *mrioc,
 			*prp_entry &= ~sgemod_mask;
 			*prp_entry |= sgemod_val;
 			prp_entry++;
-			prp_entry_dma++;
+			prp_entry_dma += prp_size;
 		}
 
 		/*
Signature · 1 line
2.39.2
author maintainer
#140 lore raw

PATCH 139/224 scsi: mpi3mr: Bad drive in topology results kernel crash

In reply to Greg Kroah-Hartman

From: Ranjan Kumar <[email protected]>

[ Upstream commit 8e45183978d64699df639e795235433a60f35047 ]

When the SAS Transport Layer support is enabled and a device exposed to the OS by the driver fails INQUIRY commands, the driver frees up the memory allocated for an internal HBA port data structure. However, in some places, the reference to the freed memory is not cleared. When the firmware sends the Device Info change event for the same device again, the freed memory is accessed and that leads to memory corruption and OS crash.

---
 drivers/scsi/mpi3mr/mpi3mr_transport.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/scsi/mpi3mr/mpi3mr_transport.c +7 -5
index 90f61a0a8f4ef..5748bd9369ff7 100644
@@ -2355,15 +2355,16 @@ int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
 	tgtdev->host_exposed = 1;
 	if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle,
 	    sas_address_parent, hba_port)) {
-		tgtdev->host_exposed = 0;
 		retval = -1;
-	} else if ((!tgtdev->starget)) {
-		if (!mrioc->is_driver_loading)
+		} else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) {
 			mpi3mr_sas_port_remove(mrioc, sas_address,
 			    sas_address_parent, hba_port);
-		tgtdev->host_exposed = 0;
 		retval = -1;
 	}
+	if (retval) {
+		tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
+		tgtdev->host_exposed = 0;
+	}
 	return retval;
 }
 
@@ -2392,6 +2393,7 @@ void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
 	mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent,
 	    hba_port);
 	tgtdev->host_exposed = 0;
+	tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
 }
 
 /**
@@ -2448,7 +2450,7 @@ static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *
 
 		tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
 			    rphy->identify.sas_address, rphy);
-		if (tgtdev) {
+		if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) {
 			port_id =
 				tgtdev->dev_spec.sas_sata_inf.hba_port->port_id;
 			mpi3mr_tgtdev_put(tgtdev);
Signature · 1 line
2.39.2
author maintainer
#141 lore raw

PATCH 140/224 scsi: storvsc: Handle BlockSize change in Hyper-V VHD/VHDX file

In reply to Greg Kroah-Hartman

From: Michael Kelley <[email protected]>

[ Upstream commit 11d9874c4204a785f43d899a1ab12f9dc8d9de3e ]

Hyper-V uses a VHD or VHDX file on the host as the underlying storage for a virtual disk. The VHD/VHDX file format is a sparse format where real disk space on the host is assigned in chunks that the VHD/VHDX file format calls the BlockSize. This BlockSize is not to be confused with the 512-byte (or 4096-byte) sector size of the underlying storage device. The default block size for a new VHD/VHDX file is 32 Mbytes. When a guest VM touches any disk space within a 32 Mbyte chunk of the VHD/VHDX file, Hyper-V allocates 32 Mbytes of real disk space for that section of the VHD/VHDX. Similarly, if a discard operation is done that covers an entire 32 Mbyte chunk, Hyper-V will free the real disk space for that portion of the VHD/VHDX. This BlockSize is surfaced in Linux as the "discard_granularity" in /sys/block/sd<x>/queue, which makes sense.

Hyper-V also has differencing disks that can overlay a VHD/VHDX file to capture changes to the VHD/VHDX while preserving the original VHD/VHDX. One example of this differencing functionality is for VM snapshots. When a snapshot is created, a differencing disk is created. If the snapshot is rolled back, Hyper-V can just delete the differencing disk, and the VM will see the original disk contents at the time the snapshot was taken. Differencing disks are used in other scenarios as well.

The BlockSize for a differencing disk defaults to 2 Mbytes, not 32 Mbytes. The smaller default is used because changes to differencing disks are typically scattered all over, and Hyper-V doesn't want to allocate 32 Mbytes of real disk space for a stray write here or there. The smaller BlockSize provides more efficient use of real disk space.

When a differencing disk is added to a VHD/VHDX, Hyper-V reports UNIT_ATTENTION with a sense code indicating "Operating parameters have changed", because the value of discard_granularity should be changed to 2 Mbytes. When the differencing disk is removed, discard_granularity should be changed back to 32 Mbytes. However, current code simply reports a message from scsi_report_sense() and the value of /sys/block/sd<x>/queue/discard_granularity is not updated. The message isn't very actionable by a sysadmin.

Fix this by having the storvsc driver check for the sense code indicating that the underly VHD/VHDX block size has changed, and do a rescan of the device to pick up the new discard_granularity. With this change the entire transition to/from differencing disks is handled automatically and transparently, with no confusing messages being output.

---
 drivers/scsi/storvsc_drv.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/scsi/storvsc_drv.c +16 -0
index 55d6fb4526804..a0665bca54b99 100644
@@ -987,6 +987,22 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
 				goto do_work;
 			}
 
+			/*
+			 * Check for "Operating parameters have changed"
+			 * due to Hyper-V changing the VHD/VHDX BlockSize
+			 * when adding/removing a differencing disk. This
+			 * causes discard_granularity to change, so do a
+			 * rescan to pick up the new granularity. We don't
+			 * want scsi_report_sense() to output a message
+			 * that a sysadmin wouldn't know what to do with.
+			 */
+			if ((asc == 0x3f) && (ascq != 0x03) &&
+					(ascq != 0x0e)) {
+				process_err_fn = storvsc_device_scan;
+				set_host_byte(scmnd, DID_REQUEUE);
+				goto do_work;
+			}
+
 			/*
 			 * Otherwise, let upper layer deal with the
 			 * error when sense message is present
Signature · 1 line
2.39.2
author maintainer
#142 lore raw

PATCH 141/224 platform/x86: int3472: Add GPIOs to Surface Go 3 Board data

In reply to Greg Kroah-Hartman

From: Daniel Scally <[email protected]>

[ Upstream commit e8059d393158e927e36898aca89986a52025b9f3 ]

Add the INT347E GPIO lookup table to the board data for the Surface Go 3. This is necessary to allow the ov7251 IR camera to probe properly on that platform.

---
 drivers/platform/x86/intel/int3472/tps68470_board_data.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/platform/x86/intel/int3472/tps68470_board_data.c +3 -2
index 309eab9c05588..322237e056f32 100644
@@ -159,9 +159,10 @@ static const struct int3472_tps68470_board_data surface_go_tps68470_board_data =
 static const struct int3472_tps68470_board_data surface_go3_tps68470_board_data = {
 	.dev_name = "i2c-INT3472:01",
 	.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
-	.n_gpiod_lookups = 1,
+	.n_gpiod_lookups = 2,
 	.tps68470_gpio_lookup_tables = {
-		&surface_go_int347a_gpios
+		&surface_go_int347a_gpios,
+		&surface_go_int347e_gpios,
 	},
 };
 
Signature · 1 line
2.39.2
author maintainer
#143 lore raw

PATCH 142/224 net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990

In reply to Greg Kroah-Hartman

From: Enrico Sau <[email protected]>

[ Upstream commit 418383e6ed6b4624a54ec05c535f13d184fbf33b ]

Add quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE for Telit FE990 0x1081 composition in order to avoid bind error.

---
 drivers/net/usb/cdc_mbim.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/usb/cdc_mbim.c +5 -0
index c89639381eca3..cd4083e0b3b9e 100644
@@ -665,6 +665,11 @@ static const struct usb_device_id mbim_devs[] = {
 	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
 	},
 
+	/* Telit FE990 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1081, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
+	},
+
 	/* default entry */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_zlp,
Signature · 1 line
2.39.2
author maintainer
#144 lore raw

PATCH 143/224 net: usb: qmi_wwan: add Telit 0x1080 composition

In reply to Greg Kroah-Hartman

From: Enrico Sau <[email protected]>

[ Upstream commit 382e363d5bed0cec5807b35761d14e55955eee63 ]

Add the following Telit FE990 composition:

0x1080: tty, adb, rmnet, tty, tty, tty, tty

---
 drivers/net/usb/qmi_wwan.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
index 554d4e2a84a4e..2cc28af52ee25 100644
@@ -1363,6 +1363,7 @@ static const struct usb_device_id products[] = {
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)},	/* Telit FN980 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)},	/* Telit LN920 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)},	/* Telit FN990 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},	/* Telit ME910 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},	/* Telit ME910 dual modem */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
Signature · 1 line
2.39.2
author maintainer
#145 lore raw

PATCH 144/224 drm/amd/display: Update clock table to include highest clock setting

In reply to Greg Kroah-Hartman

From: Swapnil Patel <[email protected]>

[ Upstream commit 2d99a7ec25cf456cd3680eb314d6454138e5aa64 ]

[Why]
Currently, the clk manager matches SocVoltage with voltage from fused settings (dfPstate clock table). And then corresponding clocks are selected.

However in certain situations, this leads to clk manager not including at least one entry with highest supported clock setting.

[How]
Update the clk manager to include at least one entry with highest supported clock setting.

---
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c    | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +18 -1
index 24715ca2fa944..01383aac6b419 100644
@@ -529,6 +529,19 @@ static struct clk_bw_params vg_bw_params = {
 
 };
 
+static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
+{
+	uint32_t max = 0;
+	int i;
+
+	for (i = 0; i < num_clocks; ++i) {
+		if (clocks[i] > max)
+			max = clocks[i];
+	}
+
+	return max;
+}
+
 static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table,
 		unsigned int voltage)
 {
@@ -572,12 +585,16 @@ static void vg_clk_mgr_helper_populate_bw_params(
 
 	bw_params->clk_table.num_entries = j + 1;
 
-	for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
+	for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) {
 		bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
 		bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
 		bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
 		bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage);
 	}
+	bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
+	bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
+	bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
+	bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS);
 
 	bw_params->vram_type = bios_info->memory_type;
 	bw_params->num_channels = bios_info->ma_channel_number;
Signature · 1 line
2.39.2
author maintainer
#146 lore raw

PATCH 145/224 sh: sanitize the flags on sigreturn

In reply to Greg Kroah-Hartman

From: Al Viro <[email protected]>

[ Upstream commit 573b22ccb7ce9ab7f0539a2e11a9d3609a8783f5 ]

We fetch %SR value from sigframe; it might have been modified by signal handler, so we can't trust it with any bits that are not modifiable in user mode.

---
 arch/sh/include/asm/processor_32.h | 1 +
 arch/sh/kernel/signal_32.c         | 3 +++
 2 files changed, 4 insertions(+)
arch/sh/include/asm/processor_32.h +1 -0
index 27aebf1e75a20..3ef7adf739c83 100644
@@ -50,6 +50,7 @@
 #define SR_FD		0x00008000
 #define SR_MD		0x40000000
 
+#define SR_USER_MASK	0x00000303	// M, Q, S, T bits
 /*
  * DSP structure and data
  */
arch/sh/kernel/signal_32.c +3 -0
index 90f495d35db29..a6bfc6f374911 100644
@@ -115,6 +115,7 @@ static int
 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
 {
 	unsigned int err = 0;
+	unsigned int sr = regs->sr & ~SR_USER_MASK;
 
 #define COPY(x)		err |= __get_user(regs->x, &sc->sc_##x)
 			COPY(regs[1]);
@@ -130,6 +131,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
 	COPY(sr);	COPY(pc);
 #undef COPY
 
+	regs->sr = (regs->sr & SR_USER_MASK) | sr;
+
 #ifdef CONFIG_SH_FPU
 	if (boot_cpu_data.flags & CPU_HAS_FPU) {
 		int owned_fp;
Signature · 1 line
2.39.2
author maintainer
#147 lore raw

PATCH 146/224 drm/amdgpu: Fix call trace warning and hang when removing amdgpu device

In reply to Greg Kroah-Hartman

From: lyndonli <[email protected]>

[ Upstream commit 93bb18d2a873d2fa9625c8ea927723660a868b95 ]

On GPUs with RAS enabled, below call trace and hang are observed when shutting down device.

v2: use DRM device unplugged flag instead of shutdown flag as the check to prevent memory wipe in shutdown stage.

[ +0.000000] RIP: 0010:amdgpu_vram_mgr_fini+0x18d/0x1c0 [amdgpu] [ +0.000001] PKRU: 55555554
[ +0.000001] Call Trace:
[ +0.000001] <TASK>
[ +0.000002] amdgpu_ttm_fini+0x140/0x1c0 [amdgpu]
[ +0.000183] amdgpu_bo_fini+0x27/0xa0 [amdgpu]
[ +0.000184] gmc_v11_0_sw_fini+0x2b/0x40 [amdgpu]
[ +0.000163] amdgpu_device_fini_sw+0xb6/0x510 [amdgpu] [ +0.000152] amdgpu_driver_release_kms+0x16/0x30 [amdgpu] [ +0.000090] drm_dev_release+0x28/0x50 [drm]
[ +0.000016] devm_drm_dev_init_release+0x38/0x60 [drm] [ +0.000011] devm_action_release+0x15/0x20
[ +0.000003] release_nodes+0x40/0xc0
[ +0.000001] devres_release_all+0x9e/0xe0
[ +0.000001] device_unbind_cleanup+0x12/0x80
[ +0.000003] device_release_driver_internal+0xff/0x160 [ +0.000001] driver_detach+0x4a/0x90
[ +0.000001] bus_remove_driver+0x6c/0xf0
[ +0.000001] driver_unregister+0x31/0x50
[ +0.000001] pci_unregister_driver+0x40/0x90
[ +0.000003] amdgpu_exit+0x15/0x120 [amdgpu]

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +1 -1
index cfd78c4a45baa..4feedf518a191 100644
@@ -1312,7 +1312,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
 
 	if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
 	    !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
-	    adev->in_suspend || adev->shutdown)
+	    adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
 		return;
 
 	if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
Signature · 1 line
2.39.2
author maintainer
#148 lore raw

PATCH 147/224 drm/amd: Fix initialization mistake for NBIO 7.3.0

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

[ Upstream commit 1717cc5f2962a4652c76ed3858b499ccae6c277c ]

The same strapping initialization issue that happened on NBIO 7.5.1 appears to be happening on NBIO 7.3.0.
Apply the same fix to 7.3.0 as well.

Note: This workaround relies upon the integrated GPU being enabled in BIOS. If the integrated GPU is disabled in BIOS a different workaround will be required.

---
 drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c +9 -5
index 4b0d563c6522c..4ef1fa4603c8e 100644
@@ -382,11 +382,6 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
 		if (def != data)
 			WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3), data);
 		break;
-	case IP_VERSION(7, 5, 1):
-		data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
-		data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
-		WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
-		fallthrough;
 	default:
 		def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL));
 		data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL,
@@ -399,6 +394,15 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
 		break;
 	}
 
+	switch (adev->ip_versions[NBIO_HWIP][0]) {
+	case IP_VERSION(7, 3, 0):
+	case IP_VERSION(7, 5, 1):
+		data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
+		data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
+		WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
+		break;
+	}
+
 	if (amdgpu_sriov_vf(adev))
 		adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
 			regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
Signature · 1 line
2.39.2
author maintainer
#149 lore raw

PATCH 148/224 net/sched: act_mirred: better wording on protection against excessive stack growth

In reply to Greg Kroah-Hartman

From: Davide Caratti <[email protected]>

[ Upstream commit 78dcdffe0418ac8f3f057f26fe71ccf4d8ed851f ]

with commit e2ca070f89ec ("net: sched: protect against stack overflow in TC act_mirred"), act_mirred protected itself against excessive stack growth using per_cpu counter of nested calls to tcf_mirred_act(), and capping it to MIRRED_RECURSION_LIMIT. However, such protection does not detect recursion/loops in case the packet is enqueued to the backlog (for example, when the mirred target device has RPS or skb timestamping enabled). Change the wording from "recursion" to "nesting" to make it more clear to readers.

Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")

---
 net/sched/act_mirred.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
net/sched/act_mirred.c +8 -8
index b8ad6ae282c02..ded6ee054be14 100644
@@ -28,8 +28,8 @@
 static LIST_HEAD(mirred_list);
 static DEFINE_SPINLOCK(mirred_list_lock);
 
-#define MIRRED_RECURSION_LIMIT    4
-static DEFINE_PER_CPU(unsigned int, mirred_rec_level);
+#define MIRRED_NEST_LIMIT    4
+static DEFINE_PER_CPU(unsigned int, mirred_nest_level);
 
 static bool tcf_mirred_is_act_redirect(int action)
 {
@@ -224,7 +224,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 	struct sk_buff *skb2 = skb;
 	bool m_mac_header_xmit;
 	struct net_device *dev;
-	unsigned int rec_level;
+	unsigned int nest_level;
 	int retval, err = 0;
 	bool use_reinsert;
 	bool want_ingress;
@@ -235,11 +235,11 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 	int mac_len;
 	bool at_nh;
 
-	rec_level = __this_cpu_inc_return(mirred_rec_level);
-	if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) {
+	nest_level = __this_cpu_inc_return(mirred_nest_level);
+	if (unlikely(nest_level > MIRRED_NEST_LIMIT)) {
 		net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
 				     netdev_name(skb->dev));
-		__this_cpu_dec(mirred_rec_level);
+		__this_cpu_dec(mirred_nest_level);
 		return TC_ACT_SHOT;
 	}
 
@@ -308,7 +308,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 			err = tcf_mirred_forward(want_ingress, skb);
 			if (err)
 				tcf_action_inc_overlimit_qstats(&m->common);
-			__this_cpu_dec(mirred_rec_level);
+			__this_cpu_dec(mirred_nest_level);
 			return TC_ACT_CONSUMED;
 		}
 	}
@@ -320,7 +320,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 		if (tcf_mirred_is_act_redirect(m_eaction))
 			retval = TC_ACT_SHOT;
 	}
-	__this_cpu_dec(mirred_rec_level);
+	__this_cpu_dec(mirred_nest_level);
 
 	return retval;
 }
Signature · 1 line
2.39.2
author maintainer
#150 lore raw

PATCH 149/224 act_mirred: use the backlog for nested calls to mirred ingress

In reply to Greg Kroah-Hartman

From: Davide Caratti <[email protected]>

[ Upstream commit ca22da2fbd693b54dc8e3b7b54ccc9f7e9ba3640 ]

William reports kernel soft-lockups on some OVS topologies when TC mirred egress->ingress action is hit by local TCP traffic [1].
The same can also be reproduced with SCTP (thanks Xin for verifying), when client and server reach themselves through mirred egress to ingress, and one of the two peers sends a "heartbeat" packet (from within a timer).

Enqueueing to backlog proved to fix this soft lockup; however, as Cong noticed [2], we should preserve - when possible - the current mirred behavior that counts as "overlimits" any eventual packet drop subsequent to the mirred forwarding action [3]. A compromise solution might use the backlog only when tcf_mirred_act() has a nest level greater than one:
change tcf_mirred_forward() accordingly.

Also, add a kselftest that can reproduce the lockup and verifies TC mirred ability to account for further packet drops after TC mirred egress->ingress (when the nest level is 1).

[1] https://lore.kernel.org/netdev/33dc43f587ec1388ba456b4915c75f02a8aae226.1663945716.git.dcaratti@redhat.com/
[2] https://lore.kernel.org/netdev/Y0w%[email protected]/
[3] such behavior is not guaranteed: for example, if RPS or skb RX
timestamping is enabled on the mirred target device, the kernel
can defer receiving the skb and return NET_RX_SUCCESS inside
tcf_mirred_forward().

---
 net/sched/act_mirred.c                        |  7 +++
 .../selftests/net/forwarding/tc_actions.sh    | 49 ++++++++++++++++++-
 2 files changed, 55 insertions(+), 1 deletion(-)
net/sched/act_mirred.c +7 -0
index ded6ee054be14..baeae5e5c8f0c 100644
@@ -205,12 +205,19 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 	return err;
 }
 
+static bool is_mirred_nested(void)
+{
+	return unlikely(__this_cpu_read(mirred_nest_level) > 1);
+}
+
 static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb)
 {
 	int err;
 
 	if (!want_ingress)
 		err = tcf_dev_queue_xmit(skb, dev_queue_xmit);
+	else if (is_mirred_nested())
+		err = netif_rx(skb);
 	else
 		err = netif_receive_skb(skb);
 
tools/testing/selftests/net/forwarding/tc_actions.sh +48 -1

61 lines not on this page · raw message

Signature · 1 line
2.39.2
author maintainer
#151 lore raw

PATCH 150/224 cifs: lock chan_lock outside match_session

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit 2f4e429c846972c8405951a9ff7a82aceeca7461 upstream.

Coverity had rightly indicated a possible deadlock due to chan_lock being done inside match_session. All callers of match_* functions should pick up the necessary locks and call them.

Fixes 724244cdb382 ("cifs: protect session channel fields with chan_lock")
---
 fs/cifs/connect.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
fs/cifs/connect.c +7 -6
@@ -1774,7 +1774,7 @@ out_err:
 	return ERR_PTR(rc);
 }
 
-/* this function must be called with ses_lock held */
+/* this function must be called with ses_lock and chan_lock held */
 static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
 {
 	if (ctx->sectype != Unspecified &&
@@ -1785,12 +1785,8 @@ static int match_session(struct cifs_ses
 	 * If an existing session is limited to less channels than
 	 * requested, it should not be reused
 	 */
-	spin_lock(&ses->chan_lock);
-	if (ses->chan_max < ctx->max_channels) {
-		spin_unlock(&ses->chan_lock);
+	if (ses->chan_max < ctx->max_channels)
 		return 0;
-	}
-	spin_unlock(&ses->chan_lock);
 
 	switch (ses->sectype) {
 	case Kerberos:
@@ -1918,10 +1914,13 @@ cifs_find_smb_ses(struct TCP_Server_Info
 			spin_unlock(&ses->ses_lock);
 			continue;
 		}
+		spin_lock(&ses->chan_lock);
 		if (!match_session(ses, ctx)) {
+			spin_unlock(&ses->chan_lock);
 			spin_unlock(&ses->ses_lock);
 			continue;
 		}
+		spin_unlock(&ses->chan_lock);
 		spin_unlock(&ses->ses_lock);
 
 		++ses->ses_count;
@@ -2742,6 +2741,7 @@ cifs_match_super(struct super_block *sb,
 
 	spin_lock(&tcp_srv->srv_lock);
 	spin_lock(&ses->ses_lock);
+	spin_lock(&ses->chan_lock);
 	spin_lock(&tcon->tc_lock);
 	if (!match_server(tcp_srv, ctx) ||
 	    !match_session(ses, ctx) ||
@@ -2754,6 +2754,7 @@ cifs_match_super(struct super_block *sb,
 	rc = compare_mount_options(sb, mnt_data);
 out:
 	spin_unlock(&tcon->tc_lock);
+	spin_unlock(&ses->chan_lock);
 	spin_unlock(&ses->ses_lock);
 	spin_unlock(&tcp_srv->srv_lock);
 
author maintainer
#152 lore raw

PATCH 151/224 cifs: append path to open_enter trace event

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit fddc6ccc487e5de07b98df8d04118d5dcb5e0407 upstream.

We do not dump the file path for smb3_open_enter ftrace calls, which is a severe handicap while debugging using ftrace evens. This change adds that info.

Unfortunately, we're not updating the path in open params in many places; which I had to do as a part of this change. SMB2_open gets path in utf16 format, but it's easier of path is supplied as char pointer in oparms.

---
 fs/cifs/cached_dir.c |    1 +
 fs/cifs/link.c       |    2 ++
 fs/cifs/smb2inode.c  |    1 +
 fs/cifs/smb2ops.c    |   11 +++++++++++
 fs/cifs/smb2pdu.c    |    4 ++--
 fs/cifs/trace.h      |   12 ++++++++----
 6 files changed, 25 insertions(+), 6 deletions(-)
fs/cifs/cached_dir.c +1 -0
@@ -184,6 +184,7 @@ int open_cached_dir(unsigned int xid, st
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
fs/cifs/link.c +2 -0
@@ -360,6 +360,7 @@ smb3_query_mf_symlink(unsigned int xid,
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
 		.cifs_sb = cifs_sb,
+		.path = path,
 		.desired_access = GENERIC_READ,
 		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
 		.disposition = FILE_OPEN,
@@ -427,6 +428,7 @@ smb3_create_mf_symlink(unsigned int xid,
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
 		.cifs_sb = cifs_sb,
+		.path = path,
 		.desired_access = GENERIC_WRITE,
 		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
 		.disposition = FILE_CREATE,
fs/cifs/smb2inode.c +1 -0
@@ -106,6 +106,7 @@ static int smb2_compound_op(const unsign
 
 	vars->oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = full_path,
 		.desired_access = desired_access,
 		.disposition = create_disposition,
 		.create_options = cifs_create_options(cifs_sb, create_options),
fs/cifs/smb2ops.c +11 -0
@@ -731,6 +731,7 @@ smb3_qfs_tcon(const unsigned int xid, st
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = "",
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -774,6 +775,7 @@ smb2_qfs_tcon(const unsigned int xid, st
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = "",
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -821,6 +823,7 @@ smb2_is_path_accessible(const unsigned i
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = full_path,
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -1105,6 +1108,7 @@ smb2_set_ea(const unsigned int xid, stru
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.desired_access = FILE_WRITE_EA,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -2096,6 +2100,7 @@ smb3_notify(const unsigned int xid, stru
 	tcon = cifs_sb_master_tcon(cifs_sb);
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -2168,6 +2173,7 @@ smb2_query_dir_first(const unsigned int
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -2500,6 +2506,7 @@ smb2_query_info_compound(const unsigned
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.desired_access = desired_access,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -2634,6 +2641,7 @@ smb311_queryfs(const unsigned int xid, s
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = "",
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, 0),
@@ -2928,6 +2936,7 @@ smb2_query_symlink(const unsigned int xi
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = full_path,
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, create_options),
@@ -3068,6 +3077,7 @@ smb2_query_reparse_tag(const unsigned in
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = full_path,
 		.desired_access = FILE_READ_ATTRIBUTES,
 		.disposition = FILE_OPEN,
 		.create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
@@ -3208,6 +3218,7 @@ get_smb2_acl_by_path(struct cifs_sb_info
 
 	oparms = (struct cifs_open_parms) {
 		.tcon = tcon,
+		.path = path,
 		.desired_access = READ_CONTROL,
 		.disposition = FILE_OPEN,
 		/*
fs/cifs/smb2pdu.c +2 -2
@@ -2742,7 +2742,7 @@ int smb311_posix_mkdir(const unsigned in
 	rqst.rq_nvec = n_iov;
 
 	/* no need to inc num_remote_opens because we close it just below */
-	trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
+	trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE,
 				    FILE_WRITE_ATTRIBUTES);
 	/* resource #4: response buffer */
 	rc = cifs_send_recv(xid, ses, server,
@@ -3010,7 +3010,7 @@ SMB2_open(const unsigned int xid, struct
 	if (rc)
 		goto creat_exit;
 
-	trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
+	trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path,
 		oparms->create_options, oparms->desired_access);
 
 	rc = cifs_send_recv(xid, ses, server,
fs/cifs/trace.h +8 -4
@@ -701,13 +701,15 @@ DECLARE_EVENT_CLASS(smb3_open_enter_clas
 	TP_PROTO(unsigned int xid,
 		__u32	tid,
 		__u64	sesid,
+		const char *full_path,
 		int	create_options,
 		int	desired_access),
-	TP_ARGS(xid, tid, sesid, create_options, desired_access),
+	TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access),
 	TP_STRUCT__entry(
 		__field(unsigned int, xid)
 		__field(__u32, tid)
 		__field(__u64, sesid)
+		__string(path, full_path)
 		__field(int, create_options)
 		__field(int, desired_access)
 	),
@@ -715,11 +717,12 @@ DECLARE_EVENT_CLASS(smb3_open_enter_clas
 		__entry->xid = xid;
 		__entry->tid = tid;
 		__entry->sesid = sesid;
+		__assign_str(path, full_path);
 		__entry->create_options = create_options;
 		__entry->desired_access = desired_access;
 	),
-	TP_printk("xid=%u sid=0x%llx tid=0x%x cr_opts=0x%x des_access=0x%x",
-		__entry->xid, __entry->sesid, __entry->tid,
+	TP_printk("xid=%u sid=0x%llx tid=0x%x path=%s cr_opts=0x%x des_access=0x%x",
+		__entry->xid, __entry->sesid, __entry->tid, __get_str(path),
 		__entry->create_options, __entry->desired_access)
 )
 
@@ -728,9 +731,10 @@ DEFINE_EVENT(smb3_open_enter_class, smb3
 	TP_PROTO(unsigned int xid,		\
 		__u32	tid,			\
 		__u64	sesid,			\
+		const char *full_path,		\
 		int	create_options,		\
 		int	desired_access),	\
-	TP_ARGS(xid, tid, sesid, create_options, desired_access))
+	TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access))
 
 DEFINE_SMB3_OPEN_ENTER_EVENT(open_enter);
 DEFINE_SMB3_OPEN_ENTER_EVENT(posix_mkdir_enter);
author maintainer
#153 lore raw

PATCH 152/224 cifs: do not poll server interfaces too regularly

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit 072a28c8907c841f7d4b56c78bce46d3ee211e73 upstream.

We have the server interface list hanging off the tcon structure today for reasons unknown. So each tcon which is connected to a file server can query them separately, which is really unnecessary. To avoid this, in the query function, we will check the time of last update of the interface list, and avoid querying the server if it is within a certain range.

---
 fs/cifs/smb2ops.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
fs/cifs/smb2ops.c +14 -0
@@ -530,6 +530,14 @@ parse_server_interfaces(struct network_i
 	p = buf;
 
 	spin_lock(&ses->iface_lock);
+	/* do not query too frequently, this time with lock held */
+	if (ses->iface_last_update &&
+	    time_before(jiffies, ses->iface_last_update +
+			(SMB_INTERFACE_POLL_INTERVAL * HZ))) {
+		spin_unlock(&ses->iface_lock);
+		return 0;
+	}
+
 	/*
 	 * Go through iface_list and do kref_put to remove
 	 * any unused ifaces. ifaces in use will be removed
@@ -696,6 +704,12 @@ SMB3_request_interfaces(const unsigned i
 	struct network_interface_info_ioctl_rsp *out_buf = NULL;
 	struct cifs_ses *ses = tcon->ses;
 
+	/* do not query too frequently */
+	if (ses->iface_last_update &&
+	    time_before(jiffies, ses->iface_last_update +
+			(SMB_INTERFACE_POLL_INTERVAL * HZ)))
+		return 0;
+
 	rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
 			FSCTL_QUERY_NETWORK_INTERFACE_INFO,
 			NULL /* no data input */, 0 /* no data input */,
author maintainer
#154 lore raw

PATCH 153/224 cifs: empty interface list when server doesnt support query interfaces

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit 896cd316b841053f6df95ab77b5f1322c16a8e18 upstream.

When querying server interfaces returns -EOPNOTSUPP, clear the list of interfaces. Assumption is that multichannel would be disabled too.

---
 fs/cifs/smb2ops.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/smb2ops.c +1 -1
@@ -717,7 +717,7 @@ SMB3_request_interfaces(const unsigned i
 	if (rc == -EOPNOTSUPP) {
 		cifs_dbg(FYI,
 			 "server does not support query network interfaces\n");
-		goto out;
+		ret_data_len = 0;
 	} else if (rc != 0) {
 		cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
 		goto out;
author maintainer
#155 lore raw

PATCH 154/224 cifs: dump pending mids for all channels in DebugData

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit d12bc6d26f92c51b28e8f4a146ffcc630b688198 upstream.

Currently, we only dump the pending mid information only on the primary channel in /proc/fs/cifs/DebugData. If multichannel is active, we do not print the pending MID list on secondary channels.

This change will dump the pending mids for all the channels based on server->conn_id.

---
 fs/cifs/cifs_debug.c |   41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)
fs/cifs/cifs_debug.c +27 -14
@@ -215,6 +215,7 @@ static int cifs_debug_data_proc_show(str
 {
 	struct mid_q_entry *mid_entry;
 	struct TCP_Server_Info *server;
+	struct TCP_Server_Info *chan_server;
 	struct cifs_ses *ses;
 	struct cifs_tcon *tcon;
 	struct cifs_server_iface *iface;
@@ -458,23 +459,35 @@ skip_rdma:
 					seq_puts(m, "\t\t[CONNECTED]\n");
 			}
 			spin_unlock(&ses->iface_lock);
+
+			seq_puts(m, "\n\n\tMIDs: ");
+			spin_lock(&ses->chan_lock);
+			for (j = 0; j < ses->chan_count; j++) {
+				chan_server = ses->chans[j].server;
+				if (!chan_server)
+					continue;
+
+				if (list_empty(&chan_server->pending_mid_q))
+					continue;
+
+				seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
+					   chan_server->conn_id);
+				spin_lock(&chan_server->mid_lock);
+				list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
+					seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
+						   mid_entry->mid_state,
+						   le16_to_cpu(mid_entry->command),
+						   mid_entry->pid,
+						   mid_entry->callback_data,
+						   mid_entry->mid);
+				}
+				spin_unlock(&chan_server->mid_lock);
+			}
+			spin_unlock(&ses->chan_lock);
+			seq_puts(m, "\n--\n");
 		}
 		if (i == 0)
 			seq_printf(m, "\n\t\t[NONE]");
-
-		seq_puts(m, "\n\n\tMIDs: ");
-		spin_lock(&server->mid_lock);
-		list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
-			seq_printf(m, "\n\tState: %d com: %d pid:"
-					" %d cbdata: %p mid %llu\n",
-					mid_entry->mid_state,
-					le16_to_cpu(mid_entry->command),
-					mid_entry->pid,
-					mid_entry->callback_data,
-					mid_entry->mid);
-		}
-		spin_unlock(&server->mid_lock);
-		seq_printf(m, "\n--\n");
 	}
 	if (c == 0)
 		seq_printf(m, "\n\t[NONE]");
author maintainer
#156 lore raw

PATCH 155/224 cifs: print session id while listing open files

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

commit 175b54abc443b6965e9379b71ec05f7c73c192e9 upstream.

In the output of /proc/fs/cifs/open_files, we only print the tree id for the tcon of each open file. It becomes difficult to know which tcon these files belong to with just the tree id.

This change dumps ses id in addition to all other data today.

---
 fs/cifs/cifs_debug.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
fs/cifs/cifs_debug.c +3 -2
@@ -175,7 +175,7 @@ static int cifs_debug_files_proc_show(st
 
 	seq_puts(m, "# Version:1\n");
 	seq_puts(m, "# Format:\n");
-	seq_puts(m, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
+	seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
 #ifdef CONFIG_CIFS_DEBUG2
 	seq_printf(m, " <filename> <mid>\n");
 #else
@@ -188,8 +188,9 @@ static int cifs_debug_files_proc_show(st
 				spin_lock(&tcon->open_file_lock);
 				list_for_each_entry(cfile, &tcon->openFileList, tlist) {
 					seq_printf(m,
-						"0x%x 0x%llx 0x%x %d %d %d %pd",
+						"0x%x 0x%llx 0x%llx 0x%x %d %d %d %pd",
 						tcon->tid,
+						ses->Suid,
 						cfile->fid.persistent_fid,
 						cfile->f_flags,
 						cfile->count,
author maintainer
#157 lore raw

PATCH 156/224 cifs: fix dentry lookups in directory handle cache

In reply to Greg Kroah-Hartman

From: Paulo Alcantara <[email protected]>

commit be4fde79812f02914e350bde0bc4cfeae8429378 upstream.

Get rid of any prefix paths in @path before lookup_positive_unlocked() as it will call ->lookup() which already adds those prefix paths through build_path_from_dentry().

This has caused a performance regression when mounting shares with a prefix path where readdir(2) would end up retrying several times to open bad directory names that contained duplicate prefix paths.

Fix this by skipping any prefix paths in @path before calling lookup_positive_unlocked().

Fixes e4029e072673 ("cifs: find and use the dentry for cached non-root directories also")
---
 fs/cifs/cached_dir.c |   36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
fs/cifs/cached_dir.c +34 -2
@@ -99,6 +99,23 @@ path_to_dentry(struct cifs_sb_info *cifs
 	return dentry;
 }
 
+static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
+				  const char *path)
+{
+	size_t len = 0;
+
+	if (!*path)
+		return path;
+
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+	    cifs_sb->prepath) {
+		len = strlen(cifs_sb->prepath) + 1;
+		if (unlikely(len > strlen(path)))
+			return ERR_PTR(-EINVAL);
+	}
+	return path + len;
+}
+
 /*
  * Open the and cache a directory handle.
  * If error then *cfid is not initialized.
@@ -125,6 +142,7 @@ int open_cached_dir(unsigned int xid, st
 	struct dentry *dentry = NULL;
 	struct cached_fid *cfid;
 	struct cached_fids *cfids;
+	const char *npath;
 
 	if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache ||
 	    is_smb1_server(tcon->ses->server))
@@ -161,6 +179,20 @@ int open_cached_dir(unsigned int xid, st
 	}
 
 	/*
+	 * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
+	 * calling ->lookup() which already adds those through
+	 * build_path_from_dentry().  Also, do it earlier as we might reconnect
+	 * below when trying to send compounded request and then potentially
+	 * having a different prefix path (e.g. after DFS failover).
+	 */
+	npath = path_no_prefix(cifs_sb, path);
+	if (IS_ERR(npath)) {
+		rc = PTR_ERR(npath);
+		kfree(utf16_path);
+		return rc;
+	}
+
+	/*
 	 * We do not hold the lock for the open because in case
 	 * SMB2_open needs to reconnect.
 	 * This is safe because no other thread will be able to get a ref
@@ -252,10 +284,10 @@ int open_cached_dir(unsigned int xid, st
 				(char *)&cfid->file_all_info))
 		cfid->file_all_info_is_valid = true;
 
-	if (!path[0])
+	if (!npath[0])
 		dentry = dget(cifs_sb->root);
 	else {
-		dentry = path_to_dentry(cifs_sb, path);
+		dentry = path_to_dentry(cifs_sb, npath);
 		if (IS_ERR(dentry)) {
 			rc = -ENOENT;
 			goto oshr_free;
author maintainer
#158 lore raw

PATCH 157/224 x86/fpu/xstate: Prevent false-positive warning in __copy_xstate_uabi_buf()

In reply to Greg Kroah-Hartman

From: Chang S. Bae <[email protected]>

commit b15888840207c2bfe678dd1f68a32db54315e71f upstream.

__copy_xstate_to_uabi_buf() copies either from the tasks XSAVE buffer or from init_fpstate into the ptrace buffer. Dynamic features, like XTILEDATA, have an all zeroes init state and are not saved in init_fpstate, which means the corresponding bit is not set in the xfeatures bitmap of the init_fpstate header.

But __copy_xstate_to_uabi_buf() retrieves addresses for both the tasks xstate and init_fpstate unconditionally via __raw_xsave_addr().

So if the tasks XSAVE buffer has a dynamic feature set, then the address retrieval for init_fpstate triggers the warning in __raw_xsave_addr() which checks the feature bit in the init_fpstate header.

Remove the address retrieval from init_fpstate for extended features. They have an all zeroes init state so init_fpstate has zeros for them. Then zeroing the user buffer for the init state is the same as copying them from init_fpstate.

---
 arch/x86/kernel/fpu/xstate.c |   30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
arch/x86/kernel/fpu/xstate.c +14 -16
@@ -1118,21 +1118,20 @@ void __copy_xstate_to_uabi_buf(struct me
 	zerofrom = offsetof(struct xregs_state, extended_state_area);
 
 	/*
-	 * The ptrace buffer is in non-compacted XSAVE format.  In
-	 * non-compacted format disabled features still occupy state space,
-	 * but there is no state to copy from in the compacted
-	 * init_fpstate. The gap tracking will zero these states.
+	 * This 'mask' indicates which states to copy from fpstate.
+	 * Those extended states that are not present in fpstate are
+	 * either disabled or initialized:
+	 *
+	 * In non-compacted format, disabled features still occupy
+	 * state space but there is no state to copy from in the
+	 * compacted init_fpstate. The gap tracking will zero these
+	 * states.
+	 *
+	 * The extended features have an all zeroes init state. Thus,
+	 * remove them from 'mask' to zero those features in the user
+	 * buffer instead of retrieving them from init_fpstate.
 	 */
-	mask = fpstate->user_xfeatures;
-
-	/*
-	 * Dynamic features are not present in init_fpstate. When they are
-	 * in an all zeros init state, remove those from 'mask' to zero
-	 * those features in the user buffer instead of retrieving them
-	 * from init_fpstate.
-	 */
-	if (fpu_state_size_dynamic())
-		mask &= (header.xfeatures | xinit->header.xcomp_bv);
+	mask = header.xfeatures;
 
 	for_each_extended_xfeature(i, mask) {
 		/*
@@ -1151,9 +1150,8 @@ void __copy_xstate_to_uabi_buf(struct me
 			pkru.pkru = pkru_val;
 			membuf_write(&to, &pkru, sizeof(pkru));
 		} else {
-			copy_feature(header.xfeatures & BIT_ULL(i), &to,
+			membuf_write(&to,
 				     __raw_xsave_addr(xsave, i),
-				     __raw_xsave_addr(xinit, i),
 				     xstate_sizes[i]);
 		}
 		/*