Skip to contentSkip to conversation

6.5.13-rc1 review

PATCH In review Greg Kroah-Hartman 6 participants 498 messages Nov 24, 2023 – Nov 25, 2023 Page 1 of 4

Subsystems (7)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.5.13-rc1 review

This is the start of the stable review cycle for the 6.5.13 release. There are 491 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 Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.

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

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

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

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 6.5.13-rc1

Steven Rostedt (Google) <[email protected]>
tracing: Have trace_event_file have ref counters

Michael Ellerman <[email protected]>
powerpc/powernv: Fix fortify source warnings in opal-prd.c

Lewis Huang <[email protected]>
drm/amd/display: Change the DMCUB mailbox memory location from FB to inbox

Tianci Yin <[email protected]>
drm/amd/display: Enable fast plane updates on DCN3.2 and above

Mario Limonciello <[email protected]>
drm/amd/display: fix a NULL pointer dereference in amdgpu_dm_i2c_xfer()

Fangzhi Zuo <[email protected]>
drm/amd/display: Fix DSC not Enabled on Direct MST Sink

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Guard against invalid RPTR/WPTR being set

Felix Kuehling <[email protected]>
drm/amdgpu: Fix possible null pointer dereference

Christian König <[email protected]>
drm/amdgpu: lower CS errors to debug severity

Christian König <[email protected]>
drm/amdgpu: fix error handling in amdgpu_bo_list_get()

Christian König <[email protected]>
drm/amdgpu: fix error handling in amdgpu_vm_init

Alex Deucher <[email protected]>
drm/amdgpu: don't use ATRM for external devices

Alex Deucher <[email protected]>
drm/amdgpu: add a retry for IP discovery init

Tim Huang <[email protected]>
drm/amdgpu: fix GRBM read timeout when do mes_self_test

Alex Deucher <[email protected]>
drm/amdgpu: don't use pci_is_thunderbolt_attached()

Alex Deucher <[email protected]>
drm/amdgpu/smu13: drop compute workload workaround

Ma Jun <[email protected]>
drm/amd/pm: Fix error of MACO flag setting code

Nirmoy Das <[email protected]>
drm/i915: Flush WC GGTT only on required platforms

Kunwu Chan <[email protected]>
drm/i915: Fix potential spectre vulnerability

Ville Syrjälä <[email protected]>
drm/i915: Bump GLK CDCLK frequency when driving multiple pipes

Chaitanya Kumar Borah <[email protected]>
drm/i915/mtl: Support HBR3 rate with C10 phy and eDP in MTL

Jani Nikula <[email protected]>

    drm: bridge: it66121: ->get_edid callback must not return err pointers

Bas Nieuwenhuizen <[email protected]>
drm/amd/pm: Handle non-terminated overdrive commands.

Brian Foster <[email protected]>
ext4: fix racy may inline data check in dio write

Jan Kara <[email protected]>
ext4: properly sync file size update after O_SYNC direct IO

Kemeng Shi <[email protected]>
ext4: add missed brelse in update_backups

Kemeng Shi <[email protected]>
ext4: remove gdb backup copy for meta bg in setup_new_flex_group_blocks

Zhang Yi <[email protected]>
ext4: correct the start block of counting reserved clusters

Kemeng Shi <[email protected]>
ext4: correct return value of ext4_convert_meta_bg

Ojaswin Mujoo <[email protected]>
ext4: mark buffer new if it is unwritten to avoid stale data exposure

Kemeng Shi <[email protected]>
ext4: correct offset of gdb backup in non meta_bg group to update_backups

Max Kellermann <[email protected]>
ext4: apply umask if ACL support is disabled

Zhang Yi <[email protected]>
ext4: make sure allocate pending entry not fail

Baokun Li <[email protected]>
ext4: fix race between writepages and remount

Heiner Kallweit <[email protected]>
Revert "net: r8169: Disable multicast filter for RTL8168H and RTL8107E"

Andrey Konovalov <[email protected]>
media: qcom: camss: Fix csid-gen2 for test pattern generator

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix invalid clock enable bit disjunction

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix set CSI2_RX_CFG1_VC_MODE when VC is greater than 3

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix missing vfe_lite clocks check

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix VFE-480 vfe_disable_output()

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix VFE-17x vfe_disable_output()

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix vfe_get() error jump

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix pm_domain_on sequence in probe

Victor Shih <[email protected]>
mmc: sdhci-pci-gli: GL9750: Mask the replay timer timeout of AER

ChunHao Lin <[email protected]>
r8169: add handling DASH when DASH is disabled

ChunHao Lin <[email protected]>
r8169: fix network lost after resume on DASH systems

Paolo Abeni <[email protected]>
selftests: mptcp: fix fastclose with csum failure

Paolo Abeni <[email protected]>
mptcp: fix setsockopt(IP_TOS) subflow locking

Geliang Tang <[email protected]>
mptcp: add validity check for sending RM_ADDR

Paolo Abeni <[email protected]>
mptcp: deal with large GSO size

Roman Gushchin <[email protected]>
mm: kmem: drop __GFP_NOFAIL when allocating objcg vectors

Stefan Roesch <[email protected]>
mm: fix for negative counter: nr_file_hugepages

Victor Shih <[email protected]>
mmc: sdhci-pci-gli: A workaround to allow GL9750 to enter ASPM L1.2

Nam Cao <[email protected]>
riscv: kprobes: allow writing to x0

Song Shuai <[email protected]>
riscv: correct pt_level name via pgtable_l5/4_enabled

Song Shuai <[email protected]>
riscv: mm: Update the comment of CONFIG_PAGE_OFFSET

Nam Cao <[email protected]>
riscv: put interrupt entries into .irqentry.text

Minda Chen <[email protected]>
riscv: Using TOOLCHAIN_HAS_ZIHINTPAUSE marco replace zihintpause

Nathan Chancellor <[email protected]>
LoongArch: Mark __percpu functions as always inline

Chuck Lever <[email protected]>
NFSD: Update nfsd_cache_append() to use xdr_stream

Mahmoud Adam <[email protected]>
nfsd: fix file memleak on client_opens_release

Mikulas Patocka <[email protected]>
dm-verity: don't use blocking calls from tasklets

Mikulas Patocka <[email protected]>
dm-bufio: fix no-sleep mode

Jani Nikula <[email protected]>

    drm/mediatek/dp: fix memory leak on ->get_edid callback error path

Jani Nikula <[email protected]>

    drm/mediatek/dp: fix memory leak on ->get_edid callback audio detection

Sakari Ailus <[email protected]>
media: ccs: Correctly initialise try compose rectangle

Vikash Garodia <[email protected]>
media: venus: hfi: add checks to handle capabilities from firmware

Vikash Garodia <[email protected]>
media: venus: hfi: fix the check to handle session buffer requirement

Vikash Garodia <[email protected]>
media: venus: hfi_parser: Add check to keep the number of codecs within range

Sean Young <[email protected]>
media: sharp: fix sharp encoding

Sean Young <[email protected]>
media: lirc: drop trailing space from scancode transmit

Jaegeuk Kim <[email protected]>
f2fs: split initial and dynamic conditions for extent_cache

Su Hui <[email protected]>
f2fs: avoid format-overflow warning

Jaegeuk Kim <[email protected]>
f2fs: set the default compress_level on ioctl

Jaegeuk Kim <[email protected]>
f2fs: do not return EFSCORRUPTED, but try to run online repair

Heiner Kallweit <[email protected]>
i2c: i801: fix potential race in i801_block_transaction_byte_by_byte

Andreas Gruenbacher <[email protected]>
gfs2: don't withdraw if init_threads() got interrupted

Klaus Kudielka <[email protected]>
net: phylink: initialize carrier state at creation

Alexander Sverdlin <[email protected]>
net: dsa: lan9303: consequently nested-lock physical MDIO

Andrew Lunn <[email protected]>
net: ethtool: Fix documentation of ethtool_sprintf()

Harald Freudenberger <[email protected]>
s390/ap: fix AP bus crash on early config change callback invocation

Tam Nguyen <[email protected]>
i2c: designware: Disable TX_EMPTY irq while waiting for block length byte

Darren Hart <[email protected]>
sbsa_gwdt: Calculate timeout with 64-bit math

Ondrej Mosnacek <[email protected]>
lsm: fix default return value for inode_getsecctx

Ondrej Mosnacek <[email protected]>
lsm: fix default return value for vm_enough_memory

Robert Marko <[email protected]>
Revert "i2c: pxa: move to generic GPIO recovery"

Johnathan Mantey <[email protected]>
Revert ncsi: Propagate carrier gain/loss events to the NCSI controller

Stefan Binding <[email protected]>
ALSA: hda/realtek: Add quirks for HP Laptops

Matus Malych <[email protected]>
ALSA: hda/realtek: Enable Mute LED on HP 255 G10

Chandradeep Dey <[email protected]>
ALSA: hda/realtek - Enable internal speaker of ASUS K6500ZC

Kailang Yang <[email protected]>
ALSA: hda/realtek - Add Dell ALC295 to pin fall back table

Eymen Yigit <[email protected]>
ALSA: hda/realtek: Enable Mute LED on HP 255 G8

Takashi Iwai <[email protected]>
ALSA: info: Fix potential deadlock at disconnection

Naohiro Aota <[email protected]>
btrfs: zoned: wait for data BG to be finished on direct IO allocation

Dave Chinner <[email protected]>
xfs: recovery should not clear di_flushiter unconditionally

David Howells <[email protected]>
cifs: Fix encryption of cleared, but unset rq_iter data buffers

Shyam Prasad N <[email protected]>
cifs: do not reset chan_max if multichannel is not supported at mount

Shyam Prasad N <[email protected]>
cifs: force interface update before a fresh session setup

Shyam Prasad N <[email protected]>
cifs: reconnect helper should set reconnect for the right channel

Paulo Alcantara <[email protected]>
smb: client: fix potential deadlock when releasing mids

Paulo Alcantara <[email protected]>
smb: client: fix use-after-free in smb2_query_info_compound()

Paulo Alcantara <[email protected]>
smb: client: fix use-after-free bug in cifs_debug_data_proc_show()

Steve French <[email protected]>
smb3: fix caching of ctime on setxattr

Steve French <[email protected]>
smb3: allow dumping session and tcon id to improve stats analysis and debugging

Steve French <[email protected]>
smb3: fix touch -h of symlink

Steve French <[email protected]>
smb3: fix creating FIFOs when mounting with "sfu" mount option

Jeff Layton <[email protected]>
fs: add ctime accessors infrastructure

Basavaraj Natikar <[email protected]>
xhci: Enable RPM on controllers that support low-power states

Helge Deller <[email protected]>
parisc/power: Fix power soft-off when running on qemu

Helge Deller <[email protected]>
parisc/pgtable: Do not drop upper 5 address bits of physical address

Helge Deller <[email protected]>
parisc: Prevent booting 64-bit kernels on PA1.x machines

Zi Yan <[email protected]>
mm/hugetlb: use nth_page() in place of direct struct page manipulation

Peter Xu <[email protected]>
mm/hugetlb: prepare hugetlb_follow_page_mask() for FOLL_PIN

Joel Fernandes (Google) <[email protected]>
rcutorture: Fix stuttering races and other issues

Paul E. McKenney <[email protected]>
torture: Make torture_hrtimeout_ns() take an hrtimer mode parameter

Paul E. McKenney <[email protected]>
torture: Move stutter_wait() timeouts to hrtimers

Paul E. McKenney <[email protected]>
torture: Make torture_hrtimeout_*() use TASK_IDLE

Dietmar Eggemann <[email protected]>
torture: Add lock_torture writer_fifo module parameter

Paul E. McKenney <[email protected]>
torture: Add a kthread-creation callback to _torture_create_kthread()

Lukas Wunner <[email protected]>
PCI: Lengthen reset delay for VideoPropulsion Torrent QN16e card

Lizhi Hou <[email protected]>
PCI: Add quirks to generate device tree node for Xilinx Alveo U50

Lizhi Hou <[email protected]>
PCI: Create device tree node for bridge

Lizhi Hou <[email protected]>
of: dynamic: Add interfaces for creating device node dynamically

Manivannan Sadhasivam <[email protected]>
PCI: qcom-ep: Add dedicated callback for writing to DBI2 registers

Pengfei Li <[email protected]>
pmdomain: imx: Make imx pgc power domain also set the fwnode

Tomeu Vizoso <[email protected]>
pmdomain: amlogic: Fix mask for the second NNA mem PD domain

Maíra Canal <[email protected]>
pmdomain: bcm: bcm2835-power: check if the ASB register is equal to enable

Dan Williams <[email protected]>
cxl/port: Fix delete_endpoint() vs parent unregistration race

Jim Harris <[email protected]>
cxl/region: Fix x1 root-decoder granularity calculations

Frank Li <[email protected]>
i3c: master: svc: fix random hot join failure since timeout error

Frank Li <[email protected]>
i3c: master: svc: fix SDA keep low when polling IBIWON timeout happen

Frank Li <[email protected]>
i3c: master: svc: fix check wrong status register in irq handler

Frank Li <[email protected]>
i3c: master: svc: fix ibi may not return mandatory data byte

Frank Li <[email protected]>
i3c: master: svc: fix wrong data return when IBI happen during start frame

Frank Li <[email protected]>
i3c: master: svc: fix race condition in ibi work thread

Joshua Yeong <[email protected]>
i3c: master: cdns: Fix reading status register

Jim Harris <[email protected]>
cxl/region: Do not try to cleanup after cxl_region_setup_targets() fails

Linus Walleij <[email protected]>
mtd: cfi_cmdset_0001: Byte swap OTP info

Florent Revest <[email protected]>
mm: make PR_MDWE_REFUSE_EXEC_GAIN an unsigned long

Zi Yan <[email protected]>
mm/memory_hotplug: use pfn math in place of direct struct page manipulation

Zi Yan <[email protected]>
mm/cma: use nth_page() in place of direct struct page manipulation

Heiko Carstens <[email protected]>
s390/cmma: fix handling of swapper_pg_dir and invalid_pg_dir

Heiko Carstens <[email protected]>
s390/cmma: fix detection of DAT pages

Heiko Carstens <[email protected]>
s390/cmma: fix initial kernel address space page table walk

Heiko Carstens <[email protected]>
s390/mm: add missing arch_set_page_dat() call to vmem_crst_alloc()

Alain Volmat <[email protected]>
dmaengine: stm32-mdma: correct desc prep when channel running

Gaurav Batra <[email protected]>
powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device

Sanjuán García, Jorge <[email protected]>
mcb: fix error handling for different scenarios when parsing

Saravana Kannan <[email protected]>
driver core: Release all resources during unbind before updating device links

Steven Rostedt (Google) <[email protected]>
tracing: Have the user copy of synthetic event address use correct context

Tiezhu Yang <[email protected]>
selftests/clone3: Fix broken test under !CONFIG_TIME_NS

Benjamin Bara <[email protected]>
i2c: core: Run atomic i2c xfer when !preemptible

Benjamin Bara <[email protected]>
kernel/reboot: emergency_restart: Set correct system_state

Eric Biggers <[email protected]>
quota: explicitly forbid quota files from being encrypted

Zhihao Cheng <[email protected]>
jbd2: fix potential data lost in recovering journal raced with synchronizing fs bdev

Krzysztof Kozlowski <[email protected]>
ASoC: codecs: wsa-macro: fix uninitialized stack variables with name prefix

Jamie Lentin <[email protected]>
hid: lenovo: Resend all settings on reset_resume for compact keyboards

Ilpo Järvinen <[email protected]>
selftests/resctrl: Reduce failures due to outliers in MBA/MBM tests

Ilpo Järvinen <[email protected]>
selftests/resctrl: Move _GNU_SOURCE define into Makefile

Ilpo Järvinen <[email protected]>
selftests/resctrl: Remove duplicate feature check from CMT test

Ilpo Järvinen <[email protected]>
selftests/resctrl: Fix uninitialized .sa_flags

Srinivas Kandagatla <[email protected]>
ASoC: codecs: wsa883x: make use of new mute_unmute_on_trigger flag

Srinivas Kandagatla <[email protected]>
ASoC: soc-dai: add flag to mute and unmute stream during trigger

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: split async and sync catchall in two functions

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: remove catchall element in GC sync path

Mimi Zohar <[email protected]>
ima: detect changes to the backing overlay file

Amir Goldstein <[email protected]>
ima: annotate iint mutex to avoid lockdep false positive warnings

Johan Hovold <[email protected]>
mfd: qcom-spmi-pmic: Fix revid implementation

Johan Hovold <[email protected]>
mfd: qcom-spmi-pmic: Fix reference leaks in revid helper

Christian Marangi <[email protected]>
leds: trigger: netdev: Move size check in set_device_name

Vignesh Viswanathan <[email protected]>
arm64: dts: qcom: ipq6018: Fix tcsr_mutex register size

Vignesh Viswanathan <[email protected]>
arm64: dts: qcom: ipq9574: Fix hwlock index for SMEM

Vasily Khoruzhick <[email protected]>
ACPI: FPDT: properly handle invalid FPDT subtables

Kathiravan Thirumoorthy <[email protected]>
firmware: qcom_scm: use 64-bit calling convention only when client is 64-bit

Vignesh Viswanathan <[email protected]>
arm64: dts: qcom: ipq8074: Fix hwlock index for SMEM

Vignesh Viswanathan <[email protected]>
arm64: dts: qcom: ipq5332: Fix hwlock index for SMEM

David Arcari <[email protected]>
thermal: intel: powerclamp: fix mismatch in get function for max_idle

Josef Bacik <[email protected]>
btrfs: don't arbitrarily slow down delalloc if we're committing

Catalin Marinas <[email protected]>
rcu: kmemleak: Ignore kmemleak false positives when RCU-freeing objects

Brian Geffon <[email protected]>
PM: hibernate: Clean up sync_read handling in snapshot_write_next()

Brian Geffon <[email protected]>
PM: hibernate: Use __get_safe_page() rather than touching the list

Biju Das <[email protected]>
dt-bindings: timer: renesas,rz-mtu3: Fix overflow/underflow interrupt names

Vignesh Viswanathan <[email protected]>
arm64: dts: qcom: ipq6018: Fix hwlock index for SMEM

Joel Fernandes (Google) <[email protected]>
rcu/tree: Defer setting of jiffies during stall reset

Chuck Lever <[email protected]>
svcrdma: Drop connection after an RDMA Read error

Ajay Singh <[email protected]>
wifi: wilc1000: use vmm_table as array in wilc struct

Uwe Kleine-König <[email protected]>
PCI: exynos: Don't discard .remove() callback

Uwe Kleine-König <[email protected]>
PCI: kirin: Don't discard .remove() callback

Heiner Kallweit <[email protected]>
PCI/ASPM: Fix L1 substate handling in aspm_attr_store_common()

Bean Huo <[email protected]>
mmc: Add quirk MMC_QUIRK_BROKEN_CACHE_FLUSH for Micron eMMC Q2J54A

Nitin Yadav <[email protected]>
mmc: sdhci_am654: fix start loop index for TAP value parsing

Dan Carpenter <[email protected]>
mmc: vub300: fix an error code

Namjae Jeon <[email protected]>
ksmbd: fix slab out of bounds write in smb_inherit_dacl()

Namjae Jeon <[email protected]>
ksmbd: handle malformed smb1 message

Marios Makassikis <[email protected]>
ksmbd: fix recursive locking in vfs helpers

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

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

Gustavo A. R. Silva <[email protected]>
clk: visconti: Fix undefined behavior bug in struct visconti_pll_provider

Gustavo A. R. Silva <[email protected]>
clk: socfpga: Fix undefined behavior bug in struct stratix10_clock_data

Ville Syrjälä <[email protected]>
powercap: intel_rapl: Downgrade BIOS locked limits pr_warn() to pr_debug()

Christian Marangi <[email protected]>
cpufreq: stats: Fix buffer overflow detection in trans_stats()

Helge Deller <[email protected]>
parisc/power: Add power soft-off when running on qemu

Helge Deller <[email protected]>
parisc/pdc: Add width field to struct pdc_model

Helge Deller <[email protected]>
parisc/agp: Use 64-bit LE values in SBA IOMMU PDIR table

Maria Yu <[email protected]>
arm64: module: Fix PLT counting when CONFIG_RANDOMIZE_BASE=n

Nathan Chancellor <[email protected]>
arm64: Restrict CPU_BIG_ENDIAN to GNU as or LLVM IAS 15.x or newer

Uwe Kleine-König <[email protected]>
PCI: keystone: Don't discard .probe() callback

Uwe Kleine-König <[email protected]>
PCI: keystone: Don't discard .remove() callback

Jarkko Sakkinen <[email protected]>
KEYS: trusted: Rollback init_trusted() consistently

Sumit Garg <[email protected]>
KEYS: trusted: tee: Refactor register SHM usage

Hao Jia <[email protected]>
sched/core: Fix RQCF_ACT_SKIP leak

Herve Codina <[email protected]>
genirq/generic_chip: Make irq_remove_generic_chip() irqdomain aware

Rong Chen <[email protected]>
mmc: meson-gx: Remove setting of CMD_CFG_ERROR

Johan Hovold <[email protected]>
wifi: ath12k: fix dfs-radar and temperature event locking

Johan Hovold <[email protected]>
wifi: ath12k: fix htt mlo-offset event locking

Johan Hovold <[email protected]>
wifi: ath11k: fix gtk offload status event locking

Johan Hovold <[email protected]>
wifi: ath11k: fix htt pktlog locking

Johan Hovold <[email protected]>
wifi: ath11k: fix dfs radar event locking

Johan Hovold <[email protected]>
wifi: ath11k: fix temperature event locking

Mark Brown <[email protected]>
regmap: Ensure range selector registers are updated after cache sync

Werner Sembach <[email protected]>
ACPI: resource: Do IRQ override on TongFang GMxXGxx

John David Anglin <[email protected]>
parisc: Add nop instructions after TLB inserts

SeongJae Park <[email protected]>
mm/damon/sysfs: check error from damon_sysfs_update_target()

SeongJae Park <[email protected]>
mm/damon/sysfs-schemes: handle tried regions sysfs directory allocation failure

SeongJae Park <[email protected]>
mm/damon/sysfs-schemes: handle tried region directory allocation failure

SeongJae Park <[email protected]>
mm/damon/core: avoid divide-by-zero during monitoring results update

SeongJae Park <[email protected]>
mm/damon: implement a function for max nr_accesses safe calculation

SeongJae Park <[email protected]>
mm/damon/ops-common: avoid divide-by-zero during region hotness calculation

SeongJae Park <[email protected]>
mm/damon/lru_sort: avoid divide-by-zero in hot threshold calculation

Mikulas Patocka <[email protected]>

    dm crypt: account large pages in cc->n_allocated_pages

Helge Deller <[email protected]>
fbdev: stifb: Make the STI next font pointer a 32-bit signed offset

Koichiro Den <[email protected]>
iommufd: Fix missing update of domains_itree after splitting iopt_area

Krister Johansen <[email protected]>
watchdog: move softlockup_panic back to early_param

SeongJae Park <[email protected]>
mm/damon/sysfs: update monitoring target regions for online input commit

SeongJae Park <[email protected]>
mm/damon/sysfs: remove requested targets when online-commit inputs

Lukas Wunner <[email protected]>
PCI/sysfs: Protect driver's D3cold preference from user space

David Woodhouse <[email protected]>
hvc/xen: fix event channel handling for secondary consoles

David Woodhouse <[email protected]>
hvc/xen: fix error path in xen_hvc_init() to always register frontend driver

David Woodhouse <[email protected]>
hvc/xen: fix console unplug

Pavel Krasavin <[email protected]>
tty: serial: meson: fix hard LOCKUP on crtscts mode

Muhammad Usama Anjum <[email protected]>
tty/sysrq: replace smp_processor_id() with get_cpu()

Krister Johansen <[email protected]>
proc: sysctl: prevent aliased sysctls from getting passed to init

Paul Moore <[email protected]>

    audit: don't WARN_ON_ONCE(!current->mm) in audit_exe_compare()

Paul Moore <[email protected]>
audit: don't take task_lock() in audit_exe_compare() code path

Johannes Weiner <[email protected]>
sched: psi: fix unprivileged polling against cgroups

Victor Shih <[email protected]>
mmc: sdhci-pci-gli: GL9755: Mask the replay timer timeout of AER

Haitao Shan <[email protected]>
KVM: x86: Fix lapic timer interrupt lost after loading a snapshot.

Tao Su <[email protected]>
KVM: x86: Clear bit12 of ICR after APIC-write VM-exit

Maciej S. Szmigiero <[email protected]>
KVM: x86: Ignore MSR_AMD64_TW_CFG access

Nicolas Saenz Julienne <[email protected]>
KVM: x86: hyper-v: Don't auto-enable stimer on write from user-space

Pu Wen <[email protected]>
x86/cpu/hygon: Fix the CPU topology evaluation for real

Koichiro Den <[email protected]>
x86/apic/msi: Fix misconfigured non-maskable MSI quirk

Mario Limonciello <[email protected]>
x86/PCI: Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4

Roxana Nicolescu <[email protected]>
crypto: x86/sha - load modules based on CPU features

Peter Wang <[email protected]>
scsi: ufs: core: Fix racing issue between ufshcd_mcq_abort() and ISR

Quinn Tran <[email protected]>
scsi: qla2xxx: Fix system crash due to bad pointer access

Manivannan Sadhasivam <[email protected]>
scsi: ufs: qcom: Update PHY settings only when scaling to higher gears

Chandrakanth patil <[email protected]>
scsi: megaraid_sas: Increase register read retry rount from 3 to 30 for selected registers

Ranjan Kumar <[email protected]>
scsi: mpt3sas: Fix loop logic

Shung-Hsi Yu <[email protected]>
bpf: Fix precision tracking for BPF_ALU | BPF_TO_BE | BPF_END

Hao Sun <[email protected]>
bpf: Fix check_stack_write_fixed_off() to correctly spill imm

Kees Cook <[email protected]>
randstruct: Fix gcc-plugin performance mode to stay in group

Nicholas Piggin <[email protected]>
powerpc/perf: Fix disabling BHRB and instruction sampling

Adrian Hunter <[email protected]>
perf intel-pt: Fix async branch flags

Vikash Garodia <[email protected]>
media: venus: hfi: add checks to perform sanity on queue pointers

Alexandre Ghiti <[email protected]>
drivers: perf: Check find_first_bit() return value

Ilkka Koskinen <[email protected]>
perf: arm_cspmu: Reject events meant for other PMUs

Harshit Mogalapalli <[email protected]>
i915/perf: Fix NULL deref bugs with drm_dbg() calls

Peter Zijlstra <[email protected]>
perf/core: Fix cpuctx refcounting

Ekaterina Esina <[email protected]>
cifs: fix check of rc in function generate_smb3signingkey

Anastasia Belova <[email protected]>
cifs: spnego: add ';' in HOST_KEY_LEN

Naomi Chu <[email protected]>
scsi: ufs: core: Expand MCQ queue slot to DeviceQueueDepth + 1

Chen Yu <[email protected]>
tools/power/turbostat: Enable the C-state Pre-wake printing

Zhang Rui <[email protected]>
tools/power/turbostat: Fix a knl bug

Vlad Buslov <[email protected]>
macvlan: Don't propagate promisc change to lower dev in passthru

Xin Long <[email protected]>
net: sched: do not offload flows with a helper in act_ct

Rahul Rameshbabu <[email protected]>
net/mlx5e: Check return value of snprintf writing to fw_version buffer for representors

Rahul Rameshbabu <[email protected]>
net/mlx5e: Check return value of snprintf writing to fw_version buffer

Saeed Mahameed <[email protected]>
net/mlx5e: Reduce the size of icosq_str

Rahul Rameshbabu <[email protected]>
net/mlx5: Increase size of irq name buffer

Rahul Rameshbabu <[email protected]>
net/mlx5e: Update doorbell for port timestamping CQ before the software counter

Rahul Rameshbabu <[email protected]>
net/mlx5e: Add recovery flow for tx devlink health reporter for unhealthy PTP SQ

Rahul Rameshbabu <[email protected]>
net/mlx5e: Make tx_port_ts logic resilient to out-of-order CQEs

Rahul Rameshbabu <[email protected]>
net/mlx5: Consolidate devlink documentation in devlink/mlx5.rst

Vlad Buslov <[email protected]>
net/mlx5e: Fix pedit endianness

Gavin Li <[email protected]>
net/mlx5e: fix double free of encap_header in update funcs

Dust Li <[email protected]>
net/mlx5e: fix double free of encap_header

Rahul Rameshbabu <[email protected]>
net/mlx5: Decouple PHC .adjtime and .adjphase implementations

Jens Axboe <[email protected]>
io_uring/fdinfo: remove need for sqpoll lock for thread/pid retrieval

Ziwei Xiao <[email protected]>
gve: Fixes for napi_poll when budget is 0

Shannon Nelson <[email protected]>
pds_core: fix up some format-truncation complaints

Shannon Nelson <[email protected]>
pds_core: use correct index to mask irq

Baruch Siach <[email protected]>
net: stmmac: avoid rx queue overrun

Baruch Siach <[email protected]>
net: stmmac: fix rx budget limit check

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: bogus ENOENT when destroying element which does not exist

Dan Carpenter <[email protected]>
netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()

Linkui Xiao <[email protected]>
netfilter: nf_conntrack_bridge: initialize err to 0

Eric Dumazet <[email protected]>
af_unix: fix use-after-free in unix_stream_read_actor()

Linus Walleij <[email protected]>
net: ethernet: cortina: Fix MTU max setting

Linus Walleij <[email protected]>
net: ethernet: cortina: Handle large frames

Linus Walleij <[email protected]>
net: ethernet: cortina: Fix max RX frame define

Eric Dumazet <[email protected]>
bonding: stop the device in bond_setup_by_slave()

Eric Dumazet <[email protected]>

    ptp: annotate data-race around q->head and q->tail

Christoph Hellwig <[email protected]>
blk-mq: make sure active queue usage is held for bio_integrity_prep()

Juergen Gross <[email protected]>
xen/events: fix delayed eoi list handling

Willem de Bruijn <[email protected]>
ppp: limit MRU to 64K

Sven Auhagen <[email protected]>
net: mvneta: fix calls to page_pool_get_stats

Shigeru Yoshida <[email protected]>
tipc: Fix kernel-infoleak due to uninitialized TLV value

Jijie Shao <[email protected]>
net: hns3: fix VF wrong speed and duplex issue

Jijie Shao <[email protected]>
net: hns3: fix VF reset fail issue

Yonglong Liu <[email protected]>
net: hns3: fix variable may not initialized problem in hns3_init_mac_addr()

Yonglong Liu <[email protected]>
net: hns3: fix out-of-bounds access may occur when coalesce info is read via debugfs

Jian Shen <[email protected]>
net: hns3: fix incorrect capability bit display for copper port

Yonglong Liu <[email protected]>
net: hns3: add barrier in vf mailbox reply process

Jian Shen <[email protected]>
net: hns3: fix add VLAN fail issue

Juergen Gross <[email protected]>
xen/events: avoid using info_for_irq() in xen_send_IPI_one()

Shigeru Yoshida <[email protected]>
tty: Fix uninit-value access in ppp_sync_receive()

Eric Dumazet <[email protected]>
ipvlan: add ipvlan_route_v6_outbound() helper

Stanislav Fomichev <[email protected]>
net: set SOCK_RCU_FREE before inserting socket into hashtable

Andrii Nakryiko <[email protected]>
bpf: fix precision backtracking instruction iteration

Andrii Nakryiko <[email protected]>
bpf: handle ldimm64 properly in check_cfg()

Kees Cook <[email protected]>
gcc-plugins: randstruct: Only warn about true flexible arrays

Dan Carpenter <[email protected]>
vhost-vdpa: fix use after free in vhost_vdpa_probe()

Stefano Garzarella <[email protected]>
vdpa_sim_blk: allocate the buffer zeroed

Nirmoy Das <[email protected]>
drm/i915/tc: Fix -Wformat-truncation in intel_tc_port_init

Andreas Gruenbacher <[email protected]>
gfs2: Silence "suspicious RCU usage in gfs2_permission" warning

Nam Cao <[email protected]>
riscv: provide riscv-specific is_trap_insn()

Andrew Jones <[email protected]>
RISC-V: hwprobe: Fix vDSO SIGSEGV

felix <[email protected]>
SUNRPC: Fix RPC client cleaned up the freed pipefs dentries

Olga Kornievskaia <[email protected]>
NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO

Dan Carpenter <[email protected]>
SUNRPC: Add an IS_ERR() check back to where it was

Olga Kornievskaia <[email protected]>
NFSv4.1: fix handling NFS4ERR_DELAY when testing for session trunking

Arnd Bergmann <[email protected]>
drm/i915/mtl: avoid stringop-overflow warning

Yi Yang <[email protected]>
mtd: rawnand: meson: check return value of devm_kasprintf()

Yi Yang <[email protected]>
mtd: rawnand: intel: check return value of devm_kasprintf()

Trond Myklebust <[email protected]>
SUNRPC: ECONNRESET might require a rebind

Krzysztof Kozlowski <[email protected]>
dt-bindings: serial: fix regex pattern for matching serial node children

Jinghao Jia <[email protected]>
samples/bpf: syscall_tp_user: Fix array out-of-bound access

Jinghao Jia <[email protected]>
samples/bpf: syscall_tp_user: Rename num_progs into nr_tests

Finn Thain <[email protected]>
sched/core: Optimize in_task() and in_interrupt() a bit

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

Yi Yang <[email protected]>
mtd: rawnand: tegra: add missing check for platform_get_irq()

Dan Carpenter <[email protected]>
pwm: Fix double shift bug

Vitaly Prosyak <[email protected]>
drm/amdgpu: fix software pci_unplug on some chips

Alex Spataru <[email protected]>
ALSA: hda/realtek: Add quirk for ASUS UX7602ZM

Zongmin Zhou <[email protected]>
drm/qxl: prevent memory leak

Tony Lindgren <[email protected]>
ASoC: ti: omap-mcbsp: Fix runtime PM underflow warnings

Philipp Stanner <[email protected]>
i2c: dev: copy userspace array safely

Deepak Gupta <[email protected]>
riscv: VMAP_STACK overflow detection thread-safe

Douglas Anderson <[email protected]>
kgdb: Flush console before entering kgdb on panic

Wayne Lin <[email protected]>
drm/amd/display: Avoid NULL dereference of timing generator

Takashi Iwai <[email protected]>
media: imon: fix access to invalid resource for the second interface

Sakari Ailus <[email protected]>
media: ccs: Fix driver quirk struct documentation

Ilpo Järvinen <[email protected]>
media: cobalt: Use FIELD_GET() to extract Link Width

Al Viro <[email protected]>
gfs2: fix an oops in gfs2_permission

Bob Peterson <[email protected]>
gfs2: ignore negated quota changes

Hans Verkuil <[email protected]>
media: ipu-bridge: increase sensor_name size

Hans Verkuil <[email protected]>
media: vivid: avoid integer overflow

Rajeshwar R Shinde <[email protected]>
media: gspca: cpia1: shift-out-of-bounds in set_flicker

Billy Tsai <[email protected]>
i3c: master: mipi-i3c-hci: Fix a kernel panic for accessing DAT_data.

zhenwei pi <[email protected]>
virtio-blk: fix implicit overflow on virtio_max_dma_size

Axel Lin <[email protected]>
i2c: sun6i-p2wi: Prevent potential division by zero

Wolfram Sang <[email protected]>
i2c: fix memleak in i2c_new_client_device()

Jarkko Nikula <[email protected]>
i2c: i801: Add support for Intel Birch Stream SoC

Jarkko Nikula <[email protected]>
i3c: mipi-i3c-hci: Fix out of bounds access in hci_dma_irq_handler

Dominique Martinet <[email protected]>
9p: v9fs_listxattr: fix %s null argument warning

Marco Elver <[email protected]>
9p/trans_fd: Annotate data-racy writes to file::f_flags

Hardik Gajjar <[email protected]>
usb: gadget: f_ncm: Always set current gadget in ncm_bind()

Wesley Cheng <[email protected]>
usb: host: xhci: Avoid XHCI resume delay if SSUSB device is not present

Zhiguo Niu <[email protected]>
f2fs: fix error handling of __get_node_page

Zhiguo Niu <[email protected]>
f2fs: fix error path of __f2fs_build_free_nids

Pierre-Louis Bossart <[email protected]>
soundwire: dmi-quirks: update HP Omen match

Neil Armstrong <[email protected]>
usb: ucsi: glink: use the connector orientation GPIO to provide switch events

Stanley Chang <[email protected]>
usb: dwc3: core: configure TX/RX threshold for DWC3_IP

Konrad Dybcio <[email protected]>
phy: qualcomm: phy-qcom-eusb2-repeater: Zero out untouched tuning regs

Konrad Dybcio <[email protected]>
phy: qualcomm: phy-qcom-eusb2-repeater: Use regmap_fields

Konrad Dybcio <[email protected]>
dt-bindings: phy: qcom,snps-eusb2-repeater: Add magic tuning overrides

Yi Yang <[email protected]>
tty: vcc: Add check for kstrdup() in vcc_probe()

Mika Westerberg <[email protected]>
thunderbolt: Apply USB 3.x bandwidth quirk only in software connection manager

Zhang Shurong <[email protected]>
iio: adc: stm32-adc: harden against NULL pointer deref in stm32_adc_probe()

Jarkko Nikula <[email protected]>
mfd: intel-lpss: Add Intel Lunar Lake-M PCI IDs

Yuezhang Mo <[email protected]>
exfat: support handle zero-size directory

Jiri Kosina <[email protected]>
HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W

Longfang Liu <[email protected]>
crypto: hisilicon/qm - prevent soft lockup in receive loop

Hans de Goede <[email protected]>
ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Tab 3 Pro YT3-X90 quirk

Bjorn Helgaas <[email protected]>
PCI: Use FIELD_GET() in Sapphire RX 5600 XT Pulse quirk

Yoshihiro Shimoda <[email protected]>
misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller

Yoshihiro Shimoda <[email protected]>
PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling

Yoshihiro Shimoda <[email protected]>
PCI: dwc: Add dw_pcie_link_set_max_link_width()

Bartosz Pawlowski <[email protected]>
PCI: Disable ATS for specific Intel IPU E2000 devices

Bartosz Pawlowski <[email protected]>
PCI: Extract ATS disabling to a helper function

Ilpo Järvinen <[email protected]>
PCI: Use FIELD_GET() to extract Link Width

Wenchao Hao <[email protected]>
scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup()

Ilpo Järvinen <[email protected]>
PCI: Do error check on own line to split long "if" conditions

Ilpo Järvinen <[email protected]>
atm: iphase: Do PCI error checks on own line

Ilpo Järvinen <[email protected]>
PCI: mvebu: Use FIELD_PREP() with Link Width

Ilpo Järvinen <[email protected]>
PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields

Linus Walleij <[email protected]>
gpiolib: of: Add quirk for mt2701-cs42448 ASoC sound

Cezary Rojewski <[email protected]>
ALSA: hda: Fix possible null-ptr-deref when assigning a stream

Vincent Whitchurch <[email protected]>
ARM: 9320/1: fix stack depot IRQ stack filter

Mikhail Khvainitski <[email protected]>
HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround

Manas Ghandat <[email protected]>
jfs: fix array-index-out-of-bounds in diAlloc

Manas Ghandat <[email protected]>
jfs: fix array-index-out-of-bounds in dbFindLeaf

Juntong Deng <[email protected]>
fs/jfs: Add validity check for db_maxag and db_agpref

Juntong Deng <[email protected]>
fs/jfs: Add check for negative db_l2nbperpage

Tyrel Datwyler <[email protected]>
scsi: ibmvfc: Remove BUG_ON in the case of an empty event pool

Yihang Li <[email protected]>
scsi: hisi_sas: Set debugfs_dir pointer to NULL after removing debugfs

Ilpo Järvinen <[email protected]>
RDMA/hfi1: Use FIELD_GET() to extract Link Width

Rander Wang <[email protected]>
ASoC: SOF: ipc4: handle EXCEPTION_CAUGHT notification from firmware

Geoffrey D. Bennett <[email protected]>
ALSA: scarlett2: Move USB IDs out from device_info struct

Lu Jialin <[email protected]>
crypto: pcrypt - Fix hungtask for PADATA_RESET

Richard Fitzgerald <[email protected]>
ASoC: SOF: Pass PCI SSID to machine driver

Richard Fitzgerald <[email protected]>
ASoC: soc-card: Add storage for PCI SSID

Trevor Wu <[email protected]>
ASoC: mediatek: mt8188-mt6359: support dynamic pinctrl

zhujun2 <[email protected]>
selftests/efivarfs: create-read: fix a resource leak

Laurentiu Tudor <[email protected]>
arm64: dts: ls208xa: use a pseudo-bus to constrain usb dma size

Lin.Cao <[email protected]>
drm/amd: check num of link levels when update pcie param

Samson Tam <[email protected]>
drm/amd/display: fix num_ways overflow error

Mario Limonciello <[email protected]>
drm/amd: Disable PP_PCIE_DPM_MASK when dynamic speed switching not supported

Qu Huang <[email protected]>
drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is NULL

Jesse Zhang <[email protected]>
drm/amdkfd: Fix shift out-of-bounds issue

Ondrej Jirman <[email protected]>
drm/panel: st7703: Pick different reset sequence

Ma Ke <[email protected]>
drm/amdgpu/vkms: fix a possible null pointer dereference

Ma Ke <[email protected]>
drm/radeon: fix a possible null pointer dereference

Ma Ke <[email protected]>
drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference

Ma Ke <[email protected]>
drm/panel: fix a possible null pointer dereference

Stanley.Yang <[email protected]>
drm/amdgpu: Fix potential null pointer derefernce

Mario Limonciello <[email protected]>
drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga

Mario Limonciello <[email protected]>
drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7

Jani Nikula <[email protected]>
drm/msm/dp: skip validity check for DP CTS EDID checksum

Philipp Stanner <[email protected]>
drm: vmwgfx_surface.c: copy user-array safely

Philipp Stanner <[email protected]>
drm_lease.c: copy user-array safely

Philipp Stanner <[email protected]>
kernel: watch_queue: copy user-array safely

Philipp Stanner <[email protected]>
kernel: kexec: copy user-array safely

Philipp Stanner <[email protected]>
string.h: add array-wrappers for (v)memdup_user()

Wenjing Liu <[email protected]>
drm/amd/display: use full update for clip size increase of large plane source

Mario Limonciello <[email protected]>
drm/amd: Update update_pcie_parameters functions to use uint8_t arguments

Xiaogang Chen <[email protected]>
drm/amdkfd: Fix a race condition of vram buffer unref in svm code

David (Ming Qiang) Wu <[email protected]>
drm/amdgpu: not to save bo in the case of RAS err_event_athub

Yu Kuai <[email protected]>

    md: don't rely on 'mddev->pers' to be set in mddev_suspend()

Ville Syrjälä <[email protected]>
drm/edid: Fixup h/vsync_end instead of h/vtotal

Wenjing Liu <[email protected]>
drm/amd/display: add seamless pipe topology transition check

Alvin Lee <[email protected]>
drm/amd/display: Don't lock phantom pipe on disabling

Alvin Lee <[email protected]>
drm/amd/display: Blank phantom OTG before enabling

baozhu.liu <[email protected]>
drm/komeda: drop all currently held locks if deadlock happens

Harish Kasiviswanathan <[email protected]>
drm/amdkfd: ratelimited SQ interrupt messages

Sui Jingfeng <[email protected]>
drm/gma500: Fix call trace when psb_gem_mm_init() fails

Olli Asikainen <[email protected]>
platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e

Herve Codina <[email protected]>
of: address: Fix address translation when address-size is greater than 2

Tzung-Bi Shih <[email protected]>
platform/chrome: kunit: initialize lock for fake ec_dev

Hans de Goede <[email protected]>
gpiolib: acpi: Add a ignore interrupt quirk for Peaq C1010

Gerhard Engleder <[email protected]>
tsnep: Fix tsnep_request_irq() format-overflow warning

Jonathan Denose <[email protected]>
ACPI: EC: Add quirk for HP 250 G7 Notebook PC

ZhengHan Wang <[email protected]>
Bluetooth: Fix double free in hci_conn_cleanup

youwan Wang <[email protected]>

    Bluetooth: btusb: Add date->evt_skb is NULL check

Gregory Greenman <[email protected]>
wifi: iwlwifi: mvm: fix size check for fw_link_id

Andrii Nakryiko <[email protected]>
bpf: Ensure proper register state printing for cond jumps

Arseniy Krasnov <[email protected]>
vsock: read from socket's error queue

Raju Lakkaraju <[email protected]>
net: sfp: add quirk for FS's 2.5G copper SFP

Douglas Anderson <[email protected]>
wifi: ath10k: Don't touch the CE interrupt registers after power up

Ma Ke <[email protected]>
wifi: ath12k: mhi: fix potential memory leak in ath12k_mhi_register()

Eric Dumazet <[email protected]>

    net: annotate data-races around sk->sk_dst_pending_confirm

Eric Dumazet <[email protected]>

    net: annotate data-races around sk->sk_tx_queue_mapping

Ingo Rohloff <[email protected]>

    wifi: mt76: mt7921e: Support MT7992 IP in Xiaomi Redmibook 15 Pro (2023)

Christian Marangi <[email protected]>
net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI

Shiju Jose <[email protected]>
ACPI: APEI: Fix AER info corruption when error status data has multiple sections

Baochen Qiang <[email protected]>
wifi: ath12k: fix possible out-of-bound write in ath12k_wmi_ext_hal_reg_caps()

Dmitry Antipov <[email protected]>
wifi: ath10k: fix clang-specific fortify warning

Baochen Qiang <[email protected]>
wifi: ath12k: fix possible out-of-bound read in ath12k_htt_pull_ppdu_stats()

Dmitry Antipov <[email protected]>
wifi: ath9k: fix clang-specific fortify warnings

Kumar Kartikeya Dwivedi <[email protected]>

    bpf: Detect IP == ksym.end as part of BPF program

Sieng-Piaw Liew <[email protected]>
atl1c: Work around the DMA RX overflow issue

Ping-Ke Shih <[email protected]>

    wifi: mac80211: don't return unset power in ieee80211_get_tx_power()

Dmitry Antipov <[email protected]>
wifi: mac80211_hwsim: fix clang-specific fortify warning

Harshitha Prem <[email protected]>
wifi: ath12k: Ignore fragments from uninitialized peer in dp

Dmitry Antipov <[email protected]>
wifi: plfxlc: fix clang-specific fortify warning

Mike Rapoport (IBM) <[email protected]>
x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size

Frederic Weisbecker <[email protected]>
workqueue: Provide one lock class key per work_on_cpu() callsite

Ran Xiaokai <[email protected]>
cpu/hotplug: Don't offline the last non-isolated CPU

Rik van Riel <[email protected]>
smp,csd: Throw an error if a CSD lock is stuck for too long

Frederic Weisbecker <[email protected]>
srcu: Only accelerate on enqueue time

Ronald Wahl <[email protected]>
clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 hardware

Jacky Bai <[email protected]>
clocksource/drivers/timer-imx-gpt: Fix potential memory leak

Ricardo Cañuelo <[email protected]>
selftests/lkdtm: Disable CONFIG_UBSAN_TRAP in test config

Denis Arefev <[email protected]>
srcu: Fix srcu_struct node grpmask overflow on 64-bit systems

Zhen Lei <[email protected]>
rcu: Dump memory object info if callback function is invalid

Shuai Xue <[email protected]>
perf/core: Bail out early if the request AUX area is out of bound

Josh Poimboeuf <[email protected]>
x86/retpoline: Make sure there are no unconverted return thunks due to KCSAN

Kent Overstreet <[email protected]>
lib/generic-radix-tree.c: Don't overflow in peek()

Filipe Manana <[email protected]>
btrfs: abort transaction on generation mismatch when marking eb as dirty

John Stultz <[email protected]>
locking/ww_mutex/test: Fix potential workqueue corruption

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

Diffstat:

 Documentation/admin-guide/kernel-parameters.txt    |  11 +
 .../bindings/phy/qcom,snps-eusb2-repeater.yaml     |  21 ++
 .../devicetree/bindings/serial/serial.yaml         |   2 +-
 .../devicetree/bindings/timer/renesas,rz-mtu3.yaml |  38 +--
 Documentation/i2c/busses/i2c-i801.rst              |   1 +
 .../ethernet/mellanox/mlx5/counters.rst            |   6 +
 .../ethernet/mellanox/mlx5/devlink.rst             | 313 ------------------
 .../ethernet/mellanox/mlx5/index.rst               |   1 -
 Documentation/networking/devlink/mlx5.rst          | 182 +++++++++++
 Makefile                                           |   4 +-
 arch/arm/include/asm/exception.h                   |   4 -
 arch/arm64/Kconfig                                 |   2 +
 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi     |  46 +--
 arch/arm64/boot/dts/qcom/ipq5332.dtsi              |   2 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi              |   4 +-
 arch/arm64/boot/dts/qcom/ipq8074.dtsi              |   2 +-
 arch/arm64/boot/dts/qcom/ipq9574.dtsi              |   2 +-
 arch/arm64/kernel/module-plts.c                    |   6 -
 arch/loongarch/include/asm/percpu.h                |  10 +-
 arch/parisc/include/uapi/asm/pdc.h                 |   1 +
 arch/parisc/kernel/entry.S                         |  88 +++--
 arch/parisc/kernel/head.S                          |   5 +-
 arch/powerpc/perf/core-book3s.c                    |   5 +-
 arch/powerpc/platforms/powernv/opal-prd.c          |  17 +-
 arch/powerpc/platforms/pseries/iommu.c             |   8 +-
 arch/riscv/include/asm/asm-prototypes.h            |   1 -
 arch/riscv/include/asm/asm.h                       |  22 ++
 arch/riscv/include/asm/hwprobe.h                   |   5 +
 arch/riscv/include/asm/page.h                      |   4 +-
 arch/riscv/include/asm/thread_info.h               |   3 -
 arch/riscv/include/asm/vdso/processor.h            |   2 +-
 arch/riscv/kernel/asm-offsets.c                    |   1 +
 arch/riscv/kernel/entry.S                          |  72 +----
 arch/riscv/kernel/probes/simulate-insn.c           |   2 +-
 arch/riscv/kernel/probes/uprobes.c                 |   6 +
 arch/riscv/kernel/traps.c                          |  36 +--
 arch/riscv/kernel/vdso/hwprobe.c                   |   2 +-
 arch/riscv/mm/ptdump.c                             |   3 +
 arch/s390/mm/page-states.c                         |  25 +-
 arch/s390/mm/vmem.c                                |   8 +-
 arch/x86/crypto/sha1_ssse3_glue.c                  |  12 +
 arch/x86/crypto/sha256_ssse3_glue.c                |  12 +
 arch/x86/include/asm/kvm-x86-ops.h                 |   1 +
 arch/x86/include/asm/kvm_host.h                    |   1 +
 arch/x86/include/asm/msr-index.h                   |   1 +
 arch/x86/include/asm/numa.h                        |   7 -
 arch/x86/kernel/apic/msi.c                         |   8 +-
 arch/x86/kernel/cpu/hygon.c                        |   8 +-
 arch/x86/kvm/hyperv.c                              |  10 +-
 arch/x86/kvm/lapic.c                               |  30 +-
 arch/x86/kvm/vmx/vmx.c                             |   4 +-
 arch/x86/kvm/x86.c                                 |   2 +
 arch/x86/mm/numa.c                                 |   7 -
 arch/x86/pci/fixup.c                               |  59 ++++
 block/blk-mq.c                                     |  75 ++---
 crypto/pcrypt.c                                    |   4 +
 drivers/acpi/acpi_fpdt.c                           |  45 ++-
 drivers/acpi/apei/ghes.c                           |  23 +-
 drivers/acpi/ec.c                                  |  10 +
 drivers/acpi/resource.c                            |  12 +
 drivers/atm/iphase.c                               |  20 +-
 drivers/base/dd.c                                  |   2 +-
 drivers/base/regmap/regcache.c                     |  30 ++
 drivers/block/virtio_blk.c                         |   4 +-
 drivers/bluetooth/btusb.c                          |   3 +
 drivers/char/agp/parisc-agp.c                      |  16 +-
 drivers/clk/qcom/gcc-ipq6018.c                     |   6 -
 drivers/clk/qcom/gcc-ipq8074.c                     |   6 -
 drivers/clk/socfpga/stratix10-clk.h                |   4 +-
 drivers/clk/visconti/pll.h                         |   4 +-
 drivers/clocksource/timer-atmel-tcb.c              |   1 +
 drivers/clocksource/timer-imx-gpt.c                |  18 +-
 drivers/cpufreq/cpufreq_stats.c                    |  14 +-
 drivers/crypto/hisilicon/qm.c                      |   2 +
 drivers/cxl/core/port.c                            |  34 +-
 drivers/cxl/core/region.c                          |  23 +-
 drivers/dma/stm32-mdma.c                           |   4 +-
 drivers/firmware/qcom_scm.c                        |   7 +
 drivers/gpio/gpiolib-acpi.c                        |  20 ++
 drivers/gpio/gpiolib-of.c                          |   4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c           |   5 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c        |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c        |   6 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |  13 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c      |  23 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c            |  16 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |   9 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c            |   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c           |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |  35 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c             |   5 +-
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c   |   6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c   |   6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c    |   6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c               |  13 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  24 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |  29 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c           |  70 ++--
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c    |   4 +-
 drivers/gpu/drm/amd/display/dc/dc.h                |   5 +
 .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  |   3 +-
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |  10 +-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 105 +++++-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h |   9 +
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c  |   2 +
 drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h  |   8 +
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h        |  22 +-
 drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c    |  50 ++-
 drivers/gpu/drm/amd/include/pptable.h              |   4 +-
 drivers/gpu/drm/amd/pm/amdgpu_pm.c                 |   8 +-
 .../gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h  |  16 +-
 .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c    |   4 +-
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c          |   2 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h      |   2 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h       |   4 +-
 drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c    |   4 +-
 .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c    |  10 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c     |   9 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   |  40 +--
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c   |   9 +-
 .../drm/arm/display/komeda/komeda_pipeline_state.c |   9 +-
 drivers/gpu/drm/bridge/ite-it66121.c               |   4 +-
 drivers/gpu/drm/drm_edid.c                         |  18 +-
 drivers/gpu/drm/drm_lease.c                        |   4 +-
 drivers/gpu/drm/gma500/psb_drv.h                   |   1 +
 drivers/gpu/drm/gma500/psb_irq.c                   |   5 +
 drivers/gpu/drm/i915/display/intel_cdclk.c         |  12 +
 drivers/gpu/drm/i915/display/intel_dp.c            |   2 +-
 drivers/gpu/drm/i915/display/intel_tc.c            |  11 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c        |   1 +
 drivers/gpu/drm/i915/gt/intel_ggtt.c               |  35 +-
 drivers/gpu/drm/i915/gt/intel_rc6.c                |  16 +-
 drivers/gpu/drm/i915/i915_perf.c                   |  15 +-
 drivers/gpu/drm/mediatek/mtk_dp.c                  |   6 +-
 drivers/gpu/drm/msm/dp/dp_panel.c                  |  21 +-
 drivers/gpu/drm/panel/panel-arm-versatile.c        |   2 +
 drivers/gpu/drm/panel/panel-sitronix-st7703.c      |  25 +-
 drivers/gpu/drm/panel/panel-tpo-tpg110.c           |   2 +
 drivers/gpu/drm/qxl/qxl_display.c                  |   3 +
 drivers/gpu/drm/radeon/radeon_connectors.c         |   2 +
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c            |   4 +-
 drivers/hid/hid-ids.h                              |   1 +
 drivers/hid/hid-lenovo.c                           | 118 ++++---
 drivers/hid/hid-quirks.c                           |   1 +
 drivers/i2c/busses/Kconfig                         |   1 +
 drivers/i2c/busses/i2c-designware-master.c         |  19 +-
 drivers/i2c/busses/i2c-i801.c                      |  22 +-
 drivers/i2c/busses/i2c-pxa.c                       |  76 ++++-
 drivers/i2c/busses/i2c-sun6i-p2wi.c                |   5 +
 drivers/i2c/i2c-core-base.c                        |  13 +-
 drivers/i2c/i2c-core.h                             |   2 +-
 drivers/i2c/i2c-dev.c                              |   4 +-
 drivers/i3c/master/i3c-master-cdns.c               |   6 +-
 drivers/i3c/master/mipi-i3c-hci/dat_v1.c           |  29 +-
 drivers/i3c/master/mipi-i3c-hci/dma.c              |   2 +-
 drivers/i3c/master/svc-i3c-master.c                |  54 +++-
 drivers/iio/adc/stm32-adc-core.c                   |   9 +-
 drivers/infiniband/hw/hfi1/pcie.c                  |   9 +-
 drivers/iommu/iommufd/io_pagetable.c               |  10 +
 drivers/leds/trigger/ledtrig-netdev.c              |   6 +-
 drivers/mcb/mcb-core.c                             |   1 +
 drivers/mcb/mcb-parse.c                            |   2 +-
 drivers/md/dm-bufio.c                              |  87 +++--
 drivers/md/dm-crypt.c                              |  15 +-
 drivers/md/dm-verity-fec.c                         |   4 +-
 drivers/md/dm-verity-target.c                      |  23 +-
 drivers/md/dm-verity.h                             |   2 +-
 drivers/md/md.c                                    |   2 +-
 drivers/media/i2c/ccs/ccs-core.c                   |   2 +-
 drivers/media/i2c/ccs/ccs-quirk.h                  |   4 +-
 drivers/media/pci/cobalt/cobalt-driver.c           |  11 +-
 drivers/media/pci/intel/ipu-bridge.h               |   2 +-
 .../media/platform/qcom/camss/camss-csid-gen2.c    |  11 +-
 .../platform/qcom/camss/camss-csiphy-3ph-1-0.c     |   2 +-
 drivers/media/platform/qcom/camss/camss-vfe-170.c  |  22 +-
 drivers/media/platform/qcom/camss/camss-vfe-480.c  |  22 +-
 drivers/media/platform/qcom/camss/camss-vfe.c      |   5 +-
 drivers/media/platform/qcom/camss/camss.c          |  12 +-
 drivers/media/platform/qcom/venus/hfi_msgs.c       |   2 +-
 drivers/media/platform/qcom/venus/hfi_parser.c     |  15 +
 drivers/media/platform/qcom/venus/hfi_venus.c      |  10 +
 drivers/media/rc/imon.c                            |   6 +
 drivers/media/rc/ir-sharp-decoder.c                |   8 +-
 drivers/media/rc/lirc_dev.c                        |   6 +-
 drivers/media/test-drivers/vivid/vivid-rds-gen.c   |   2 +-
 drivers/media/usb/gspca/cpia1.c                    |   3 +
 drivers/mfd/intel-lpss-pci.c                       |  13 +
 drivers/mfd/qcom-spmi-pmic.c                       | 101 ++++--
 drivers/misc/pci_endpoint_test.c                   |   4 +
 drivers/mmc/core/block.c                           |   4 +-
 drivers/mmc/core/card.h                            |   4 +
 drivers/mmc/core/mmc.c                             |   8 +-
 drivers/mmc/core/quirks.h                          |   7 +-
 drivers/mmc/host/meson-gx-mmc.c                    |   1 -
 drivers/mmc/host/sdhci-pci-gli.c                   |  30 ++
 drivers/mmc/host/sdhci_am654.c                     |   2 +-
 drivers/mmc/host/vub300.c                          |   1 +
 drivers/mtd/chips/cfi_cmdset_0001.c                |  20 +-
 drivers/mtd/nand/raw/intel-nand-controller.c       |  10 +
 drivers/mtd/nand/raw/meson_nand.c                  |   3 +
 drivers/mtd/nand/raw/tegra_nand.c                  |   4 +
 drivers/net/bonding/bond_main.c                    |   6 +
 drivers/net/dsa/lan9303_mdio.c                     |   4 +-
 drivers/net/ethernet/amd/pds_core/adminq.c         |   2 +-
 drivers/net/ethernet/amd/pds_core/core.h           |   2 +-
 drivers/net/ethernet/amd/pds_core/dev.c            |   8 +-
 drivers/net/ethernet/amd/pds_core/devlink.c        |   2 +-
 drivers/net/ethernet/atheros/atl1c/atl1c.h         |   3 -
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c    |  67 +---
 drivers/net/ethernet/cortina/gemini.c              |  45 ++-
 drivers/net/ethernet/cortina/gemini.h              |   4 +-
 drivers/net/ethernet/engleder/tsnep.h              |   2 +-
 drivers/net/ethernet/engleder/tsnep_main.c         |  12 +-
 drivers/net/ethernet/google/gve/gve_main.c         |   8 +-
 drivers/net/ethernet/google/gve/gve_rx.c           |   4 -
 drivers/net/ethernet/google/gve/gve_tx.c           |   4 -
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |   9 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c    |   2 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    |  33 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  25 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |   1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c   |   7 +
 drivers/net/ethernet/marvell/mvneta.c              |  28 +-
 .../net/ethernet/mellanox/mlx5/core/en/health.h    |   1 +
 drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c   | 255 +++++++++++----
 drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h   |  59 +++-
 .../ethernet/mellanox/mlx5/core/en/reporter_rx.c   |   4 +-
 .../ethernet/mellanox/mlx5/core/en/reporter_tx.c   |  65 ++++
 .../net/ethernet/mellanox/mlx5/core/en/tc_tun.c    |  30 +-
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   |  16 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c   |  12 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_stats.c |   4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_stats.h |   4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |  60 ++--
 drivers/net/ethernet/mellanox/mlx5/core/en_tx.c    |  28 +-
 .../net/ethernet/mellanox/mlx5/core/lib/clock.c    |   7 +-
 drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c  |   6 +-
 drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h  |   3 +
 drivers/net/ethernet/realtek/r8169_main.c          |  46 ++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   3 +-
 drivers/net/ipvlan/ipvlan_core.c                   |  41 ++-
 drivers/net/macvlan.c                              |   2 +-
 drivers/net/phy/phylink.c                          |   1 +
 drivers/net/phy/sfp.c                              |   8 +
 drivers/net/ppp/ppp_synctty.c                      |   6 +-
 drivers/net/wireless/ath/ath10k/debug.c            |   2 +-
 drivers/net/wireless/ath/ath10k/snoc.c             |  18 +-
 drivers/net/wireless/ath/ath11k/dp_rx.c            |   8 +-
 drivers/net/wireless/ath/ath11k/wmi.c              |  19 +-
 drivers/net/wireless/ath/ath12k/dp.c               |   1 +
 drivers/net/wireless/ath/ath12k/dp_rx.c            |  33 +-
 drivers/net/wireless/ath/ath12k/mhi.c              |  11 +-
 drivers/net/wireless/ath/ath12k/peer.h             |   3 +
 drivers/net/wireless/ath/ath12k/wmi.c              |  17 +-
 drivers/net/wireless/ath/ath9k/debug.c             |   2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_debug.c     |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/link.c      |   4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c        |  14 +-
 drivers/net/wireless/mediatek/mt76/mt7921/pci.c    |   2 +
 drivers/net/wireless/microchip/wilc1000/wlan.c     |   2 +-
 drivers/net/wireless/purelifi/plfxlc/mac.c         |   2 +-
 drivers/net/wireless/virtual/mac80211_hwsim.c      |   2 +-
 drivers/of/address.c                               |  30 +-
 drivers/of/dynamic.c                               | 164 ++++++++++
 drivers/of/unittest.c                              |  19 +-
 drivers/parisc/power.c                             |  16 +-
 drivers/pci/Kconfig                                |  12 +
 drivers/pci/Makefile                               |   1 +
 drivers/pci/bus.c                                  |   2 +
 drivers/pci/controller/dwc/pci-exynos.c            |   4 +-
 drivers/pci/controller/dwc/pci-keystone.c          |   8 +-
 drivers/pci/controller/dwc/pcie-designware.c       |  93 +++---
 drivers/pci/controller/dwc/pcie-kirin.c            |   4 +-
 drivers/pci/controller/dwc/pcie-qcom-ep.c          |  17 +
 drivers/pci/controller/dwc/pcie-tegra194.c         |   9 +-
 drivers/pci/controller/pci-mvebu.c                 |   2 +-
 drivers/pci/of.c                                   |  79 +++++
 drivers/pci/of_property.c                          | 355 +++++++++++++++++++++
 drivers/pci/pci-acpi.c                             |   2 +-
 drivers/pci/pci-sysfs.c                            |  10 +-
 drivers/pci/pci.c                                  |  22 +-
 drivers/pci/pci.h                                  |  12 +
 drivers/pci/pcie/aer.c                             |  10 +
 drivers/pci/pcie/aspm.c                            |   2 +
 drivers/pci/probe.c                                |   6 +-
 drivers/pci/quirks.c                               |  64 +++-
 drivers/pci/remove.c                               |   1 +
 drivers/perf/arm_cspmu/arm_cspmu.c                 |   3 +
 drivers/perf/riscv_pmu_sbi.c                       |   5 +
 drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c     | 131 ++++++--
 drivers/platform/chrome/cros_ec_proto_test.c       |   1 +
 drivers/platform/x86/thinkpad_acpi.c               |   1 +
 drivers/powercap/intel_rapl_common.c               |   2 +-
 drivers/ptp/ptp_chardev.c                          |   3 +-
 drivers/ptp/ptp_clock.c                            |   5 +-
 drivers/ptp/ptp_private.h                          |   8 +-
 drivers/ptp/ptp_sysfs.c                            |   3 +-
 drivers/s390/crypto/ap_bus.c                       |   4 +
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c             |  13 +-
 drivers/scsi/ibmvscsi/ibmvfc.c                     | 124 ++++++-
 drivers/scsi/libfc/fc_lport.c                      |   6 +
 drivers/scsi/megaraid/megaraid_sas_base.c          |   4 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c                |   4 +-
 drivers/scsi/qla2xxx/qla_os.c                      |  12 +-
 drivers/soc/amlogic/meson-ee-pwrc.c                |   2 +-
 drivers/soc/bcm/bcm2835-power.c                    |   2 +-
 drivers/soc/imx/gpc.c                              |   1 +
 drivers/soundwire/dmi-quirks.c                     |   2 +-
 drivers/thermal/intel/intel_powerclamp.c           |   2 +-
 drivers/thunderbolt/quirks.c                       |   3 +
 drivers/tty/hvc/hvc_xen.c                          |  39 ++-
 drivers/tty/serial/meson_uart.c                    |  14 +-
 drivers/tty/sysrq.c                                |   3 +-
 drivers/tty/vcc.c                                  |  16 +-
 drivers/ufs/core/ufs-mcq.c                         |   5 +-
 drivers/ufs/core/ufshcd.c                          |   3 +-
 drivers/ufs/host/ufs-qcom.c                        |   9 +-
 drivers/usb/dwc3/core.c                            | 160 +++++++---
 drivers/usb/dwc3/core.h                            |  13 +
 drivers/usb/gadget/function/f_ncm.c                |  27 +-
 drivers/usb/host/xhci-pci.c                        |   4 +-
 drivers/usb/host/xhci.c                            |  12 +-
 drivers/usb/typec/ucsi/ucsi_glink.c                |  54 +++-
 drivers/vdpa/vdpa_sim/vdpa_sim_blk.c               |   4 +-
 drivers/vhost/vdpa.c                               |   1 -
 drivers/watchdog/sbsa_gwdt.c                       |   4 +-
 drivers/xen/events/events_base.c                   |  16 +-
 fs/9p/xattr.c                                      |   5 +-
 fs/btrfs/block-group.c                             |   4 +-
 fs/btrfs/ctree.c                                   | 109 ++++---
 fs/btrfs/ctree.h                                   |  11 +-
 fs/btrfs/delalloc-space.c                          |   3 -
 fs/btrfs/delayed-inode.c                           |   2 +-
 fs/btrfs/dev-replace.c                             |   2 +-
 fs/btrfs/dir-item.c                                |   8 +-
 fs/btrfs/disk-io.c                                 |  13 +-
 fs/btrfs/disk-io.h                                 |   3 +-
 fs/btrfs/extent-tree.c                             |  36 ++-
 fs/btrfs/file-item.c                               |  17 +-
 fs/btrfs/file.c                                    |  34 +-
 fs/btrfs/free-space-cache.c                        |   6 +-
 fs/btrfs/free-space-tree.c                         |  17 +-
 fs/btrfs/inode-item.c                              |  16 +-
 fs/btrfs/inode.c                                   |  17 +-
 fs/btrfs/ioctl.c                                   |   4 +-
 fs/btrfs/qgroup.c                                  |  14 +-
 fs/btrfs/relocation.c                              |  10 +-
 fs/btrfs/root-tree.c                               |   4 +-
 fs/btrfs/tests/extent-buffer-tests.c               |   6 +-
 fs/btrfs/tests/inode-tests.c                       |  12 +-
 fs/btrfs/tree-log.c                                |  12 +-
 fs/btrfs/uuid-tree.c                               |   6 +-
 fs/btrfs/volumes.c                                 |  10 +-
 fs/btrfs/xattr.c                                   |   8 +-
 fs/exfat/namei.c                                   |  29 +-
 fs/ext4/acl.h                                      |   5 +
 fs/ext4/ext4.h                                     |   3 +-
 fs/ext4/extents_status.c                           | 127 +++++---
 fs/ext4/file.c                                     | 169 +++++-----
 fs/ext4/inode.c                                    |  14 +-
 fs/ext4/resize.c                                   |  23 +-
 fs/ext4/super.c                                    |  14 +
 fs/f2fs/compress.c                                 |   2 +-
 fs/f2fs/extent_cache.c                             |  53 ++-
 fs/f2fs/file.c                                     |   9 +
 fs/f2fs/node.c                                     |  18 +-
 fs/f2fs/xattr.c                                    |  20 +-
 fs/gfs2/inode.c                                    |  14 +-
 fs/gfs2/ops_fstype.c                               |   4 +-
 fs/gfs2/quota.c                                    |  11 +
 fs/gfs2/super.c                                    |   2 +-
 fs/inode.c                                         |  16 +
 fs/jbd2/recovery.c                                 |   8 +
 fs/jfs/jfs_dmap.c                                  |  23 +-
 fs/jfs/jfs_imap.c                                  |   5 +-
 fs/nfs/nfs4proc.c                                  |  12 +-
 fs/nfsd/nfs4state.c                                |   2 +-
 fs/nfsd/nfscache.c                                 |  23 +-
 fs/overlayfs/super.c                               |   2 +-
 fs/proc/proc_sysctl.c                              |   8 +-
 fs/quota/dquot.c                                   |  14 +
 fs/smb/client/cached_dir.c                         |  84 +++--
 fs/smb/client/cifs_debug.c                         |   6 +
 fs/smb/client/cifs_ioctl.h                         |   6 +
 fs/smb/client/cifs_spnego.c                        |   4 +-
 fs/smb/client/cifsfs.c                             |   1 +
 fs/smb/client/cifsglob.h                           |  12 +-
 fs/smb/client/cifspdu.h                            |   2 +-
 fs/smb/client/cifsproto.h                          |   7 +-
 fs/smb/client/connect.c                            |  15 +-
 fs/smb/client/inode.c                              |   4 +
 fs/smb/client/ioctl.c                              |  25 ++
 fs/smb/client/sess.c                               |   1 -
 fs/smb/client/smb2misc.c                           |   2 +-
 fs/smb/client/smb2ops.c                            |   8 +-
 fs/smb/client/smb2transport.c                      |   5 +-
 fs/smb/client/transport.c                          |  11 +-
 fs/smb/client/xattr.c                              |   5 +-
 fs/smb/server/smb_common.c                         |  11 +
 fs/smb/server/smbacl.c                             |  29 +-
 fs/smb/server/vfs.c                                |  23 +-
 fs/xfs/xfs_inode_item_recover.c                    |  32 +-
 include/acpi/ghes.h                                |   4 +
 include/linux/bpf.h                                |   8 +-
 include/linux/damon.h                              |   7 +
 include/linux/ethtool.h                            |   4 +-
 include/linux/f2fs_fs.h                            |   1 +
 include/linux/fs.h                                 |  45 ++-
 include/linux/generic-radix-tree.h                 |   7 +
 include/linux/irq.h                                |  26 +-
 include/linux/lsm_hook_defs.h                      |   4 +-
 include/linux/mmc/card.h                           |   2 +
 include/linux/msi.h                                |   6 -
 include/linux/of.h                                 |  23 ++
 include/linux/pci_ids.h                            |   2 +
 include/linux/perf_event.h                         |  13 +-
 include/linux/preempt.h                            |  15 +-
 include/linux/pwm.h                                |   4 +-
 include/linux/socket.h                             |   1 +
 include/linux/string.h                             |  40 +++
 include/linux/sunrpc/clnt.h                        |   1 +
 include/linux/sysctl.h                             |   6 +
 include/linux/torture.h                            |  10 +-
 include/linux/trace_events.h                       |   4 +
 include/linux/workqueue.h                          |  46 ++-
 include/net/netfilter/nf_tables.h                  |   4 +-
 include/net/sock.h                                 |  26 +-
 include/net/tc_act/tc_ct.h                         |   9 +
 include/sound/soc-acpi.h                           |   7 +
 include/sound/soc-card.h                           |  37 +++
 include/sound/soc-dai.h                            |   1 +
 include/sound/soc.h                                |  11 +
 include/sound/sof.h                                |   8 +
 include/uapi/linux/prctl.h                         |   2 +-
 include/uapi/linux/vm_sockets.h                    |  17 +
 include/video/sticore.h                            |   2 +-
 init/Makefile                                      |   1 +
 init/main.c                                        |   4 +
 io_uring/fdinfo.c                                  |   9 +-
 io_uring/sqpoll.c                                  |  12 +-
 kernel/audit_watch.c                               |   9 +-
 kernel/bpf/core.c                                  |   6 +-
 kernel/bpf/verifier.c                              |  64 +++-
 kernel/cgroup/cgroup.c                             |  12 -
 kernel/cpu.c                                       |  11 +-
 kernel/debug/debug_core.c                          |   3 +
 kernel/events/core.c                               |  17 +
 kernel/events/ring_buffer.c                        |   6 +
 kernel/irq/debugfs.c                               |   1 -
 kernel/irq/generic-chip.c                          |  25 +-
 kernel/irq/msi.c                                   |  12 +-
 kernel/kexec.c                                     |   2 +-
 kernel/locking/locktorture.c                       |  12 +-
 kernel/locking/test-ww_mutex.c                     |  20 +-
 kernel/padata.c                                    |   2 +-
 kernel/power/snapshot.c                            |  16 +-
 kernel/rcu/rcu.h                                   |   7 +
 kernel/rcu/srcutiny.c                              |   1 +
 kernel/rcu/srcutree.c                              |  11 +-
 kernel/rcu/tasks.h                                 |   1 +
 kernel/rcu/tiny.c                                  |   1 +
 kernel/rcu/tree.c                                  |  22 ++
 kernel/rcu/tree.h                                  |   4 +
 kernel/rcu/tree_stall.h                            |  20 +-
 kernel/reboot.c                                    |   1 +
 kernel/sched/core.c                                |   5 +-
 kernel/smp.c                                       |  13 +-
 kernel/torture.c                                   |  67 ++--
 kernel/trace/trace.c                               |  15 +
 kernel/trace/trace.h                               |   3 +
 kernel/trace/trace_events.c                        |  43 ++-
 kernel/trace/trace_events_filter.c                 |   3 +
 kernel/trace/trace_events_synth.c                  |   2 +-
 kernel/watch_queue.c                               |   2 +-
 kernel/watchdog.c                                  |   7 +
 kernel/workqueue.c                                 |  20 +-
 lib/generic-radix-tree.c                           |  17 +-
 mm/cma.c                                           |   2 +-
 mm/damon/core.c                                    |  10 +-
 mm/damon/lru_sort.c                                |   4 +-
 mm/damon/ops-common.c                              |   5 +-
 mm/damon/sysfs-schemes.c                           |   5 +
 mm/damon/sysfs.c                                   |  89 +++---
 mm/huge_memory.c                                   |  16 +-
 mm/hugetlb.c                                       |  33 +-
 mm/memcontrol.c                                    |   3 +-
 mm/memory_hotplug.c                                |   2 +-
 net/9p/client.c                                    |   2 +-
 net/9p/trans_fd.c                                  |  13 +-
 net/bluetooth/hci_conn.c                           |   6 +-
 net/bluetooth/hci_sysfs.c                          |  23 +-
 net/bridge/netfilter/nf_conntrack_bridge.c         |   2 +-
 net/core/sock.c                                    |   2 +-
 net/ipv4/inet_hashtables.c                         |   2 +-
 net/ipv4/tcp_output.c                              |   2 +-
 net/mac80211/cfg.c                                 |   4 +
 net/mptcp/pm_netlink.c                             |   5 +-
 net/mptcp/protocol.c                               |   4 +
 net/mptcp/sockopt.c                                |   3 +
 net/ncsi/ncsi-aen.c                                |   5 -
 net/netfilter/nf_tables_api.c                      |  58 ++--
 net/netfilter/nft_byteorder.c                      |   5 +-
 net/netfilter/nft_meta.c                           |   2 +-
 net/sched/act_ct.c                                 |   3 +
 net/sunrpc/clnt.c                                  |   7 +-
 net/sunrpc/rpcb_clnt.c                             |   4 +
 net/sunrpc/xprtrdma/svc_rdma_recvfrom.c            |   3 +-
 net/tipc/netlink_compat.c                          |   1 +
 net/unix/af_unix.c                                 |   9 +-
 net/vmw_vsock/af_vsock.c                           |   6 +
 samples/bpf/syscall_tp_user.c                      |  45 ++-
 scripts/Makefile.vmlinux                           |   1 +
 scripts/gcc-plugins/randomize_layout_plugin.c      |  21 +-
 security/integrity/iint.c                          |  48 ++-
 security/integrity/ima/ima_api.c                   |   5 +
 security/integrity/ima/ima_main.c                  |  16 +-
 security/integrity/integrity.h                     |   2 +
 security/keys/trusted-keys/trusted_core.c          |  20 +-
 security/keys/trusted-keys/trusted_tee.c           |  64 ++--
 sound/core/info.c                                  |  21 +-
 sound/hda/hdac_stream.c                            |   6 +-
 sound/pci/hda/patch_realtek.c                      |  26 +-
 sound/soc/codecs/lpass-wsa-macro.c                 |   3 +
 sound/soc/codecs/wsa883x.c                         |   7 +-
 sound/soc/intel/common/soc-acpi-intel-cht-match.c  |  43 +++
 sound/soc/mediatek/mt8188/mt8188-mt6359.c          |  21 ++
 sound/soc/soc-dai.c                                |   7 +
 sound/soc/soc-pcm.c                                |  12 +-
 sound/soc/sof/ipc4.c                               |   3 +
 sound/soc/sof/sof-audio.c                          |   7 +
 sound/soc/sof/sof-pci-dev.c                        |   8 +
 sound/soc/ti/omap-mcbsp.c                          |   6 +-
 sound/usb/mixer_scarlett_gen2.c                    |  63 ++--
 tools/include/uapi/linux/prctl.h                   |   2 +-
 tools/perf/util/intel-pt.c                         |   2 +
 tools/power/x86/turbostat/turbostat.c              |   3 +-
 tools/testing/cxl/test/cxl.c                       |   2 +-
 tools/testing/selftests/bpf/verifier/ld_imm64.c    |   8 +-
 tools/testing/selftests/clone3/clone3.c            |   7 +-
 tools/testing/selftests/efivarfs/create-read.c     |   2 +
 tools/testing/selftests/lkdtm/config               |   1 -
 tools/testing/selftests/lkdtm/tests.txt            |   2 +-
 tools/testing/selftests/net/mptcp/mptcp_join.sh    |   2 +-
 tools/testing/selftests/resctrl/Makefile           |   2 +-
 tools/testing/selftests/resctrl/cmt_test.c         |   3 -
 tools/testing/selftests/resctrl/mba_test.c         |   2 +-
 tools/testing/selftests/resctrl/mbm_test.c         |   2 +-
 tools/testing/selftests/resctrl/resctrl.h          |   1 -
 tools/testing/selftests/resctrl/resctrl_val.c      |   4 +-
 550 files changed, 6181 insertions(+), 2845 deletions(-)
author maintainer
#1 lore raw

PATCH 1/491 locking/ww_mutex/test: Fix potential workqueue corruption

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

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

From: John Stultz <[email protected]>

[ Upstream commit bccdd808902f8c677317cec47c306e42b93b849e ]

In some cases running with the test-ww_mutex code, I was seeing odd behavior where sometimes it seemed flush_workqueue was returning before all the work threads were finished.

Often this would cause strange crashes as the mutexes would be freed while they were being used.

Looking at the code, there is a lifetime problem as the controlling thread that spawns the work allocates the "struct stress" structures that are passed to the workqueue threads. Then when the workqueue threads are finished, they free the stress struct that was passed to them.

Unfortunately the workqueue work_struct node is in the stress struct. Which means the work_struct is freed before the work thread returns and while flush_workqueue is waiting.

It seems like a better idea to have the controlling thread both allocate and free the stress structures, so that we can be sure we don't corrupt the workqueue by freeing the structure prematurely.

So this patch reworks the test to do so, and with this change I no longer see the early flush_workqueue returns.

---
 kernel/locking/test-ww_mutex.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
kernel/locking/test-ww_mutex.c +12 -8
index 93cca6e698600..7c5a8f05497f2 100644
@@ -466,7 +466,6 @@ static void stress_inorder_work(struct work_struct *work)
 	} while (!time_after(jiffies, stress->timeout));
 
 	kfree(order);
-	kfree(stress);
 }
 
 struct reorder_lock {
@@ -531,7 +530,6 @@ static void stress_reorder_work(struct work_struct *work)
 	list_for_each_entry_safe(ll, ln, &locks, link)
 		kfree(ll);
 	kfree(order);
-	kfree(stress);
 }
 
 static void stress_one_work(struct work_struct *work)
@@ -552,8 +550,6 @@ static void stress_one_work(struct work_struct *work)
 			break;
 		}
 	} while (!time_after(jiffies, stress->timeout));
-
-	kfree(stress);
 }
 
 #define STRESS_INORDER BIT(0)
@@ -564,15 +560,24 @@ static void stress_one_work(struct work_struct *work)
 static int stress(int nlocks, int nthreads, unsigned int flags)
 {
 	struct ww_mutex *locks;
-	int n;
+	struct stress *stress_array;
+	int n, count;
 
 	locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL);
 	if (!locks)
 		return -ENOMEM;
 
+	stress_array = kmalloc_array(nthreads, sizeof(*stress_array),
+				     GFP_KERNEL);
+	if (!stress_array) {
+		kfree(locks);
+		return -ENOMEM;
+	}
+
 	for (n = 0; n < nlocks; n++)
 		ww_mutex_init(&locks[n], &ww_class);
 
+	count = 0;
 	for (n = 0; nthreads; n++) {
 		struct stress *stress;
 		void (*fn)(struct work_struct *work);
@@ -596,9 +601,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
 		if (!fn)
 			continue;
 
-		stress = kmalloc(sizeof(*stress), GFP_KERNEL);
-		if (!stress)
-			break;
+		stress = &stress_array[count++];
 
 		INIT_WORK(&stress->work, fn);
 		stress->locks = locks;
@@ -613,6 +616,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
 
 	for (n = 0; n < nlocks; n++)
 		ww_mutex_destroy(&locks[n]);
+	kfree(stress_array);
 	kfree(locks);
 
 	return 0;
Signature · 1 line
2.42.0
author maintainer
#2 lore raw

PATCH 2/491 btrfs: abort transaction on generation mismatch when marking eb as dirty

In reply to Greg Kroah-Hartman

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

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

From: Filipe Manana <[email protected]>

[ Upstream commit 50564b651d01c19ce732819c5b3c3fd60707188e ]

When marking an extent buffer as dirty, at btrfs_mark_buffer_dirty(), we check if its generation matches the running transaction and if not we just print a warning. Such mismatch is an indicator that something really went wrong and only printing a warning message (and stack trace) is not enough to prevent a corruption. Allowing a transaction to commit with such an extent buffer will trigger an error if we ever try to read it from disk due to a generation mismatch with its parent generation.

So abort the current transaction with -EUCLEAN if we notice a generation mismatch. For this we need to pass a transaction handle to btrfs_mark_buffer_dirty() which is always available except in test code, in which case we can pass NULL since it operates on dummy extent buffers and all test roots have a single node/leaf (root node at level 0).

---
 fs/btrfs/block-group.c               |   4 +-
 fs/btrfs/ctree.c                     | 109 +++++++++++++++------------
 fs/btrfs/ctree.h                     |  11 ++-
 fs/btrfs/delayed-inode.c             |   2 +-
 fs/btrfs/dev-replace.c               |   2 +-
 fs/btrfs/dir-item.c                  |   8 +-
 fs/btrfs/disk-io.c                   |  13 +++-
 fs/btrfs/disk-io.h                   |   3 +-
 fs/btrfs/extent-tree.c               |  36 +++++----
 fs/btrfs/file-item.c                 |  17 +++--
 fs/btrfs/file.c                      |  34 ++++-----
 fs/btrfs/free-space-cache.c          |   6 +-
 fs/btrfs/free-space-tree.c           |  17 +++--
 fs/btrfs/inode-item.c                |  16 ++--
 fs/btrfs/inode.c                     |  10 +--
 fs/btrfs/ioctl.c                     |   4 +-
 fs/btrfs/qgroup.c                    |  14 ++--
 fs/btrfs/relocation.c                |  10 +--
 fs/btrfs/root-tree.c                 |   4 +-
 fs/btrfs/tests/extent-buffer-tests.c |   6 +-
 fs/btrfs/tests/inode-tests.c         |  12 ++-
 fs/btrfs/tree-log.c                  |  12 +--
 fs/btrfs/uuid-tree.c                 |   6 +-
 fs/btrfs/volumes.c                   |  10 +--
 fs/btrfs/xattr.c                     |   8 +-
 25 files changed, 205 insertions(+), 169 deletions(-)
fs/btrfs/block-group.c +2 -2
index 5e7a19fca79c4..bf65f801d8439 100644
@@ -2587,7 +2587,7 @@ static int insert_dev_extent(struct btrfs_trans_handle *trans,
 	btrfs_set_dev_extent_chunk_offset(leaf, extent, chunk_offset);
 
 	btrfs_set_dev_extent_length(leaf, extent, num_bytes);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 out:
 	btrfs_free_path(path);
 	return ret;
@@ -3011,7 +3011,7 @@ static int update_block_group_item(struct btrfs_trans_handle *trans,
 						   cache->global_root_id);
 	btrfs_set_stack_block_group_flags(&bgi, cache->flags);
 	write_extent_buffer(leaf, &bgi, bi, sizeof(bgi));
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 fail:
 	btrfs_release_path(path);
 	/*
fs/btrfs/ctree.c +59 -50

370 lines not on this page · raw message

fs/btrfs/ctree.h +7 -4
index ff40acd63a374..06333a74d6c4c 100644
@@ -518,7 +518,7 @@ int btrfs_previous_item(struct btrfs_root *root,
 			int type);
 int btrfs_previous_extent_item(struct btrfs_root *root,
 			struct btrfs_path *path, u64 min_objectid);
-void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
+void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans,
 			     struct btrfs_path *path,
 			     const struct btrfs_key *new_key);
 struct extent_buffer *btrfs_root_node(struct btrfs_root *root);
@@ -545,8 +545,10 @@ int btrfs_block_can_be_shared(struct btrfs_trans_handle *trans,
 			      struct extent_buffer *buf);
 int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		  struct btrfs_path *path, int level, int slot);
-void btrfs_extend_item(struct btrfs_path *path, u32 data_size);
-void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end);
+void btrfs_extend_item(struct btrfs_trans_handle *trans,
+		       struct btrfs_path *path, u32 data_size);
+void btrfs_truncate_item(struct btrfs_trans_handle *trans,
+			 struct btrfs_path *path, u32 new_size, int from_end);
 int btrfs_split_item(struct btrfs_trans_handle *trans,
 		     struct btrfs_root *root,
 		     struct btrfs_path *path,
@@ -610,7 +612,8 @@ struct btrfs_item_batch {
 	int nr;
 };
 
-void btrfs_setup_item_for_insert(struct btrfs_root *root,
+void btrfs_setup_item_for_insert(struct btrfs_trans_handle *trans,
+				 struct btrfs_root *root,
 				 struct btrfs_path *path,
 				 const struct btrfs_key *key,
 				 u32 data_size);
fs/btrfs/delayed-inode.c +1 -1
index 142e0a0f6a9fe..5d3229b42b3e2 100644
@@ -1030,7 +1030,7 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
 				    struct btrfs_inode_item);
 	write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item,
 			    sizeof(struct btrfs_inode_item));
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	if (!test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags))
 		goto out;
fs/btrfs/dev-replace.c +1 -1
index 5f10965fd72bf..5549cbd9bdf6a 100644
@@ -442,7 +442,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans)
 	dev_replace->item_needs_writeback = 0;
 	up_write(&dev_replace->rwsem);
 
-	btrfs_mark_buffer_dirty(eb);
+	btrfs_mark_buffer_dirty(trans, eb);
 
 out:
 	btrfs_free_path(path);
fs/btrfs/dir-item.c +4 -4
index 082eb0e195981..9c07d5c3e5ad2 100644
@@ -38,7 +38,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
 		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
 		if (di)
 			return ERR_PTR(-EEXIST);
-		btrfs_extend_item(path, data_size);
+		btrfs_extend_item(trans, path, data_size);
 	} else if (ret < 0)
 		return ERR_PTR(ret);
 	WARN_ON(ret > 0);
@@ -93,7 +93,7 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
 
 	write_extent_buffer(leaf, name, name_ptr, name_len);
 	write_extent_buffer(leaf, data, data_ptr, data_len);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 
 	return ret;
 }
@@ -153,7 +153,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans,
 	name_ptr = (unsigned long)(dir_item + 1);
 
 	write_extent_buffer(leaf, name->name, name_ptr, name->len);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 second_insert:
 	/* FIXME, use some real flag for selecting the extra index */
@@ -439,7 +439,7 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
 		start = btrfs_item_ptr_offset(leaf, path->slots[0]);
 		memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
 			item_len - (ptr + sub_item_len - start));
-		btrfs_truncate_item(path, item_len - sub_item_len, 1);
+		btrfs_truncate_item(trans, path, item_len - sub_item_len, 1);
 	}
 	return ret;
 }
fs/btrfs/disk-io.c +9 -4
index 681594df7334f..1ae781f533582 100644
@@ -872,7 +872,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 	}
 
 	root->node = leaf;
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	root->commit_root = btrfs_root_node(root);
 	set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
@@ -947,7 +947,7 @@ int btrfs_alloc_log_tree_node(struct btrfs_trans_handle *trans,
 
 	root->node = leaf;
 
-	btrfs_mark_buffer_dirty(root->node);
+	btrfs_mark_buffer_dirty(trans, root->node);
 	btrfs_tree_unlock(root->node);
 
 	return 0;
@@ -4426,7 +4426,8 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
 	btrfs_close_devices(fs_info->fs_devices);
 }
 
-void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
+void btrfs_mark_buffer_dirty(struct btrfs_trans_handle *trans,
+			     struct extent_buffer *buf)
 {
 	struct btrfs_fs_info *fs_info = buf->fs_info;
 	u64 transid = btrfs_header_generation(buf);
@@ -4440,10 +4441,14 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
 	if (unlikely(test_bit(EXTENT_BUFFER_UNMAPPED, &buf->bflags)))
 		return;
 #endif
+	/* This is an active transaction (its state < TRANS_STATE_UNBLOCKED). */
+	ASSERT(trans->transid == fs_info->generation);
 	btrfs_assert_tree_write_locked(buf);
-	if (transid != fs_info->generation)
+	if (transid != fs_info->generation) {
 		WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n",
 			buf->start, transid, fs_info->generation);
+		btrfs_abort_transaction(trans, -EUCLEAN);
+	}
 	set_extent_buffer_dirty(buf);
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
 	/*
fs/btrfs/disk-io.h +2 -1
index b03767f4d7edf..e5bdb96912438 100644
@@ -105,7 +105,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 }
 
 void btrfs_put_root(struct btrfs_root *root);
-void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
+void btrfs_mark_buffer_dirty(struct btrfs_trans_handle *trans,
+			     struct extent_buffer *buf);
 int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
 			  int atomic);
 int btrfs_read_extent_buffer(struct extent_buffer *buf,
fs/btrfs/extent-tree.c +20 -16
index 14ea6b587e97b..118c56c512bd8 100644
@@ -596,7 +596,7 @@ static noinline int insert_extent_data_ref(struct btrfs_trans_handle *trans,
 			btrfs_set_extent_data_ref_count(leaf, ref, num_refs);
 		}
 	}
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	ret = 0;
 fail:
 	btrfs_release_path(path);
@@ -644,7 +644,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
 			btrfs_set_extent_data_ref_count(leaf, ref1, num_refs);
 		else if (key.type == BTRFS_SHARED_DATA_REF_KEY)
 			btrfs_set_shared_data_ref_count(leaf, ref2, num_refs);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 	}
 	return ret;
 }
@@ -997,7 +997,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
  * helper to add new inline back ref
  */
 static noinline_for_stack
-void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
+void setup_inline_extent_backref(struct btrfs_trans_handle *trans,
 				 struct btrfs_path *path,
 				 struct btrfs_extent_inline_ref *iref,
 				 u64 parent, u64 root_objectid,
@@ -1020,7 +1020,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
 	type = extent_ref_type(parent, owner);
 	size = btrfs_extent_inline_ref_size(type);
 
-	btrfs_extend_item(path, size);
+	btrfs_extend_item(trans, path, size);
 
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
 	refs = btrfs_extent_refs(leaf, ei);
@@ -1054,7 +1054,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
 	} else {
 		btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid);
 	}
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 }
 
 static int lookup_extent_backref(struct btrfs_trans_handle *trans,
@@ -1087,7 +1087,9 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
 /*
  * helper to update/remove inline back ref
  */
-static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *path,
+static noinline_for_stack int update_inline_extent_backref(
+				  struct btrfs_trans_handle *trans,
+				  struct btrfs_path *path,
 				  struct btrfs_extent_inline_ref *iref,
 				  int refs_to_mod,
 				  struct btrfs_delayed_extent_op *extent_op)
@@ -1195,9 +1197,9 @@ static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *pa
 			memmove_extent_buffer(leaf, ptr, ptr + size,
 					      end - ptr - size);
 		item_size -= size;
-		btrfs_truncate_item(path, item_size, 1);
+		btrfs_truncate_item(trans, path, item_size, 1);
 	}
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	return 0;
 }
 
@@ -1227,9 +1229,10 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
 				   bytenr, num_bytes, root_objectid, path->slots[0]);
 			return -EUCLEAN;
 		}
-		ret = update_inline_extent_backref(path, iref, refs_to_add, extent_op);
+		ret = update_inline_extent_backref(trans, path, iref,
+						   refs_to_add, extent_op);
 	} else if (ret == -ENOENT) {
-		setup_inline_extent_backref(trans->fs_info, path, iref, parent,
+		setup_inline_extent_backref(trans, path, iref, parent,
 					    root_objectid, owner, offset,
 					    refs_to_add, extent_op);
 		ret = 0;
@@ -1247,7 +1250,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
 
 	BUG_ON(!is_data && refs_to_drop != 1);
 	if (iref)
-		ret = update_inline_extent_backref(path, iref, -refs_to_drop, NULL);
+		ret = update_inline_extent_backref(trans, path, iref,
+						   -refs_to_drop, NULL);
 	else if (is_data)
 		ret = remove_extent_data_ref(trans, root, path, refs_to_drop);
 	else
@@ -1531,7 +1535,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 	if (extent_op)
 		__run_delayed_extent_op(extent_op, leaf, item);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	/* now insert the actual backref */
@@ -1697,7 +1701,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
 	__run_delayed_extent_op(extent_op, leaf, ei);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 out:
 	btrfs_free_path(path);
 	return err;
@@ -3171,7 +3175,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
 			}
 		} else {
 			btrfs_set_extent_refs(leaf, ei, refs);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 		}
 		if (found_extent) {
 			ret = remove_extent_backref(trans, extent_root, path,
@@ -4679,7 +4683,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
 		btrfs_set_extent_data_ref_count(leaf, ref, ref_mod);
 	}
 
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	btrfs_free_path(path);
 
 	return alloc_reserved_extent(trans, ins->objectid, ins->offset);
@@ -4754,7 +4758,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
 		btrfs_set_extent_inline_ref_offset(leaf, iref, ref->root);
 	}
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_free_path(path);
 
 	return alloc_reserved_extent(trans, node->bytenr, fs_info->nodesize);
fs/btrfs/file-item.c +9 -8
index 1ce5dd1544995..45cae356e89ba 100644
@@ -194,7 +194,7 @@ int btrfs_insert_hole_extent(struct btrfs_trans_handle *trans,
 	btrfs_set_file_extent_encryption(leaf, item, 0);
 	btrfs_set_file_extent_other_encoding(leaf, item, 0);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 out:
 	btrfs_free_path(path);
 	return ret;
@@ -811,11 +811,12 @@ blk_status_t btrfs_alloc_dummy_sum(struct btrfs_bio *bbio)
  * This calls btrfs_truncate_item with the correct args based on the overlap,
  * and fixes up the key as required.
  */
-static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
+static noinline void truncate_one_csum(struct btrfs_trans_handle *trans,
 				       struct btrfs_path *path,
 				       struct btrfs_key *key,
 				       u64 bytenr, u64 len)
 {
+	struct btrfs_fs_info *fs_info = trans->fs_info;
 	struct extent_buffer *leaf;
 	const u32 csum_size = fs_info->csum_size;
 	u64 csum_end;
@@ -836,7 +837,7 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
 		 */
 		u32 new_size = (bytenr - key->offset) >> blocksize_bits;
 		new_size *= csum_size;
-		btrfs_truncate_item(path, new_size, 1);
+		btrfs_truncate_item(trans, path, new_size, 1);
 	} else if (key->offset >= bytenr && csum_end > end_byte &&
 		   end_byte > key->offset) {
 		/*
@@ -848,10 +849,10 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
 		u32 new_size = (csum_end - end_byte) >> blocksize_bits;
 		new_size *= csum_size;
 
-		btrfs_truncate_item(path, new_size, 0);
+		btrfs_truncate_item(trans, path, new_size, 0);
 
 		key->offset = end_byte;
-		btrfs_set_item_key_safe(fs_info, path, key);
+		btrfs_set_item_key_safe(trans, path, key);
 	} else {
 		BUG();
 	}
@@ -994,7 +995,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
 
 			key.offset = end_byte - 1;
 		} else {
-			truncate_one_csum(fs_info, path, &key, bytenr, len);
+			truncate_one_csum(trans, path, &key, bytenr, len);
 			if (key.offset < bytenr)
 				break;
 		}
@@ -1202,7 +1203,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
 		diff /= csum_size;
 		diff *= csum_size;
 
-		btrfs_extend_item(path, diff);
+		btrfs_extend_item(trans, path, diff);
 		ret = 0;
 		goto csum;
 	}
@@ -1249,7 +1250,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
 	ins_size /= csum_size;
 	total_bytes += ins_size * fs_info->sectorsize;
 
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	if (total_bytes < sums->len) {
 		btrfs_release_path(path);
 		cond_resched();
fs/btrfs/file.c +17 -17
index eae9175f2c29b..a407af38a9237 100644
@@ -368,7 +368,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 			btrfs_set_file_extent_offset(leaf, fi, extent_offset);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							extent_end - args->start);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 
 			if (update_refs && disk_bytenr > 0) {
 				btrfs_init_generic_ref(&ref,
@@ -405,13 +405,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 
 			memcpy(&new_key, &key, sizeof(new_key));
 			new_key.offset = args->end;
-			btrfs_set_item_key_safe(fs_info, path, &new_key);
+			btrfs_set_item_key_safe(trans, path, &new_key);
 
 			extent_offset += args->end - key.offset;
 			btrfs_set_file_extent_offset(leaf, fi, extent_offset);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							extent_end - args->end);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 			if (update_refs && disk_bytenr > 0)
 				args->bytes_found += args->end - key.offset;
 			break;
@@ -431,7 +431,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							args->start - key.offset);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 			if (update_refs && disk_bytenr > 0)
 				args->bytes_found += extent_end - args->start;
 			if (args->end == extent_end)
@@ -536,7 +536,8 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 			if (btrfs_comp_cpu_keys(&key, &slot_key) > 0)
 				path->slots[0]++;
 		}
-		btrfs_setup_item_for_insert(root, path, &key, args->extent_item_size);
+		btrfs_setup_item_for_insert(trans, root, path, &key,
+					    args->extent_item_size);
 		args->extent_inserted = true;
 	}
 
@@ -593,7 +594,6 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot,
 int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 			      struct btrfs_inode *inode, u64 start, u64 end)
 {
-	struct btrfs_fs_info *fs_info = trans->fs_info;
 	struct btrfs_root *root = inode->root;
 	struct extent_buffer *leaf;
 	struct btrfs_path *path;
@@ -664,7 +664,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 				     ino, bytenr, orig_offset,
 				     &other_start, &other_end)) {
 			new_key.offset = end;
-			btrfs_set_item_key_safe(fs_info, path, &new_key);
+			btrfs_set_item_key_safe(trans, path, &new_key);
 			fi = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_file_extent_item);
 			btrfs_set_file_extent_generation(leaf, fi,
@@ -679,7 +679,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 							 trans->transid);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							end - other_start);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 			goto out;
 		}
 	}
@@ -698,7 +698,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 							 trans->transid);
 			path->slots[0]++;
 			new_key.offset = start;
-			btrfs_set_item_key_safe(fs_info, path, &new_key);
+			btrfs_set_item_key_safe(trans, path, &new_key);
 
 			fi = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_file_extent_item);
@@ -708,7 +708,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 							other_end - start);
 			btrfs_set_file_extent_offset(leaf, fi,
 						     start - orig_offset);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 			goto out;
 		}
 	}
@@ -742,7 +742,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 		btrfs_set_file_extent_offset(leaf, fi, split - orig_offset);
 		btrfs_set_file_extent_num_bytes(leaf, fi,
 						extent_end - split);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 
 		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, bytenr,
 				       num_bytes, 0);
@@ -814,7 +814,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 		btrfs_set_file_extent_type(leaf, fi,
 					   BTRFS_FILE_EXTENT_REG);
 		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 	} else {
 		fi = btrfs_item_ptr(leaf, del_slot - 1,
 			   struct btrfs_file_extent_item);
@@ -823,7 +823,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
 		btrfs_set_file_extent_num_bytes(leaf, fi,
 						extent_end - key.offset);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 
 		ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
 		if (ret < 0) {
@@ -2103,7 +2103,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
 		btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
 		btrfs_set_file_extent_offset(leaf, fi, 0);
 		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 		goto out;
 	}
 
@@ -2111,7 +2111,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
 		u64 num_bytes;
 
 		key.offset = offset;
-		btrfs_set_item_key_safe(fs_info, path, &key);
+		btrfs_set_item_key_safe(trans, path, &key);
 		fi = btrfs_item_ptr(leaf, path->slots[0],
 				    struct btrfs_file_extent_item);
 		num_bytes = btrfs_file_extent_num_bytes(leaf, fi) + end -
@@ -2120,7 +2120,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
 		btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
 		btrfs_set_file_extent_offset(leaf, fi, 0);
 		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 		goto out;
 	}
 	btrfs_release_path(path);
@@ -2272,7 +2272,7 @@ static int btrfs_insert_replace_extent(struct btrfs_trans_handle *trans,
 	btrfs_set_file_extent_num_bytes(leaf, extent, replace_len);
 	if (extent_info->is_new_extent)
 		btrfs_set_file_extent_generation(leaf, extent, trans->transid);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	ret = btrfs_inode_set_file_extent_range(inode, extent_info->file_offset,
fs/btrfs/free-space-cache.c +3 -3
index 8808004180759..6b7383ae5a70c 100644
@@ -195,7 +195,7 @@ static int __create_free_space_inode(struct btrfs_root *root,
 	btrfs_set_inode_nlink(leaf, inode_item, 1);
 	btrfs_set_inode_transid(leaf, inode_item, trans->transid);
 	btrfs_set_inode_block_group(leaf, inode_item, offset);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	key.objectid = BTRFS_FREE_SPACE_OBJECTID;
@@ -213,7 +213,7 @@ static int __create_free_space_inode(struct btrfs_root *root,
 				struct btrfs_free_space_header);
 	memzero_extent_buffer(leaf, (unsigned long)header, sizeof(*header));
 	btrfs_set_free_space_key(leaf, header, &disk_key);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	return 0;
@@ -1185,7 +1185,7 @@ update_cache_item(struct btrfs_trans_handle *trans,
 	btrfs_set_free_space_entries(leaf, header, entries);
 	btrfs_set_free_space_bitmaps(leaf, header, bitmaps);
 	btrfs_set_free_space_generation(leaf, header, trans->transid);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	return 0;
fs/btrfs/free-space-tree.c +9 -8
index f169378e2ca6e..ae060a26e1191 100644
@@ -89,7 +89,7 @@ static int add_new_free_space_info(struct btrfs_trans_handle *trans,
 			      struct btrfs_free_space_info);
 	btrfs_set_free_space_extent_count(leaf, info, 0);
 	btrfs_set_free_space_flags(leaf, info, 0);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	ret = 0;
 out:
@@ -287,7 +287,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
 	flags |= BTRFS_FREE_SPACE_USING_BITMAPS;
 	btrfs_set_free_space_flags(leaf, info, flags);
 	expected_extent_count = btrfs_free_space_extent_count(leaf, info);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	if (extent_count != expected_extent_count) {
@@ -324,7 +324,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
 		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
 		write_extent_buffer(leaf, bitmap_cursor, ptr,
 				    data_size);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 		btrfs_release_path(path);
 
 		i += extent_size;
@@ -430,7 +430,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
 	flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS;
 	btrfs_set_free_space_flags(leaf, info, flags);
 	expected_extent_count = btrfs_free_space_extent_count(leaf, info);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	nrbits = block_group->length >> block_group->fs_info->sectorsize_bits;
@@ -495,7 +495,7 @@ static int update_free_space_extent_count(struct btrfs_trans_handle *trans,
 
 	extent_count += new_extents;
 	btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	btrfs_release_path(path);
 
 	if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
@@ -533,7 +533,8 @@ int free_space_test_bit(struct btrfs_block_group *block_group,
 	return !!extent_buffer_test_bit(leaf, ptr, i);
 }
 
-static void free_space_set_bits(struct btrfs_block_group *block_group,
+static void free_space_set_bits(struct btrfs_trans_handle *trans,
+				struct btrfs_block_group *block_group,
 				struct btrfs_path *path, u64 *start, u64 *size,
 				int bit)
 {
@@ -563,7 +564,7 @@ static void free_space_set_bits(struct btrfs_block_group *block_group,
 		extent_buffer_bitmap_set(leaf, ptr, first, last - first);
 	else
 		extent_buffer_bitmap_clear(leaf, ptr, first, last - first);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	*size -= end - *start;
 	*start = end;
@@ -656,7 +657,7 @@ static int modify_free_space_bitmap(struct btrfs_trans_handle *trans,
 	cur_start = start;
 	cur_size = size;
 	while (1) {
-		free_space_set_bits(block_group, path, &cur_start, &cur_size,
+		free_space_set_bits(trans, block_group, path, &cur_start, &cur_size,
 				    !remove);
 		if (cur_size == 0)
 			break;
fs/btrfs/inode-item.c +8 -8
index 4c322b720a80a..d3ff97374d48a 100644
@@ -167,7 +167,7 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
 	memmove_extent_buffer(leaf, ptr, ptr + del_len,
 			      item_size - (ptr + del_len - item_start));
 
-	btrfs_truncate_item(path, item_size - del_len, 1);
+	btrfs_truncate_item(trans, path, item_size - del_len, 1);
 
 out:
 	btrfs_free_path(path);
@@ -229,7 +229,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
 	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
 	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
 			      item_size - (ptr + sub_item_len - item_start));
-	btrfs_truncate_item(path, item_size - sub_item_len, 1);
+	btrfs_truncate_item(trans, path, item_size - sub_item_len, 1);
 out:
 	btrfs_free_path(path);
 
@@ -282,7 +282,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
 						   name))
 			goto out;
 
-		btrfs_extend_item(path, ins_len);
+		btrfs_extend_item(trans, path, ins_len);
 		ret = 0;
 	}
 	if (ret < 0)
@@ -299,7 +299,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
 
 	ptr = (unsigned long)&extref->name;
 	write_extent_buffer(path->nodes[0], name->name, ptr, name->len);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 
 out:
 	btrfs_free_path(path);
@@ -338,7 +338,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
 			goto out;
 
 		old_size = btrfs_item_size(path->nodes[0], path->slots[0]);
-		btrfs_extend_item(path, ins_len);
+		btrfs_extend_item(trans, path, ins_len);
 		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
 				     struct btrfs_inode_ref);
 		ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
@@ -364,7 +364,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
 		ptr = (unsigned long)(ref + 1);
 	}
 	write_extent_buffer(path->nodes[0], name->name, ptr, name->len);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 
 out:
 	btrfs_free_path(path);
@@ -591,7 +591,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 				num_dec = (orig_num_bytes - extent_num_bytes);
 				if (extent_start != 0)
 					control->sub_bytes += num_dec;
-				btrfs_mark_buffer_dirty(leaf);
+				btrfs_mark_buffer_dirty(trans, leaf);
 			} else {
 				extent_num_bytes =
 					btrfs_file_extent_disk_num_bytes(leaf, fi);
@@ -617,7 +617,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 
 				btrfs_set_file_extent_ram_bytes(leaf, fi, size);
 				size = btrfs_file_extent_calc_inline_size(size);
-				btrfs_truncate_item(path, size, 1);
+				btrfs_truncate_item(trans, path, size, 1);
 			} else if (!del_item) {
 				/*
 				 * We have to bail so the last_size is set to
fs/btrfs/inode.c +5 -5
index 0f4498dfa30c9..58e104f118f96 100644
@@ -573,7 +573,7 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
 		kunmap_local(kaddr);
 		put_page(page);
 	}
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	/*
@@ -3072,7 +3072,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
 			btrfs_item_ptr_offset(leaf, path->slots[0]),
 			sizeof(struct btrfs_file_extent_item));
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_release_path(path);
 
 	/*
@@ -4134,7 +4134,7 @@ static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans,
 				    struct btrfs_inode_item);
 
 	fill_inode_item(trans, leaf, inode_item, &inode->vfs_inode);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_set_inode_last_trans(trans, inode);
 	ret = 0;
 failed:
@@ -6476,7 +6476,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
 		}
 	}
 
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	/*
 	 * We don't need the path anymore, plus inheriting properties, adding
 	 * ACLs, security xattrs, orphan item or adding the link, will result in
@@ -9630,7 +9630,7 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
 
 	ptr = btrfs_file_extent_inline_start(ei);
 	write_extent_buffer(leaf, symname, ptr, name_len);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 	btrfs_free_path(path);
 
 	d_instantiate_new(dentry, inode);
fs/btrfs/ioctl.c +2 -2
index 6d0df9bc1e72b..8bdf9bed25c75 100644
@@ -663,7 +663,7 @@ static noinline int create_subvol(struct mnt_idmap *idmap,
 		goto out;
 	}
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	inode_item = &root_item->inode;
 	btrfs_set_stack_inode_generation(inode_item, 1);
@@ -2947,7 +2947,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 
 	btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
 	btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	btrfs_release_path(path);
 
 	btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL);
fs/btrfs/qgroup.c +7 -7
index 2637d6b157ff9..74cabaa59be71 100644
@@ -622,7 +622,7 @@ static int add_qgroup_relation_item(struct btrfs_trans_handle *trans, u64 src,
 
 	ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0);
 
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 
 	btrfs_free_path(path);
 	return ret;
@@ -700,7 +700,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
 	btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
 	btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	btrfs_release_path(path);
 
@@ -719,7 +719,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
 	btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
 	btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	ret = 0;
 out:
@@ -808,7 +808,7 @@ static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
 	btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, qgroup->rsv_rfer);
 	btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, qgroup->rsv_excl);
 
-	btrfs_mark_buffer_dirty(l);
+	btrfs_mark_buffer_dirty(trans, l);
 
 out:
 	btrfs_free_path(path);
@@ -854,7 +854,7 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
 	btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
 	btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
 
-	btrfs_mark_buffer_dirty(l);
+	btrfs_mark_buffer_dirty(trans, l);
 
 out:
 	btrfs_free_path(path);
@@ -896,7 +896,7 @@ static int update_qgroup_status_item(struct btrfs_trans_handle *trans)
 	btrfs_set_qgroup_status_rescan(l, ptr,
 				fs_info->qgroup_rescan_progress.objectid);
 
-	btrfs_mark_buffer_dirty(l);
+	btrfs_mark_buffer_dirty(trans, l);
 
 out:
 	btrfs_free_path(path);
@@ -1069,7 +1069,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 				      BTRFS_QGROUP_STATUS_FLAGS_MASK);
 	btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	key.objectid = 0;
 	key.type = BTRFS_ROOT_REF_KEY;
fs/btrfs/relocation.c +5 -5
index 62ed57551824c..31781af447553 100644
@@ -1181,7 +1181,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
 		}
 	}
 	if (dirty)
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 	if (inode)
 		btrfs_add_delayed_iput(BTRFS_I(inode));
 	return ret;
@@ -1374,13 +1374,13 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
 		 */
 		btrfs_set_node_blockptr(parent, slot, new_bytenr);
 		btrfs_set_node_ptr_generation(parent, slot, new_ptr_gen);
-		btrfs_mark_buffer_dirty(parent);
+		btrfs_mark_buffer_dirty(trans, parent);
 
 		btrfs_set_node_blockptr(path->nodes[level],
 					path->slots[level], old_bytenr);
 		btrfs_set_node_ptr_generation(path->nodes[level],
 					      path->slots[level], old_ptr_gen);
-		btrfs_mark_buffer_dirty(path->nodes[level]);
+		btrfs_mark_buffer_dirty(trans, path->nodes[level]);
 
 		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr,
 				       blocksize, path->nodes[level]->start);
@@ -2517,7 +2517,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
 						node->eb->start);
 			btrfs_set_node_ptr_generation(upper->eb, slot,
 						      trans->transid);
-			btrfs_mark_buffer_dirty(upper->eb);
+			btrfs_mark_buffer_dirty(trans, upper->eb);
 
 			btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF,
 					       node->eb->start, blocksize,
@@ -3833,7 +3833,7 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
 	btrfs_set_inode_mode(leaf, item, S_IFREG | 0600);
 	btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS |
 					  BTRFS_INODE_PREALLOC);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 out:
 	btrfs_free_path(path);
 	return ret;
fs/btrfs/root-tree.c +2 -2
index 859874579456f..5b0f1bccc409c 100644
@@ -191,7 +191,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
 	btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
 
 	write_extent_buffer(l, item, ptr, sizeof(*item));
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 out:
 	btrfs_free_path(path);
 	return ret;
@@ -438,7 +438,7 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
 	btrfs_set_root_ref_name_len(leaf, ref, name->len);
 	ptr = (unsigned long)(ref + 1);
 	write_extent_buffer(leaf, name->name, ptr, name->len);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	if (key.type == BTRFS_ROOT_BACKREF_KEY) {
 		btrfs_release_path(path);
fs/btrfs/tests/extent-buffer-tests.c +5 -1
index 5ef0b90e25c3b..6a43a64ba55ad 100644
@@ -61,7 +61,11 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
 	key.type = BTRFS_EXTENT_CSUM_KEY;
 	key.offset = 0;
 
-	btrfs_setup_item_for_insert(root, path, &key, value_len);
+	/*
+	 * Passing a NULL trans handle is fine here, we have a dummy root eb
+	 * and the tree is a single node (level 0).
+	 */
+	btrfs_setup_item_for_insert(NULL, root, path, &key, value_len);
 	write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0),
 			    value_len);
 
fs/btrfs/tests/inode-tests.c +10 -2
index 05b03f5eab83b..492d69d2fa737 100644
@@ -34,7 +34,11 @@ static void insert_extent(struct btrfs_root *root, u64 start, u64 len,
 	key.type = BTRFS_EXTENT_DATA_KEY;
 	key.offset = start;
 
-	btrfs_setup_item_for_insert(root, &path, &key, value_len);
+	/*
+	 * Passing a NULL trans handle is fine here, we have a dummy root eb
+	 * and the tree is a single node (level 0).
+	 */
+	btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len);
 	fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
 	btrfs_set_file_extent_generation(leaf, fi, 1);
 	btrfs_set_file_extent_type(leaf, fi, type);
@@ -64,7 +68,11 @@ static void insert_inode_item_key(struct btrfs_root *root)
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 
-	btrfs_setup_item_for_insert(root, &path, &key, value_len);
+	/*
+	 * Passing a NULL trans handle is fine here, we have a dummy root eb
+	 * and the tree is a single node (level 0).
+	 */
+	btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len);
 }
 
 /*
fs/btrfs/tree-log.c +6 -6
index a00e7a0bc713d..ad0d934991741 100644
@@ -504,9 +504,9 @@ static int overwrite_item(struct btrfs_trans_handle *trans,
 		found_size = btrfs_item_size(path->nodes[0],
 						path->slots[0]);
 		if (found_size > item_size)
-			btrfs_truncate_item(path, item_size, 1);
+			btrfs_truncate_item(trans, path, item_size, 1);
 		else if (found_size < item_size)
-			btrfs_extend_item(path, item_size - found_size);
+			btrfs_extend_item(trans, path, item_size - found_size);
 	} else if (ret) {
 		return ret;
 	}
@@ -574,7 +574,7 @@ static int overwrite_item(struct btrfs_trans_handle *trans,
 		}
 	}
 no_copy:
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	btrfs_release_path(path);
 	return 0;
 }
@@ -3530,7 +3530,7 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
 		last_offset = max(last_offset, curr_end);
 	}
 	btrfs_set_dir_log_end(path->nodes[0], item, last_offset);
-	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
 	btrfs_release_path(path);
 	return 0;
 }
@@ -4488,7 +4488,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
 		dst_index++;
 	}
 
-	btrfs_mark_buffer_dirty(dst_path->nodes[0]);
+	btrfs_mark_buffer_dirty(trans, dst_path->nodes[0]);
 	btrfs_release_path(dst_path);
 out:
 	kfree(ins_data);
@@ -4693,7 +4693,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
 	write_extent_buffer(leaf, &fi,
 			    btrfs_item_ptr_offset(leaf, path->slots[0]),
 			    sizeof(fi));
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	btrfs_release_path(path);
 
fs/btrfs/uuid-tree.c +3 -3
index 7c7001f42b14c..5be74f9e47ebf 100644
@@ -124,7 +124,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
 		 * An item with that type already exists.
 		 * Extend the item and store the new subid at the end.
 		 */
-		btrfs_extend_item(path, sizeof(subid_le));
+		btrfs_extend_item(trans, path, sizeof(subid_le));
 		eb = path->nodes[0];
 		slot = path->slots[0];
 		offset = btrfs_item_ptr_offset(eb, slot);
@@ -139,7 +139,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
 	ret = 0;
 	subid_le = cpu_to_le64(subid_cpu);
 	write_extent_buffer(eb, &subid_le, offset, sizeof(subid_le));
-	btrfs_mark_buffer_dirty(eb);
+	btrfs_mark_buffer_dirty(trans, eb);
 
 out:
 	btrfs_free_path(path);
@@ -221,7 +221,7 @@ int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
 	move_src = offset + sizeof(subid);
 	move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot));
 	memmove_extent_buffer(eb, move_dst, move_src, move_len);
-	btrfs_truncate_item(path, item_size - sizeof(subid), 1);
+	btrfs_truncate_item(trans, path, item_size - sizeof(subid), 1);
 
 out:
 	btrfs_free_path(path);
fs/btrfs/volumes.c +5 -5
index 5019e9244d2d2..1df496c809376 100644
@@ -1908,7 +1908,7 @@ static int btrfs_add_dev_item(struct btrfs_trans_handle *trans,
 	ptr = btrfs_device_fsid(dev_item);
 	write_extent_buffer(leaf, trans->fs_info->fs_devices->metadata_uuid,
 			    ptr, BTRFS_FSID_SIZE);
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 	ret = 0;
 out:
@@ -2613,7 +2613,7 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans)
 		if (device->fs_devices->seeding) {
 			btrfs_set_device_generation(leaf, dev_item,
 						    device->generation);
-			btrfs_mark_buffer_dirty(leaf);
+			btrfs_mark_buffer_dirty(trans, leaf);
 		}
 
 		path->slots[0]++;
@@ -2911,7 +2911,7 @@ static noinline int btrfs_update_device(struct btrfs_trans_handle *trans,
 				     btrfs_device_get_disk_total_bytes(device));
 	btrfs_set_device_bytes_used(leaf, dev_item,
 				    btrfs_device_get_bytes_used(device));
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 
 out:
 	btrfs_free_path(path);
@@ -3499,7 +3499,7 @@ static int insert_balance_item(struct btrfs_fs_info *fs_info,
 
 	btrfs_set_balance_flags(leaf, item, bctl->flags);
 
-	btrfs_mark_buffer_dirty(leaf);
+	btrfs_mark_buffer_dirty(trans, leaf);
 out:
 	btrfs_free_path(path);
 	err = btrfs_commit_transaction(trans);
@@ -7513,7 +7513,7 @@ static int update_dev_stat_item(struct btrfs_trans_handle *trans,
 	for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
 		btrfs_set_dev_stats_value(eb, ptr, i,
 					  btrfs_dev_stat_read(device, i));
-	btrfs_mark_buffer_dirty(eb);
+	btrfs_mark_buffer_dirty(trans, eb);
 
 out:
 	btrfs_free_path(path);
fs/btrfs/xattr.c +4 -4
index fc4b20c2688a0..c454b8ce6babe 100644
@@ -188,15 +188,15 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
 		if (old_data_len + name_len + sizeof(*di) == item_size) {
 			/* No other xattrs packed in the same leaf item. */
 			if (size > old_data_len)
-				btrfs_extend_item(path, size - old_data_len);
+				btrfs_extend_item(trans, path, size - old_data_len);
 			else if (size < old_data_len)
-				btrfs_truncate_item(path, data_size, 1);
+				btrfs_truncate_item(trans, path, data_size, 1);
 		} else {
 			/* There are other xattrs packed in the same item. */
 			ret = btrfs_delete_one_dir_name(trans, root, path, di);
 			if (ret)
 				goto out;
-			btrfs_extend_item(path, data_size);
+			btrfs_extend_item(trans, path, data_size);
 		}
 
 		ptr = btrfs_item_ptr(leaf, slot, char);
@@ -205,7 +205,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
 		btrfs_set_dir_data_len(leaf, di, size);
 		data_ptr = ((unsigned long)(di + 1)) + name_len;
 		write_extent_buffer(leaf, value, data_ptr, size);
-		btrfs_mark_buffer_dirty(leaf);
+		btrfs_mark_buffer_dirty(trans, leaf);
 	} else {
 		/*
 		 * Insert, and we had space for the xattr, so path->slots[0] is
Signature · 1 line
2.42.0
author maintainer
#3 lore raw

PATCH 3/491 lib/generic-radix-tree.c: Dont overflow in peek()

In reply to Greg Kroah-Hartman

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

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

From: Kent Overstreet <[email protected]>

[ Upstream commit 9492261ff2460252cf2d8de89cdf854c7e2b28a0 ]

When we started spreading new inode numbers throughout most of the 64 bit inode space, that triggered some corner case bugs, in particular some integer overflows related to the radix tree code. Oops.

---
 include/linux/generic-radix-tree.h |  7 +++++++
 lib/generic-radix-tree.c           | 17 ++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
include/linux/generic-radix-tree.h +7 -0
index 107613f7d7920..f6cd0f909d9fb 100644
@@ -38,6 +38,7 @@
 
 #include <asm/page.h>
 #include <linux/bug.h>
+#include <linux/limits.h>
 #include <linux/log2.h>
 #include <linux/math.h>
 #include <linux/types.h>
@@ -184,6 +185,12 @@ void *__genradix_iter_peek(struct genradix_iter *, struct __genradix *, size_t);
 static inline void __genradix_iter_advance(struct genradix_iter *iter,
 					   size_t obj_size)
 {
+	if (iter->offset + obj_size < iter->offset) {
+		iter->offset	= SIZE_MAX;
+		iter->pos	= SIZE_MAX;
+		return;
+	}
+
 	iter->offset += obj_size;
 
 	if (!is_power_of_2(obj_size) &&
lib/generic-radix-tree.c +14 -3
index f25eb111c0516..7dfa88282b006 100644
@@ -166,6 +166,10 @@ void *__genradix_iter_peek(struct genradix_iter *iter,
 	struct genradix_root *r;
 	struct genradix_node *n;
 	unsigned level, i;
+
+	if (iter->offset == SIZE_MAX)
+		return NULL;
+
 restart:
 	r = READ_ONCE(radix->root);
 	if (!r)
@@ -184,10 +188,17 @@ void *__genradix_iter_peek(struct genradix_iter *iter,
 			(GENRADIX_ARY - 1);
 
 		while (!n->children[i]) {
+			size_t objs_per_ptr = genradix_depth_size(level);
+
+			if (iter->offset + objs_per_ptr < iter->offset) {
+				iter->offset	= SIZE_MAX;
+				iter->pos	= SIZE_MAX;
+				return NULL;
+			}
+
 			i++;
-			iter->offset = round_down(iter->offset +
-					   genradix_depth_size(level),
-					   genradix_depth_size(level));
+			iter->offset = round_down(iter->offset + objs_per_ptr,
+						  objs_per_ptr);
 			iter->pos = (iter->offset >> PAGE_SHIFT) *
 				objs_per_page;
 			if (i == GENRADIX_ARY)
Signature · 1 line
2.42.0
author maintainer
#4 lore raw

PATCH 4/491 x86/retpoline: Make sure there are no unconverted return thunks due to KCSAN

In reply to Greg Kroah-Hartman

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

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

From: Josh Poimboeuf <[email protected]>

[ Upstream commit 2d7ce49f58dc95495b3e22e45d2be7de909b2c63 ]

Enabling CONFIG_KCSAN leads to unconverted, default return thunks to remain after patching.

As David Kaplan describes in his debugging of the issue, it is caused by a couple of KCSAN-generated constructors which aren't processed by objtool:

"When KCSAN is enabled, GCC generates lots of constructor functions named _sub_I_00099_0 which call __tsan_init and then return. The returns in these are generally annotated normally by objtool and fixed up at runtime. But objtool runs on vmlinux.o and vmlinux.o does not include a couple of object files that are in vmlinux, like init/version-timestamp.o and .vmlinux.export.o, both of which contain _sub_I_00099_0 functions. As a result, the returns in these functions are not annotated, and the panic occurs when we call one of them in do_ctors and it uses the default return thunk.

This difference can be seen by counting the number of these functions in the object files:

  $ objdump -d vmlinux.o|grep -c "<_sub_I_00099_0>:"
  2601
  $ objdump -d vmlinux|grep -c "<_sub_I_00099_0>:"
  2603

If these functions are only run during kernel boot, there is no speculation concern."

Fix it by disabling KCSAN on version-timestamp.o and .vmlinux.export.o so the extra functions don't get generated. KASAN and GCOV are already disabled for those files.

[ bp: Massage commit message. ]

---
 init/Makefile            | 1 +
 scripts/Makefile.vmlinux | 1 +
 2 files changed, 2 insertions(+)
init/Makefile +1 -0
index ec557ada3c12e..cbac576c57d63 100644
@@ -60,4 +60,5 @@ include/generated/utsversion.h: FORCE
 $(obj)/version-timestamp.o: include/generated/utsversion.h
 CFLAGS_version-timestamp.o := -include include/generated/utsversion.h
 KASAN_SANITIZE_version-timestamp.o := n
+KCSAN_SANITIZE_version-timestamp.o := n
 GCOV_PROFILE_version-timestamp.o := n
scripts/Makefile.vmlinux +1 -0
index 3cd6ca15f390d..c9f3e03124d7f 100644
@@ -19,6 +19,7 @@ quiet_cmd_cc_o_c = CC      $@
 
 ifdef CONFIG_MODULES
 KASAN_SANITIZE_.vmlinux.export.o := n
+KCSAN_SANITIZE_.vmlinux.export.o := n
 GCOV_PROFILE_.vmlinux.export.o := n
 targets += .vmlinux.export.o
 vmlinux: .vmlinux.export.o
Signature · 1 line
2.42.0
author maintainer
#5 lore raw

PATCH 5/491 perf/core: Bail out early if the request AUX area is out of bound

In reply to Greg Kroah-Hartman

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

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

From: Shuai Xue <[email protected]>

[ Upstream commit 54aee5f15b83437f23b2b2469bcf21bdd9823916 ]

When perf-record with a large AUX area, e.g 4GB, it fails with:

#perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 failed to mmap with 12 (Cannot allocate memory)

and it reveals a WARNING with __alloc_pages():

	------------[ cut here ]------------
	WARNING: CPU: 44 PID: 17573 at mm/page_alloc.c:5568 __alloc_pages+0x1ec/0x248
	Call trace:
	 __alloc_pages+0x1ec/0x248
	 __kmalloc_large_node+0xc0/0x1f8
	 __kmalloc_node+0x134/0x1e8
	 rb_alloc_aux+0xe0/0x298
	 perf_mmap+0x440/0x660
	 mmap_region+0x308/0x8a8
	 do_mmap+0x3c0/0x528
	 vm_mmap_pgoff+0xf4/0x1b8
	 ksys_mmap_pgoff+0x18c/0x218
	 __arm64_sys_mmap+0x38/0x58
	 invoke_syscall+0x50/0x128
	 el0_svc_common.constprop.0+0x58/0x188
	 do_el0_svc+0x34/0x50
	 el0_svc+0x34/0x108
	 el0t_64_sync_handler+0xb8/0xc0
	 el0t_64_sync+0x1a4/0x1a8

'rb->aux_pages' allocated by kcalloc() is a pointer array which is used to maintains AUX trace pages. The allocated page for this array is physically contiguous (and virtually contiguous) with an order of 0..MAX_ORDER. If the size of pointer array crosses the limitation set by MAX_ORDER, it reveals a WARNING.

So bail out early with -ENOMEM if the request AUX area is out of bound, e.g.:

#perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 failed to mmap with 12 (Cannot allocate memory)

---
 kernel/events/ring_buffer.c | 6 ++++++
 1 file changed, 6 insertions(+)
kernel/events/ring_buffer.c +6 -0
index a0433f37b0243..4a260ceed9c73 100644
@@ -699,6 +699,12 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
 		watermark = 0;
 	}
 
+	/*
+	 * kcalloc_node() is unable to allocate buffer if the size is larger
+	 * than: PAGE_SIZE << MAX_ORDER; directly bail out in this case.
+	 */
+	if (get_order((unsigned long)nr_pages * sizeof(void *)) > MAX_ORDER)
+		return -ENOMEM;
 	rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL,
 				     node);
 	if (!rb->aux_pages)
Signature · 1 line
2.42.0
author maintainer
#6 lore raw

PATCH 6/491 rcu: Dump memory object info if callback function is invalid

In reply to Greg Kroah-Hartman

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

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

From: Zhen Lei <[email protected]>

[ Upstream commit 2cbc482d325ee58001472c4359b311958c4efdd1 ]

When a structure containing an RCU callback rhp is (incorrectly) freed and reallocated after rhp is passed to call_rcu(), it is not unusual for rhp->func to be set to NULL. This defeats the debugging prints used by __call_rcu_common() in kernels built with CONFIG_DEBUG_OBJECTS_RCU_HEAD=y, which expect to identify the offending code using the identity of this function.

And in kernels build without CONFIG_DEBUG_OBJECTS_RCU_HEAD=y, things are even worse, as can be seen from this splat:

Unable to handle kernel NULL pointer dereference at virtual address 0

... ...
PC is at 0x0
LR is at rcu_do_batch+0x1c0/0x3b8
... ...
(rcu_do_batch) from (rcu_core+0x1d4/0x284) (rcu_core) from (__do_softirq+0x24c/0x344) (__do_softirq) from (__irq_exit_rcu+0x64/0x108) (__irq_exit_rcu) from (irq_exit+0x8/0x10) (irq_exit) from (__handle_domain_irq+0x74/0x9c) (__handle_domain_irq) from (gic_handle_irq+0x8c/0x98) (gic_handle_irq) from (__irq_svc+0x5c/0x94) (__irq_svc) from (arch_cpu_idle+0x20/0x3c) (arch_cpu_idle) from (default_idle_call+0x4c/0x78) (default_idle_call) from (do_idle+0xf8/0x150) (do_idle) from (cpu_startup_entry+0x18/0x20) (cpu_startup_entry) from (0xc01530)

This commit therefore adds calls to mem_dump_obj(rhp) to output some information, for example:

slab kmalloc-256 start ffff410c45019900 pointer offset 0 size 256

This provides the rough size of the memory block and the offset of the rcu_head structure, which as least provides at least a few clues to help locate the problem. If the problem is reproducible, additional slab debugging can be enabled, for example, CONFIG_DEBUG_SLAB=y, which can provide significantly more information.

---
 kernel/rcu/rcu.h      | 7 +++++++
 kernel/rcu/srcutiny.c | 1 +
 kernel/rcu/srcutree.c | 1 +
 kernel/rcu/tasks.h    | 1 +
 kernel/rcu/tiny.c     | 1 +
 kernel/rcu/tree.c     | 1 +
 6 files changed, 12 insertions(+)
kernel/rcu/rcu.h +7 -0
index 98c1544cf572b..7ae3496b0b58d 100644
@@ -10,6 +10,7 @@
 #ifndef __LINUX_RCU_H
 #define __LINUX_RCU_H
 
+#include <linux/slab.h>
 #include <trace/events/rcu.h>
 
 /*
@@ -248,6 +249,12 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head)
 }
 #endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
+static inline void debug_rcu_head_callback(struct rcu_head *rhp)
+{
+	if (unlikely(!rhp->func))
+		kmem_dump_obj(rhp);
+}
+
 extern int rcu_cpu_stall_suppress_at_boot;
 
 static inline bool rcu_stall_is_suppressed_at_boot(void)
kernel/rcu/srcutiny.c +1 -0
index 336af24e0fe35..c38e5933a5d69 100644
@@ -138,6 +138,7 @@ void srcu_drive_gp(struct work_struct *wp)
 	while (lh) {
 		rhp = lh;
 		lh = lh->next;
+		debug_rcu_head_callback(rhp);
 		local_bh_disable();
 		rhp->func(rhp);
 		local_bh_enable();
kernel/rcu/srcutree.c +1 -0
index 253ed509b6abb..c6481032d42be 100644
@@ -1735,6 +1735,7 @@ static void srcu_invoke_callbacks(struct work_struct *work)
 	rhp = rcu_cblist_dequeue(&ready_cbs);
 	for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) {
 		debug_rcu_head_unqueue(rhp);
+		debug_rcu_head_callback(rhp);
 		local_bh_disable();
 		rhp->func(rhp);
 		local_bh_enable();
kernel/rcu/tasks.h +1 -0
index b770add3f8430..b64d45cdea9c4 100644
@@ -493,6 +493,7 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu
 	raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags);
 	len = rcl.len;
 	for (rhp = rcu_cblist_dequeue(&rcl); rhp; rhp = rcu_cblist_dequeue(&rcl)) {
+		debug_rcu_head_callback(rhp);
 		local_bh_disable();
 		rhp->func(rhp);
 		local_bh_enable();
kernel/rcu/tiny.c +1 -0
index 42f7589e51e09..fec804b790803 100644
@@ -97,6 +97,7 @@ static inline bool rcu_reclaim_tiny(struct rcu_head *head)
 
 	trace_rcu_invoke_callback("", head);
 	f = head->func;
+	debug_rcu_head_callback(head);
 	WRITE_ONCE(head->func, (rcu_callback_t)0L);
 	f(head);
 	rcu_lock_release(&rcu_callback_map);
kernel/rcu/tree.c +1 -0
index 1449cb69a0e0e..9b9ebe6205b93 100644
@@ -2131,6 +2131,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
 		trace_rcu_invoke_callback(rcu_state.name, rhp);
 
 		f = rhp->func;
+		debug_rcu_head_callback(rhp);
 		WRITE_ONCE(rhp->func, (rcu_callback_t)0L);
 		f(rhp);
 
Signature · 1 line
2.42.0
author maintainer
#7 lore raw

PATCH 7/491 srcu: Fix srcu_struct node grpmask overflow on 64-bit systems

In reply to Greg Kroah-Hartman

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

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

From: Denis Arefev <[email protected]>

[ Upstream commit d8d5b7bf6f2105883bbd91bbd4d5b67e4e3dff71 ]

The value of a bitwise expression 1 << (cpu - sdp->mynode->grplo) is subject to overflow due to a failure to cast operands to a larger data type before performing the bitwise operation.

The maximum result of this subtraction is defined by the RCU_FANOUT_LEAF Kconfig option, which on 64-bit systems defaults to 16 (resulting in a maximum shift of 15), but which can be set up as high as 64 (resulting in a maximum shift of 63). A value of 31 can result in sign extension, resulting in 0xffffffff80000000 instead of the desired 0x80000000. A value of 32 or greater triggers undefined behavior per the C standard.

This bug has not been known to cause issues because almost all kernels take the default CONFIG_RCU_FANOUT_LEAF=16. Furthermore, as long as a given compiler gives a deterministic non-zero result for 1<<N for N>=32, the code correctly invokes all SRCU callbacks, albeit wasting CPU time along the way.

This commit therefore substitutes the correct 1UL for the buggy 1.

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

---
 kernel/rcu/srcutree.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/srcutree.c +2 -2
index c6481032d42be..7522517b63b6f 100644
@@ -223,7 +223,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
 				snp->grplo = cpu;
 			snp->grphi = cpu;
 		}
-		sdp->grpmask = 1 << (cpu - sdp->mynode->grplo);
+		sdp->grpmask = 1UL << (cpu - sdp->mynode->grplo);
 	}
 	smp_store_release(&ssp->srcu_sup->srcu_size_state, SRCU_SIZE_WAIT_BARRIER);
 	return true;
@@ -833,7 +833,7 @@ static void srcu_schedule_cbs_snp(struct srcu_struct *ssp, struct srcu_node *snp
 	int cpu;
 
 	for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) {
-		if (!(mask & (1 << (cpu - snp->grplo))))
+		if (!(mask & (1UL << (cpu - snp->grplo))))
 			continue;
 		srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, cpu), delay);
 	}
Signature · 1 line
2.42.0
author maintainer
#8 lore raw

PATCH 8/491 selftests/lkdtm: Disable CONFIG_UBSAN_TRAP in test config

In reply to Greg Kroah-Hartman

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

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

From: Ricardo Cañuelo <[email protected]>

[ Upstream commit cf77bf698887c3b9ebed76dea492b07a3c2c7632 ]

The lkdtm selftest config fragment enables CONFIG_UBSAN_TRAP to make the ARRAY_BOUNDS test kill the calling process when an out-of-bound access is detected by UBSAN. However, after this [1] commit, UBSAN is triggered under many new scenarios that weren't detected before, such as in struct definitions with fixed-size trailing arrays used as flexible arrays. As a result, CONFIG_UBSAN_TRAP=y has become a very aggressive option to enable except for specific situations.

make kselftest-merge applies CONFIG_UBSAN_TRAP=y to the kernel config for all selftests, which makes many of them fail because of system hangs during boot.

This change removes the config option from the lkdtm kselftest and configures the ARRAY_BOUNDS test to look for UBSAN reports rather than relying on the calling process being killed.

[1] commit 2d47c6956ab3 ("ubsan: Tighten UBSAN_BOUNDS on GCC")'

---
 tools/testing/selftests/lkdtm/config    | 1 -
 tools/testing/selftests/lkdtm/tests.txt | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)
tools/testing/selftests/lkdtm/config +0 -1
index 5d52f64dfb430..7afe05e8c4d79 100644
@@ -9,7 +9,6 @@ CONFIG_INIT_ON_FREE_DEFAULT_ON=y
 CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
 CONFIG_UBSAN=y
 CONFIG_UBSAN_BOUNDS=y
-CONFIG_UBSAN_TRAP=y
 CONFIG_STACKPROTECTOR_STRONG=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB_DEBUG_ON=y
tools/testing/selftests/lkdtm/tests.txt +1 -1
index 607b8d7e3ea34..2f3a1b96da6e3 100644
@@ -7,7 +7,7 @@ EXCEPTION
 #EXHAUST_STACK Corrupts memory on failure
 #CORRUPT_STACK Crashes entire system on success
 #CORRUPT_STACK_STRONG Crashes entire system on success
-ARRAY_BOUNDS
+ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds
 CORRUPT_LIST_ADD list_add corruption
 CORRUPT_LIST_DEL list_del corruption
 STACK_GUARD_PAGE_LEADING
Signature · 1 line
2.42.0
author maintainer
#9 lore raw

PATCH 9/491 clocksource/drivers/timer-imx-gpt: Fix potential memory leak

In reply to Greg Kroah-Hartman

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

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

From: Jacky Bai <[email protected]>

[ Upstream commit 8051a993ce222a5158bccc6ac22ace9253dd71cb ]

Fix coverity Issue CID 250382: Resource leak (RESOURCE_LEAK). Add kfree when error return.

---
 drivers/clocksource/timer-imx-gpt.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/clocksource/timer-imx-gpt.c +13 -5
index 28ab4f1a7c713..6a878d227a13b 100644
@@ -434,12 +434,16 @@ static int __init mxc_timer_init_dt(struct device_node *np,  enum imx_gpt_type t
 		return -ENOMEM;
 
 	imxtm->base = of_iomap(np, 0);
-	if (!imxtm->base)
-		return -ENXIO;
+	if (!imxtm->base) {
+		ret = -ENXIO;
+		goto err_kfree;
+	}
 
 	imxtm->irq = irq_of_parse_and_map(np, 0);
-	if (imxtm->irq <= 0)
-		return -EINVAL;
+	if (imxtm->irq <= 0) {
+		ret = -EINVAL;
+		goto err_kfree;
+	}
 
 	imxtm->clk_ipg = of_clk_get_by_name(np, "ipg");
 
@@ -452,11 +456,15 @@ static int __init mxc_timer_init_dt(struct device_node *np,  enum imx_gpt_type t
 
 	ret = _mxc_timer_init(imxtm);
 	if (ret)
-		return ret;
+		goto err_kfree;
 
 	initialized = 1;
 
 	return 0;
+
+err_kfree:
+	kfree(imxtm);
+	return ret;
 }
 
 static int __init imx1_timer_init_dt(struct device_node *np)
Signature · 1 line
2.42.0
author maintainer
#10 lore raw

PATCH 10/491 clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 hardware

In reply to Greg Kroah-Hartman

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

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

From: Ronald Wahl <[email protected]>

[ Upstream commit 6d3bc4c02d59996d1d3180d8ed409a9d7d5900e0 ]

On SAM9 hardware two cascaded 16 bit timers are used to form a 32 bit high resolution timer that is used as scheduler clock when the kernel has been configured that way (CONFIG_ATMEL_CLOCKSOURCE_TCB).

The driver initially triggers a reset-to-zero of the two timers but this reset is only performed on the next rising clock. For the first timer this is ok - it will be in the next 60ns (16MHz clock). For the chained second timer this will only happen after the first timer overflows, i.e. after 2^16 clocks (~4ms with a 16MHz clock). So with other words the scheduler clock resets to 0 after the first 2^16 clock cycles.

It looks like that the scheduler does not like this and behaves wrongly over its lifetime, e.g. some tasks are scheduled with a long delay. Why that is and if there are additional requirements for this behaviour has not been further analysed.

There is a simple fix for resetting the second timer as well when the first timer is reset and this is to set the ATMEL_TC_ASWTRG_SET bit in the Channel Mode register (CMR) of the first timer. This will also rise the TIOA line (clock input of the second timer) when a software trigger respective SYNC is issued.

---
 drivers/clocksource/timer-atmel-tcb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/clocksource/timer-atmel-tcb.c +1 -0
index 27af17c995900..2a90c92a9182a 100644
@@ -315,6 +315,7 @@ static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx)
 	writel(mck_divisor_idx			/* likely divide-by-8 */
 			| ATMEL_TC_WAVE
 			| ATMEL_TC_WAVESEL_UP		/* free-run */
+			| ATMEL_TC_ASWTRG_SET		/* TIOA0 rises at software trigger */
 			| ATMEL_TC_ACPA_SET		/* TIOA0 rises at 0 */
 			| ATMEL_TC_ACPC_CLEAR,		/* (duty cycle 50%) */
 			tcaddr + ATMEL_TC_REG(0, CMR));
Signature · 1 line
2.42.0
author maintainer
#11 lore raw

PATCH 11/491 srcu: Only accelerate on enqueue time

In reply to Greg Kroah-Hartman

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

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

From: Frederic Weisbecker <[email protected]>

[ Upstream commit 8a77f38bcd28d3c22ab7dd8eff3f299d43c00411 ]

Acceleration in SRCU happens on enqueue time for each new callback. This operation is expected not to fail and therefore any similar attempt from other places shouldn't find any remaining callbacks to accelerate.

Moreover accelerations performed beyond enqueue time are error prone because rcu_seq_snap() then may return the snapshot for a new grace period that is not going to be started.

Remove these dangerous and needless accelerations and introduce instead assertions reporting leaking unaccelerated callbacks beyond enqueue time.

---
 kernel/rcu/srcutree.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
kernel/rcu/srcutree.c +2 -4
index 7522517b63b6f..2f770a9a2a13a 100644
@@ -782,8 +782,7 @@ static void srcu_gp_start(struct srcu_struct *ssp)
 	spin_lock_rcu_node(sdp);  /* Interrupts already disabled. */
 	rcu_segcblist_advance(&sdp->srcu_cblist,
 			      rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
-	(void)rcu_segcblist_accelerate(&sdp->srcu_cblist,
-				       rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq));
+	WARN_ON_ONCE(!rcu_segcblist_segempty(&sdp->srcu_cblist, RCU_NEXT_TAIL));
 	spin_unlock_rcu_node(sdp);  /* Interrupts remain disabled. */
 	WRITE_ONCE(ssp->srcu_sup->srcu_gp_start, jiffies);
 	WRITE_ONCE(ssp->srcu_sup->srcu_n_exp_nodelay, 0);
@@ -1719,6 +1718,7 @@ static void srcu_invoke_callbacks(struct work_struct *work)
 	ssp = sdp->ssp;
 	rcu_cblist_init(&ready_cbs);
 	spin_lock_irq_rcu_node(sdp);
+	WARN_ON_ONCE(!rcu_segcblist_segempty(&sdp->srcu_cblist, RCU_NEXT_TAIL));
 	rcu_segcblist_advance(&sdp->srcu_cblist,
 			      rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
 	if (sdp->srcu_cblist_invoking ||
@@ -1748,8 +1748,6 @@ static void srcu_invoke_callbacks(struct work_struct *work)
 	 */
 	spin_lock_irq_rcu_node(sdp);
 	rcu_segcblist_add_len(&sdp->srcu_cblist, -len);
-	(void)rcu_segcblist_accelerate(&sdp->srcu_cblist,
-				       rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq));
 	sdp->srcu_cblist_invoking = false;
 	more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist);
 	spin_unlock_irq_rcu_node(sdp);
Signature · 1 line
2.42.0
author maintainer
#12 lore raw

PATCH 12/491 smp,csd: Throw an error if a CSD lock is stuck for too long

In reply to Greg Kroah-Hartman

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

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

From: Rik van Riel <[email protected]>

[ Upstream commit 94b3f0b5af2c7af69e3d6e0cdd9b0ea535f22186 ]

The CSD lock seems to get stuck in 2 "modes". When it gets stuck temporarily, it usually gets released in a few seconds, and sometimes up to one or two minutes.

If the CSD lock stays stuck for more than several minutes, it never seems to get unstuck, and gradually more and more things in the system end up also getting stuck.

In the latter case, we should just give up, so the system can dump out a little more information about what went wrong, and, with panic_on_oops and a kdump kernel loaded, dump a whole bunch more information about what might have gone wrong. In addition, there is an smp.panic_on_ipistall kernel boot parameter that by default retains the old behavior, but when set enables the panic after the CSD lock has been stuck for more than the specified number of milliseconds, as in 300,000 for five minutes.

[ paulmck: Apply Imran Khan feedback. ]
[ paulmck: Apply Leonardo Bras feedback. ]

---
 Documentation/admin-guide/kernel-parameters.txt |  7 +++++++
 kernel/smp.c                                    | 13 ++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +7 -0
index 23ebe34ff901e..b951b4c2808f1 100644
@@ -5781,6 +5781,13 @@
 			This feature may be more efficiently disabled
 			using the csdlock_debug- kernel parameter.
 
+	smp.panic_on_ipistall= [KNL]
+			If a csd_lock_timeout extends for more than
+			the specified number of milliseconds, panic the
+			system.  By default, let CSD-lock acquisition
+			take as long as they take.  Specifying 300,000
+			for this value provides a 5-minute timeout.
+
 	smsc-ircc2.nopnp	[HW] Don't use PNP to discover SMC devices
 	smsc-ircc2.ircc_cfg=	[HW] Device configuration I/O port
 	smsc-ircc2.ircc_sir=	[HW] SIR base I/O port
kernel/smp.c +12 -1
index 385179dae360e..0a9a3262f7822 100644
@@ -168,6 +168,8 @@ static DEFINE_PER_CPU(void *, cur_csd_info);
 
 static ulong csd_lock_timeout = 5000;  /* CSD lock timeout in milliseconds. */
 module_param(csd_lock_timeout, ulong, 0444);
+static int panic_on_ipistall;  /* CSD panic timeout in milliseconds, 300000 for five minutes. */
+module_param(panic_on_ipistall, int, 0444);
 
 static atomic_t csd_bug_count = ATOMIC_INIT(0);
 
@@ -228,6 +230,7 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 *
 	}
 
 	ts2 = sched_clock();
+	/* How long since we last checked for a stuck CSD lock.*/
 	ts_delta = ts2 - *ts1;
 	if (likely(ts_delta <= csd_lock_timeout_ns || csd_lock_timeout_ns == 0))
 		return false;
@@ -241,9 +244,17 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 *
 	else
 		cpux = cpu;
 	cpu_cur_csd = smp_load_acquire(&per_cpu(cur_csd, cpux)); /* Before func and info. */
+	/* How long since this CSD lock was stuck. */
+	ts_delta = ts2 - ts0;
 	pr_alert("csd: %s non-responsive CSD lock (#%d) on CPU#%d, waiting %llu ns for CPU#%02d %pS(%ps).\n",
-		 firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts2 - ts0,
+		 firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts_delta,
 		 cpu, csd->func, csd->info);
+	/*
+	 * If the CSD lock is still stuck after 5 minutes, it is unlikely
+	 * to become unstuck. Use a signed comparison to avoid triggering
+	 * on underflows when the TSC is out of sync between sockets.
+	 */
+	BUG_ON(panic_on_ipistall > 0 && (s64)ts_delta > ((s64)panic_on_ipistall * NSEC_PER_MSEC));
 	if (cpu_cur_csd && csd != cpu_cur_csd) {
 		pr_alert("\tcsd: CSD lock (#%d) handling prior %pS(%ps) request.\n",
 			 *bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)),
Signature · 1 line
2.42.0
author maintainer
#13 lore raw

PATCH 13/491 cpu/hotplug: Dont offline the last non-isolated CPU

In reply to Greg Kroah-Hartman

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

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

From: Ran Xiaokai <[email protected]>

[ Upstream commit 38685e2a0476127db766f81b1c06019ddc4c9ffa ]

If a system has isolated CPUs via the "isolcpus=" command line parameter, then an attempt to offline the last housekeeping CPU will result in a WARN_ON() when rebuilding the scheduler domains and a subsequent panic due to and unhandled empty CPU mas in partition_sched_domains_locked().

cpuset_hotplug_workfn()
rebuild_sched_domains_locked()

    ndoms = generate_sched_domains(&doms, &attr);
      cpumask_and(doms[0], top_cpuset.effective_cpus, housekeeping_cpumask(HK_FLAG_DOMAIN));

Thus results in an empty CPU mask which triggers the warning and then the subsequent crash:

WARNING: CPU: 4 PID: 80 at kernel/sched/topology.c:2366 build_sched_domains+0x120c/0x1408
Call trace:
 build_sched_domains+0x120c/0x1408
 partition_sched_domains_locked+0x234/0x880
 rebuild_sched_domains_locked+0x37c/0x798
 rebuild_sched_domains+0x30/0x58
 cpuset_hotplug_workfn+0x2a8/0x930

Unable to handle kernel paging request at virtual address fffe80027ab37080
 partition_sched_domains_locked+0x318/0x880
 rebuild_sched_domains_locked+0x37c/0x798

Aside of the resulting crash, it does not make any sense to offline the last last housekeeping CPU.

Prevent this by masking out the non-housekeeping CPUs when selecting a target CPU for initiating the CPU unplug operation via the work queue.

---
 kernel/cpu.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/cpu.c +7 -4
index 26119d2154102..189ba5fd9af4b 100644
@@ -1503,11 +1503,14 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
 	/*
 	 * Ensure that the control task does not run on the to be offlined
 	 * CPU to prevent a deadlock against cfs_b->period_timer.
+	 * Also keep at least one housekeeping cpu onlined to avoid generating
+	 * an empty sched_domain span.
 	 */
-	cpu = cpumask_any_but(cpu_online_mask, cpu);
-	if (cpu >= nr_cpu_ids)
-		return -EBUSY;
-	return work_on_cpu(cpu, __cpu_down_maps_locked, &work);
+	for_each_cpu_and(cpu, cpu_online_mask, housekeeping_cpumask(HK_TYPE_DOMAIN)) {
+		if (cpu != work.cpu)
+			return work_on_cpu(cpu, __cpu_down_maps_locked, &work);
+	}
+	return -EBUSY;
 }
 
 static int cpu_down(unsigned int cpu, enum cpuhp_state target)
Signature · 1 line
2.42.0
author maintainer
#14 lore raw

PATCH 14/491 workqueue: Provide one lock class key per work_on_cpu() callsite

In reply to Greg Kroah-Hartman

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

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

From: Frederic Weisbecker <[email protected]>

[ Upstream commit 265f3ed077036f053981f5eea0b5b43e7c5b39ff ]

All callers of work_on_cpu() share the same lock class key for all the functions queued. As a result the workqueue related locking scenario for a function A may be spuriously accounted as an inversion against the locking scenario of function B such as in the following model:

	long A(void *arg)
	{
		mutex_lock(&mutex);
		mutex_unlock(&mutex);
	}

	long B(void *arg)
	{
	}

	void launchA(void)
	{
		work_on_cpu(0, A, NULL);
	}

	void launchB(void)
	{
		mutex_lock(&mutex);
		work_on_cpu(1, B, NULL);
		mutex_unlock(&mutex);
	}

launchA and launchB running concurrently have no chance to deadlock. However the above can be reported by lockdep as a possible locking inversion because the works containing A() and B() are treated as belonging to the same locking class.

The following shows an existing example of such a spurious lockdep splat:

	 ======================================================
	 WARNING: possible circular locking dependency detected
	 6.6.0-rc1-00065-g934ebd6e5359 #35409 Not tainted
	 ------------------------------------------------------
	 kworker/0:1/9 is trying to acquire lock:
	 ffffffff9bc72f30 (cpu_hotplug_lock){++++}-{0:0}, at: _cpu_down+0x57/0x2b0

	 but task is already holding lock:
	 ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500

	 which lock already depends on the new lock.

	 the existing dependency chain (in reverse order) is:

	 -> #2 ((work_completion)(&wfc.work)){+.+.}-{0:0}:
			__flush_work+0x83/0x4e0
			work_on_cpu+0x97/0xc0
			rcu_nocb_cpu_offload+0x62/0xb0
			rcu_nocb_toggle+0xd0/0x1d0
			kthread+0xe6/0x120
			ret_from_fork+0x2f/0x40
			ret_from_fork_asm+0x1b/0x30

	 -> #1 (rcu_state.barrier_mutex){+.+.}-{3:3}:
			__mutex_lock+0x81/0xc80
			rcu_nocb_cpu_deoffload+0x38/0xb0
			rcu_nocb_toggle+0x144/0x1d0
			kthread+0xe6/0x120
			ret_from_fork+0x2f/0x40
			ret_from_fork_asm+0x1b/0x30

	 -> #0 (cpu_hotplug_lock){++++}-{0:0}:
			__lock_acquire+0x1538/0x2500
			lock_acquire+0xbf/0x2a0
			percpu_down_write+0x31/0x200
			_cpu_down+0x57/0x2b0
			__cpu_down_maps_locked+0x10/0x20
			work_for_cpu_fn+0x15/0x20
			process_scheduled_works+0x2a7/0x500
			worker_thread+0x173/0x330
			kthread+0xe6/0x120
			ret_from_fork+0x2f/0x40
			ret_from_fork_asm+0x1b/0x30

	 other info that might help us debug this:

	 Chain exists of:
	   cpu_hotplug_lock --> rcu_state.barrier_mutex --> (work_completion)(&wfc.work)

	  Possible unsafe locking scenario:

			CPU0                    CPU1
			----                    ----
	   lock((work_completion)(&wfc.work));
									lock(rcu_state.barrier_mutex);
									lock((work_completion)(&wfc.work));
	   lock(cpu_hotplug_lock);

	  *** DEADLOCK ***

	 2 locks held by kworker/0:1/9:
	  #0: ffff900481068b38 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x212/0x500
	  #1: ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500

	 stack backtrace:
	 CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.6.0-rc1-00065-g934ebd6e5359 #35409
	 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
	 Workqueue: events work_for_cpu_fn
	 Call Trace:
	 rcu-torture: rcu_torture_read_exit: Start of episode
	  <TASK>
	  dump_stack_lvl+0x4a/0x80
	  check_noncircular+0x132/0x150
	  __lock_acquire+0x1538/0x2500
	  lock_acquire+0xbf/0x2a0
	  ? _cpu_down+0x57/0x2b0
	  percpu_down_write+0x31/0x200
	  ? _cpu_down+0x57/0x2b0
	  _cpu_down+0x57/0x2b0
	  __cpu_down_maps_locked+0x10/0x20
	  work_for_cpu_fn+0x15/0x20
	  process_scheduled_works+0x2a7/0x500
	  worker_thread+0x173/0x330
	  ? __pfx_worker_thread+0x10/0x10
	  kthread+0xe6/0x120
	  ? __pfx_kthread+0x10/0x10
	  ret_from_fork+0x2f/0x40
	  ? __pfx_kthread+0x10/0x10
	  ret_from_fork_asm+0x1b/0x30
	  </TASK

Fix this with providing one lock class key per work_on_cpu() caller.

---
 include/linux/workqueue.h | 46 +++++++++++++++++++++++++++++++++------
 kernel/workqueue.c        | 20 ++++++++++-------
 2 files changed, 51 insertions(+), 15 deletions(-)
include/linux/workqueue.h +39 -7
index 683efe29fa698..ca26c1f94f044 100644
@@ -222,18 +222,16 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
  * to generate better code.
  */
 #ifdef CONFIG_LOCKDEP
-#define __INIT_WORK(_work, _func, _onstack)				\
+#define __INIT_WORK_KEY(_work, _func, _onstack, _key)			\
 	do {								\
-		static struct lock_class_key __key;			\
-									\
 		__init_work((_work), _onstack);				\
 		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
-		lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \
+		lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, (_key), 0); \
 		INIT_LIST_HEAD(&(_work)->entry);			\
 		(_work)->func = (_func);				\
 	} while (0)
 #else
-#define __INIT_WORK(_work, _func, _onstack)				\
+#define __INIT_WORK_KEY(_work, _func, _onstack, _key)			\
 	do {								\
 		__init_work((_work), _onstack);				\
 		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
@@ -242,12 +240,22 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
 	} while (0)
 #endif
 
+#define __INIT_WORK(_work, _func, _onstack)				\
+	do {								\
+		static __maybe_unused struct lock_class_key __key;	\
+									\
+		__INIT_WORK_KEY(_work, _func, _onstack, &__key);	\
+	} while (0)
+
 #define INIT_WORK(_work, _func)						\
 	__INIT_WORK((_work), (_func), 0)
 
 #define INIT_WORK_ONSTACK(_work, _func)					\
 	__INIT_WORK((_work), (_func), 1)
 
+#define INIT_WORK_ONSTACK_KEY(_work, _func, _key)			\
+	__INIT_WORK_KEY((_work), (_func), 1, _key)
+
 #define __INIT_DELAYED_WORK(_work, _func, _tflags)			\
 	do {								\
 		INIT_WORK(&(_work)->work, (_func));			\
@@ -683,8 +691,32 @@ static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg)
 	return fn(arg);
 }
 #else
-long work_on_cpu(int cpu, long (*fn)(void *), void *arg);
-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg);
+long work_on_cpu_key(int cpu, long (*fn)(void *),
+		     void *arg, struct lock_class_key *key);
+/*
+ * A new key is defined for each caller to make sure the work
+ * associated with the function doesn't share its locking class.
+ */
+#define work_on_cpu(_cpu, _fn, _arg)			\
+({							\
+	static struct lock_class_key __key;		\
+							\
+	work_on_cpu_key(_cpu, _fn, _arg, &__key);	\
+})
+
+long work_on_cpu_safe_key(int cpu, long (*fn)(void *),
+			  void *arg, struct lock_class_key *key);
+
+/*
+ * A new key is defined for each caller to make sure the work
+ * associated with the function doesn't share its locking class.
+ */
+#define work_on_cpu_safe(_cpu, _fn, _arg)		\
+({							\
+	static struct lock_class_key __key;		\
+							\
+	work_on_cpu_safe_key(_cpu, _fn, _arg, &__key);	\
+})
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_FREEZER
kernel/workqueue.c +12 -8
index e4a37d7a6752d..a7fcb25417726 100644
@@ -5571,50 +5571,54 @@ static void work_for_cpu_fn(struct work_struct *work)
 }
 
 /**
- * work_on_cpu - run a function in thread context on a particular cpu
+ * work_on_cpu_key - run a function in thread context on a particular cpu
  * @cpu: the cpu to run on
  * @fn: the function to run
  * @arg: the function arg
+ * @key: The lock class key for lock debugging purposes
  *
  * It is up to the caller to ensure that the cpu doesn't go offline.
  * The caller must not hold any locks which would prevent @fn from completing.
  *
  * Return: The value @fn returns.
  */
-long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
+long work_on_cpu_key(int cpu, long (*fn)(void *),
+		     void *arg, struct lock_class_key *key)
 {
 	struct work_for_cpu wfc = { .fn = fn, .arg = arg };
 
-	INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
+	INIT_WORK_ONSTACK_KEY(&wfc.work, work_for_cpu_fn, key);
 	schedule_work_on(cpu, &wfc.work);
 	flush_work(&wfc.work);
 	destroy_work_on_stack(&wfc.work);
 	return wfc.ret;
 }
-EXPORT_SYMBOL_GPL(work_on_cpu);
+EXPORT_SYMBOL_GPL(work_on_cpu_key);
 
 /**
- * work_on_cpu_safe - run a function in thread context on a particular cpu
+ * work_on_cpu_safe_key - run a function in thread context on a particular cpu
  * @cpu: the cpu to run on
  * @fn:  the function to run
  * @arg: the function argument
+ * @key: The lock class key for lock debugging purposes
  *
  * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold
  * any locks which would prevent @fn from completing.
  *
  * Return: The value @fn returns.
  */
-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg)
+long work_on_cpu_safe_key(int cpu, long (*fn)(void *),
+			  void *arg, struct lock_class_key *key)
 {
 	long ret = -ENODEV;
 
 	cpus_read_lock();
 	if (cpu_online(cpu))
-		ret = work_on_cpu(cpu, fn, arg);
+		ret = work_on_cpu_key(cpu, fn, arg, key);
 	cpus_read_unlock();
 	return ret;
 }
-EXPORT_SYMBOL_GPL(work_on_cpu_safe);
+EXPORT_SYMBOL_GPL(work_on_cpu_safe_key);
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_FREEZER
Signature · 1 line
2.42.0
author maintainer
#15 lore raw

PATCH 15/491 x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size

In reply to Greg Kroah-Hartman

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

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

From: Mike Rapoport (IBM) <[email protected]>

[ Upstream commit a1e2b8b36820d8c91275f207e77e91645b7c6836 ]

Qi Zheng reported crashes in a production environment and provided a simplified example as a reproducer:

 |  For example, if we use Qemu to start a two NUMA node kernel,
 |  one of the nodes has 2M memory (less than NODE_MIN_SIZE),
 |  and the other node has 2G, then we will encounter the
 |  following panic:
 |
 |    BUG: kernel NULL pointer dereference, address: 0000000000000000
 |    <...>
 |    RIP: 0010:_raw_spin_lock_irqsave+0x22/0x40
 |    <...>
 |    Call Trace:
 |      <TASK>
 |      deactivate_slab()
 |      bootstrap()
 |      kmem_cache_init()
 |      start_kernel()
 |      secondary_startup_64_no_verify()

The crashes happen because of inconsistency between the nodemask that has nodes with less than 4MB as memoryless, and the actual memory fed into the core mm.

The commit:

9391a3f9c7f1 ("[PATCH] x86_64: Clear more state when ignoring empty node in SRAT parsing")

... that introduced minimal size of a NUMA node does not explain why a node size cannot be less than 4MB and what boot failures this restriction might fix.

Fixes have been submitted to the core MM code to tighten up the memory topologies it accepts and to not crash on weird input:

mm: page_alloc: skip memoryless nodes entirely
mm: memory_hotplug: drop memoryless node from fallback lists

Andrew has accepted them into the -mm tree, but there are no stable SHA1's yet.

This patch drops the limitation for minimal node size on x86:

- which works around the crash without the fixes to the core MM.
- makes x86 topologies less weird,
- removes an arbitrary and undocumented limitation on NUMA topologies.

[ mingo: Improved changelog clarity. ]

---
 arch/x86/include/asm/numa.h | 7 -------
 arch/x86/mm/numa.c          | 7 -------
 2 files changed, 14 deletions(-)
arch/x86/include/asm/numa.h +0 -7
index e3bae2b60a0db..ef2844d691735 100644
@@ -12,13 +12,6 @@
 
 #define NR_NODE_MEMBLKS		(MAX_NUMNODES*2)
 
-/*
- * Too small node sizes may confuse the VM badly. Usually they
- * result from BIOS bugs. So dont recognize nodes as standalone
- * NUMA entities that have less than this amount of RAM listed:
- */
-#define NODE_MIN_SIZE (4*1024*1024)
-
 extern int numa_off;
 
 /*
arch/x86/mm/numa.c +0 -7
index c01c5506fd4ae..aa39d678fe81d 100644
@@ -602,13 +602,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)
 		if (start >= end)
 			continue;
 
-		/*
-		 * Don't confuse VM with a node that doesn't have the
-		 * minimum amount of memory:
-		 */
-		if (end && (end - start) < NODE_MIN_SIZE)
-			continue;
-
 		alloc_node_data(nid);
 	}
 
Signature · 1 line
2.42.0
author maintainer
#16 lore raw

PATCH 16/491 wifi: plfxlc: fix clang-specific fortify warning

In reply to Greg Kroah-Hartman

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

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

From: Dmitry Antipov <[email protected]>

[ Upstream commit a763e92c78615ea838f5b9a841398b1d4adb968e ]

When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following (somewhat confusing due to absence of an actual source code location):

In file included from drivers/net/wireless/purelifi/plfxlc/mac.c:6:
In file included from ./include/linux/netdevice.h:24:
In file included from ./include/linux/timer.h:6:
In file included from ./include/linux/ktime.h:24:
In file included from ./include/linux/time.h:60:
In file included from ./include/linux/time32.h:13:
In file included from ./include/linux/timex.h:67:
In file included from ./arch/x86/include/asm/timex.h:5:
In file included from ./arch/x86/include/asm/processor.h:23:
In file included from ./arch/x86/include/asm/msr.h:11:
In file included from ./arch/x86/include/asm/cpumask.h:5:
In file included from ./include/linux/cpumask.h:12:
In file included from ./include/linux/bitmap.h:11:
In file included from ./include/linux/string.h:254:
./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]

                        __read_overflow2_field(q_size_field, size);

The compiler actually complains on 'plfxlc_get_et_strings()' where fortification logic inteprets call to 'memcpy()' as an attempt to copy the whole 'et_strings' array from its first member and so issues an overread warning. This warning may be silenced by passing an address of the whole array and not the first member to 'memcpy()'.

---
 drivers/net/wireless/purelifi/plfxlc/mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/purelifi/plfxlc/mac.c +1 -1
index 94ee831b5de35..506d2f31efb5a 100644
@@ -666,7 +666,7 @@ static void plfxlc_get_et_strings(struct ieee80211_hw *hw,
 				  u32 sset, u8 *data)
 {
 	if (sset == ETH_SS_STATS)
-		memcpy(data, *et_strings, sizeof(et_strings));
+		memcpy(data, et_strings, sizeof(et_strings));
 }
 
 static void plfxlc_get_et_stats(struct ieee80211_hw *hw,
Signature · 1 line
2.42.0
author maintainer
#17 lore raw

PATCH 17/491 wifi: ath12k: Ignore fragments from uninitialized peer in dp

In reply to Greg Kroah-Hartman

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

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

From: Harshitha Prem <[email protected]>

[ Upstream commit bbc86757ca62423c3b6bd8f7176da1ff43450769 ]

When max virtual ap interfaces are configured in all the bands with ACS and hostapd restart is done every 60s, a crash is observed at random times.

In the above scenario, a fragmented packet is received for self peer, for which rx_tid and rx_frags are not initialized in datapath. While handling this fragment, crash is observed as the rx_frag list is uninitialized and when we walk in ath12k_dp_rx_h_sort_frags, skb null leads to exception.

To address this, before processing received fragments we check dp_setup_done flag is set to ensure that peer has completed its dp peer setup for fragment queue, else ignore processing the fragments.

Call trace:
    PC points to "ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]"
    LR points to "ath12k_dp_process_rx_err+0x480/0xfcc [ath12k]".
    The Backtrace obtained is as follows:
    ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]
    ath12k_dp_service_srng+0x78/0x260 [ath12k]
    ath12k_pci_write32+0x990/0xb0c [ath12k]
    __napi_poll+0x30/0xa4
    net_rx_action+0x118/0x270
    __do_softirq+0x10c/0x244
    irq_exit+0x64/0xb4
    __handle_domain_irq+0x88/0xac
    gic_handle_irq+0x74/0xbc
    el1_irq+0xf0/0x1c0
    arch_cpu_idle+0x10/0x18
    do_idle+0x104/0x248
    cpu_startup_entry+0x20/0x64
    rest_init+0xd0/0xdc
    arch_call_rest_init+0xc/0x14

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

---
 drivers/net/wireless/ath/ath12k/dp.c    | 1 +
 drivers/net/wireless/ath/ath12k/dp_rx.c | 9 +++++++++
 drivers/net/wireless/ath/ath12k/peer.h  | 3 +++
 3 files changed, 13 insertions(+)
drivers/net/wireless/ath/ath12k/dp.c +1 -0
index f933896f2a68d..6893466f61f04 100644
@@ -38,6 +38,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
 
 	ath12k_dp_rx_peer_tid_cleanup(ar, peer);
 	crypto_free_shash(peer->tfm_mmic);
+	peer->dp_setup_done = false;
 	spin_unlock_bh(&ab->base_lock);
 }
 
drivers/net/wireless/ath/ath12k/dp_rx.c +9 -0
index fcb91b8ef00e3..73edcb1908b91 100644
@@ -2747,6 +2747,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
 	}
 
 	peer->tfm_mmic = tfm;
+	peer->dp_setup_done = true;
 	spin_unlock_bh(&ab->base_lock);
 
 	return 0;
@@ -3213,6 +3214,14 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
 		ret = -ENOENT;
 		goto out_unlock;
 	}
+
+	if (!peer->dp_setup_done) {
+		ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
+			    peer->addr, peer_id);
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+
 	rx_tid = &peer->rx_tid[tid];
 
 	if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
drivers/net/wireless/ath/ath12k/peer.h +3 -0
index b296dc0e2f671..c6edb24cbedd8 100644
@@ -44,6 +44,9 @@ struct ath12k_peer {
 	struct ppdu_user_delayba ppdu_stats_delayba;
 	bool delayba_flag;
 	bool is_authorized;
+
+	/* protected by ab->data_lock */
+	bool dp_setup_done;
 };
 
 void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id);
Signature · 1 line
2.42.0
author maintainer
#18 lore raw

PATCH 18/491 wifi: mac80211_hwsim: fix clang-specific fortify warning

In reply to Greg Kroah-Hartman

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

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

From: Dmitry Antipov <[email protected]>

[ Upstream commit cbaccdc42483c65016f1bae89128c08dc17cfb2a ]

When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following (somewhat confusing due to absence of an actual source code location):

In file included from drivers/net/wireless/virtual/mac80211_hwsim.c:18:
In file included from ./include/linux/slab.h:16:
In file included from ./include/linux/gfp.h:7:
In file included from ./include/linux/mmzone.h:8:
In file included from ./include/linux/spinlock.h:56:
In file included from ./include/linux/preempt.h:79:
In file included from ./arch/x86/include/asm/preempt.h:9:
In file included from ./include/linux/thread_info.h:60:
In file included from ./arch/x86/include/asm/thread_info.h:53:
In file included from ./arch/x86/include/asm/cpufeature.h:5:
In file included from ./arch/x86/include/asm/processor.h:23:
In file included from ./arch/x86/include/asm/msr.h:11:
In file included from ./arch/x86/include/asm/cpumask.h:5:
In file included from ./include/linux/cpumask.h:12:
In file included from ./include/linux/bitmap.h:11:
In file included from ./include/linux/string.h:254:
./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]

                        __read_overflow2_field(q_size_field, size);

The compiler actually complains on 'mac80211_hwsim_get_et_strings()' where fortification logic inteprets call to 'memcpy()' as an attempt to copy the whole 'mac80211_hwsim_gstrings_stats' array from its first member and so issues an overread warning. This warning may be silenced by passing an address of the whole array and not the first member to 'memcpy()'.

---
 drivers/net/wireless/virtual/mac80211_hwsim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/virtual/mac80211_hwsim.c +1 -1
index 23307c8baea21..6dc153a267872 100644
@@ -3170,7 +3170,7 @@ static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw,
 					  u32 sset, u8 *data)
 {
 	if (sset == ETH_SS_STATS)
-		memcpy(data, *mac80211_hwsim_gstrings_stats,
+		memcpy(data, mac80211_hwsim_gstrings_stats,
 		       sizeof(mac80211_hwsim_gstrings_stats));
 }
 
Signature · 1 line
2.42.0
author maintainer
#19 lore raw

PATCH 19/491 wifi: mac80211: dont return unset power in ieee80211_get_tx_power()

In reply to Greg Kroah-Hartman

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

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

From: Ping-Ke Shih <[email protected]>

[ Upstream commit e160ab85166e77347d0cbe5149045cb25e83937f ]

We can get a UBSAN warning if ieee80211_get_tx_power() returns the INT_MIN value mac80211 internally uses for "unset power level".

 UBSAN: signed-integer-overflow in net/wireless/nl80211.c:3816:5
 -2147483648 * 100 cannot be represented in type 'int'
 CPU: 0 PID: 20433 Comm: insmod Tainted: G        WC OE
 Call Trace:
  dump_stack+0x74/0x92
  ubsan_epilogue+0x9/0x50
  handle_overflow+0x8d/0xd0
  __ubsan_handle_mul_overflow+0xe/0x10
  nl80211_send_iface+0x688/0x6b0 [cfg80211]
  [...]
  cfg80211_register_wdev+0x78/0xb0 [cfg80211]
  cfg80211_netdev_notifier_call+0x200/0x620 [cfg80211]
  [...]
  ieee80211_if_add+0x60e/0x8f0 [mac80211]
  ieee80211_register_hw+0xda5/0x1170 [mac80211]

In this case, simply return an error instead, to indicate that no data is available.

---
 net/mac80211/cfg.c | 4 ++++
 1 file changed, 4 insertions(+)
net/mac80211/cfg.c +4 -0
index 0e3a1753a51c6..715da615f0359 100644
@@ -3121,6 +3121,10 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
 	else
 		*dbm = sdata->vif.bss_conf.txpower;
 
+	/* INT_MIN indicates no power level was set yet */
+	if (*dbm == INT_MIN)
+		return -EINVAL;
+
 	return 0;
 }
 
Signature · 1 line
2.42.0
author maintainer
#20 lore raw

PATCH 20/491 atl1c: Work around the DMA RX overflow issue

In reply to Greg Kroah-Hartman

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

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

From: Sieng-Piaw Liew <[email protected]>

[ Upstream commit 86565682e9053e5deb128193ea9e88531bbae9cf ]

This is based on alx driver commit 881d0327db37 ("net: alx: Work around the DMA RX overflow issue").

The alx and atl1c drivers had RX overflow error which was why a custom allocator was created to avoid certain addresses. The simpler workaround then created for alx driver, but not for atl1c due to lack of tester.

Instead of using a custom allocator, check the allocated skb address and use skb_reserve() to move away from problematic 0x...fc0 address.

Tested on AR8131 on Acer 4540.

---
 drivers/net/ethernet/atheros/atl1c/atl1c.h    |  3 -
 .../net/ethernet/atheros/atl1c/atl1c_main.c   | 67 +++++--------------
 2 files changed, 16 insertions(+), 54 deletions(-)
drivers/net/ethernet/atheros/atl1c/atl1c.h +0 -3
index 43d821fe7a542..63ba64dbb7310 100644
@@ -504,15 +504,12 @@ struct atl1c_rrd_ring {
 	u16 next_to_use;
 	u16 next_to_clean;
 	struct napi_struct napi;
-	struct page *rx_page;
-	unsigned int rx_page_offset;
 };
 
 /* board specific private data structure */
 struct atl1c_adapter {
 	struct net_device   *netdev;
 	struct pci_dev      *pdev;
-	unsigned int	    rx_frag_size;
 	struct atl1c_hw        hw;
 	struct atl1c_hw_stats  hw_stats;
 	struct mii_if_info  mii;    /* MII interface info */
drivers/net/ethernet/atheros/atl1c/atl1c_main.c +16 -51

111 lines not on this page · raw message

Signature · 1 line
2.42.0
author maintainer
#21 lore raw

PATCH 21/491 bpf: Detect IP == ksym.end as part of BPF program

In reply to Greg Kroah-Hartman

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

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

From: Kumar Kartikeya Dwivedi <[email protected]>

[ Upstream commit 66d9111f3517f85ef2af0337ece02683ce0faf21 ]

Now that bpf_throw kfunc is the first such call instruction that has noreturn semantics within the verifier, this also kicks in dead code elimination in unprecedented ways. For one, any instruction following a bpf_throw call will never be marked as seen. Moreover, if a callchain ends up throwing, any instructions after the call instruction to the eventually throwing subprog in callers will also never be marked as seen.

The tempting way to fix this would be to emit extra 'int3' instructions which bump the jited_len of a program, and ensure that during runtime when a program throws, we can discover its boundaries even if the call instruction to bpf_throw (or to subprogs that always throw) is emitted as the final instruction in the program.

An example of such a program would be this:

do_something():

	...
	r0 = 0
	exit

foo():

	r1 = 0
	call bpf_throw
	r0 = 0
	exit

bar(cond):

	if r1 != 0 goto pc+2
	call do_something
	exit
	call foo
	r0 = 0  // Never seen by verifier
	exit	//

main(ctx):

	r1 = ...
	call bar
	r0 = 0
	exit

Here, if we do end up throwing, the stacktrace would be the following:

bpf_throw
foo
bar
main

In bar, the final instruction emitted will be the call to foo, as such, the return address will be the subsequent instruction (which the JIT emits as int3 on x86). This will end up lying outside the jited_len of the program, thus, when unwinding, we will fail to discover the return address as belonging to any program and end up in a panic due to the unreliable stack unwinding of BPF programs that we never expect.

To remedy this case, make bpf_prog_ksym_find treat IP == ksym.end as part of the BPF program, so that is_bpf_text_address returns true when such a case occurs, and we are able to unwind reliably when the final instruction ends up being a call instruction.

---
 kernel/bpf/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/bpf/core.c +5 -1
index e3e45b651cd40..33d1a76b7fc5d 100644
@@ -613,7 +613,11 @@ static __always_inline int bpf_tree_comp(void *key, struct latch_tree_node *n)
 
 	if (val < ksym->start)
 		return -1;
-	if (val >= ksym->end)
+	/* Ensure that we detect return addresses as part of the program, when
+	 * the final instruction is a call for a program part of the stack
+	 * trace. Therefore, do val > ksym->end instead of val >= ksym->end.
+	 */
+	if (val > ksym->end)
 		return  1;
 
 	return 0;
Signature · 1 line
2.42.0
author maintainer
#22 lore raw

PATCH 22/491 wifi: ath9k: fix clang-specific fortify warnings

In reply to Greg Kroah-Hartman

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

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

From: Dmitry Antipov <[email protected]>

[ Upstream commit 95f97fe0ac974467ab4da215985a32b2fdf48af0 ]

When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following (somewhat confusing due to absence of an actual source code location):

In file included from drivers/net/wireless/ath/ath9k/debug.c:17:
In file included from ./include/linux/slab.h:16:
In file included from ./include/linux/gfp.h:7:
In file included from ./include/linux/mmzone.h:8:
In file included from ./include/linux/spinlock.h:56:
In file included from ./include/linux/preempt.h:79:
In file included from ./arch/x86/include/asm/preempt.h:9:
In file included from ./include/linux/thread_info.h:60:
In file included from ./arch/x86/include/asm/thread_info.h:53:
In file included from ./arch/x86/include/asm/cpufeature.h:5:
In file included from ./arch/x86/include/asm/processor.h:23:
In file included from ./arch/x86/include/asm/msr.h:11:
In file included from ./arch/x86/include/asm/cpumask.h:5:
In file included from ./include/linux/cpumask.h:12:
In file included from ./include/linux/bitmap.h:11:
In file included from ./include/linux/string.h:254:
./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]

                        __read_overflow2_field(q_size_field, size);

In file included from drivers/net/wireless/ath/ath9k/htc_drv_debug.c:17:
In file included from drivers/net/wireless/ath/ath9k/htc.h:20:
In file included from ./include/linux/module.h:13:
In file included from ./include/linux/stat.h:19:
In file included from ./include/linux/time.h:60:
In file included from ./include/linux/time32.h:13:
In file included from ./include/linux/timex.h:67:
In file included from ./arch/x86/include/asm/timex.h:5:
In file included from ./arch/x86/include/asm/processor.h:23:
In file included from ./arch/x86/include/asm/msr.h:11:
In file included from ./arch/x86/include/asm/cpumask.h:5:
In file included from ./include/linux/cpumask.h:12:
In file included from ./include/linux/bitmap.h:11:
In file included from ./include/linux/string.h:254:
./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]

                        __read_overflow2_field(q_size_field, size);

The compiler actually complains on 'ath9k_get_et_strings()' and 'ath9k_htc_get_et_strings()' due to the same reason: fortification logic inteprets call to 'memcpy()' as an attempt to copy the whole array from it's first member and so issues an overread warning. These warnings may be silenced by passing an address of the whole array and not the first member to 'memcpy()'.

---
 drivers/net/wireless/ath/ath9k/debug.c         | 2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/debug.c +1 -1
index fb7a2952d0ce8..d9bac1c343490 100644
@@ -1333,7 +1333,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw,
 			  u32 sset, u8 *data)
 {
 	if (sset == ETH_SS_STATS)
-		memcpy(data, *ath9k_gstrings_stats,
+		memcpy(data, ath9k_gstrings_stats,
 		       sizeof(ath9k_gstrings_stats));
 }
 
drivers/net/wireless/ath/ath9k/htc_drv_debug.c +1 -1
index c55aab01fff5d..e79bbcd3279af 100644
@@ -428,7 +428,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
 			      u32 sset, u8 *data)
 {
 	if (sset == ETH_SS_STATS)
-		memcpy(data, *ath9k_htc_gstrings_stats,
+		memcpy(data, ath9k_htc_gstrings_stats,
 		       sizeof(ath9k_htc_gstrings_stats));
 }
 
Signature · 1 line
2.42.0
author maintainer
#23 lore raw

PATCH 23/491 wifi: ath12k: fix possible out-of-bound read in ath12k_htt_pull_ppdu_stats()

In reply to Greg Kroah-Hartman

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

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

From: Baochen Qiang <[email protected]>

[ Upstream commit 1bc44a505a229bb1dd4957e11aa594edeea3690e ]

len is extracted from HTT message and could be an unexpected value in case errors happen, so add validation before using to avoid possible out-of-bound read in the following message iteration and parsing.

The same issue also applies to ppdu_info->ppdu_stats.common.num_users, so validate it before using too.

These are found during code review.

Compile test only.

---
 drivers/net/wireless/ath/ath12k/dp_rx.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
drivers/net/wireless/ath/ath12k/dp_rx.c +17 -0
index 73edcb1908b91..8dd744c381eeb 100644
@@ -1555,6 +1555,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
 
 	msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
 	len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
+	if (len > (skb->len - struct_size(msg, data, 0))) {
+		ath12k_warn(ab,
+			    "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
+			    len, skb->len);
+		return -EINVAL;
+	}
+
 	pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
 	ppdu_id = le32_to_cpu(msg->ppdu_id);
 
@@ -1583,6 +1590,16 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
 		goto exit;
 	}
 
+	if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
+		spin_unlock_bh(&ar->data_lock);
+		ath12k_warn(ab,
+			    "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
+			    ppdu_info->ppdu_stats.common.num_users,
+			    HTT_PPDU_STATS_MAX_USERS);
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	/* back up data rate tlv for all peers */
 	if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
 	    (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
Signature · 1 line
2.42.0
author maintainer
#24 lore raw

PATCH 24/491 wifi: ath10k: fix clang-specific fortify warning

In reply to Greg Kroah-Hartman

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

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

From: Dmitry Antipov <[email protected]>

[ Upstream commit cb4c132ebfeac5962f7258ffc831caa0c4dada1a ]

When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've noticed the following (somewhat confusing due to absence of an actual source code location):

In file included from drivers/net/wireless/ath/ath10k/debug.c:8:
In file included from ./include/linux/module.h:13:
In file included from ./include/linux/stat.h:19:
In file included from ./include/linux/time.h:60:
In file included from ./include/linux/time32.h:13:
In file included from ./include/linux/timex.h:67:
In file included from ./arch/x86/include/asm/timex.h:5:
In file included from ./arch/x86/include/asm/processor.h:23:
In file included from ./arch/x86/include/asm/msr.h:11:
In file included from ./arch/x86/include/asm/cpumask.h:5:
In file included from ./include/linux/cpumask.h:12:
In file included from ./include/linux/bitmap.h:11:
In file included from ./include/linux/string.h:254:
./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]

                        __read_overflow2_field(q_size_field, size);

The compiler actually complains on 'ath10k_debug_get_et_strings()' where fortification logic inteprets call to 'memcpy()' as an attempt to copy the whole 'ath10k_gstrings_stats' array from it's first member and so issues an overread warning. This warning may be silenced by passing an address of the whole array and not the first member to 'memcpy()'.

---
 drivers/net/wireless/ath/ath10k/debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath10k/debug.c +1 -1
index f9518e1c99039..fe89bc61e5317 100644
@@ -1140,7 +1140,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
 				 u32 sset, u8 *data)
 {
 	if (sset == ETH_SS_STATS)
-		memcpy(data, *ath10k_gstrings_stats,
+		memcpy(data, ath10k_gstrings_stats,
 		       sizeof(ath10k_gstrings_stats));
 }
 
Signature · 1 line
2.42.0
author maintainer
#25 lore raw

PATCH 25/491 wifi: ath12k: fix possible out-of-bound write in ath12k_wmi_ext_hal_reg_caps()

In reply to Greg Kroah-Hartman

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

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

From: Baochen Qiang <[email protected]>

[ Upstream commit b302dce3d9edea5b93d1902a541684a967f3c63c ]

reg_cap.phy_id is extracted from WMI event and could be an unexpected value in case some errors happen. As a result out-of-bound write may occur to soc->hal_reg_cap. Fix it by validating reg_cap.phy_id before using it.

This is found during code review.

Compile tested only.

---
 drivers/net/wireless/ath/ath12k/wmi.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/wireless/ath/ath12k/wmi.c +6 -0
index eebc5a65ce3b4..416b22fa53ebf 100644
@@ -3799,6 +3799,12 @@ static int ath12k_wmi_ext_hal_reg_caps(struct ath12k_base *soc,
 			ath12k_warn(soc, "failed to extract reg cap %d\n", i);
 			return ret;
 		}
+
+		if (reg_cap.phy_id >= MAX_RADIOS) {
+			ath12k_warn(soc, "unexpected phy id %u\n", reg_cap.phy_id);
+			return -EINVAL;
+		}
+
 		soc->hal_reg_cap[reg_cap.phy_id] = reg_cap;
 	}
 	return 0;
Signature · 1 line
2.42.0
author maintainer
#26 lore raw

PATCH 26/491 ACPI: APEI: Fix AER info corruption when error status data has multiple sections

In reply to Greg Kroah-Hartman

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

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

From: Shiju Jose <[email protected]>

[ Upstream commit e2abc47a5a1a9f641e7cacdca643fdd40729bf6e ]

ghes_handle_aer() passes AER data to the PCI core for logging and recovery by calling aer_recover_queue() with a pointer to struct aer_capability_regs.

The problem was that aer_recover_queue() queues the pointer directly without copying the aer_capability_regs data. The pointer was to the ghes->estatus buffer, which could be reused before aer_recover_work_func() reads the data.

To avoid this problem, allocate a new aer_capability_regs structure from the ghes_estatus_pool, copy the AER data from the ghes->estatus buffer into it, pass a pointer to the new struct to aer_recover_queue(), and free it after aer_recover_work_func() has processed it.

---
 drivers/acpi/apei/ghes.c | 23 ++++++++++++++++++++++-
 drivers/pci/pcie/aer.c   | 10 ++++++++++
 include/acpi/ghes.h      |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)
drivers/acpi/apei/ghes.c +22 -1
index ef59d6ea16da0..63ad0541db381 100644
@@ -209,6 +209,20 @@ int ghes_estatus_pool_init(unsigned int num_ghes)
 	return -ENOMEM;
 }
 
+/**
+ * ghes_estatus_pool_region_free - free previously allocated memory
+ *				   from the ghes_estatus_pool.
+ * @addr: address of memory to free.
+ * @size: size of memory to free.
+ *
+ * Returns none.
+ */
+void ghes_estatus_pool_region_free(unsigned long addr, u32 size)
+{
+	gen_pool_free(ghes_estatus_pool, addr, size);
+}
+EXPORT_SYMBOL_GPL(ghes_estatus_pool_region_free);
+
 static int map_gen_v2(struct ghes *ghes)
 {
 	return apei_map_generic_address(&ghes->generic_v2->read_ack_register);
@@ -564,6 +578,7 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
 	    pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
 		unsigned int devfn;
 		int aer_severity;
+		u8 *aer_info;
 
 		devfn = PCI_DEVFN(pcie_err->device_id.device,
 				  pcie_err->device_id.function);
@@ -577,11 +592,17 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
 		if (gdata->flags & CPER_SEC_RESET)
 			aer_severity = AER_FATAL;
 
+		aer_info = (void *)gen_pool_alloc(ghes_estatus_pool,
+						  sizeof(struct aer_capability_regs));
+		if (!aer_info)
+			return;
+		memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs));
+
 		aer_recover_queue(pcie_err->device_id.segment,
 				  pcie_err->device_id.bus,
 				  devfn, aer_severity,
 				  (struct aer_capability_regs *)
-				  pcie_err->aer_info);
+				  aer_info);
 	}
 #endif
 }
drivers/pci/pcie/aer.c +10 -0
index f6c24ded134cd..67025ee2b7454 100644
@@ -29,6 +29,7 @@
 #include <linux/kfifo.h>
 #include <linux/slab.h>
 #include <acpi/apei.h>
+#include <acpi/ghes.h>
 #include <ras/ras_event.h>
 
 #include "../pci.h"
@@ -1010,6 +1011,15 @@ static void aer_recover_work_func(struct work_struct *work)
 			continue;
 		}
 		cper_print_aer(pdev, entry.severity, entry.regs);
+		/*
+		 * Memory for aer_capability_regs(entry.regs) is being allocated from the
+		 * ghes_estatus_pool to protect it from overwriting when multiple sections
+		 * are present in the error status. Thus free the same after processing
+		 * the data.
+		 */
+		ghes_estatus_pool_region_free((unsigned long)entry.regs,
+					      sizeof(struct aer_capability_regs));
+
 		if (entry.severity == AER_NONFATAL)
 			pcie_do_recovery(pdev, pci_channel_io_normal,
 					 aer_root_reset);
include/acpi/ghes.h +4 -0
index 3c8bba9f1114a..be1dd4c1a9174 100644
@@ -73,8 +73,12 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb);
 void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
 
 struct list_head *ghes_get_devices(void);
+
+void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
 #else
 static inline struct list_head *ghes_get_devices(void) { return NULL; }
+
+static inline void ghes_estatus_pool_region_free(unsigned long addr, u32 size) { return; }
 #endif
 
 int ghes_estatus_pool_init(unsigned int num_ghes);
Signature · 1 line
2.42.0
author maintainer
#27 lore raw

PATCH 27/491 net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI

In reply to Greg Kroah-Hartman

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

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

From: Christian Marangi <[email protected]>

[ Upstream commit d387e34fec407f881fdf165b5d7ec128ebff362f ]

Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd NRZ in their EEPROM.

The module also require the ignore tx fault fixup similar to Huawei MA5671A as it gets disabled on error messages with serial redirection enabled.

---
 drivers/net/phy/sfp.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/phy/sfp.c +5 -0
index d855a18308d78..338b9769d91a1 100644
@@ -452,6 +452,11 @@ static const struct sfp_quirk sfp_quirks[] = {
 	// Rollball protocol to talk to the PHY.
 	SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt),
 
+	// Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
+	// NRZ in their EEPROM
+	SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex,
+		  sfp_fixup_ignore_tx_fault),
+
 	SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
 
 	// HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports
Signature · 1 line
2.42.0
author maintainer
#28 lore raw

PATCH 28/491 wifi: mt76: mt7921e: Support MT7992 IP in Xiaomi Redmibook 15 Pro (2023)

In reply to Greg Kroah-Hartman

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

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

From: Ingo Rohloff <[email protected]>

[ Upstream commit fce9c967820a72f600abbf061d7077861685a14d ]

In the Xiaomi Redmibook 15 Pro (2023) laptop I have got, a wifi chip is used, which according to its PCI Vendor ID is from "ITTIM Technology".

This chip works flawlessly with the mt7921e module. The driver doesn't bind to this PCI device, because the Vendor ID from "ITTIM Technology" is not recognized.

This patch adds the PCI Vendor ID from "ITTIM Technology" to the list of PCI Vendor IDs and lets the mt7921e driver bind to the mentioned wifi chip.

---
 drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 ++
 include/linux/pci_ids.h                         | 2 ++
 2 files changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/pci.c +2 -0
index 95610a117d2f0..ed5a220763ce6 100644
@@ -17,6 +17,8 @@ static const struct pci_device_id mt7921_pci_device_table[] = {
 		.driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922),
 		.driver_data = (kernel_ulong_t)MT7922_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ITTIM, 0x7922),
+		.driver_data = (kernel_ulong_t)MT7922_FIRMWARE_WM },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0608),
 		.driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0616),
include/linux/pci_ids.h +2 -0
index 7702f078ef4ad..54bc1ca7b66fc 100644
@@ -180,6 +180,8 @@
 #define PCI_DEVICE_ID_BERKOM_A4T		0xffa4
 #define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO	0xffa8
 
+#define PCI_VENDOR_ID_ITTIM		0x0b48
+
 #define PCI_VENDOR_ID_COMPAQ		0x0e11
 #define PCI_DEVICE_ID_COMPAQ_TOKENRING	0x0508
 #define PCI_DEVICE_ID_COMPAQ_TACHYON	0xa0fc
Signature · 1 line
2.42.0
author maintainer
#29 lore raw

PATCH 29/491 net: annotate data-races around sk->sk_tx_queue_mapping

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 0bb4d124d34044179b42a769a0c76f389ae973b6 ]

This field can be read or written without socket lock being held.

Add annotations to avoid load-store tearing.

---
 include/net/sock.h | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
include/net/sock.h +16 -4
index fc189910e63fc..df19f99d26357 100644
@@ -2006,21 +2006,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
 	/* sk_tx_queue_mapping accept only upto a 16-bit value */
 	if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX))
 		return;
-	sk->sk_tx_queue_mapping = tx_queue;
+	/* Paired with READ_ONCE() in sk_tx_queue_get() and
+	 * other WRITE_ONCE() because socket lock might be not held.
+	 */
+	WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue);
 }
 
 #define NO_QUEUE_MAPPING	USHRT_MAX
 
 static inline void sk_tx_queue_clear(struct sock *sk)
 {
-	sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING;
+	/* Paired with READ_ONCE() in sk_tx_queue_get() and
+	 * other WRITE_ONCE() because socket lock might be not held.
+	 */
+	WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING);
 }
 
 static inline int sk_tx_queue_get(const struct sock *sk)
 {
-	if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING)
-		return sk->sk_tx_queue_mapping;
+	if (sk) {
+		/* Paired with WRITE_ONCE() in sk_tx_queue_clear()
+		 * and sk_tx_queue_set().
+		 */
+		int val = READ_ONCE(sk->sk_tx_queue_mapping);
 
+		if (val != NO_QUEUE_MAPPING)
+			return val;
+	}
 	return -1;
 }
 
Signature · 1 line
2.42.0
author maintainer
#30 lore raw

PATCH 30/491 net: annotate data-races around sk->sk_dst_pending_confirm

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit eb44ad4e635132754bfbcb18103f1dcb7058aedd ]

This field can be read or written without socket lock being held.

Add annotations to avoid load-store tearing.

---
 include/net/sock.h    | 6 +++---
 net/core/sock.c       | 2 +-
 net/ipv4/tcp_output.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
include/net/sock.h +3 -3
index df19f99d26357..b9f0ef4bb527a 100644
@@ -2181,7 +2181,7 @@ static inline void __dst_negative_advice(struct sock *sk)
 		if (ndst != dst) {
 			rcu_assign_pointer(sk->sk_dst_cache, ndst);
 			sk_tx_queue_clear(sk);
-			sk->sk_dst_pending_confirm = 0;
+			WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
 		}
 	}
 }
@@ -2198,7 +2198,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst)
 	struct dst_entry *old_dst;
 
 	sk_tx_queue_clear(sk);
-	sk->sk_dst_pending_confirm = 0;
+	WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
 	old_dst = rcu_dereference_protected(sk->sk_dst_cache,
 					    lockdep_sock_is_held(sk));
 	rcu_assign_pointer(sk->sk_dst_cache, dst);
@@ -2211,7 +2211,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst)
 	struct dst_entry *old_dst;
 
 	sk_tx_queue_clear(sk);
-	sk->sk_dst_pending_confirm = 0;
+	WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
 	old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst);
 	dst_release(old_dst);
 }
net/core/sock.c +1 -1
index eef27812013a4..6df04c705200a 100644
@@ -600,7 +600,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
 	    INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check, ipv4_dst_check,
 			       dst, cookie) == NULL) {
 		sk_tx_queue_clear(sk);
-		sk->sk_dst_pending_confirm = 0;
+		WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
 		RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
 		dst_release(dst);
 		return NULL;
net/ipv4/tcp_output.c +1 -1
index afa819eede6a3..c2403fea8ec9a 100644
@@ -1316,7 +1316,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
 	skb->destructor = skb_is_tcp_pure_ack(skb) ? __sock_wfree : tcp_wfree;
 	refcount_add(skb->truesize, &sk->sk_wmem_alloc);
 
-	skb_set_dst_pending_confirm(skb, sk->sk_dst_pending_confirm);
+	skb_set_dst_pending_confirm(skb, READ_ONCE(sk->sk_dst_pending_confirm));
 
 	/* Build TCP header and checksum it. */
 	th = (struct tcphdr *)skb->data;
Signature · 1 line
2.42.0
author maintainer
#31 lore raw

PATCH 31/491 wifi: ath12k: mhi: fix potential memory leak in ath12k_mhi_register()

In reply to Greg Kroah-Hartman

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

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

From: Ma Ke <[email protected]>

[ Upstream commit 47c27aa7ded4b8ead19b3487cc42a6185b762903 ]

mhi_alloc_controller() allocates a memory space for mhi_ctrl. When some errors occur, mhi_ctrl should be freed by mhi_free_controller() and set ab_pci->mhi_ctrl = NULL.

We can fix it by calling mhi_free_controller() when the failure happens and set ab_pci->mhi_ctrl = NULL in all of the places where we call mhi_free_controller().

---
 drivers/net/wireless/ath/ath12k/mhi.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath12k/mhi.c +7 -4
index 42f1140baa4fe..f83d3e09ae366 100644
@@ -370,8 +370,7 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci)
 	ret = ath12k_mhi_get_msi(ab_pci);
 	if (ret) {
 		ath12k_err(ab, "failed to get msi for mhi\n");
-		mhi_free_controller(mhi_ctrl);
-		return ret;
+		goto free_controller;
 	}
 
 	mhi_ctrl->iova_start = 0;
@@ -388,11 +387,15 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci)
 	ret = mhi_register_controller(mhi_ctrl, ab->hw_params->mhi_config);
 	if (ret) {
 		ath12k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
-		mhi_free_controller(mhi_ctrl);
-		return ret;
+		goto free_controller;
 	}
 
 	return 0;
+
+free_controller:
+	mhi_free_controller(mhi_ctrl);
+	ab_pci->mhi_ctrl = NULL;
+	return ret;
 }
 
 void ath12k_mhi_unregister(struct ath12k_pci *ab_pci)
Signature · 1 line
2.42.0
author maintainer
#32 lore raw

PATCH 32/491 wifi: ath10k: Dont touch the CE interrupt registers after power up

In reply to Greg Kroah-Hartman

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

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

From: Douglas Anderson <[email protected]>

[ Upstream commit 170c75d43a77dc937c58f07ecf847ba1b42ab74e ]

As talked about in commit d66d24ac300c ("ath10k: Keep track of which interrupts fired, don't poll them"), if we access the copy engine register at a bad time then ath10k can go boom. However, it's not necessarily easy to know when it's safe to access them.

The ChromeOS test labs saw a crash that looked like this at shutdown/reboot time (on a chromeos-5.15 kernel, but likely the problem could also reproduce upstream):

Internal error: synchronous external abort: 96000010 [#1] PREEMPT SMP
...
CPU: 4 PID: 6168 Comm: reboot Not tainted 5.15.111-lockdep-19350-g1d624fe6758f #1 010b9b233ab055c27c6dc88efb0be2f4e9e86f51
Hardware name: Google Kingoftown (DT)
...
pc : ath10k_snoc_read32+0x50/0x74 [ath10k_snoc]
lr : ath10k_snoc_read32+0x24/0x74 [ath10k_snoc]
...
Call trace:
ath10k_snoc_read32+0x50/0x74 [ath10k_snoc ...]
ath10k_ce_disable_interrupt+0x190/0x65c [ath10k_core ...]
ath10k_ce_disable_interrupts+0x8c/0x120 [ath10k_core ...]
ath10k_snoc_hif_stop+0x78/0x660 [ath10k_snoc ...]
ath10k_core_stop+0x13c/0x1ec [ath10k_core ...]
ath10k_halt+0x398/0x5b0 [ath10k_core ...]
ath10k_stop+0xfc/0x1a8 [ath10k_core ...]
drv_stop+0x148/0x6b4 [mac80211 ...]
ieee80211_stop_device+0x70/0x80 [mac80211 ...]
ieee80211_do_stop+0x10d8/0x15b0 [mac80211 ...]
ieee80211_stop+0x144/0x1a0 [mac80211 ...]
__dev_close_many+0x1e8/0x2c0
dev_close_many+0x198/0x33c
dev_close+0x140/0x210
cfg80211_shutdown_all_interfaces+0xc8/0x1e0 [cfg80211 ...]
ieee80211_remove_interfaces+0x118/0x5c4 [mac80211 ...]
ieee80211_unregister_hw+0x64/0x1f4 [mac80211 ...]
ath10k_mac_unregister+0x4c/0xf0 [ath10k_core ...]
ath10k_core_unregister+0x80/0xb0 [ath10k_core ...]
ath10k_snoc_free_resources+0xb8/0x1ec [ath10k_snoc ...]
ath10k_snoc_shutdown+0x98/0xd0 [ath10k_snoc ...]
platform_shutdown+0x7c/0xa0
device_shutdown+0x3e0/0x58c
kernel_restart_prepare+0x68/0xa0
kernel_restart+0x28/0x7c

Though there's no known way to reproduce the problem, it makes sense that it would be the same issue where we're trying to access copy engine registers when it's not allowed.

Let's fix this by changing how we "disable" the interrupts. Instead of tweaking the copy engine registers we'll just use disable_irq() and enable_irq(). Then we'll configure the interrupts once at power up time.

Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1

---
 drivers/net/wireless/ath/ath10k/snoc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath10k/snoc.c +14 -4
index 26214c00cd0d7..2c39bad7ebfb9 100644
@@ -828,12 +828,20 @@ static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar,
 
 static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
 {
-	ath10k_ce_disable_interrupts(ar);
+	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+	int id;
+
+	for (id = 0; id < CE_COUNT_MAX; id++)
+		disable_irq(ar_snoc->ce_irqs[id].irq_line);
 }
 
 static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
 {
-	ath10k_ce_enable_interrupts(ar);
+	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+	int id;
+
+	for (id = 0; id < CE_COUNT_MAX; id++)
+		enable_irq(ar_snoc->ce_irqs[id].irq_line);
 }
 
 static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
@@ -1090,6 +1098,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar,
 		goto err_free_rri;
 	}
 
+	ath10k_ce_enable_interrupts(ar);
+
 	return 0;
 
 err_free_rri:
@@ -1253,8 +1263,8 @@ static int ath10k_snoc_request_irq(struct ath10k *ar)
 
 	for (id = 0; id < CE_COUNT_MAX; id++) {
 		ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
-				  ath10k_snoc_per_engine_handler, 0,
-				  ce_name[id], ar);
+				  ath10k_snoc_per_engine_handler,
+				  IRQF_NO_AUTOEN, ce_name[id], ar);
 		if (ret) {
 			ath10k_err(ar,
 				   "failed to register IRQ handler for CE %d: %d\n",
Signature · 1 line
2.42.0
author maintainer
#33 lore raw

PATCH 33/491 net: sfp: add quirk for FSs 2.5G copper SFP

In reply to Greg Kroah-Hartman

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

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

From: Raju Lakkaraju <[email protected]>

[ Upstream commit e27aca3760c08b7b05aea71068bd609aa93e7b35 ]

Add a quirk for a copper SFP that identifies itself as "FS" "SFP-2.5G-T". This module's PHY is inaccessible, and can only run at 2500base-X with the host without negotiation. Add a quirk to enable the 2500base-X interface mode with 2500base-T support and disable auto negotiation.

---
 drivers/net/phy/sfp.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/phy/sfp.c +3 -0
index 338b9769d91a1..f411ded5344a8 100644
@@ -468,6 +468,9 @@ static const struct sfp_quirk sfp_quirks[] = {
 	SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
 		  sfp_fixup_ignore_tx_fault),
 
+	// FS 2.5G Base-T
+	SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
+
 	// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
 	// 2500MBd NRZ in their EEPROM
 	SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
Signature · 1 line
2.42.0
author maintainer
#34 lore raw

PATCH 34/491 vsock: read from sockets error queue

In reply to Greg Kroah-Hartman

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

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

From: Arseniy Krasnov <[email protected]>

[ Upstream commit 49dbe25adac42d3e06f65d1420946bec65896222 ]

This adds handling of MSG_ERRQUEUE input flag in receive call. This flag is used to read socket's error queue instead of data queue. Possible scenario of error queue usage is receiving completions for transmission with MSG_ZEROCOPY flag. This patch also adds new defines: 'SOL_VSOCK' and 'VSOCK_RECVERR'.

---
 include/linux/socket.h          |  1 +
 include/uapi/linux/vm_sockets.h | 17 +++++++++++++++++
 net/vmw_vsock/af_vsock.c        |  6 ++++++
 3 files changed, 24 insertions(+)
include/linux/socket.h +1 -0
index 39b74d83c7c4a..cfcb7e2c3813f 100644
@@ -383,6 +383,7 @@ struct ucred {
 #define SOL_MPTCP	284
 #define SOL_MCTP	285
 #define SOL_SMC		286
+#define SOL_VSOCK	287
 
 /* IPX options */
 #define IPX_TYPE	1
include/uapi/linux/vm_sockets.h +17 -0
index c60ca33eac594..ed07181d4eff9 100644
@@ -191,4 +191,21 @@ struct sockaddr_vm {
 
 #define IOCTL_VM_SOCKETS_GET_LOCAL_CID		_IO(7, 0xb9)
 
+/* MSG_ZEROCOPY notifications are encoded in the standard error format,
+ * sock_extended_err. See Documentation/networking/msg_zerocopy.rst in
+ * kernel source tree for more details.
+ */
+
+/* 'cmsg_level' field value of 'struct cmsghdr' for notification parsing
+ * when MSG_ZEROCOPY flag is used on transmissions.
+ */
+
+#define SOL_VSOCK	287
+
+/* 'cmsg_type' field value of 'struct cmsghdr' for notification parsing
+ * when MSG_ZEROCOPY flag is used on transmissions.
+ */
+
+#define VSOCK_RECVERR	1
+
 #endif /* _UAPI_VM_SOCKETS_H */
net/vmw_vsock/af_vsock.c +6 -0
index 020cf17ab7e47..ccd8cefeea7ba 100644
@@ -89,6 +89,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/cred.h>
+#include <linux/errqueue.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -110,6 +111,7 @@
 #include <linux/workqueue.h>
 #include <net/sock.h>
 #include <net/af_vsock.h>
+#include <uapi/linux/vm_sockets.h>
 
 static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
 static void vsock_sk_destruct(struct sock *sk);
@@ -2134,6 +2136,10 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	int err;
 
 	sk = sock->sk;
+
+	if (unlikely(flags & MSG_ERRQUEUE))
+		return sock_recv_errqueue(sk, msg, len, SOL_VSOCK, VSOCK_RECVERR);
+
 	vsk = vsock_sk(sk);
 	err = 0;
 
Signature · 1 line
2.42.0
author maintainer
#35 lore raw

PATCH 35/491 bpf: Ensure proper register state printing for cond jumps

In reply to Greg Kroah-Hartman

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

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

From: Andrii Nakryiko <[email protected]>

[ Upstream commit 1a8a315f008a58f54fecb012b928aa6a494435b3 ]

Verifier emits relevant register state involved in any given instruction next to it after ; to the right, if possible. Or, worst case, on the separate line repeating instruction index.

E.g., a nice and simple case would be:

2: (d5) if r0 s<= 0x0 goto pc+1 ; R0_w=0

But if there is some intervening extra output (e.g., precision backtracking log) involved, we are supposed to see the state after the precision backtrack log:

4: (75) if r0 s>= 0x0 goto pc+1
mark_precise: frame0: last_idx 4 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r0 stack= before 2: (d5) if r0 s<= 0x0 goto pc+1
mark_precise: frame0: regs=r0 stack= before 1: (b7) r0 = 0
6: R0_w=0

First off, note that in 6: R0_w=0 instruction index corresponds to the next instruction, not to the conditional jump instruction itself, which is wrong and we'll get to that.

But besides that, the above is a happy case that does work today. Yet, if it so happens that precision backtracking had to traverse some of the parent states, this 6: R0_w=0 state output would be missing.

This is due to a quirk of print_verifier_state() routine, which performs mark_verifier_state_clean(env) at the end. This marks all registers as "non-scratched", which means that subsequent logic to print *relevant* registers (that is, "scratched ones") fails and doesn't see anything relevant to print and skips the output altogether.

print_verifier_state() is used both to print instruction context, but also to print an **entire** verifier state indiscriminately, e.g., during precision backtracking (and in a few other situations, like during entering or exiting subprogram). Which means if we have to print entire parent state before getting to printing instruction context state, instruction context is marked as clean and is omitted.

Long story short, this is definitely not intentional. So we fix this behavior in this patch by teaching print_verifier_state() to clear scratch state only if it was used to print instruction state, not the parent/callback state. This is determined by print_all option, so if it's not set, we don't clear scratch state. This fixes missing instruction state for these cases.

As for the mismatched instruction index, we fix that by making sure we call print_insn_state() early inside check_cond_jmp_op() before we adjusted insn_idx based on jump branch taken logic. And with that we get desired correct information:

9: (16) if w4 == 0x1 goto pc+9
mark_precise: frame0: last_idx 9 first_idx 9 subseq_idx -1
mark_precise: frame0: parent state regs=r4 stack=: R2_w=1944 R4_rw=P1 R10=fp0
mark_precise: frame0: last_idx 8 first_idx 0 subseq_idx 9
mark_precise: frame0: regs=r4 stack= before 8: (66) if w4 s> 0x3 goto pc+5
mark_precise: frame0: regs=r4 stack= before 7: (b7) r4 = 1
9: R4=1

---
 kernel/bpf/verifier.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +6 -1
index e7e2687c35884..c3b6f282128bf 100644
@@ -1513,7 +1513,8 @@ static void print_verifier_state(struct bpf_verifier_env *env,
 	if (state->in_async_callback_fn)
 		verbose(env, " async_cb");
 	verbose(env, "\n");
-	mark_verifier_state_clean(env);
+	if (!print_all)
+		mark_verifier_state_clean(env);
 }
 
 static inline u32 vlog_alignment(u32 pos)
@@ -13915,6 +13916,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
 		    !sanitize_speculative_path(env, insn, *insn_idx + 1,
 					       *insn_idx))
 			return -EFAULT;
+		if (env->log.level & BPF_LOG_LEVEL)
+			print_insn_state(env, this_branch->frame[this_branch->curframe]);
 		*insn_idx += insn->off;
 		return 0;
 	} else if (pred == 0) {
@@ -13927,6 +13930,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
 					       *insn_idx + insn->off + 1,
 					       *insn_idx))
 			return -EFAULT;
+		if (env->log.level & BPF_LOG_LEVEL)
+			print_insn_state(env, this_branch->frame[this_branch->curframe]);
 		return 0;
 	}
 
Signature · 1 line
2.42.0
author maintainer
#36 lore raw

PATCH 36/491 wifi: iwlwifi: mvm: fix size check for fw_link_id

In reply to Greg Kroah-Hartman

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

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

From: Gregory Greenman <[email protected]>

[ Upstream commit e25bd1853cc8308158d97e5b3696ea3689fa0840 ]

Check that fw_link_id does not exceed the size of link_id_to_link_conf array. There's no any codepath that can cause that, but it's still safer to verify in case fw_link_id gets corrupted.

---
 drivers/net/wireless/intel/iwlwifi/mvm/link.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/link.c +2 -2
index 6e1ad65527d12..4ab55a1fcbf04 100644
@@ -60,7 +60,7 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) {
 		link_info->fw_link_id = iwl_mvm_get_free_fw_link_id(mvm,
 								    mvmvif);
-		if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)
+		if (link_info->fw_link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf))
 			return -EINVAL;
 
 		rcu_assign_pointer(mvm->link_id_to_link_conf[link_info->fw_link_id],
@@ -243,7 +243,7 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	int ret;
 
 	if (WARN_ON(!link_info ||
-		    link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID))
+		    link_info->fw_link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf)))
 		return -EINVAL;
 
 	RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id],
Signature · 1 line
2.42.0
author maintainer
#37 lore raw

PATCH 37/491 Bluetooth: btusb: Add date->evt_skb is NULL check

In reply to Greg Kroah-Hartman

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

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

From: youwan Wang <[email protected]>

[ Upstream commit 624820f7c8826dd010e8b1963303c145f99816e9 ]

fix crash because of null pointers

[ 6104.969662] BUG: kernel NULL pointer dereference, address: 00000000000000c8
[ 6104.969667] #PF: supervisor read access in kernel mode
[ 6104.969668] #PF: error_code(0x0000) - not-present page
[ 6104.969670] PGD 0 P4D 0
[ 6104.969673] Oops: 0000 [#1] SMP NOPTI
[ 6104.969684] RIP: 0010:btusb_mtk_hci_wmt_sync+0x144/0x220 [btusb]
[ 6104.969688] RSP: 0018:ffffb8d681533d48 EFLAGS: 00010246
[ 6104.969689] RAX: 0000000000000000 RBX: ffff8ad560bb2000 RCX: 0000000000000006
[ 6104.969691] RDX: 0000000000000000 RSI: ffffb8d681533d08 RDI: 0000000000000000
[ 6104.969692] RBP: ffffb8d681533d70 R08: 0000000000000001 R09: 0000000000000001
[ 6104.969694] R10: 0000000000000001 R11: 00000000fa83b2da R12: ffff8ad461d1d7c0
[ 6104.969695] R13: 0000000000000000 R14: ffff8ad459618c18 R15: ffffb8d681533d90
[ 6104.969697] FS:  00007f5a1cab9d40(0000) GS:ffff8ad578200000(0000) knlGS:00000
[ 6104.969699] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 6104.969700] CR2: 00000000000000c8 CR3: 000000018620c001 CR4: 0000000000760ef0
[ 6104.969701] PKRU: 55555554
[ 6104.969702] Call Trace:
[ 6104.969708]  btusb_mtk_shutdown+0x44/0x80 [btusb]
[ 6104.969732]  hci_dev_do_close+0x470/0x5c0 [bluetooth]
[ 6104.969748]  hci_rfkill_set_block+0x56/0xa0 [bluetooth]
[ 6104.969753]  rfkill_set_block+0x92/0x160
[ 6104.969755]  rfkill_fop_write+0x136/0x1e0
[ 6104.969759]  __vfs_write+0x18/0x40
[ 6104.969761]  vfs_write+0xdf/0x1c0
[ 6104.969763]  ksys_write+0xb1/0xe0
[ 6104.969765]  __x64_sys_write+0x1a/0x20
[ 6104.969769]  do_syscall_64+0x51/0x180
[ 6104.969771]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 6104.969773] RIP: 0033:0x7f5a21f18fef
[ 6104.9] RSP: 002b:00007ffeefe39010 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
[ 6104.969780] RAX: ffffffffffffffda RBX: 000055c10a7560a0 RCX: 00007f5a21f18fef
[ 6104.969781] RDX: 0000000000000008 RSI: 00007ffeefe39060 RDI: 0000000000000012
[ 6104.969782] RBP: 00007ffeefe39060 R08: 0000000000000000 R09: 0000000000000017
[ 6104.969784] R10: 00007ffeefe38d97 R11: 0000000000000293 R12: 0000000000000002
[ 6104.969785] R13: 00007ffeefe39220 R14: 00007ffeefe391a0 R15: 000055c10a72acf0
---
 drivers/bluetooth/btusb.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/bluetooth/btusb.c +3 -0
index ca9e2a210fff2..ea29469fe0cff 100644
@@ -2803,6 +2803,9 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
 		goto err_free_wc;
 	}
 
+	if (data->evt_skb == NULL)
+		goto err_free_wc;
+
 	/* Parse and handle the return WMT event */
 	wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data;
 	if (wmt_evt->whdr.op != hdr->op) {
Signature · 1 line
2.42.0
author maintainer
#38 lore raw

PATCH 38/491 Bluetooth: Fix double free in hci_conn_cleanup

In reply to Greg Kroah-Hartman

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

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

From: ZhengHan Wang <[email protected]>

[ Upstream commit a85fb91e3d728bdfc80833167e8162cce8bc7004 ]

syzbot reports a slab use-after-free in hci_conn_hash_flush [1]. After releasing an object using hci_conn_del_sysfs in the hci_conn_cleanup function, releasing the same object again using the hci_dev_put and hci_conn_put functions causes a double free. Here's a simplified flow:

hci_conn_del_sysfs:
hci_dev_put
put_device
kobject_put
kref_put
kobject_release
kobject_cleanup
kfree_const
kfree(name)

hci_dev_put:
...
kfree(name)

hci_conn_put:
put_device

    ...
      kfree(name)

This patch drop the hci_dev_put and hci_conn_put function call in hci_conn_cleanup function, because the object is freed in hci_conn_del_sysfs function.

This patch also fixes the refcounting in hci_conn_add_sysfs() and hci_conn_del_sysfs() to take into account device_add() failures.

This fixes CVE-2023-28464.

---
 net/bluetooth/hci_conn.c  |  6 ++----
 net/bluetooth/hci_sysfs.c | 23 ++++++++++++-----------
 2 files changed, 14 insertions(+), 15 deletions(-)
net/bluetooth/hci_conn.c +2 -4
index 4e03642488230..c090627ff9751 100644
@@ -172,13 +172,11 @@ static void hci_conn_cleanup(struct hci_conn *conn)
 			hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
 	}
 
-	hci_conn_del_sysfs(conn);
-
 	debugfs_remove_recursive(conn->debugfs);
 
-	hci_dev_put(hdev);
+	hci_conn_del_sysfs(conn);
 
-	hci_conn_put(conn);
+	hci_dev_put(hdev);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
net/bluetooth/hci_sysfs.c +12 -11
index 15b33579007cb..367e32fe30eb8 100644
@@ -35,7 +35,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 
-	BT_DBG("conn %p", conn);
+	bt_dev_dbg(hdev, "conn %p", conn);
 
 	conn->dev.type = &bt_link;
 	conn->dev.class = &bt_class;
@@ -48,27 +48,30 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 
-	BT_DBG("conn %p", conn);
+	bt_dev_dbg(hdev, "conn %p", conn);
 
 	if (device_is_registered(&conn->dev))
 		return;
 
 	dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
 
-	if (device_add(&conn->dev) < 0) {
+	if (device_add(&conn->dev) < 0)
 		bt_dev_err(hdev, "failed to register connection device");
-		return;
-	}
-
-	hci_dev_hold(hdev);
 }
 
 void hci_conn_del_sysfs(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 
-	if (!device_is_registered(&conn->dev))
+	bt_dev_dbg(hdev, "conn %p", conn);
+
+	if (!device_is_registered(&conn->dev)) {
+		/* If device_add() has *not* succeeded, use *only* put_device()
+		 * to drop the reference count.
+		 */
+		put_device(&conn->dev);
 		return;
+	}
 
 	while (1) {
 		struct device *dev;
@@ -80,9 +83,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
 		put_device(dev);
 	}
 
-	device_del(&conn->dev);
-
-	hci_dev_put(hdev);
+	device_unregister(&conn->dev);
 }
 
 static void bt_host_release(struct device *dev)
Signature · 1 line
2.42.0
author maintainer
#39 lore raw

PATCH 39/491 ACPI: EC: Add quirk for HP 250 G7 Notebook PC

In reply to Greg Kroah-Hartman

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

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

From: Jonathan Denose <[email protected]>

[ Upstream commit 891ddc03e2f4395e24795596e032f57d5ab37fe7 ]

Add GPE quirk entry for HP 250 G7 Notebook PC.

This change allows the lid switch to be identified as the lid switch and not a keyboard button. With the lid switch properly identified, the device triggers suspend correctly on lid close.

---
 drivers/acpi/ec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/acpi/ec.c +10 -0
index c95d0edb0be9e..a59c11df73754 100644
@@ -1924,6 +1924,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"),
 		},
 	},
+	{
+		/*
+		 * HP 250 G7 Notebook PC
+		 */
+		.callback = ec_honor_dsdt_gpe,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP 250 G7 Notebook PC"),
+		},
+	},
 	{
 		/*
 		 * Samsung hardware
Signature · 1 line
2.42.0
author maintainer
#40 lore raw

PATCH 40/491 tsnep: Fix tsnep_request_irq() format-overflow warning

In reply to Greg Kroah-Hartman

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

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

From: Gerhard Engleder <[email protected]>

[ Upstream commit 00e984cb986b31e9313745e51daceaa1e1eb7351 ]

Compiler warns about a possible format-overflow in tsnep_request_irq():
drivers/net/ethernet/engleder/tsnep_main.c:884:55: warning: 'sprintf' may write a terminating nul past the end of the destination [-Wformat-overflow=]

                         sprintf(queue->name, "%s-rx-%d", name,
                                                       ^
drivers/net/ethernet/engleder/tsnep_main.c:881:55: warning: 'sprintf' may write a terminating nul past the end of the destination [-Wformat-overflow=]
                         sprintf(queue->name, "%s-tx-%d", name,
                                                       ^
drivers/net/ethernet/engleder/tsnep_main.c:878:49: warning: '-txrx-' directive writing 6 bytes into a region of size between 5 and 25 [-Wformat-overflow=]
                         sprintf(queue->name, "%s-txrx-%d", name,
                                                 ^~~~~~

Actually overflow cannot happen. Name is limited to IFNAMSIZ, because netdev_name() is called during ndo_open(). queue_index is single char, because less than 10 queues are supported.

Fix warning with snprintf(). Additionally increase buffer to 32 bytes, because those 7 additional bytes were unused anyway.

---
 drivers/net/ethernet/engleder/tsnep.h      |  2 +-
 drivers/net/ethernet/engleder/tsnep_main.c | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/net/ethernet/engleder/tsnep.h +1 -1
index 11b29f56aaf9c..b91abe9efb517 100644
@@ -142,7 +142,7 @@ struct tsnep_rx {
 
 struct tsnep_queue {
 	struct tsnep_adapter *adapter;
-	char name[IFNAMSIZ + 9];
+	char name[IFNAMSIZ + 16];
 
 	struct tsnep_tx *tx;
 	struct tsnep_rx *rx;
drivers/net/ethernet/engleder/tsnep_main.c +6 -6
index 479156576bc8a..e3fc894fa3f6f 100644
@@ -1778,14 +1778,14 @@ static int tsnep_request_irq(struct tsnep_queue *queue, bool first)
 		dev = queue->adapter;
 	} else {
 		if (queue->tx && queue->rx)
-			sprintf(queue->name, "%s-txrx-%d", name,
-				queue->rx->queue_index);
+			snprintf(queue->name, sizeof(queue->name), "%s-txrx-%d",
+				 name, queue->rx->queue_index);
 		else if (queue->tx)
-			sprintf(queue->name, "%s-tx-%d", name,
-				queue->tx->queue_index);
+			snprintf(queue->name, sizeof(queue->name), "%s-tx-%d",
+				 name, queue->tx->queue_index);
 		else
-			sprintf(queue->name, "%s-rx-%d", name,
-				queue->rx->queue_index);
+			snprintf(queue->name, sizeof(queue->name), "%s-rx-%d",
+				 name, queue->rx->queue_index);
 		handler = tsnep_irq_txrx;
 		dev = queue;
 	}
Signature · 1 line
2.42.0
author maintainer
#41 lore raw

PATCH 41/491 gpiolib: acpi: Add a ignore interrupt quirk for Peaq C1010

In reply to Greg Kroah-Hartman

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

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

From: Hans de Goede <[email protected]>

[ Upstream commit 6cc64f6173751d212c9833bde39e856b4f585a3e ]

On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to a "dolby" button. At the ACPI level an _AEI event-handler is connected which sets an ACPI variable to 1 on both edges. This variable can be polled + cleared to 0 using WMI.

Since the variable is set on both edges the WMI interface is pretty useless even when polling. So instead of writing a custom WMI driver for this the x86-android-tablets code instantiates a gpio-keys platform device for the "dolby" button.

Add an ignore_interrupt quirk for INT33FC:00 pin 3 on the Peaq C1010, so that it is not seen as busy when the gpio-keys driver requests it.

Note this replaces a hack in x86-android-tablets where it would call acpi_gpiochip_free_interrupts() on the INT33FC:00 GPIO controller. acpi_gpiochip_free_interrupts() is considered private (internal) gpiolib API so x86-android-tablets should stop using it.

---
 drivers/gpio/gpiolib-acpi.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
drivers/gpio/gpiolib-acpi.c +20 -0
index a775d2bdac94f..980ec04892173 100644
@@ -1655,6 +1655,26 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
 			.ignore_wake = "SYNA1202:00@16",
 		},
 	},
+	{
+		/*
+		 * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to
+		 * a "dolby" button. At the ACPI level an _AEI event-handler
+		 * is connected which sets an ACPI variable to 1 on both
+		 * edges. This variable can be polled + cleared to 0 using
+		 * WMI. But since the variable is set on both edges the WMI
+		 * interface is pretty useless even when polling.
+		 * So instead the x86-android-tablets code instantiates
+		 * a gpio-keys platform device for it.
+		 * Ignore the _AEI handler for the pin, so that it is not busy.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"),
+		},
+		.driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+			.ignore_interrupt = "INT33FC:00@3",
+		},
+	},
 	{} /* Terminating entry */
 };
 
Signature · 1 line
2.42.0
author maintainer
#42 lore raw

PATCH 42/491 platform/chrome: kunit: initialize lock for fake ec_dev

In reply to Greg Kroah-Hartman

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

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

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

[ Upstream commit e410b4ade83d06a046f6e32b5085997502ba0559 ]

cros_ec_cmd_xfer() uses ec_dev->lock. Initialize it.

Otherwise, dmesg shows the following:

Quoted 8 lines

DEBUG_LOCKS_WARN_ON(lock->magic != lock)
...

Call Trace:
 ? __mutex_lock
 ? __warn
 ? __mutex_lock
 ...
 ? cros_ec_cmd_xfer
---
 drivers/platform/chrome/cros_ec_proto_test.c | 1 +
 1 file changed, 1 insertion(+)
drivers/platform/chrome/cros_ec_proto_test.c +1 -0
index 5b9748e0463bc..63e38671e95a6 100644
@@ -2668,6 +2668,7 @@ static int cros_ec_proto_test_init(struct kunit *test)
 	ec_dev->dev->release = cros_ec_proto_test_release;
 	ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock;
 	ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock;
+	mutex_init(&ec_dev->lock);
 
 	priv->msg = (struct cros_ec_command *)priv->_msg;
 
Signature · 1 line
2.42.0
author maintainer
#43 lore raw

PATCH 43/491 of: address: Fix address translation when address-size is greater than 2

In reply to Greg Kroah-Hartman

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

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

From: Herve Codina <[email protected]>

[ Upstream commit 42604f8eb7ba04b589375049cc76282dad4677d2 ]

With the recent addition of of_pci_prop_ranges() in commit 407d1a51921e ("PCI: Create device tree node for bridge"), the ranges property can have a 3 cells child address, a 3 cells parent address and a 2 cells child size.

A range item property for a PCI device is filled as follow:
<BAR_nbr> 0 0 <phys.hi> <phys.mid> <phys.low> <BAR_sizeh> <BAR_sizel> <-- Child --> <-- Parent (PCI definition) --> <- BAR size (64bit) -->

This allow to translate BAR addresses from the DT. For instance:
pci@0,0 {
#address-cells = <0x03>;
#size-cells = <0x02>;
device_type = "pci";
compatible = "pci11ab,100", "pciclass,060400", "pciclass,0604"; ranges = <0x82000000 0x00 0xe8000000

            0x82000000 0x00 0xe8000000
	    0x00 0x4400000>;
  ...
  dev@0,0 {
    #address-cells = <0x03>;
    #size-cells = <0x02>;
    compatible = "pci1055,9660", "pciclass,020000", "pciclass,0200";
    /* Translations for BAR0 to BAR5 */
    ranges = <0x00 0x00 0x00 0x82010000 0x00 0xe8000000 0x00 0x2000000
              0x01 0x00 0x00 0x82010000 0x00 0xea000000 0x00 0x1000000
              0x02 0x00 0x00 0x82010000 0x00 0xeb000000 0x00 0x800000
              0x03 0x00 0x00 0x82010000 0x00 0xeb800000 0x00 0x800000
              0x04 0x00 0x00 0x82010000 0x00 0xec000000 0x00 0x20000
              0x05 0x00 0x00 0x82010000 0x00 0xec020000 0x00 0x2000>;
    ...
    pci-ep-bus@0 {
      #address-cells = <0x01>;
      #size-cells = <0x01>;
      compatible = "simple-bus";
      /* Translate 0xe2000000 to BAR0 and 0xe0000000 to BAR1 */
      ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
                0xe0000000 0x01 0x00 0x00 0x1000000>;
      ...
    };

};
};

During the translation process, the "default-flags" map() function is used to select the matching item in the ranges table and determine the address offset from this matching item.
This map() function simply calls of_read_number() and when address-size is greater than 2, the map() function skips the extra high address part (ie part over 64bit). This lead to a wrong matching item and a wrong offset computation.
Also during the translation itself, the extra high part related to the parent address is not present in the translated address.

Fix the "default-flags" map() and translate() in order to take into account the child extra high address part in map() and the parent extra high address part in translate() and so having a correct address translation for ranges patterns such as the one given in the example above.

---
 drivers/of/address.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)
drivers/of/address.c +28 -2
index e692809ff8227..3219c51777507 100644
@@ -100,6 +100,32 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
 	return IORESOURCE_MEM;
 }
 
+static u64 of_bus_default_flags_map(__be32 *addr, const __be32 *range, int na,
+				    int ns, int pna)
+{
+	u64 cp, s, da;
+
+	/* Check that flags match */
+	if (*addr != *range)
+		return OF_BAD_ADDR;
+
+	/* Read address values, skipping high cell */
+	cp = of_read_number(range + 1, na - 1);
+	s  = of_read_number(range + na + pna, ns);
+	da = of_read_number(addr + 1, na - 1);
+
+	pr_debug("default flags map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
+
+	if (da < cp || da >= (cp + s))
+		return OF_BAD_ADDR;
+	return da - cp;
+}
+
+static int of_bus_default_flags_translate(__be32 *addr, u64 offset, int na)
+{
+	/* Keep "flags" part (high cell) in translated address */
+	return of_bus_default_translate(addr + 1, offset, na - 1);
+}
 
 #ifdef CONFIG_PCI
 static unsigned int of_bus_pci_get_flags(const __be32 *addr)
@@ -374,8 +400,8 @@ static struct of_bus of_busses[] = {
 		.addresses = "reg",
 		.match = of_bus_default_flags_match,
 		.count_cells = of_bus_default_count_cells,
-		.map = of_bus_default_map,
-		.translate = of_bus_default_translate,
+		.map = of_bus_default_flags_map,
+		.translate = of_bus_default_flags_translate,
 		.has_flags = true,
 		.get_flags = of_bus_default_flags_get_flags,
 	},
Signature · 1 line
2.42.0
author maintainer
#44 lore raw

PATCH 44/491 platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e

In reply to Greg Kroah-Hartman

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

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

From: Olli Asikainen <[email protected]>

[ Upstream commit 916646758aea81a143ce89103910f715ed923346 ]

Thinkpad X120e also needs this battery quirk.

---
 drivers/platform/x86/thinkpad_acpi.c | 1 +
 1 file changed, 1 insertion(+)
drivers/platform/x86/thinkpad_acpi.c +1 -0
index ad460417f901a..4b13d3e704bf3 100644
@@ -9810,6 +9810,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = {
 	 * Individual addressing is broken on models that expose the
 	 * primary battery as BAT1.
 	 */
+	TPACPI_Q_LNV('8', 'F', true),       /* Thinkpad X120e */
 	TPACPI_Q_LNV('J', '7', true),       /* B5400 */
 	TPACPI_Q_LNV('J', 'I', true),       /* Thinkpad 11e */
 	TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */
Signature · 1 line
2.42.0
author maintainer
#45 lore raw

PATCH 45/491 drm/gma500: Fix call trace when psb_gem_mm_init() fails

In reply to Greg Kroah-Hartman

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

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

From: Sui Jingfeng <[email protected]>

[ Upstream commit da596080b2b400c50fe9f8f237bcaf09fed06af8 ]

Because the gma_irq_install() is call after psb_gem_mm_init() function, when psb_gem_mm_init() fails, the interrupt line haven't been allocated. Yet the gma_irq_uninstall() is called in the psb_driver_unload() function without checking if checking the irq is registered or not.

The calltrace is appended as following:

[   20.539253] ioremap memtype_reserve failed -16
[   20.543895] gma500 0000:00:02.0: Failure to map stolen base.
[   20.565049] ------------[ cut here ]------------
[   20.565066] Trying to free already-free IRQ 16
[   20.565087] WARNING: CPU: 1 PID: 381 at kernel/irq/manage.c:1893 free_irq+0x209/0x370
[   20.565316] CPU: 1 PID: 381 Comm: systemd-udevd Tainted: G         C         6.5.0-rc1+ #368
[   20.565329] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./IMB-140D Plus, BIOS P1.10 11/18/2013
[   20.565338] RIP: 0010:free_irq+0x209/0x370
[   20.565357] Code: 41 5d 41 5e 41 5f 5d 31 d2 89 d1 89 d6 89 d7 41 89 d1 c3 cc cc cc cc 8b 75 d0 48 c7 c7 e0 77 12 9f 4c 89 4d c8 e8 57 fe f4 ff <0f> 0b 48 8b 75 c8 4c 89 f7 e8 29 f3 f1 00 49 8b 47 40 48 8b 40 78
[   20.565369] RSP: 0018:ffffae3b40733808 EFLAGS: 00010046
[   20.565382] RAX: 0000000000000000 RBX: ffff9f8082bfe000 RCX: 0000000000000000
[   20.565390] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   20.565397] RBP: ffffae3b40733840 R08: 0000000000000000 R09: 0000000000000000
[   20.565405] R10: 0000000000000000 R11: 0000000000000000 R12: ffff9f80871c3100
[   20.565413] R13: ffff9f80835d3360 R14: ffff9f80835d32a4 R15: ffff9f80835d3200
[   20.565424] FS:  00007f13d36458c0(0000) GS:ffff9f8138880000(0000) knlGS:0000000000000000
[   20.565434] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   20.565441] CR2: 00007f0d046f3f20 CR3: 0000000006c8c000 CR4: 00000000000006e0
[   20.565450] Call Trace:
[   20.565458]  <TASK>
[   20.565470]  ? show_regs+0x72/0x90
[   20.565488]  ? free_irq+0x209/0x370
[   20.565504]  ? __warn+0x8d/0x160
[   20.565520]  ? free_irq+0x209/0x370
[   20.565536]  ? report_bug+0x1bb/0x1d0
[   20.565555]  ? handle_bug+0x46/0x90
[   20.565572]  ? exc_invalid_op+0x19/0x80
[   20.565587]  ? asm_exc_invalid_op+0x1b/0x20
[   20.565607]  ? free_irq+0x209/0x370
[   20.565625]  ? free_irq+0x209/0x370
[   20.565644]  gma_irq_uninstall+0x15b/0x1e0 [gma500_gfx]
[   20.565728]  psb_driver_unload+0x27/0x190 [gma500_gfx]
[   20.565800]  psb_pci_probe+0x5d2/0x790 [gma500_gfx]
[   20.565873]  local_pci_probe+0x48/0xb0
[   20.565892]  pci_device_probe+0xc8/0x280
[   20.565912]  really_probe+0x1d2/0x440
[   20.565929]  __driver_probe_device+0x8a/0x190
[   20.565944]  driver_probe_device+0x23/0xd0
[   20.565957]  __driver_attach+0x10f/0x220
[   20.565971]  ? __pfx___driver_attach+0x10/0x10
[   20.565984]  bus_for_each_dev+0x7a/0xe0
[   20.566002]  driver_attach+0x1e/0x30
[   20.566014]  bus_add_driver+0x127/0x240
[   20.566029]  driver_register+0x64/0x140
[   20.566043]  ? __pfx_psb_init+0x10/0x10 [gma500_gfx]
[   20.566111]  __pci_register_driver+0x68/0x80
[   20.566128]  psb_init+0x2c/0xff0 [gma500_gfx]
[   20.566194]  do_one_initcall+0x46/0x330
[   20.566214]  ? kmalloc_trace+0x2a/0xb0
[   20.566233]  do_init_module+0x6a/0x270
[   20.566250]  load_module+0x207f/0x23a0
[   20.566278]  init_module_from_file+0x9c/0xf0
[   20.566293]  ? init_module_from_file+0x9c/0xf0
[   20.566315]  idempotent_init_module+0x184/0x240
[   20.566335]  __x64_sys_finit_module+0x64/0xd0
[   20.566352]  do_syscall_64+0x59/0x90
[   20.566366]  ? ksys_mmap_pgoff+0x123/0x270
[   20.566378]  ? __secure_computing+0x9b/0x110
[   20.566392]  ? exit_to_user_mode_prepare+0x39/0x190
[   20.566406]  ? syscall_exit_to_user_mode+0x2a/0x50
[   20.566420]  ? do_syscall_64+0x69/0x90
[   20.566433]  ? do_syscall_64+0x69/0x90
[   20.566445]  ? do_syscall_64+0x69/0x90
[   20.566458]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[   20.566472] RIP: 0033:0x7f13d351ea3d
[   20.566485] Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 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 8b 0d c3 a3 0f 00 f7 d8 64 89 01 48
[   20.566496] RSP: 002b:00007ffe566c1fd8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[   20.566510] RAX: ffffffffffffffda RBX: 000055e66806eec0 RCX: 00007f13d351ea3d
[   20.566519] RDX: 0000000000000000 RSI: 00007f13d36d9441 RDI: 0000000000000010
[   20.566527] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000002
[   20.566535] R10: 0000000000000010 R11: 0000000000000246 R12: 00007f13d36d9441
[   20.566543] R13: 000055e6681108c0 R14: 000055e66805ba70 R15: 000055e66819a9c0
[   20.566559]  </TASK>
[   20.566566] ---[ end trace 0000000000000000 ]---
---
 drivers/gpu/drm/gma500/psb_drv.h | 1 +
 drivers/gpu/drm/gma500/psb_irq.c | 5 +++++
 2 files changed, 6 insertions(+)
drivers/gpu/drm/gma500/psb_drv.h +1 -0
index f7f709df99b49..70d9adafa2333 100644
@@ -424,6 +424,7 @@ struct drm_psb_private {
 	uint32_t pipestat[PSB_NUM_PIPE];
 
 	spinlock_t irqmask_lock;
+	bool irq_enabled;
 
 	/* Power */
 	bool pm_initialized;
drivers/gpu/drm/gma500/psb_irq.c +5 -0
index 343c51250207d..7bbb79b0497d8 100644
@@ -327,6 +327,8 @@ int gma_irq_install(struct drm_device *dev)
 
 	gma_irq_postinstall(dev);
 
+	dev_priv->irq_enabled = true;
+
 	return 0;
 }
 
@@ -337,6 +339,9 @@ void gma_irq_uninstall(struct drm_device *dev)
 	unsigned long irqflags;
 	unsigned int i;
 
+	if (!dev_priv->irq_enabled)
+		return;
+
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
 	if (dev_priv->ops->hotplug_enable)
Signature · 1 line
2.42.0
author maintainer
#46 lore raw

PATCH 46/491 drm/amdkfd: ratelimited SQ interrupt messages

In reply to Greg Kroah-Hartman

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

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

From: Harish Kasiviswanathan <[email protected]>

[ Upstream commit 37fb87910724f21a1f27a75743d4f9accdee77fb ]

No functional change. Use ratelimited version of pr_ to avoid overflowing of dmesg buffer

---
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c | 6 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c  | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c +3 -3
index c7991e07b6be5..a7697ec8188e0 100644
@@ -268,7 +268,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev,
 						SQ_INTERRUPT_WORD_WAVE_CTXID1, ENCODING);
 			switch (encoding) {
 			case SQ_INTERRUPT_WORD_ENCODING_AUTO:
-				pr_debug(
+				pr_debug_ratelimited(
 					"sq_intr: auto, se %d, ttrace %d, wlt %d, ttrac_buf0_full %d, ttrac_buf1_full %d, ttrace_utc_err %d\n",
 					REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_AUTO_CTXID1,
 							SE_ID),
@@ -284,7 +284,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev,
 							THREAD_TRACE_UTC_ERROR));
 				break;
 			case SQ_INTERRUPT_WORD_ENCODING_INST:
-				pr_debug("sq_intr: inst, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n",
+				pr_debug_ratelimited("sq_intr: inst, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n",
 					REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_WAVE_CTXID1,
 							SE_ID),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0,
@@ -310,7 +310,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev,
 			case SQ_INTERRUPT_WORD_ENCODING_ERROR:
 				sq_intr_err_type = REG_GET_FIELD(context_id0, KFD_CTXID0,
 								ERR_TYPE);
-				pr_warn("sq_intr: error, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d, err_type %d\n",
+				pr_warn_ratelimited("sq_intr: error, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d, err_type %d\n",
 					REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_WAVE_CTXID1,
 							SE_ID),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0,
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c +3 -3
index f933bd231fb9c..2a65792fd1162 100644
@@ -150,7 +150,7 @@ enum SQ_INTERRUPT_ERROR_TYPE {
 
 static void print_sq_intr_info_auto(uint32_t context_id0, uint32_t context_id1)
 {
-	pr_debug(
+	pr_debug_ratelimited(
 		"sq_intr: auto, ttrace %d, wlt %d, ttrace_buf_full %d, reg_tms %d, cmd_tms %d, host_cmd_ovf %d, host_reg_ovf %d, immed_ovf %d, ttrace_utc_err %d\n",
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID0, THREAD_TRACE),
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID0, WLT),
@@ -165,7 +165,7 @@ static void print_sq_intr_info_auto(uint32_t context_id0, uint32_t context_id1)
 
 static void print_sq_intr_info_inst(uint32_t context_id0, uint32_t context_id1)
 {
-	pr_debug(
+	pr_debug_ratelimited(
 		"sq_intr: inst, data 0x%08x, sh %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n",
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, DATA),
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, SH_ID),
@@ -177,7 +177,7 @@ static void print_sq_intr_info_inst(uint32_t context_id0, uint32_t context_id1)
 
 static void print_sq_intr_info_error(uint32_t context_id0, uint32_t context_id1)
 {
-	pr_warn(
+	pr_warn_ratelimited(
 		"sq_intr: error, detail 0x%08x, type %d, sh %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n",
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_ERROR_CTXID0, DETAIL),
 		REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_ERROR_CTXID0, TYPE),
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +3 -3
index f0731a6a5306c..02695ccd22d6e 100644
@@ -333,7 +333,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev,
 			encoding = REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, ENCODING);
 			switch (encoding) {
 			case SQ_INTERRUPT_WORD_ENCODING_AUTO:
-				pr_debug(
+				pr_debug_ratelimited(
 					"sq_intr: auto, se %d, ttrace %d, wlt %d, ttrac_buf_full %d, reg_tms %d, cmd_tms %d, host_cmd_ovf %d, host_reg_ovf %d, immed_ovf %d, ttrace_utc_err %d\n",
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, SE_ID),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE),
@@ -347,7 +347,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev,
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE_UTC_ERROR));
 				break;
 			case SQ_INTERRUPT_WORD_ENCODING_INST:
-				pr_debug("sq_intr: inst, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, intr_data 0x%x\n",
+				pr_debug_ratelimited("sq_intr: inst, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, intr_data 0x%x\n",
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID),
@@ -366,7 +366,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev,
 				break;
 			case SQ_INTERRUPT_WORD_ENCODING_ERROR:
 				sq_intr_err = REG_GET_FIELD(sq_int_data, KFD_SQ_INT_DATA, ERR_TYPE);
-				pr_warn("sq_intr: error, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, err_type %d\n",
+				pr_warn_ratelimited("sq_intr: error, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, err_type %d\n",
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA),
 					REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID),
Signature · 1 line
2.42.0
author maintainer
#47 lore raw

PATCH 47/491 drm/komeda: drop all currently held locks if deadlock happens

In reply to Greg Kroah-Hartman

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

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

From: baozhu.liu <[email protected]>

[ Upstream commit 19ecbe8325a2a7ffda5ff4790955b84eaccba49f ]

If komeda_pipeline_unbound_components() returns -EDEADLK,
it means that a deadlock happened in the locking context. Currently, komeda is not dealing with the deadlock properly,producing the following output when CONFIG_DEBUG_WW_MUTEX_SLOWPATH is enabled:

 ------------[ cut here ]------------
[   26.103984] WARNING: CPU: 2 PID: 345 at drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c:1248
	       komeda_release_unclaimed_resources+0x13c/0x170
[   26.117453] Modules linked in:
[   26.120511] CPU: 2 PID: 345 Comm: [email protected] Kdump: loaded Tainted: G   W  5.10.110-SE-SDK1.8-dirty #16
[   26.131374] Hardware name: Siengine Se1000 Evaluation board (DT)
[   26.137379] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--)
[   26.143385] pc : komeda_release_unclaimed_resources+0x13c/0x170
[   26.149301] lr : komeda_release_unclaimed_resources+0xbc/0x170
[   26.155130] sp : ffff800017b8b8d0
[   26.158442] pmr_save: 000000e0
[   26.161493] x29: ffff800017b8b8d0 x28: ffff000cf2f96200
[   26.166805] x27: ffff000c8f5a8800 x26: 0000000000000000
[   26.172116] x25: 0000000000000038 x24: ffff8000116a0140
[   26.177428] x23: 0000000000000038 x22: ffff000cf2f96200
[   26.182739] x21: ffff000cfc300300 x20: ffff000c8ab77080
[   26.188051] x19: 0000000000000003 x18: 0000000000000000
[   26.193362] x17: 0000000000000000 x16: 0000000000000000
[   26.198672] x15: b400e638f738ba38 x14: 0000000000000000
[   26.203983] x13: 0000000106400a00 x12: 0000000000000000
[   26.209294] x11: 0000000000000000 x10: 0000000000000000
[   26.214604] x9 : ffff800012f80000 x8 : ffff000ca3308000
[   26.219915] x7 : 0000000ff3000000 x6 : ffff80001084034c
[   26.225226] x5 : ffff800017b8bc40 x4 : 000000000000000f
[   26.230536] x3 : ffff000ca3308000 x2 : 0000000000000000
[   26.235847] x1 : 0000000000000000 x0 : ffffffffffffffdd
[   26.241158] Call trace:
[   26.243604] komeda_release_unclaimed_resources+0x13c/0x170
[   26.249175] komeda_crtc_atomic_check+0x68/0xf0
[   26.253706] drm_atomic_helper_check_planes+0x138/0x1f4
[   26.258929] komeda_kms_check+0x284/0x36c
[   26.262939] drm_atomic_check_only+0x40c/0x714
[   26.267381] drm_atomic_nonblocking_commit+0x1c/0x60
[   26.272344] drm_mode_atomic_ioctl+0xa3c/0xb8c
[   26.276787] drm_ioctl_kernel+0xc4/0x120
[   26.280708] drm_ioctl+0x268/0x534
[   26.284109] __arm64_sys_ioctl+0xa8/0xf0
[   26.288030] el0_svc_common.constprop.0+0x80/0x240
[   26.292817] do_el0_svc+0x24/0x90
[   26.296132] el0_svc+0x20/0x30
[   26.299185] el0_sync_handler+0xe8/0xf0
[   26.303018] el0_sync+0x1a4/0x1c0
[   26.306330] irq event stamp: 0
[   26.309384] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[   26.315650] hardirqs last disabled at (0): [<ffff800010056d34>] copy_process+0x5d0/0x183c
[   26.323825] softirqs last  enabled at (0): [<ffff800010056d34>] copy_process+0x5d0/0x183c
[   26.331997] softirqs last disabled at (0): [<0000000000000000>] 0x0
[   26.338261] ---[ end trace 20ae984fa860184a ]---
[   26.343021] ------------[ cut here ]------------
[   26.347646] WARNING: CPU: 3 PID: 345 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x84/0x90
[   26.357727] Modules linked in:
[   26.360783] CPU: 3 PID: 345 Comm: [email protected] Kdump: loaded Tainted: G   W  5.10.110-SE-SDK1.8-dirty #16
[   26.371645] Hardware name: Siengine Se1000 Evaluation board (DT)
[   26.377647] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--)
[   26.383649] pc : drm_modeset_drop_locks+0x84/0x90
[   26.388351] lr : drm_mode_atomic_ioctl+0x860/0xb8c
[   26.393137] sp : ffff800017b8bb10
[   26.396447] pmr_save: 000000e0
[   26.399497] x29: ffff800017b8bb10 x28: 0000000000000001
[   26.404807] x27: 0000000000000038 x26: 0000000000000002
[   26.410115] x25: ffff000cecbefa00 x24: ffff000cf2f96200
[   26.415423] x23: 0000000000000001 x22: 0000000000000018
[   26.420731] x21: 0000000000000001 x20: ffff800017b8bc10
[   26.426039] x19: 0000000000000000 x18: 0000000000000000
[   26.431347] x17: 0000000002e8bf2c x16: 0000000002e94c6b
[   26.436655] x15: 0000000002ea48b9 x14: ffff8000121f0300
[   26.441963] x13: 0000000002ee2ca8 x12: ffff80001129cae0
[   26.447272] x11: ffff800012435000 x10: ffff000ed46b5e88
[   26.452580] x9 : ffff000c9935e600 x8 : 0000000000000000
[   26.457888] x7 : 000000008020001e x6 : 000000008020001f
[   26.463196] x5 : ffff80001085fbe0 x4 : fffffe0033a59f20
[   26.468504] x3 : 000000008020001e x2 : 0000000000000000
[   26.473813] x1 : 0000000000000000 x0 : ffff000c8f596090
[   26.479122] Call trace:
[   26.481566] drm_modeset_drop_locks+0x84/0x90
[   26.485918] drm_mode_atomic_ioctl+0x860/0xb8c
[   26.490359] drm_ioctl_kernel+0xc4/0x120
[   26.494278] drm_ioctl+0x268/0x534
[   26.497677] __arm64_sys_ioctl+0xa8/0xf0
[   26.501598] el0_svc_common.constprop.0+0x80/0x240
[   26.506384] do_el0_svc+0x24/0x90
[   26.509697] el0_svc+0x20/0x30
[   26.512748] el0_sync_handler+0xe8/0xf0
[   26.516580] el0_sync+0x1a4/0x1c0
[   26.519891] irq event stamp: 0
[   26.522943] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[   26.529207] hardirqs last disabled at (0): [<ffff800010056d34>] copy_process+0x5d0/0x183c
[   26.537379] softirqs last  enabled at (0): [<ffff800010056d34>] copy_process+0x5d0/0x183c
[   26.545550] softirqs last disabled at (0): [<0000000000000000>] 0x0
[   26.551812] ---[ end trace 20ae984fa860184b ]---

According to the call trace information,it can be located to be WARN_ON(IS_ERR(c_st)) in the komeda_pipeline_unbound_components function; Then follow the function.
komeda_pipeline_unbound_components
-> komeda_component_get_state_and_set_user
-> komeda_pipeline_get_state_and_set_crtc

    -> komeda_pipeline_get_state
      ->drm_atomic_get_private_obj_state
        -> drm_atomic_get_private_obj_state
          -> drm_modeset_lock

komeda_pipeline_unbound_components
-> komeda_component_get_state_and_set_user
-> komeda_component_get_state

    -> drm_atomic_get_private_obj_state
     -> drm_modeset_lock

ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); if (ret)

	return ERR_PTR(ret);

Here it return -EDEADLK.

deal with the deadlock as suggested by [1], using the function drm_modeset_backoff().
[1] https://docs.kernel.org/gpu/drm-kms.html?highlight=kms#kms-locking

Therefore, handling this problem can be solved
by adding return -EDEADLK back to the drm_modeset_backoff processing flow in the drm_mode_atomic_ioctl function.

---
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c   | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +6 -3
index 3276a3e82c628..916f2c36bf2f7 100644
@@ -1223,7 +1223,7 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 	return 0;
 }
 
-static void
+static int
 komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
 				   struct komeda_pipeline_state *new)
 {
@@ -1243,8 +1243,12 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
 		c = komeda_pipeline_get_component(pipe, id);
 		c_st = komeda_component_get_state_and_set_user(c,
 				drm_st, NULL, new->crtc);
+		if (PTR_ERR(c_st) == -EDEADLK)
+			return -EDEADLK;
 		WARN_ON(IS_ERR(c_st));
 	}
+
+	return 0;
 }
 
 /* release unclaimed pipeline resource */
@@ -1266,9 +1270,8 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 	if (WARN_ON(IS_ERR_OR_NULL(st)))
 		return -EINVAL;
 
-	komeda_pipeline_unbound_components(pipe, st);
+	return komeda_pipeline_unbound_components(pipe, st);
 
-	return 0;
 }
 
 /* Since standalone disabled components must be disabled separately and in the
Signature · 1 line
2.42.0
author maintainer
#48 lore raw

PATCH 48/491 drm/amd/display: Blank phantom OTG before enabling

In reply to Greg Kroah-Hartman

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

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

From: Alvin Lee <[email protected]>

[ Upstream commit e87a6c5b7780b5f423797351eb586ed96cc6d151 ]

[Description]
Before enabling the phantom OTG for an update we must enable DPG to avoid underflow.

---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 50 +------------------
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 10 +++-
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    | 46 +++++++++++++++++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.h    |  5 ++
 .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  5 ++
 6 files changed, 68 insertions(+), 49 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -48
index 609048160aa20..ab79bcd264164 100644
@@ -1070,53 +1070,6 @@ static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *contex
 	}
 }
 
-static void phantom_pipe_blank(
-		struct dc *dc,
-		struct timing_generator *tg,
-		int width,
-		int height)
-{
-	struct dce_hwseq *hws = dc->hwseq;
-	enum dc_color_space color_space;
-	struct tg_color black_color = {0};
-	struct output_pixel_processor *opp = NULL;
-	uint32_t num_opps, opp_id_src0, opp_id_src1;
-	uint32_t otg_active_width, otg_active_height;
-	uint32_t i;
-
-	/* program opp dpg blank color */
-	color_space = COLOR_SPACE_SRGB;
-	color_space_to_black_color(dc, color_space, &black_color);
-
-	otg_active_width = width;
-	otg_active_height = height;
-
-	/* get the OPTC source */
-	tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-	ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
-
-	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-		if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
-			opp = dc->res_pool->opps[i];
-			break;
-		}
-	}
-
-	if (opp && opp->funcs->opp_set_disp_pattern_generator)
-		opp->funcs->opp_set_disp_pattern_generator(
-				opp,
-				CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-				CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-				COLOR_DEPTH_UNDEFINED,
-				&black_color,
-				otg_active_width,
-				otg_active_height,
-				0);
-
-	if (tg->funcs->is_tg_enabled(tg))
-		hws->funcs.wait_for_blank_complete(opp);
-}
-
 static void dc_update_viusal_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
 {
 	if (dc->ctx->dce_version >= DCN_VERSION_1_0) {
@@ -1207,7 +1160,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
 
 					main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width;
 					main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height;
-					phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height);
+					if (dc->hwss.blank_phantom)
+						dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
 					tg->funcs->enable_crtc(tg);
 				}
 			}
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +9 -1
index 62a077adcdbfa..84fe449a2c7ed 100644
@@ -1846,8 +1846,16 @@ void dcn20_program_front_end_for_ctx(
 			dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
 			struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
 
-			if (tg->funcs->enable_crtc)
+			if (tg->funcs->enable_crtc) {
+				if (dc->hwss.blank_phantom) {
+					int main_pipe_width, main_pipe_height;
+
+					main_pipe_width = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.width;
+					main_pipe_height = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.height;
+					dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
+				}
 				tg->funcs->enable_crtc(tg);
+			}
 		}
 	}
 	/* OTG blank before disabling all front ends */
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +46 -0

49 lines not on this page · raw message

drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +5 -0
index 2d2628f31bed7..616d5219119e9 100644
@@ -115,4 +115,9 @@ void dcn32_init_blank(
 		struct dc *dc,
 		struct timing_generator *tg);
 
+void dcn32_blank_phantom(struct dc *dc,
+		struct timing_generator *tg,
+		int width,
+		int height);
+
 #endif /* __DC_HWSS_DCN32_H__ */
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +1 -0
index 777b2fac20c4e..279f312f74076 100644
@@ -115,6 +115,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
 	.update_phantom_vp_position = dcn32_update_phantom_vp_position,
 	.update_dsc_pg = dcn32_update_dsc_pg,
 	.apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom,
+	.blank_phantom = dcn32_blank_phantom,
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +5 -0
index 02ff99f7bec2b..7a702e216e530 100644
@@ -388,6 +388,11 @@ struct hw_sequencer_funcs {
 	void (*z10_restore)(const struct dc *dc);
 	void (*z10_save_init)(struct dc *dc);
 
+	void (*blank_phantom)(struct dc *dc,
+			struct timing_generator *tg,
+			int width,
+			int height);
+
 	void (*update_visual_confirm_color)(struct dc *dc,
 			struct pipe_ctx *pipe_ctx,
 			int mpcc_id);
Signature · 1 line
2.42.0
author maintainer
#49 lore raw

PATCH 49/491 drm/amd/display: Dont lock phantom pipe on disabling

In reply to Greg Kroah-Hartman

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

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

From: Alvin Lee <[email protected]>

[ Upstream commit cbb4c9bc55427774ca4d819933e1b5fa38a6fb44 ]

[Description]
- When disabling a phantom pipe, we first enable the phantom OTG so the double buffer update can successfully take place
- However, want to avoid locking the phantom otherwise setting DPG_EN=1 for the phantom pipe is blocked (without this we could hit underflow due to phantom HUBP being blanked by default)

---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +2 -1
index 9834b75f1837b..79befa17bb037 100644
@@ -111,7 +111,8 @@ void dcn10_lock_all_pipes(struct dc *dc,
 		if (pipe_ctx->top_pipe ||
 		    !pipe_ctx->stream ||
 		    (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) ||
-		    !tg->funcs->is_tg_enabled(tg))
+		    !tg->funcs->is_tg_enabled(tg) ||
+			pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM)
 			continue;
 
 		if (lock)
Signature · 1 line
2.42.0
author maintainer
#50 lore raw

PATCH 50/491 drm/amd/display: add seamless pipe topology transition check

In reply to Greg Kroah-Hartman

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

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

From: Wenjing Liu <[email protected]>

[ Upstream commit 15c6798ae26d5c7a7776f4f7d0c1fa8c462688a2 ]

[why]
We have a few cases where we need to perform update topology update in dc update interface. However some of the updates are not seamless This could cause user noticible glitches. To enforce seamless transition we are adding a checking condition and error logging so the corruption as result of non seamless transition can be easily spotted.

---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  8 +++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    | 52 +++++++++++++++++++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.h    |  4 ++
 .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  3 ++
 5 files changed, 68 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc.c +8 -0
index ab79bcd264164..93e6265e58509 100644
@@ -4414,6 +4414,14 @@ bool dc_update_planes_and_stream(struct dc *dc,
 				update_type,
 				context);
 	} else {
+		if (!stream_update &&
+				dc->hwss.is_pipe_topology_transition_seamless &&
+				!dc->hwss.is_pipe_topology_transition_seamless(
+						dc, dc->current_state, context)) {
+
+			DC_LOG_ERROR("performing non-seamless pipe topology transition with surface only update!\n");
+			BREAK_TO_DEBUGGER();
+		}
 		commit_planes_for_stream(
 				dc,
 				srf_updates,
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +52 -0

55 lines not on this page · raw message

drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +4 -0
index 616d5219119e9..9992e40acd217 100644
@@ -120,4 +120,8 @@ void dcn32_blank_phantom(struct dc *dc,
 		int width,
 		int height);
 
+bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
+		const struct dc_state *cur_ctx,
+		const struct dc_state *new_ctx);
+
 #endif /* __DC_HWSS_DCN32_H__ */
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +1 -0
index 279f312f74076..12e0f48a13e48 100644
@@ -116,6 +116,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
 	.update_dsc_pg = dcn32_update_dsc_pg,
 	.apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom,
 	.blank_phantom = dcn32_blank_phantom,
+	.is_pipe_topology_transition_seamless = dcn32_is_pipe_topology_transition_seamless,
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +3 -0
index 7a702e216e530..66e680902c95c 100644
@@ -401,6 +401,9 @@ struct hw_sequencer_funcs {
 			struct dc_state *context,
 			struct pipe_ctx *phantom_pipe);
 	void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe);
+	bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
+			const struct dc_state *cur_ctx,
+			const struct dc_state *new_ctx);
 
 	void (*commit_subvp_config)(struct dc *dc, struct dc_state *context);
 	void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context);
Signature · 1 line
2.42.0
author maintainer
#51 lore raw

PATCH 51/491 drm/edid: Fixup h/vsync_end instead of h/vtotal

In reply to Greg Kroah-Hartman

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

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

From: Ville Syrjälä <[email protected]>

[ Upstream commit 2682768bde745b10ae126a322cdcaf532cf88851 ]

There are some weird EDIDs floating around that have the sync pulse extending beyond the end of the blanking period.

On the currently problemtic machine (HP Omni 120) EDID reports the following mode:
"1600x900": 60 108000 1600 1780 1860 1800 900 910 913 1000 0x40 0x5 which is then "corrected" to have htotal=1861 by the current drm_edid.c code.

The fixup code was originally added in commit 7064fef56369 ("drm: work around EDIDs with bad htotal/vtotal values"). Googling around we end up in
https://bugs.launchpad.net/ubuntu/hardy/+source/xserver-xorg-video-intel/+bug/297245
where we find an EDID for a Dell Studio 15, which reports:
(II) VESA(0): clock: 65.0 MHz Image Size: 331 x 207 mm
(II) VESA(0): h_active: 1280 h_sync: 1328 h_sync_end 1360 h_blank_end 1337 h_border: 0 (II) VESA(0): v_active: 800 v_sync: 803 v_sync_end 809 v_blanking: 810 v_border: 0

Note that if we use the hblank size (as opposed of the hsync_end) from the DTD to determine htotal we get exactly 60Hz refresh rate in both cases, whereas using hsync_end to determine htotal we get a slightly lower refresh rates. This makes me believe the using the hblank size is what was intended even in those cases.

Also note that in case of the HP Onmi 120 the VBIOS boots with these:
crtc timings: 108000 1600 1780 1860 1800 900 910 913 1000, type: 0x40 flags: 0x5
ie. it just blindly stuffs the bogus hsync_end and htotal from the DTD into the transcoder timing registers, and the display works. I believe the (at least more modern) hardware will automagically terminate the hsync pulse when the timing generator reaches htotal, which again points that we should use the hblank size to determine htotal. Unfortunatley the old bug reports for the Dell machines are extremely lacking in useful details so we have no idea what kind of timings the VBIOS programmed into the hardware :(

Let's just flip this quirk around and reduce the length of the sync pulse instead of extending the blanking period. This at least seems to be the correct thing to do on more modern hardware. And if any issues crop up on older hardware we need to debug them properly.

v2: Add debug message breadcrumbs (Jani)

---
 drivers/gpu/drm/drm_edid.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/gpu/drm/drm_edid.c +13 -5
index 69d855123d3e3..f1ceb7d08519e 100644
@@ -3499,11 +3499,19 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
 	mode->vsync_end = mode->vsync_start + vsync_pulse_width;
 	mode->vtotal = mode->vdisplay + vblank;
 
-	/* Some EDIDs have bogus h/vtotal values */
-	if (mode->hsync_end > mode->htotal)
-		mode->htotal = mode->hsync_end + 1;
-	if (mode->vsync_end > mode->vtotal)
-		mode->vtotal = mode->vsync_end + 1;
+	/* Some EDIDs have bogus h/vsync_end values */
+	if (mode->hsync_end > mode->htotal) {
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] reducing hsync_end %d->%d\n",
+			    connector->base.id, connector->name,
+			    mode->hsync_end, mode->htotal);
+		mode->hsync_end = mode->htotal;
+	}
+	if (mode->vsync_end > mode->vtotal) {
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] reducing vsync_end %d->%d\n",
+			    connector->base.id, connector->name,
+			    mode->vsync_end, mode->vtotal);
+		mode->vsync_end = mode->vtotal;
+	}
 
 	drm_mode_do_interlace_quirk(mode, pt);
 
Signature · 1 line
2.42.0
author maintainer
#52 lore raw

PATCH 52/491 md: dont rely on mddev->pers to be set in mddev_suspend()

In reply to Greg Kroah-Hartman

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

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

From: Yu Kuai <[email protected]>

[ Upstream commit b721e7885eb242aa2459ee66bb42ceef1bcf0f0c ]

'active_io' used to be initialized while the array is running, and 'mddev->pers' is set while the array is running as well. Hence caller must hold 'reconfig_mutex' and guarantee 'mddev->pers' is set before calling mddev_suspend().

Now that 'active_io' is initialized when mddev is allocated, such restriction doesn't exist anymore. In the meantime, follow up patches will refactor mddev_suspend(), hence add checking for 'mddev->pers' to prevent null-ptr-deref.

---
 drivers/md/md.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/md.c +1 -1
index 78d51dddf3a00..34b7196d9634c 100644
@@ -449,7 +449,7 @@ void mddev_suspend(struct mddev *mddev)
 	set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags);
 	percpu_ref_kill(&mddev->active_io);
 
-	if (mddev->pers->prepare_suspend)
+	if (mddev->pers && mddev->pers->prepare_suspend)
 		mddev->pers->prepare_suspend(mddev);
 
 	wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io));
Signature · 1 line
2.42.0
author maintainer
#53 lore raw

PATCH 53/491 drm/amdgpu: not to save bo in the case of RAS err_event_athub

In reply to Greg Kroah-Hartman

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

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

From: David (Ming Qiang) Wu <[email protected]>

[ Upstream commit fa1f1cc09d588a90c8ce3f507c47df257461d148 ]

err_event_athub will corrupt VCPU buffer and not good to be restored in amdgpu_vcn_resume() and in this case the VCPU buffer needs to be cleared for VCN firmware to work properly.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +7 -0
index ae455aab5d29d..7e54abca45206 100644
@@ -292,8 +292,15 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
 	void *ptr;
 	int i, idx;
 
+	bool in_ras_intr = amdgpu_ras_intr_triggered();
+
 	cancel_delayed_work_sync(&adev->vcn.idle_work);
 
+	/* err_event_athub will corrupt VCPU buffer, so we need to
+	 * restore fw data and clear buffer in amdgpu_vcn_resume() */
+	if (in_ras_intr)
+		return 0;
+
 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 		if (adev->vcn.harvest_config & (1 << i))
 			continue;
Signature · 1 line
2.42.0
author maintainer
#54 lore raw

PATCH 54/491 drm/amdkfd: Fix a race condition of vram buffer unref in svm code

In reply to Greg Kroah-Hartman

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

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

From: Xiaogang Chen <[email protected]>

[ Upstream commit 709c348261618da7ed89d6c303e2ceb9e453ba74 ]

prange->svm_bo unref can happen in both mmu callback and a callback after migrate to system ram. Both are async call in different tasks. Sync svm_bo unref operation to avoid random "use-after-free".

---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +9 -2
index 50f943e04f8a4..e1d73a7223675 100644
@@ -617,8 +617,15 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
 
 void svm_range_vram_node_free(struct svm_range *prange)
 {
-	svm_range_bo_unref(prange->svm_bo);
-	prange->ttm_res = NULL;
+	/* serialize prange->svm_bo unref */
+	mutex_lock(&prange->lock);
+	/* prange->svm_bo has not been unref */
+	if (prange->ttm_res) {
+		prange->ttm_res = NULL;
+		mutex_unlock(&prange->lock);
+		svm_range_bo_unref(prange->svm_bo);
+	} else
+		mutex_unlock(&prange->lock);
 }
 
 struct kfd_node *
Signature · 1 line
2.42.0
author maintainer
#55 lore raw

PATCH 55/491 drm/amd: Update `update_pcie_parameters` functions to use uint8_t arguments

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello <[email protected]>

[ Upstream commit 7752ccf85b929a22e658ec145283e8f31232f4bb ]

The matching values for pcie_gen_cap and pcie_width_cap when fetched from powerplay tables are 1 byte, so narrow the arguments to match to ensure min() and max() comparisons without casts.

---
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c               | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h           | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h            | 4 ++--
 drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c         | 4 ++--
 drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 8 ++++----
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c          | 4 ++--
 6 files changed, 12 insertions(+), 12 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +1 -1
index 222af2fae7458..16c03771c1239 100644
@@ -1232,7 +1232,7 @@ static int smu_smc_hw_setup(struct smu_context *smu)
 {
 	struct smu_feature *feature = &smu->smu_feature;
 	struct amdgpu_device *adev = smu->adev;
-	uint32_t pcie_gen = 0, pcie_width = 0;
+	uint8_t pcie_gen = 0, pcie_width = 0;
 	uint64_t features_supported;
 	int ret = 0;
 
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +1 -1
index 6e2069dcb6b9d..d1d7713b97794 100644
@@ -856,7 +856,7 @@ struct pptable_funcs {
 	 * &pcie_gen_cap: Maximum allowed PCIe generation.
 	 * &pcie_width_cap: Maximum allowed PCIe width.
 	 */
-	int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
+	int (*update_pcie_parameters)(struct smu_context *smu, uint8_t pcie_gen_cap, uint8_t pcie_width_cap);
 
 	/**
 	 * @i2c_init: Initialize i2c.
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +2 -2
index 355c156d871af..cc02f979e9e98 100644
@@ -296,8 +296,8 @@ int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu,
 					uint32_t pptable_id);
 
 int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
-				     uint32_t pcie_gen_cap,
-				     uint32_t pcie_width_cap);
+				     uint8_t pcie_gen_cap,
+				     uint8_t pcie_width_cap);
 
 #endif
 #endif
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +2 -2
index 95f6d821bacbc..addaa69119b8e 100644
@@ -2375,8 +2375,8 @@ static int navi10_get_power_limit(struct smu_context *smu,
 }
 
 static int navi10_update_pcie_parameters(struct smu_context *smu,
-				     uint32_t pcie_gen_cap,
-				     uint32_t pcie_width_cap)
+					 uint8_t pcie_gen_cap,
+					 uint8_t pcie_width_cap)
 {
 	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 	PPTable_t *pptable = smu->smu_table.driver_pptable;
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +4 -4
index 9119b0df2419f..9a5f3d31e7780 100644
@@ -2084,14 +2084,14 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
 #define MAX(a, b)	((a) > (b) ? (a) : (b))
 
 static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
-					 uint32_t pcie_gen_cap,
-					 uint32_t pcie_width_cap)
+						 uint8_t pcie_gen_cap,
+						 uint8_t pcie_width_cap)
 {
 	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 	struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table;
 	uint8_t *table_member1, *table_member2;
-	uint32_t min_gen_speed, max_gen_speed;
-	uint32_t min_lane_width, max_lane_width;
+	uint8_t min_gen_speed, max_gen_speed;
+	uint8_t min_lane_width, max_lane_width;
 	uint32_t smu_pcie_arg;
 	int ret, i;
 
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +2 -2
index 9b62b45ebb7f0..4fa94f583b87c 100644
@@ -2426,8 +2426,8 @@ int smu_v13_0_mode1_reset(struct smu_context *smu)
 }
 
 int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
-				     uint32_t pcie_gen_cap,
-				     uint32_t pcie_width_cap)
+				     uint8_t pcie_gen_cap,
+				     uint8_t pcie_width_cap)
 {
 	struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 	struct smu_13_0_pcie_table *pcie_table =
Signature · 1 line
2.42.0
author maintainer
#56 lore raw

PATCH 56/491 drm/amd/display: use full update for clip size increase of large plane source

In reply to Greg Kroah-Hartman

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

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

From: Wenjing Liu <[email protected]>

[ Upstream commit 05b78277ef0efc1deebc8a22384fffec29a3676e ]

[why]
Clip size increase will increase viewport, which could cause us to switch to MPC combine.
If we skip full update, we are not able to change to MPC combine in fast update. This will cause corruption showing on the video plane.

[how]
treat clip size increase of a surface larger than 5k as a full update.

---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 12 ++++++++++--
 drivers/gpu/drm/amd/display/dc/dc.h      |  5 +++++
 2 files changed, 15 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +10 -2
index 93e6265e58509..b386f3b0fd428 100644
@@ -993,7 +993,8 @@ static bool dc_construct(struct dc *dc,
 	/* set i2c speed if not done by the respective dcnxxx__resource.c */
 	if (dc->caps.i2c_speed_in_khz_hdcp == 0)
 		dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz;
-
+	if (dc->caps.max_optimizable_video_width == 0)
+		dc->caps.max_optimizable_video_width = 5120;
 	dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
 	if (!dc->clk_mgr)
 		goto fail;
@@ -2430,6 +2431,7 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
 }
 
 static enum surface_update_type get_scaling_info_update_type(
+		const struct dc *dc,
 		const struct dc_surface_update *u)
 {
 	union surface_update_flags *update_flags = &u->surface->update_flags;
@@ -2464,6 +2466,12 @@ static enum surface_update_type get_scaling_info_update_type(
 			update_flags->bits.clock_change = 1;
 	}
 
+	if (u->scaling_info->src_rect.width > dc->caps.max_optimizable_video_width &&
+		(u->scaling_info->clip_rect.width > u->surface->clip_rect.width ||
+		 u->scaling_info->clip_rect.height > u->surface->clip_rect.height))
+		 /* Changing clip size of a large surface may result in MPC slice count change */
+		update_flags->bits.bandwidth_change = 1;
+
 	if (u->scaling_info->src_rect.x != u->surface->src_rect.x
 			|| u->scaling_info->src_rect.y != u->surface->src_rect.y
 			|| u->scaling_info->clip_rect.x != u->surface->clip_rect.x
@@ -2501,7 +2509,7 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
 	type = get_plane_info_update_type(u);
 	elevate_update_type(&overall_type, type);
 
-	type = get_scaling_info_update_type(u);
+	type = get_scaling_info_update_type(dc, u);
 	elevate_update_type(&overall_type, type);
 
 	if (u->flip_addr) {
drivers/gpu/drm/amd/display/dc/dc.h +5 -0
index 81258392d44a1..dc0e0af616506 100644
@@ -229,6 +229,11 @@ struct dc_caps {
 	uint32_t dmdata_alloc_size;
 	unsigned int max_cursor_size;
 	unsigned int max_video_width;
+	/*
+	 * max video plane width that can be safely assumed to be always
+	 * supported by single DPP pipe.
+	 */
+	unsigned int max_optimizable_video_width;
 	unsigned int min_horizontal_blanking_period;
 	int linear_pitch_alignment;
 	bool dcc_const_color;
Signature · 1 line
2.42.0
author maintainer
#57 lore raw

PATCH 57/491 string.h: add array-wrappers for (v)memdup_user()

In reply to Greg Kroah-Hartman

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

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

From: Philipp Stanner <[email protected]>

[ Upstream commit 313ebe47d75558511aa1237b6e35c663b5c0ec6f ]

Currently, user array duplications are sometimes done without an overflow check. Sometimes the checks are done manually; sometimes the array size is calculated with array_size() and sometimes by calculating n * size directly in code.

Introduce wrappers for arrays for memdup_user() and vmemdup_user() to provide a standardized and safe way for duplicating user arrays.

This is both for new code as well as replacing usage of (v)memdup_user() in existing code that uses, e.g., n * size to calculate array sizes.

---
 include/linux/string.h | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
include/linux/string.h +40 -0
index 9e3cb6923b0ef..5077776e995e0 100644
@@ -5,7 +5,9 @@
 #include <linux/compiler.h>	/* for inline */
 #include <linux/types.h>	/* for size_t */
 #include <linux/stddef.h>	/* for NULL */
+#include <linux/err.h>		/* for ERR_PTR() */
 #include <linux/errno.h>	/* for E2BIG */
+#include <linux/overflow.h>	/* for check_mul_overflow() */
 #include <linux/stdarg.h>
 #include <uapi/linux/string.h>
 
@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t);
 extern void *vmemdup_user(const void __user *, size_t);
 extern void *memdup_user_nul(const void __user *, size_t);
 
+/**
+ * memdup_array_user - duplicate array from user space
+ * @src: source address in user space
+ * @n: number of array members to copy
+ * @size: size of one array member
+ *
+ * Return: an ERR_PTR() on failure. Result is physically
+ * contiguous, to be freed by kfree().
+ */
+static inline void *memdup_array_user(const void __user *src, size_t n, size_t size)
+{
+	size_t nbytes;
+
+	if (check_mul_overflow(n, size, &nbytes))
+		return ERR_PTR(-EOVERFLOW);
+
+	return memdup_user(src, nbytes);
+}
+
+/**
+ * vmemdup_array_user - duplicate array from user space
+ * @src: source address in user space
+ * @n: number of array members to copy
+ * @size: size of one array member
+ *
+ * Return: an ERR_PTR() on failure. Result may be not
+ * physically contiguous. Use kvfree() to free.
+ */
+static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size)
+{
+	size_t nbytes;
+
+	if (check_mul_overflow(n, size, &nbytes))
+		return ERR_PTR(-EOVERFLOW);
+
+	return vmemdup_user(src, nbytes);
+}
+
 /*
  * Include machine specific inline routines
  */
Signature · 1 line
2.42.0
author maintainer
#58 lore raw

PATCH 58/491 kernel: kexec: copy user-array safely

In reply to Greg Kroah-Hartman

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

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

From: Philipp Stanner <[email protected]>

[ Upstream commit 569c8d82f95eb5993c84fb61a649a9c4ddd208b3 ]

Currently, there is no overflow-check with memdup_user().

Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely.

---
 kernel/kexec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/kexec.c +1 -1
index 92d301f987766..f6067c1bb0893 100644
@@ -242,7 +242,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 		((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
 		return -EINVAL;
 
-	ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0]));
+	ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0]));
 	if (IS_ERR(ksegments))
 		return PTR_ERR(ksegments);
 
Signature · 1 line
2.42.0
author maintainer
#59 lore raw

PATCH 59/491 kernel: watch_queue: copy user-array safely

In reply to Greg Kroah-Hartman

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

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

From: Philipp Stanner <[email protected]>

[ Upstream commit ca0776571d3163bd03b3e8c9e3da936abfaecbf6 ]

Currently, there is no overflow-check with memdup_user().

Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely.

---
 kernel/watch_queue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/watch_queue.c +1 -1
index d0b6b390ee423..778b4056700ff 100644
@@ -331,7 +331,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe,
 	    filter.__reserved != 0)
 		return -EINVAL;
 
-	tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf));
+	tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf));
 	if (IS_ERR(tf))
 		return PTR_ERR(tf);
 
Signature · 1 line
2.42.0
author maintainer
#60 lore raw

PATCH 60/491 drm_lease.c: copy user-array safely

In reply to Greg Kroah-Hartman

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

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

From: Philipp Stanner <[email protected]>

[ Upstream commit f37d63e219c39199a59b8b8a211412ff27192830 ]

Currently, there is no overflow-check with memdup_user().

Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely.

---
 drivers/gpu/drm/drm_lease.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_lease.c +2 -2
index 150fe15550680..94375c6a54256 100644
@@ -510,8 +510,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	/* Handle leased objects, if any */
 	idr_init(&leases);
 	if (object_count != 0) {
-		object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
-					 array_size(object_count, sizeof(__u32)));
+		object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids),
+					       object_count, sizeof(__u32));
 		if (IS_ERR(object_ids)) {
 			ret = PTR_ERR(object_ids);
 			idr_destroy(&leases);
Signature · 1 line
2.42.0
author maintainer
#61 lore raw

PATCH 61/491 drm: vmwgfx_surface.c: copy user-array safely

In reply to Greg Kroah-Hartman

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

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

From: Philipp Stanner <[email protected]>

[ Upstream commit 06ab64a0d836ac430c5f94669710a78aa43942cb ]

Currently, there is no overflow-check with memdup_user().

Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +2 -2
index 3829be282ff00..17463aeeef28f 100644
@@ -774,9 +774,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	       sizeof(metadata->mip_levels));
 	metadata->num_sizes = num_sizes;
 	metadata->sizes =
-		memdup_user((struct drm_vmw_size __user *)(unsigned long)
+		memdup_array_user((struct drm_vmw_size __user *)(unsigned long)
 			    req->size_addr,
-			    sizeof(*metadata->sizes) * metadata->num_sizes);
+			    metadata->num_sizes, sizeof(*metadata->sizes));
 	if (IS_ERR(metadata->sizes)) {
 		ret = PTR_ERR(metadata->sizes);
 		goto out_no_sizes;
Signature · 1 line
2.42.0
author maintainer
#62 lore raw

PATCH 62/491 drm/msm/dp: skip validity check for DP CTS EDID checksum

In reply to Greg Kroah-Hartman

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

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

From: Jani Nikula <[email protected]>

[ Upstream commit a251c9d8e30833b260101edb9383b176ee2b7cb1 ]

The DP CTS test for EDID last block checksum expects the checksum for the last block, invalid or not. Skip the validity check.

For the most part (*), the EDIDs returned by drm_get_edid() will be valid anyway, and there's the CTS workaround to get the checksum for completely invalid EDIDs. See commit 7948fe12d47a ("drm/msm/dp: return correct edid checksum after corrupted edid checksum read").

This lets us remove one user of drm_edid_block_valid() with hopes the function can be removed altogether in the future.

(*) drm_get_edid() ignores checksum errors on CTA extensions.

Patchwork: https://patchwork.freedesktop.org/patch/555361/

---
 drivers/gpu/drm/msm/dp/dp_panel.c | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)
drivers/gpu/drm/msm/dp/dp_panel.c +2 -19
index 42d52510ffd4a..86a8e06c7a60f 100644
@@ -289,26 +289,9 @@ int dp_panel_get_modes(struct dp_panel *dp_panel,
 
 static u8 dp_panel_get_edid_checksum(struct edid *edid)
 {
-	struct edid *last_block;
-	u8 *raw_edid;
-	bool is_edid_corrupt = false;
+	edid += edid->extensions;
 
-	if (!edid) {
-		DRM_ERROR("invalid edid input\n");
-		return 0;
-	}
-
-	raw_edid = (u8 *)edid;
-	raw_edid += (edid->extensions * EDID_LENGTH);
-	last_block = (struct edid *)raw_edid;
-
-	/* block type extension */
-	drm_edid_block_valid(raw_edid, 1, false, &is_edid_corrupt);
-	if (!is_edid_corrupt)
-		return last_block->checksum;
-
-	DRM_ERROR("Invalid block, no checksum\n");
-	return 0;
+	return edid->checksum;
 }
 
 void dp_panel_handle_sink_request(struct dp_panel *dp_panel)
Signature · 1 line
2.42.0
author maintainer
#63 lore raw

PATCH 63/491 drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello <[email protected]>

[ Upstream commit 760efbca74a405dc439a013a5efaa9fadc95a8c3 ]

For pptable structs that use flexible array sizes, use flexible arrays.

---
 drivers/gpu/drm/amd/include/pptable.h                 | 4 ++--
 drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/include/pptable.h +2 -2
index 0b6a057e0a4c4..5aac8d545bdc6 100644
@@ -78,7 +78,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER
 typedef struct _ATOM_PPLIB_STATE
 {
     UCHAR ucNonClockStateIndex;
-    UCHAR ucClockStateIndices[1]; // variable-sized
+    UCHAR ucClockStateIndices[]; // variable-sized
 } ATOM_PPLIB_STATE;
 
 
@@ -473,7 +473,7 @@ typedef struct _ATOM_PPLIB_STATE_V2
       /**
       * Driver will read the first ucNumDPMLevels in this array
       */
-      UCHAR clockInfoIndex[1];
+      UCHAR clockInfoIndex[];
 } ATOM_PPLIB_STATE_V2;
 
 typedef struct _StateArray{
drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +2 -2
index b0ac4d121adca..41444e27bfc0c 100644
@@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record {
 typedef struct _ATOM_Tonga_MCLK_Dependency_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries; 										/* Number of entries. */
-	ATOM_Tonga_MCLK_Dependency_Record entries[1];				/* Dynamically allocate entries. */
+	ATOM_Tonga_MCLK_Dependency_Record entries[];				/* Dynamically allocate entries. */
 } ATOM_Tonga_MCLK_Dependency_Table;
 
 typedef struct _ATOM_Tonga_SCLK_Dependency_Record {
@@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record {
 typedef struct _ATOM_Tonga_SCLK_Dependency_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries; 										/* Number of entries. */
-	ATOM_Tonga_SCLK_Dependency_Record entries[1];				 /* Dynamically allocate entries. */
+	ATOM_Tonga_SCLK_Dependency_Record entries[];				 /* Dynamically allocate entries. */
 } ATOM_Tonga_SCLK_Dependency_Table;
 
 typedef struct _ATOM_Polaris_SCLK_Dependency_Record {
Signature · 1 line
2.42.0
author maintainer
#64 lore raw

PATCH 64/491 drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello <[email protected]>

[ Upstream commit 0f0e59075b5c22f1e871fbd508d6e4f495048356 ]

For pptable structs that use flexible array sizes, use flexible arrays.

---
 .../gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h    | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +6 -6
index 41444e27bfc0c..e0e40b054c08b 100644
@@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State {
 typedef struct _ATOM_Tonga_State_Array {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries;		/* Number of entries. */
-	ATOM_Tonga_State entries[1];	/* Dynamically allocate entries. */
+	ATOM_Tonga_State entries[];	/* Dynamically allocate entries. */
 } ATOM_Tonga_State_Array;
 
 typedef struct _ATOM_Tonga_MCLK_Dependency_Record {
@@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record {
 typedef struct _ATOM_Polaris_SCLK_Dependency_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries;							/* Number of entries. */
-	ATOM_Polaris_SCLK_Dependency_Record entries[1];				 /* Dynamically allocate entries. */
+	ATOM_Polaris_SCLK_Dependency_Record entries[];				 /* Dynamically allocate entries. */
 } ATOM_Polaris_SCLK_Dependency_Table;
 
 typedef struct _ATOM_Tonga_PCIE_Record {
@@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Record {
 typedef struct _ATOM_Tonga_PCIE_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries; 										/* Number of entries. */
-	ATOM_Tonga_PCIE_Record entries[1];							/* Dynamically allocate entries. */
+	ATOM_Tonga_PCIE_Record entries[];							/* Dynamically allocate entries. */
 } ATOM_Tonga_PCIE_Table;
 
 typedef struct _ATOM_Polaris10_PCIE_Record {
@@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Record {
 typedef struct _ATOM_Polaris10_PCIE_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries;                                         /* Number of entries. */
-	ATOM_Polaris10_PCIE_Record entries[1];                      /* Dynamically allocate entries. */
+	ATOM_Polaris10_PCIE_Record entries[];                      /* Dynamically allocate entries. */
 } ATOM_Polaris10_PCIE_Table;
 
 
@@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Record {
 typedef struct _ATOM_Tonga_MM_Dependency_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries; 										/* Number of entries. */
-	ATOM_Tonga_MM_Dependency_Record entries[1]; 			   /* Dynamically allocate entries. */
+	ATOM_Tonga_MM_Dependency_Record entries[]; 			   /* Dynamically allocate entries. */
 } ATOM_Tonga_MM_Dependency_Table;
 
 typedef struct _ATOM_Tonga_Voltage_Lookup_Record {
@@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record {
 typedef struct _ATOM_Tonga_Voltage_Lookup_Table {
 	UCHAR ucRevId;
 	UCHAR ucNumEntries; 										/* Number of entries. */
-	ATOM_Tonga_Voltage_Lookup_Record entries[1];				/* Dynamically allocate entries. */
+	ATOM_Tonga_Voltage_Lookup_Record entries[];				/* Dynamically allocate entries. */
 } ATOM_Tonga_Voltage_Lookup_Table;
 
 typedef struct _ATOM_Tonga_Fan_Table {
Signature · 1 line
2.42.0
author maintainer
#65 lore raw

PATCH 65/491 drm/amdgpu: Fix potential null pointer derefernce

In reply to Greg Kroah-Hartman

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

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

From: Stanley.Yang <[email protected]>

[ Upstream commit 80285ae1ec8717b597b20de38866c29d84d321a1 ]

The amdgpu_ras_get_context may return NULL if device not support ras feature, so add check before using.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -1
index 8940ee73f2dfe..ecc61a6d13e13 100644
@@ -5399,7 +5399,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 	 * Flush RAM to disk so that after reboot
 	 * the user can read log and see why the system rebooted.
 	 */
-	if (need_emergency_restart && amdgpu_ras_get_context(adev)->reboot) {
+	if (need_emergency_restart && amdgpu_ras_get_context(adev) &&
+		amdgpu_ras_get_context(adev)->reboot) {
 		DRM_WARN("Emergency reboot.");
 
 		ksys_sync_helper();
Signature · 1 line
2.42.0
author maintainer
#66 lore raw

PATCH 66/491 drm/panel: fix a possible null pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ma Ke <[email protected]>

[ Upstream commit 924e5814d1f84e6fa5cb19c6eceb69f066225229 ]

In versatile_panel_get_modes(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd.

---
 drivers/gpu/drm/panel/panel-arm-versatile.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/panel/panel-arm-versatile.c +2 -0
index abb0788843c60..503ecea72c5ea 100644
@@ -267,6 +267,8 @@ static int versatile_panel_get_modes(struct drm_panel *panel,
 	connector->display_info.bus_flags = vpanel->panel_type->bus_flags;
 
 	mode = drm_mode_duplicate(connector->dev, &vpanel->panel_type->mode);
+	if (!mode)
+		return -ENOMEM;
 	drm_mode_set_name(mode);
 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 
Signature · 1 line
2.42.0
author maintainer
#67 lore raw

PATCH 67/491 drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ma Ke <[email protected]>

[ Upstream commit f22def5970c423ea7f87d5247bd0ef91416b0658 ]

In tpg110_get_modes(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd.

---
 drivers/gpu/drm/panel/panel-tpo-tpg110.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/panel/panel-tpo-tpg110.c +2 -0
index 845304435e235..f6a212e542cb9 100644
@@ -379,6 +379,8 @@ static int tpg110_get_modes(struct drm_panel *panel,
 	connector->display_info.bus_flags = tpg->panel_mode->bus_flags;
 
 	mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode);
+	if (!mode)
+		return -ENOMEM;
 	drm_mode_set_name(mode);
 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 
Signature · 1 line
2.42.0
author maintainer
#68 lore raw

PATCH 68/491 drm/radeon: fix a possible null pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ma Ke <[email protected]>

[ Upstream commit 2c1fe3c480f9e1deefd50d4b18be4a046011ee1f ]

In radeon_tv_get_modes(), the return value of drm_cvt_mode() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_cvt_mode(). Add a check to avoid null point dereference.

---
 drivers/gpu/drm/radeon/radeon_connectors.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/radeon/radeon_connectors.c +2 -0
index 07193cd0c4174..4859d965d67e3 100644
@@ -1122,6 +1122,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector)
 	else {
 		/* only 800x600 is supported right now on pre-avivo chips */
 		tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false);
+		if (!tv_mode)
+			return 0;
 		tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 		drm_mode_probed_add(connector, tv_mode);
 	}
Signature · 1 line
2.42.0
author maintainer
#69 lore raw

PATCH 69/491 drm/amdgpu/vkms: fix a possible null pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ma Ke <[email protected]>

[ Upstream commit cd90511557fdfb394bb4ac4c3b539b007383914c ]

In amdgpu_vkms_conn_get_modes(), the return value of drm_cvt_mode() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_cvt_mode(). Add a check to avoid null pointer dereference.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +2 -0
index d0748bcfad16b..75d25fba80821 100644
@@ -239,6 +239,8 @@ static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
 
 	for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
 		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
+		if (!mode)
+			continue;
 		drm_mode_probed_add(connector, mode);
 	}
 
Signature · 1 line
2.42.0
author maintainer
#70 lore raw

PATCH 70/491 drm/panel: st7703: Pick different reset sequence

In reply to Greg Kroah-Hartman

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

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

From: Ondrej Jirman <[email protected]>

[ Upstream commit d12d635bb03c7cb4830acb641eb176ee9ff2aa89 ]

Switching to a different reset sequence, enabling IOVCC before enabling VCC.

There also needs to be a delay after enabling the supplies and before deasserting the reset. The datasheet specifies 1ms after the supplies reach the required voltage. Use 10-20ms to also give the power supplies some time to reach the required voltage, too.

This fixes intermittent panel initialization failures and screen corruption during resume from sleep on panel xingbangda,xbd599 (e.g. used in PinePhone).

---
 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 25 ++++++++++---------
 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/gpu/drm/panel/panel-sitronix-st7703.c +13 -12
index 3aa31f3d61574..687749bbec62c 100644
@@ -506,29 +506,30 @@ static int st7703_prepare(struct drm_panel *panel)
 		return 0;
 
 	dev_dbg(ctx->dev, "Resetting the panel\n");
-	ret = regulator_enable(ctx->vcc);
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+	ret = regulator_enable(ctx->iovcc);
 	if (ret < 0) {
-		dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
+		dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
 		return ret;
 	}
-	ret = regulator_enable(ctx->iovcc);
+
+	ret = regulator_enable(ctx->vcc);
 	if (ret < 0) {
-		dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
-		goto disable_vcc;
+		dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
+		regulator_disable(ctx->iovcc);
+		return ret;
 	}
 
-	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
-	usleep_range(20, 40);
+	/* Give power supplies time to stabilize before deasserting reset. */
+	usleep_range(10000, 20000);
+
 	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
-	msleep(20);
+	usleep_range(15000, 20000);
 
 	ctx->prepared = true;
 
 	return 0;
-
-disable_vcc:
-	regulator_disable(ctx->vcc);
-	return ret;
 }
 
 static const u32 mantix_bus_formats[] = {
Signature · 1 line
2.42.0
author maintainer
#71 lore raw

PATCH 71/491 drm/amdkfd: Fix shift out-of-bounds issue

In reply to Greg Kroah-Hartman

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

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

From: Jesse Zhang <[email protected]>

[ Upstream commit 282c1d793076c2edac6c3db51b7e8ed2b41d60a5 ]

[  567.613292] shift exponent 255 is too large for 64-bit type 'long unsigned int'
[  567.614498] CPU: 5 PID: 238 Comm: kworker/5:1 Tainted: G           OE      6.2.0-34-generic #34~22.04.1-Ubuntu
[  567.614502] Hardware name: AMD Splinter/Splinter-RPL, BIOS WS43927N_871 09/25/2023
[  567.614504] Workqueue: events send_exception_work_handler [amdgpu]
[  567.614748] Call Trace:
[  567.614750]  <TASK>
[  567.614753]  dump_stack_lvl+0x48/0x70
[  567.614761]  dump_stack+0x10/0x20
[  567.614763]  __ubsan_handle_shift_out_of_bounds+0x156/0x310
[  567.614769]  ? srso_alias_return_thunk+0x5/0x7f
[  567.614773]  ? update_sd_lb_stats.constprop.0+0xf2/0x3c0
[  567.614780]  svm_range_split_by_granularity.cold+0x2b/0x34 [amdgpu]
[  567.615047]  ? srso_alias_return_thunk+0x5/0x7f
[  567.615052]  svm_migrate_to_ram+0x185/0x4d0 [amdgpu]
[  567.615286]  do_swap_page+0x7b6/0xa30
[  567.615291]  ? srso_alias_return_thunk+0x5/0x7f
[  567.615294]  ? __free_pages+0x119/0x130
[  567.615299]  handle_pte_fault+0x227/0x280
[  567.615303]  __handle_mm_fault+0x3c0/0x720
[  567.615311]  handle_mm_fault+0x119/0x330
[  567.615314]  ? lock_mm_and_find_vma+0x44/0x250
[  567.615318]  do_user_addr_fault+0x1a9/0x640
[  567.615323]  exc_page_fault+0x81/0x1b0
[  567.615328]  asm_exc_page_fault+0x27/0x30
[  567.615332] RIP: 0010:__get_user_8+0x1c/0x30
---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +1 -1
index e1d73a7223675..a5c394fcbb350 100644
@@ -756,7 +756,7 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange,
 			prange->flags &= ~attrs[i].value;
 			break;
 		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
-			prange->granularity = attrs[i].value;
+			prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F);
 			break;
 		default:
 			WARN_ONCE(1, "svm_range_check_attrs wasn't called?");
Signature · 1 line
2.42.0
author maintainer
#72 lore raw

PATCH 72/491 drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is NULL

In reply to Greg Kroah-Hartman

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

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

From: Qu Huang <[email protected]>

[ Upstream commit 5104fdf50d326db2c1a994f8b35dcd46e63ae4ad ]

In certain types of chips, such as VEGA20, reading the amdgpu_regs_smc file could result in an abnormal null pointer access when the smc_rreg pointer is NULL. Below are the steps to reproduce this issue and the corresponding exception log:

1. Navigate to the directory: /sys/kernel/debug/dri/0
2. Execute command: cat amdgpu_regs_smc
3. Exception Log::

[4005007.702554] BUG: kernel NULL pointer dereference, address: 0000000000000000
[4005007.702562] #PF: supervisor instruction fetch in kernel mode
[4005007.702567] #PF: error_code(0x0010) - not-present page
[4005007.702570] PGD 0 P4D 0
[4005007.702576] Oops: 0010 [#1] SMP NOPTI
[4005007.702581] CPU: 4 PID: 62563 Comm: cat Tainted: G           OE     5.15.0-43-generic #46-Ubunt       u
[4005007.702590] RIP: 0010:0x0
[4005007.702598] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6.
[4005007.702600] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206
[4005007.702605] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68
[4005007.702609] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000
[4005007.702612] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980
[4005007.702615] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000
[4005007.702618] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000
[4005007.702622] FS:  00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000
[4005007.702626] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[4005007.702629] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0
[4005007.702633] Call Trace:
[4005007.702636]  <TASK>
[4005007.702640]  amdgpu_debugfs_regs_smc_read+0xb0/0x120 [amdgpu]
[4005007.703002]  full_proxy_read+0x5c/0x80
[4005007.703011]  vfs_read+0x9f/0x1a0
[4005007.703019]  ksys_read+0x67/0xe0
[4005007.703023]  __x64_sys_read+0x19/0x20
[4005007.703028]  do_syscall_64+0x5c/0xc0
[4005007.703034]  ? do_user_addr_fault+0x1e3/0x670
[4005007.703040]  ? exit_to_user_mode_prepare+0x37/0xb0
[4005007.703047]  ? irqentry_exit_to_user_mode+0x9/0x20
[4005007.703052]  ? irqentry_exit+0x19/0x30
[4005007.703057]  ? exc_page_fault+0x89/0x160
[4005007.703062]  ? asm_exc_page_fault+0x8/0x30
[4005007.703068]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[4005007.703075] RIP: 0033:0x7f5e07672992
[4005007.703079] Code: c0 e9 b2 fe ff ff 50 48 8d 3d fa b2 0c 00 e8 c5 1d 02 00 0f 1f 44 00 00 f3 0f        1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 e       c 28 48 89 54 24
[4005007.703083] RSP: 002b:00007ffe03097898 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[4005007.703088] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f5e07672992
[4005007.703091] RDX: 0000000000020000 RSI: 00007f5e06753000 RDI: 0000000000000003
[4005007.703094] RBP: 00007f5e06753000 R08: 00007f5e06752010 R09: 00007f5e06752010
[4005007.703096] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000022000
[4005007.703099] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000
[4005007.703105]  </TASK>
[4005007.703107] Modules linked in: nf_tables libcrc32c nfnetlink algif_hash af_alg binfmt_misc nls_       iso8859_1 ipmi_ssif ast intel_rapl_msr intel_rapl_common drm_vram_helper drm_ttm_helper amd64_edac t       tm edac_mce_amd kvm_amd ccp mac_hid k10temp kvm acpi_ipmi ipmi_si rapl sch_fq_codel ipmi_devintf ipm       i_msghandler msr parport_pc ppdev lp parport mtd pstore_blk efi_pstore ramoops pstore_zone reed_solo       mon ip_tables x_tables autofs4 ib_uverbs ib_core amdgpu(OE) amddrm_ttm_helper(OE) amdttm(OE) iommu_v       2 amd_sched(OE) amdkcl(OE) drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec rc_core        drm igb ahci xhci_pci libahci i2c_piix4 i2c_algo_bit xhci_pci_renesas dca
[4005007.703184] CR2: 0000000000000000
[4005007.703188] ---[ end trace ac65a538d240da39 ]---
[4005007.800865] RIP: 0010:0x0
[4005007.800871] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6.
[4005007.800874] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206
[4005007.800878] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68
[4005007.800881] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000
[4005007.800883] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980
[4005007.800886] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000
[4005007.800888] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000
[4005007.800891] FS:  00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000
[4005007.800895] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[4005007.800898] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +6 -0
index 56e89e76ff179..33cada366eeb1 100644
@@ -747,6 +747,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
 	ssize_t result = 0;
 	int r;
 
+	if (!adev->smc_rreg)
+		return -EPERM;
+
 	if (size & 0x3 || *pos & 0x3)
 		return -EINVAL;
 
@@ -803,6 +806,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
 	ssize_t result = 0;
 	int r;
 
+	if (!adev->smc_wreg)
+		return -EPERM;
+
 	if (size & 0x3 || *pos & 0x3)
 		return -EINVAL;
 
Signature · 1 line
2.42.0
author maintainer
#73 lore raw

PATCH 73/491 drm/amd: Disable PP_PCIE_DPM_MASK when dynamic speed switching not supported

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello <[email protected]>

[ Upstream commit fbf1035b033a51eee48d5f42e781b02fff272ca0 ]

Rather than individual ASICs checking for the quirk, set the quirk at the driver level.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c              | 2 ++
 drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c     | 4 +---
 drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c          | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -0
index ecc61a6d13e13..65779cbdbad13 100644
@@ -2318,6 +2318,8 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
 		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
 	if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)
 		adev->pm.pp_feature &= ~PP_OVERDRIVE_MASK;
+	if (!amdgpu_device_pcie_dynamic_switching_supported())
+		adev->pm.pp_feature &= ~PP_PCIE_DPM_MASK;
 
 	total = true;
 	for (i = 0; i < adev->num_ip_blocks; i++) {
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +1 -3
index 1cb4022644977..a38888176805d 100644
@@ -1823,9 +1823,7 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 
 	data->mclk_dpm_key_disabled = hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true;
 	data->sclk_dpm_key_disabled = hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true;
-	data->pcie_dpm_key_disabled =
-		!amdgpu_device_pcie_dynamic_switching_supported() ||
-		!(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
+	data->pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
 	/* need to set voltage control types before EVV patching */
 	data->voltage_control = SMU7_VOLTAGE_CONTROL_NONE;
 	data->vddci_control = SMU7_VOLTAGE_CONTROL_NONE;
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +1 -1
index 9a5f3d31e7780..94f22df5ac205 100644
@@ -2107,7 +2107,7 @@ static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
 	min_lane_width = min_lane_width > max_lane_width ?
 			 max_lane_width : min_lane_width;
 
-	if (!amdgpu_device_pcie_dynamic_switching_supported()) {
+	if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
 		pcie_table->pcie_gen[0] = max_gen_speed;
 		pcie_table->pcie_lane[0] = max_lane_width;
 	} else {
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +1 -1
index 4fa94f583b87c..223e890575a2b 100644
@@ -2436,7 +2436,7 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
 	uint32_t smu_pcie_arg;
 	int ret, i;
 
-	if (!amdgpu_device_pcie_dynamic_switching_supported()) {
+	if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
 		if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap)
 			pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1];
 
Signature · 1 line
2.42.0
author maintainer
#74 lore raw

PATCH 74/491 drm/amd/display: fix num_ways overflow error

In reply to Greg Kroah-Hartman

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

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

From: Samson Tam <[email protected]>

[ Upstream commit 79f3f1b66753b3a3a269d73676bf50987921f267 ]

[Why]
Helper function calculates num_ways using 32-bit. But is
returned as 8-bit. If num_ways exceeds 8-bit, then it reports back the incorrect num_ways and erroneously uses MALL when it should not

[How]
Make returned value 32-bit and convert after it checks
against caps.cache_num_ways, which is under 8-bit

---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +4 -3
index 5b3d0e5b90a3e..ccbcfd6bd6b85 100644
@@ -216,7 +216,7 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
 static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
 {
 	int i;
-	uint8_t num_ways = 0;
+	uint32_t num_ways = 0;
 	uint32_t mall_ss_size_bytes = 0;
 
 	mall_ss_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_size_bytes;
@@ -246,7 +246,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
 bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
 	union dmub_rb_cmd cmd;
-	uint8_t ways, i;
+	uint8_t i;
+	uint32_t ways;
 	int j;
 	bool mall_ss_unsupported = false;
 	struct dc_plane_state *plane = NULL;
@@ -306,7 +307,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
 				cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
 				cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
 				cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
-				cmd.cab.cab_alloc_ways = ways;
+				cmd.cab.cab_alloc_ways = (uint8_t)ways;
 
 				dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
 
Signature · 1 line
2.42.0
author maintainer
#75 lore raw

PATCH 75/491 drm/amd: check num of link levels when update pcie param

In reply to Greg Kroah-Hartman

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

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

From: Lin.Cao <[email protected]>

[ Upstream commit 406e8845356d18bdf3d3a23b347faf67706472ec ]

In SR-IOV environment, the value of pcie_table->num_of_link_levels will be 0, and num_of_levels - 1 will cause array index out of bounds

---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +3 -0
index 223e890575a2b..3bc60ecc7bfef 100644
@@ -2436,6 +2436,9 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
 	uint32_t smu_pcie_arg;
 	int ret, i;
 
+	if (!num_of_levels)
+		return 0;
+
 	if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
 		if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap)
 			pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1];
Signature · 1 line
2.42.0
author maintainer
#76 lore raw

PATCH 76/491 arm64: dts: ls208xa: use a pseudo-bus to constrain usb dma size

In reply to Greg Kroah-Hartman

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

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

From: Laurentiu Tudor <[email protected]>

[ Upstream commit b39d5016456871a88f5cd141914a5043591b46f3 ]

Wrap the usb controllers in an intermediate simple-bus and use it to constrain the dma address size of these usb controllers to the 40b that they generate toward the interconnect. This is required because the SoC uses 48b address sizes and this mismatch would lead to smmu context faults [1] because the usb generates 40b addresses while the smmu page tables are populated with 48b wide addresses.

[1]
xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
xhci-hcd xhci-hcd.0.auto: hcc params 0x0220f66d hci version 0x100 quirks 0x0000000002000010 xhci-hcd xhci-hcd.0.auto: irq 108, io mem 0x03100000
xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0 SuperSpeed
arm-smmu 5000000.iommu: Unhandled context fault: fsr=0x402, iova=0xffffffb000, fsynr=0x0, cbfrsynra=0xc01, cb=3

---
 .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 46 +++++++++++--------
 1 file changed, 27 insertions(+), 19 deletions(-)
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +27 -19
index d2f5345d05600..717288bbdb8b6 100644
@@ -1186,26 +1186,34 @@
 			dma-coherent;
 		};
 
-		usb0: usb@3100000 {
-			status = "disabled";
-			compatible = "snps,dwc3";
-			reg = <0x0 0x3100000 0x0 0x10000>;
-			interrupts = <0 80 0x4>; /* Level high type */
-			dr_mode = "host";
-			snps,quirk-frame-length-adjustment = <0x20>;
-			snps,dis_rxdet_inp3_quirk;
-			snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
-		};
+		bus: bus {
+			#address-cells = <2>;
+			#size-cells = <2>;
+			compatible = "simple-bus";
+			ranges;
+			dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>;
+
+			usb0: usb@3100000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x3100000 0x0 0x10000>;
+				interrupts = <0 80 0x4>; /* Level high type */
+				dr_mode = "host";
+				snps,quirk-frame-length-adjustment = <0x20>;
+				snps,dis_rxdet_inp3_quirk;
+				snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+				status = "disabled";
+			};
 
-		usb1: usb@3110000 {
-			status = "disabled";
-			compatible = "snps,dwc3";
-			reg = <0x0 0x3110000 0x0 0x10000>;
-			interrupts = <0 81 0x4>; /* Level high type */
-			dr_mode = "host";
-			snps,quirk-frame-length-adjustment = <0x20>;
-			snps,dis_rxdet_inp3_quirk;
-			snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+			usb1: usb@3110000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x3110000 0x0 0x10000>;
+				interrupts = <0 81 0x4>; /* Level high type */
+				dr_mode = "host";
+				snps,quirk-frame-length-adjustment = <0x20>;
+				snps,dis_rxdet_inp3_quirk;
+				snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+				status = "disabled";
+			};
 		};
 
 		ccn@4000000 {
Signature · 1 line
2.42.0
author maintainer
#77 lore raw

PATCH 77/491 selftests/efivarfs: create-read: fix a resource leak

In reply to Greg Kroah-Hartman

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

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

From: zhujun2 <[email protected]>

[ Upstream commit 3f6f8a8c5e11a9b384a36df4f40f0c9a653b6975 ]

The opened file should be closed in main(), otherwise resource leak will occur that this problem was discovered by code reading

---
 tools/testing/selftests/efivarfs/create-read.c | 2 ++
 1 file changed, 2 insertions(+)
tools/testing/selftests/efivarfs/create-read.c +2 -0
index 9674a19396a32..7bc7af4eb2c17 100644
@@ -32,8 +32,10 @@ int main(int argc, char **argv)
 	rc = read(fd, buf, sizeof(buf));
 	if (rc != 0) {
 		fprintf(stderr, "Reading a new var should return EOF\n");
+		close(fd);
 		return EXIT_FAILURE;
 	}
 
+	close(fd);
 	return EXIT_SUCCESS;
 }
Signature · 1 line
2.42.0
author maintainer
#78 lore raw

PATCH 78/491 ASoC: mediatek: mt8188-mt6359: support dynamic pinctrl

In reply to Greg Kroah-Hartman

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

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

From: Trevor Wu <[email protected]>

[ Upstream commit d601bb78f06b9e3cbb52e6b87b88add9920a11b6 ]

To avoid power leakage, it is recommended to replace the default pinctrl state with dynamic pinctrl since certain audio pinmux functions can remain in a HIGH state even when audio is disabled. Linking pinctrl with DAPM using SND_SOC_DAPM_PINCTRL will ensure that audio pins remain in GPIO mode by default and only switch to an audio function when necessary.

---
 sound/soc/mediatek/mt8188/mt8188-mt6359.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
sound/soc/mediatek/mt8188/mt8188-mt6359.c +21 -0
index ac69c23e0da1c..7048ff52ab86a 100644
@@ -246,6 +246,11 @@ static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_SINK("HDMI"),
 	SND_SOC_DAPM_SINK("DP"),
+
+	/* dynamic pinctrl */
+	SND_SOC_DAPM_PINCTRL("ETDM_SPK_PIN", "aud_etdm_spk_on", "aud_etdm_spk_off"),
+	SND_SOC_DAPM_PINCTRL("ETDM_HP_PIN", "aud_etdm_hp_on", "aud_etdm_hp_off"),
+	SND_SOC_DAPM_PINCTRL("MTKAIF_PIN", "aud_mtkaif_on", "aud_mtkaif_off"),
 };
 
 static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
@@ -267,6 +272,7 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
 		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
 	struct snd_soc_component *cmpnt_codec =
 		asoc_rtd_to_codec(rtd, 0)->component;
+	struct snd_soc_dapm_widget *pin_w = NULL, *w;
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct mtkaif_param *param;
@@ -306,6 +312,18 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
 		return 0;
 	}
 
+	for_each_card_widgets(rtd->card, w) {
+		if (!strcmp(w->name, "MTKAIF_PIN")) {
+			pin_w = w;
+			break;
+		}
+	}
+
+	if (pin_w)
+		dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_PRE_PMU);
+	else
+		dev_dbg(afe->dev, "%s(), no pinmux widget, please check if default on\n", __func__);
+
 	pm_runtime_get_sync(afe->dev);
 	mt6359_mtkaif_calibration_enable(cmpnt_codec);
 
@@ -403,6 +421,9 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
 	for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++)
 		param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
 
+	if (pin_w)
+		dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_POST_PMD);
+
 	dev_dbg(afe->dev, "%s(), end, calibration ok %d\n",
 		__func__, param->mtkaif_calibration_ok);
 
Signature · 1 line
2.42.0
author maintainer
#79 lore raw

PATCH 79/491 ASoC: soc-card: Add storage for PCI SSID

In reply to Greg Kroah-Hartman

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

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

From: Richard Fitzgerald <[email protected]>

[ Upstream commit 47f56e38a199bd45514b8e0142399cba4feeaf1a ]

Add members to struct snd_soc_card to store the PCI subsystem ID (SSID) of the soundcard.

The PCI specification provides two registers to store a vendor-specific SSID that can be read by drivers to uniquely identify a particular "soundcard". This is defined in the PCI specification to distinguish products that use the same silicon (and therefore have the same silicon ID) so that product-specific differences can be applied.

PCI only defines 0xFFFF as an invalid value. 0x0000 is not defined as invalid. So the usual pattern of zero-filling the struct and then assuming a zero value unset will not work. A flag is included to indicate when the SSID information has been filled in.

Unlike DMI information, which has a free-format entirely up to the vendor, the PCI SSID has a strictly defined format and a registry of vendor IDs.

It is usual in Windows drivers that the SSID is used as the sole identifier of the specific end-product and the Windows driver contains tables mapping that to information about the hardware setup, rather than using ACPI properties.

This SSID is important information for ASoC components that need to apply hardware-specific configuration on PCI-based systems.

As the SSID is a generic part of the PCI specification and is treated as identifying the "soundcard", it is reasonable to include this information in struct snd_soc_card, instead of components inventing their own custom ways to pass this information around.

---
 include/sound/soc-card.h | 37 +++++++++++++++++++++++++++++++++++++
 include/sound/soc.h      | 11 +++++++++++
 2 files changed, 48 insertions(+)
include/sound/soc-card.h +37 -0
index fc94dfb0021fd..e8ff2e089cd00 100644
@@ -59,6 +59,43 @@ int snd_soc_card_add_dai_link(struct snd_soc_card *card,
 void snd_soc_card_remove_dai_link(struct snd_soc_card *card,
 				  struct snd_soc_dai_link *dai_link);
 
+#ifdef CONFIG_PCI
+static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card,
+					     unsigned short vendor,
+					     unsigned short device)
+{
+	card->pci_subsystem_vendor = vendor;
+	card->pci_subsystem_device = device;
+	card->pci_subsystem_set = true;
+}
+
+static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card,
+					    unsigned short *vendor,
+					    unsigned short *device)
+{
+	if (!card->pci_subsystem_set)
+		return -ENOENT;
+
+	*vendor = card->pci_subsystem_vendor;
+	*device = card->pci_subsystem_device;
+
+	return 0;
+}
+#else /* !CONFIG_PCI */
+static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card,
+					     unsigned short vendor,
+					     unsigned short device)
+{
+}
+
+static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card,
+					    unsigned short *vendor,
+					    unsigned short *device)
+{
+	return -ENOENT;
+}
+#endif /* CONFIG_PCI */
+
 /* device driver data */
 static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
 					    void *data)
include/sound/soc.h +11 -0
index cf34810882347..0c54b343d3e5d 100644
@@ -931,6 +931,17 @@ struct snd_soc_card {
 #ifdef CONFIG_DMI
 	char dmi_longname[80];
 #endif /* CONFIG_DMI */
+
+#ifdef CONFIG_PCI
+	/*
+	 * PCI does not define 0 as invalid, so pci_subsystem_set indicates
+	 * whether a value has been written to these fields.
+	 */
+	unsigned short pci_subsystem_vendor;
+	unsigned short pci_subsystem_device;
+	bool pci_subsystem_set;
+#endif /* CONFIG_PCI */
+
 	char topology_shortname[32];
 
 	struct device *dev;
Signature · 1 line
2.42.0
author maintainer
#80 lore raw

PATCH 80/491 ASoC: SOF: Pass PCI SSID to machine driver

In reply to Greg Kroah-Hartman

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

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

From: Richard Fitzgerald <[email protected]>

[ Upstream commit ba2de401d32625fe538d3f2c00ca73740dd2d516 ]

Pass the PCI SSID of the audio interface through to the machine driver. This allows the machine driver to use the SSID to uniquely identify the specific hardware configuration and apply any platform-specific configuration.

struct snd_sof_pdata is passed around inside the SOF code, but it then passes configuration information to the machine driver through struct snd_soc_acpi_mach and struct snd_soc_acpi_mach_params. So SSID information has been added to both snd_sof_pdata and snd_soc_acpi_mach_params.

PCI does not define 0x0000 as an invalid value so we can't use zero to indicate that the struct member was not written. Instead a flag is included to indicate that a value has been written to the subsystem_vendor and subsystem_device members.

sof_pci_probe() creates the struct snd_sof_pdata. It is passed a struct pci_dev so it can fill in the SSID value.

sof_machine_check() finds the appropriate struct snd_soc_acpi_mach. It copies the SSID information across to the struct snd_soc_acpi_mach_params. This done before calling any custom set_mach_params() so that it could be used by the set_mach_params() callback to apply variant params.

The machine driver receives the struct snd_soc_acpi_mach as its platform_data.

---
 include/sound/soc-acpi.h    | 7 +++++++
 include/sound/sof.h         | 8 ++++++++
 sound/soc/sof/sof-audio.c   | 7 +++++++
 sound/soc/sof/sof-pci-dev.c | 8 ++++++++
 4 files changed, 30 insertions(+)
include/sound/soc-acpi.h +7 -0
index 528279056b3ab..1a5f90b0a5463 100644
@@ -67,6 +67,10 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
  * @i2s_link_mask: I2S/TDM links enabled on the board
  * @num_dai_drivers: number of elements in @dai_drivers
  * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
+ * @subsystem_vendor: optional PCI SSID vendor value
+ * @subsystem_device: optional PCI SSID device value
+ * @subsystem_id_set: true if a value has been written to
+ *		      subsystem_vendor and subsystem_device.
  */
 struct snd_soc_acpi_mach_params {
 	u32 acpi_ipc_irq_index;
@@ -79,6 +83,9 @@ struct snd_soc_acpi_mach_params {
 	u32 i2s_link_mask;
 	u32 num_dai_drivers;
 	struct snd_soc_dai_driver *dai_drivers;
+	unsigned short subsystem_vendor;
+	unsigned short subsystem_device;
+	bool subsystem_id_set;
 };
 
 /**
include/sound/sof.h +8 -0
index d3c41f87ac319..51294f2ba302c 100644
@@ -64,6 +64,14 @@ struct snd_sof_pdata {
 	const char *name;
 	const char *platform;
 
+	/*
+	 * PCI SSID. As PCI does not define 0 as invalid, the subsystem_id_set
+	 * flag indicates that a value has been written to these members.
+	 */
+	unsigned short subsystem_vendor;
+	unsigned short subsystem_device;
+	bool subsystem_id_set;
+
 	struct device *dev;
 
 	/*
sound/soc/sof/sof-audio.c +7 -0
index e5405f854a910..563fe6f7789f7 100644
@@ -1032,6 +1032,13 @@ int sof_machine_check(struct snd_sof_dev *sdev)
 		mach = snd_sof_machine_select(sdev);
 		if (mach) {
 			sof_pdata->machine = mach;
+
+			if (sof_pdata->subsystem_id_set) {
+				mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor;
+				mach->mach_params.subsystem_device = sof_pdata->subsystem_device;
+				mach->mach_params.subsystem_id_set = true;
+			}
+
 			snd_sof_set_mach_params(mach, sdev);
 			return 0;
 		}
sound/soc/sof/sof-pci-dev.c +8 -0
index f42c85df88a80..69a2352f2e1a0 100644
@@ -221,6 +221,14 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 		return ret;
 
 	sof_pdata->name = pci_name(pci);
+
+	/* PCI defines a vendor ID of 0xFFFF as invalid. */
+	if (pci->subsystem_vendor != 0xFFFF) {
+		sof_pdata->subsystem_vendor = pci->subsystem_vendor;
+		sof_pdata->subsystem_device = pci->subsystem_device;
+		sof_pdata->subsystem_id_set = true;
+	}
+
 	sof_pdata->desc = desc;
 	sof_pdata->dev = dev;
 
Signature · 1 line
2.42.0
author maintainer
#81 lore raw

PATCH 81/491 crypto: pcrypt - Fix hungtask for PADATA_RESET

In reply to Greg Kroah-Hartman

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

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

From: Lu Jialin <[email protected]>

[ Upstream commit 8f4f68e788c3a7a696546291258bfa5fdb215523 ]

We found a hungtask bug in test_aead_vec_cfg as follows:

INFO: task cryptomgr_test:391009 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Call trace:
 __switch_to+0x98/0xe0
 __schedule+0x6c4/0xf40
 schedule+0xd8/0x1b4
 schedule_timeout+0x474/0x560
 wait_for_common+0x368/0x4e0
 wait_for_completion+0x20/0x30
 wait_for_completion+0x20/0x30
 test_aead_vec_cfg+0xab4/0xd50
 test_aead+0x144/0x1f0
 alg_test_aead+0xd8/0x1e0
 alg_test+0x634/0x890
 cryptomgr_test+0x40/0x70
 kthread+0x1e0/0x220
 ret_from_fork+0x10/0x18
 Kernel panic - not syncing: hung_task: blocked tasks

For padata_do_parallel, when the return err is 0 or -EBUSY, it will call wait_for_completion(&wait->completion) in test_aead_vec_cfg. In normal case, aead_request_complete() will be called in pcrypt_aead_serial and the return err is 0 for padata_do_parallel. But, when pinst->flags is PADATA_RESET, the return err is -EBUSY for padata_do_parallel, and it won't call aead_request_complete(). Therefore, test_aead_vec_cfg will hung at wait_for_completion(&wait->completion), which will cause hungtask.

The problem comes as following:

(padata_do_parallel)                 |
    rcu_read_lock_bh();              |
    err = -EINVAL;                   |   (padata_replace)
                                     |     pinst->flags |= PADATA_RESET;
    err = -EBUSY                     |
    if (pinst->flags & PADATA_RESET) |
        rcu_read_unlock_bh()         |

return err

In order to resolve the problem, we replace the return err -EBUSY with -EAGAIN, which means parallel_data is changing, and the caller should call it again.

v3:
remove retry and just change the return err.
v2:
introduce padata_try_do_parallel() in pcrypt_aead_encrypt and pcrypt_aead_decrypt to solve the hungtask.

---
 crypto/pcrypt.c | 4 ++++
 kernel/padata.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
crypto/pcrypt.c +4 -0
index 8c1d0ca412137..d0d954fe9d54f 100644
@@ -117,6 +117,8 @@ static int pcrypt_aead_encrypt(struct aead_request *req)
 	err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu);
 	if (!err)
 		return -EINPROGRESS;
+	if (err == -EBUSY)
+		return -EAGAIN;
 
 	return err;
 }
@@ -164,6 +166,8 @@ static int pcrypt_aead_decrypt(struct aead_request *req)
 	err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu);
 	if (!err)
 		return -EINPROGRESS;
+	if (err == -EBUSY)
+		return -EAGAIN;
 
 	return err;
 }
kernel/padata.c +1 -1
index ff349e1084c1d..179fb1518070c 100644
@@ -202,7 +202,7 @@ int padata_do_parallel(struct padata_shell *ps,
 		*cb_cpu = cpu;
 	}
 
-	err =  -EBUSY;
+	err = -EBUSY;
 	if ((pinst->flags & PADATA_RESET))
 		goto out;
 
Signature · 1 line
2.42.0
author maintainer
#82 lore raw

PATCH 82/491 ALSA: scarlett2: Move USB IDs out from device_info struct

In reply to Greg Kroah-Hartman

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

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

From: Geoffrey D. Bennett <[email protected]>

[ Upstream commit d98cc489029dba4d99714c2e8ec4f5ba249f6851 ]

By moving the USB IDs from the device_info struct into scarlett2_devices[], that will allow for devices with different USB IDs to share the same device_info.

---
 sound/usb/mixer_scarlett_gen2.c | 63 ++++++++++++---------------------
 1 file changed, 23 insertions(+), 40 deletions(-)
sound/usb/mixer_scarlett_gen2.c +23 -40
index 9d11bb08667e7..48f5c9b9790dc 100644
@@ -317,8 +317,6 @@ struct scarlett2_mux_entry {
 };
 
 struct scarlett2_device_info {
-	u32 usb_id; /* USB device identifier */
-
 	/* Gen 3 devices have an internal MSD mode switch that needs
 	 * to be disabled in order to access the full functionality of
 	 * the device.
@@ -440,8 +438,6 @@ struct scarlett2_data {
 /*** Model-specific data ***/
 
 static const struct scarlett2_device_info s6i6_gen2_info = {
-	.usb_id = USB_ID(0x1235, 0x8203),
-
 	.config_set = SCARLETT2_CONFIG_SET_GEN_2,
 	.level_input_count = 2,
 	.pad_input_count = 2,
@@ -486,8 +482,6 @@ static const struct scarlett2_device_info s6i6_gen2_info = {
 };
 
 static const struct scarlett2_device_info s18i8_gen2_info = {
-	.usb_id = USB_ID(0x1235, 0x8204),
-
 	.config_set = SCARLETT2_CONFIG_SET_GEN_2,
 	.level_input_count = 2,
 	.pad_input_count = 4,
@@ -535,8 +529,6 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
 };
 
 static const struct scarlett2_device_info s18i20_gen2_info = {
-	.usb_id = USB_ID(0x1235, 0x8201),
-
 	.config_set = SCARLETT2_CONFIG_SET_GEN_2,
 	.line_out_hw_vol = 1,
 
@@ -589,8 +581,6 @@ static const struct scarlett2_device_info s18i20_gen2_info = {
 };
 
 static const struct scarlett2_device_info solo_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8211),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_NO_MIXER,
 	.level_input_count = 1,
@@ -602,8 +592,6 @@ static const struct scarlett2_device_info solo_gen3_info = {
 };
 
 static const struct scarlett2_device_info s2i2_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8210),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_NO_MIXER,
 	.level_input_count = 2,
@@ -614,8 +602,6 @@ static const struct scarlett2_device_info s2i2_gen3_info = {
 };
 
 static const struct scarlett2_device_info s4i4_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8212),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_GEN_3,
 	.level_input_count = 2,
@@ -660,8 +646,6 @@ static const struct scarlett2_device_info s4i4_gen3_info = {
 };
 
 static const struct scarlett2_device_info s8i6_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8213),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_GEN_3,
 	.level_input_count = 2,
@@ -713,8 +697,6 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
 };
 
 static const struct scarlett2_device_info s18i8_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8214),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_GEN_3,
 	.line_out_hw_vol = 1,
@@ -783,8 +765,6 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
 };
 
 static const struct scarlett2_device_info s18i20_gen3_info = {
-	.usb_id = USB_ID(0x1235, 0x8215),
-
 	.has_msd_mode = 1,
 	.config_set = SCARLETT2_CONFIG_SET_GEN_3,
 	.line_out_hw_vol = 1,
@@ -848,8 +828,6 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
 };
 
 static const struct scarlett2_device_info clarett_8pre_info = {
-	.usb_id = USB_ID(0x1235, 0x820c),
-
 	.config_set = SCARLETT2_CONFIG_SET_CLARETT,
 	.line_out_hw_vol = 1,
 	.level_input_count = 2,
@@ -902,25 +880,30 @@ static const struct scarlett2_device_info clarett_8pre_info = {
 	} },
 };
 
-static const struct scarlett2_device_info *scarlett2_devices[] = {
+struct scarlett2_device_entry {
+	const u32 usb_id; /* USB device identifier */
+	const struct scarlett2_device_info *info;
+};
+
+static const struct scarlett2_device_entry scarlett2_devices[] = {
 	/* Supported Gen 2 devices */
-	&s6i6_gen2_info,
-	&s18i8_gen2_info,
-	&s18i20_gen2_info,
+	{ USB_ID(0x1235, 0x8203), &s6i6_gen2_info },
+	{ USB_ID(0x1235, 0x8204), &s18i8_gen2_info },
+	{ USB_ID(0x1235, 0x8201), &s18i20_gen2_info },
 
 	/* Supported Gen 3 devices */
-	&solo_gen3_info,
-	&s2i2_gen3_info,
-	&s4i4_gen3_info,
-	&s8i6_gen3_info,
-	&s18i8_gen3_info,
-	&s18i20_gen3_info,
+	{ USB_ID(0x1235, 0x8211), &solo_gen3_info },
+	{ USB_ID(0x1235, 0x8210), &s2i2_gen3_info },
+	{ USB_ID(0x1235, 0x8212), &s4i4_gen3_info },
+	{ USB_ID(0x1235, 0x8213), &s8i6_gen3_info },
+	{ USB_ID(0x1235, 0x8214), &s18i8_gen3_info },
+	{ USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
 
 	/* Supported Clarett+ devices */
-	&clarett_8pre_info,
+	{ USB_ID(0x1235, 0x820c), &clarett_8pre_info },
 
 	/* End of list */
-	NULL
+	{ 0, NULL },
 };
 
 /* get the starting port index number for a given port type/direction */
@@ -4072,17 +4055,17 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
 
 static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
 {
-	const struct scarlett2_device_info **info = scarlett2_devices;
+	const struct scarlett2_device_entry *entry = scarlett2_devices;
 	int err;
 
-	/* Find device in scarlett2_devices */
-	while (*info && (*info)->usb_id != mixer->chip->usb_id)
-		info++;
-	if (!*info)
+	/* Find entry in scarlett2_devices */
+	while (entry->usb_id && entry->usb_id != mixer->chip->usb_id)
+		entry++;
+	if (!entry->usb_id)
 		return -EINVAL;
 
 	/* Initialise private data */
-	err = scarlett2_init_private(mixer, *info);
+	err = scarlett2_init_private(mixer, entry->info);
 	if (err < 0)
 		return err;
 
Signature · 1 line
2.42.0
author maintainer
#83 lore raw

PATCH 83/491 ASoC: SOF: ipc4: handle EXCEPTION_CAUGHT notification from firmware

In reply to Greg Kroah-Hartman

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

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

From: Rander Wang <[email protected]>

[ Upstream commit c1c48fd6bbe788458e3685fea74bdb3cb148ff93 ]

Driver will receive exception IPC message and process it by snd_sof_dsp_panic.

---
 sound/soc/sof/ipc4.c | 3 +++
 1 file changed, 3 insertions(+)
sound/soc/sof/ipc4.c +3 -0
index ab6eddd91bb77..1b09496733fb8 100644
@@ -614,6 +614,9 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev)
 	case SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS:
 		sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary));
 		break;
+	case SOF_IPC4_NOTIFY_EXCEPTION_CAUGHT:
+		snd_sof_dsp_panic(sdev, 0, true);
+		break;
 	default:
 		dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n",
 			ipc4_msg->primary, ipc4_msg->extension);
Signature · 1 line
2.42.0
author maintainer
#84 lore raw

PATCH 84/491 RDMA/hfi1: Use FIELD_GET() to extract Link Width

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit 8bf7187d978610b9e327a3d92728c8864a575ebd ]

Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of custom masking and shifting, and remove extract_width() which only wraps that FIELD_GET().

---
 drivers/infiniband/hw/hfi1/pcie.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/infiniband/hw/hfi1/pcie.c +2 -7
index 08732e1ac9662..c132a9c073bff 100644
@@ -3,6 +3,7 @@
  * Copyright(c) 2015 - 2019 Intel Corporation.
  */
 
+#include <linux/bitfield.h>
 #include <linux/pci.h>
 #include <linux/io.h>
 #include <linux/delay.h>
@@ -210,12 +211,6 @@ static u32 extract_speed(u16 linkstat)
 	return speed;
 }
 
-/* return the PCIe link speed from the given link status */
-static u32 extract_width(u16 linkstat)
-{
-	return (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
-}
-
 /* read the link status and set dd->{lbus_width,lbus_speed,lbus_info} */
 static void update_lbus_info(struct hfi1_devdata *dd)
 {
@@ -228,7 +223,7 @@ static void update_lbus_info(struct hfi1_devdata *dd)
 		return;
 	}
 
-	dd->lbus_width = extract_width(linkstat);
+	dd->lbus_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat);
 	dd->lbus_speed = extract_speed(linkstat);
 	snprintf(dd->lbus_info, sizeof(dd->lbus_info),
 		 "PCIe,%uMHz,x%u", dd->lbus_speed, dd->lbus_width);
Signature · 1 line
2.42.0
author maintainer
#85 lore raw

PATCH 85/491 scsi: hisi_sas: Set debugfs_dir pointer to NULL after removing debugfs

In reply to Greg Kroah-Hartman

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

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

From: Yihang Li <[email protected]>

[ Upstream commit 6de426f9276c448e2db7238911c97fb157cb23be ]

If init debugfs failed during device registration due to memory allocation failure, debugfs_remove_recursive() is called, after which debugfs_dir is not set to NULL. debugfs_remove_recursive() will be called again during device removal. As a result, illegal pointer is accessed.

[ 1665.467244] hisi_sas_v3_hw 0000:b4:02.0: failed to init debugfs!
...
[ 1669.836708] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0
[ 1669.872669] pc : down_write+0x24/0x70
[ 1669.876315] lr : down_write+0x1c/0x70
[ 1669.879961] sp : ffff000036f53a30
[ 1669.883260] x29: ffff000036f53a30 x28: ffffa027c31549f8
[ 1669.888547] x27: ffffa027c3140000 x26: 0000000000000000
[ 1669.893834] x25: ffffa027bf37c270 x24: ffffa027bf37c270
[ 1669.899122] x23: ffff0000095406b8 x22: ffff0000095406a8
[ 1669.904408] x21: 0000000000000000 x20: ffffa027bf37c310
[ 1669.909695] x19: 00000000000000a0 x18: ffff8027dcd86f10
[ 1669.914982] x17: 0000000000000000 x16: 0000000000000000
[ 1669.920268] x15: 0000000000000000 x14: ffffa0274014f870
[ 1669.925555] x13: 0000000000000040 x12: 0000000000000228
[ 1669.930842] x11: 0000000000000020 x10: 0000000000000bb0
[ 1669.936129] x9 : ffff000036f537f0 x8 : ffff80273088ca10
[ 1669.941416] x7 : 000000000000001d x6 : 00000000ffffffff
[ 1669.946702] x5 : ffff000008a36310 x4 : ffff80273088be00
[ 1669.951989] x3 : ffff000009513e90 x2 : 0000000000000000
[ 1669.957276] x1 : 00000000000000a0 x0 : ffffffff00000001
[ 1669.962563] Call trace:
[ 1669.965000]  down_write+0x24/0x70
[ 1669.968301]  debugfs_remove_recursive+0x5c/0x1b0
[ 1669.972905]  hisi_sas_debugfs_exit+0x24/0x30 [hisi_sas_main]
[ 1669.978541]  hisi_sas_v3_remove+0x130/0x150 [hisi_sas_v3_hw]
[ 1669.984175]  pci_device_remove+0x48/0xd8
[ 1669.988082]  device_release_driver_internal+0x1b4/0x250
[ 1669.993282]  device_release_driver+0x28/0x38
[ 1669.997534]  pci_stop_bus_device+0x84/0xb8
[ 1670.001611]  pci_stop_and_remove_bus_device_locked+0x24/0x40
[ 1670.007244]  remove_store+0xfc/0x140
[ 1670.010802]  dev_attr_store+0x44/0x60
[ 1670.014448]  sysfs_kf_write+0x58/0x80
[ 1670.018095]  kernfs_fop_write+0xe8/0x1f0
[ 1670.022000]  __vfs_write+0x60/0x190
[ 1670.025472]  vfs_write+0xac/0x1c0
[ 1670.028771]  ksys_write+0x6c/0xd8
[ 1670.032071]  __arm64_sys_write+0x24/0x30
[ 1670.035977]  el0_svc_common+0x78/0x130
[ 1670.039710]  el0_svc_handler+0x38/0x78
[ 1670.043442]  el0_svc+0x8/0xc

To fix this, set debugfs_dir to NULL after debugfs_remove_recursive().

---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +7 -6
index 2f33e6b4a92fb..9285ae508afa6 100644
@@ -4861,6 +4861,12 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
 	hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
 }
 
+static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
+{
+	debugfs_remove_recursive(hisi_hba->debugfs_dir);
+	hisi_hba->debugfs_dir = NULL;
+}
+
 static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
 {
 	struct device *dev = hisi_hba->dev;
@@ -4884,18 +4890,13 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
 
 	for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
 		if (debugfs_alloc_v3_hw(hisi_hba, i)) {
-			debugfs_remove_recursive(hisi_hba->debugfs_dir);
+			debugfs_exit_v3_hw(hisi_hba);
 			dev_dbg(dev, "failed to init debugfs!\n");
 			break;
 		}
 	}
 }
 
-static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
-{
-	debugfs_remove_recursive(hisi_hba->debugfs_dir);
-}
-
 static int
 hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
Signature · 1 line
2.42.0
author maintainer
#86 lore raw

PATCH 86/491 scsi: ibmvfc: Remove BUG_ON in the case of an empty event pool

In reply to Greg Kroah-Hartman

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

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

From: Tyrel Datwyler <[email protected]>

[ Upstream commit b39f2d10b86d0af353ea339e5815820026bca48f ]

In practice the driver should never send more commands than are allocated to a queue's event pool. In the unlikely event that this happens, the code asserts a BUG_ON, and in the case that the kernel is not configured to crash on panic returns a junk event pointer from the empty event list causing things to spiral from there. This BUG_ON is a historical artifact of the ibmvfc driver first being upstreamed, and it is well known now that the use of BUG_ON is bad practice except in the most unrecoverable scenario. There is nothing about this scenario that prevents the driver from recovering and carrying on.

Remove the BUG_ON in question from ibmvfc_get_event() and return a NULL pointer in the case of an empty event pool. Update all call sites to ibmvfc_get_event() to check for a NULL pointer and perfrom the appropriate failure or recovery action.

---
 drivers/scsi/ibmvscsi/ibmvfc.c | 124 ++++++++++++++++++++++++++++++++-
 1 file changed, 122 insertions(+), 2 deletions(-)
drivers/scsi/ibmvscsi/ibmvfc.c +122 -2
index 470e8e6c41b62..c98346e464b48 100644
@@ -1518,7 +1518,11 @@ static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_queue *queue)
 	unsigned long flags;
 
 	spin_lock_irqsave(&queue->l_lock, flags);
-	BUG_ON(list_empty(&queue->free));
+	if (list_empty(&queue->free)) {
+		ibmvfc_log(queue->vhost, 4, "empty event pool on queue:%ld\n", queue->hwq_id);
+		spin_unlock_irqrestore(&queue->l_lock, flags);
+		return NULL;
+	}
 	evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list);
 	atomic_set(&evt->free, 0);
 	list_del(&evt->queue_list);
@@ -1947,9 +1951,15 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 	if (vhost->using_channels) {
 		scsi_channel = hwq % vhost->scsi_scrqs.active_queues;
 		evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[scsi_channel]);
+		if (!evt)
+			return SCSI_MLQUEUE_HOST_BUSY;
+
 		evt->hwq = hwq % vhost->scsi_scrqs.active_queues;
-	} else
+	} else {
 		evt = ibmvfc_get_event(&vhost->crq);
+		if (!evt)
+			return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT);
 	evt->cmnd = cmnd;
@@ -2037,6 +2047,11 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job)
 
 	vhost->aborting_passthru = 1;
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return -ENOMEM;
+	}
+
 	ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT);
 
 	tmf = &evt->iu.tmf;
@@ -2095,6 +2110,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id)
 		goto unlock_out;
 
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		rc = -ENOMEM;
+		goto unlock_out;
+	}
 	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
 	plogi = &evt->iu.plogi;
 	memset(plogi, 0, sizeof(*plogi));
@@ -2213,6 +2232,11 @@ static int ibmvfc_bsg_request(struct bsg_job *job)
 	}
 
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		rc = -ENOMEM;
+		goto out;
+	}
 	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
 	mad = &evt->iu.passthru;
 
@@ -2301,6 +2325,11 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
 		else
 			evt = ibmvfc_get_event(&vhost->crq);
 
+		if (!evt) {
+			spin_unlock_irqrestore(vhost->host->host_lock, flags);
+			return -ENOMEM;
+		}
+
 		ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
 		tmf = ibmvfc_init_vfc_cmd(evt, sdev);
 		iu = ibmvfc_get_fcp_iu(vhost, tmf);
@@ -2504,6 +2533,8 @@ static struct ibmvfc_event *ibmvfc_init_tmf(struct ibmvfc_queue *queue,
 	struct ibmvfc_tmf *tmf;
 
 	evt = ibmvfc_get_event(queue);
+	if (!evt)
+		return NULL;
 	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
 
 	tmf = &evt->iu.tmf;
@@ -2560,6 +2591,11 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type)
 
 		if (found_evt && vhost->logged_in) {
 			evt = ibmvfc_init_tmf(&queues[i], sdev, type);
+			if (!evt) {
+				spin_unlock(queues[i].q_lock);
+				spin_unlock_irqrestore(vhost->host->host_lock, flags);
+				return -ENOMEM;
+			}
 			evt->sync_iu = &queues[i].cancel_rsp;
 			ibmvfc_send_event(evt, vhost, default_timeout);
 			list_add_tail(&evt->cancel, &cancelq);
@@ -2773,6 +2809,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
 
 	if (vhost->state == IBMVFC_ACTIVE) {
 		evt = ibmvfc_get_event(&vhost->crq);
+		if (!evt) {
+			spin_unlock_irqrestore(vhost->host->host_lock, flags);
+			return -ENOMEM;
+		}
 		ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
 		tmf = ibmvfc_init_vfc_cmd(evt, sdev);
 		iu = ibmvfc_get_fcp_iu(vhost, tmf);
@@ -4031,6 +4071,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt)
 
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 	vhost->discovery_threads++;
 	ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT);
 	evt->tgt = tgt;
@@ -4138,6 +4184,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
 	kref_get(&tgt->kref);
 	tgt->logo_rcvd = 0;
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 	vhost->discovery_threads++;
 	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
 	ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT);
@@ -4214,6 +4266,8 @@ static struct ibmvfc_event *__ibmvfc_tgt_get_implicit_logout_evt(struct ibmvfc_t
 
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt)
+		return NULL;
 	ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT);
 	evt->tgt = tgt;
 	mad = &evt->iu.implicit_logout;
@@ -4241,6 +4295,13 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
 	vhost->discovery_threads++;
 	evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt,
 						   ibmvfc_tgt_implicit_logout_done);
+	if (!evt) {
+		vhost->discovery_threads--;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 
 	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
 	if (ibmvfc_send_event(evt, vhost, default_timeout)) {
@@ -4380,6 +4441,12 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt)
 
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 	vhost->discovery_threads++;
 	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
 	ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT);
@@ -4546,6 +4613,14 @@ static void ibmvfc_adisc_timeout(struct timer_list *t)
 	vhost->abort_threads++;
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		tgt_err(tgt, "Failed to get cancel event for ADISC.\n");
+		vhost->abort_threads--;
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return;
+	}
 	ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT);
 
 	evt->tgt = tgt;
@@ -4596,6 +4671,12 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
 
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 	vhost->discovery_threads++;
 	ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT);
 	evt->tgt = tgt;
@@ -4699,6 +4780,12 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt)
 
 	kref_get(&tgt->kref);
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		__ibmvfc_reset_host(vhost);
+		return;
+	}
 	vhost->discovery_threads++;
 	evt->tgt = tgt;
 	ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT);
@@ -4871,6 +4958,13 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost)
 {
 	struct ibmvfc_discover_targets *mad;
 	struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq);
+	int level = IBMVFC_DEFAULT_LOG_LEVEL;
+
+	if (!evt) {
+		ibmvfc_log(vhost, level, "Discover Targets failed: no available events\n");
+		ibmvfc_hard_reset_host(vhost);
+		return;
+	}
 
 	ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT);
 	mad = &evt->iu.discover_targets;
@@ -4948,8 +5042,15 @@ static void ibmvfc_channel_setup(struct ibmvfc_host *vhost)
 	struct ibmvfc_scsi_channels *scrqs = &vhost->scsi_scrqs;
 	unsigned int num_channels =
 		min(vhost->client_scsi_channels, vhost->max_vios_scsi_channels);
+	int level = IBMVFC_DEFAULT_LOG_LEVEL;
 	int i;
 
+	if (!evt) {
+		ibmvfc_log(vhost, level, "Channel Setup failed: no available events\n");
+		ibmvfc_hard_reset_host(vhost);
+		return;
+	}
+
 	memset(setup_buf, 0, sizeof(*setup_buf));
 	if (num_channels == 0)
 		setup_buf->flags = cpu_to_be32(IBMVFC_CANCEL_CHANNELS);
@@ -5011,6 +5112,13 @@ static void ibmvfc_channel_enquiry(struct ibmvfc_host *vhost)
 {
 	struct ibmvfc_channel_enquiry *mad;
 	struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq);
+	int level = IBMVFC_DEFAULT_LOG_LEVEL;
+
+	if (!evt) {
+		ibmvfc_log(vhost, level, "Channel Enquiry failed: no available events\n");
+		ibmvfc_hard_reset_host(vhost);
+		return;
+	}
 
 	ibmvfc_init_event(evt, ibmvfc_channel_enquiry_done, IBMVFC_MAD_FORMAT);
 	mad = &evt->iu.channel_enquiry;
@@ -5133,6 +5241,12 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost)
 	struct ibmvfc_npiv_login_mad *mad;
 	struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq);
 
+	if (!evt) {
+		ibmvfc_dbg(vhost, "NPIV Login failed: no available events\n");
+		ibmvfc_hard_reset_host(vhost);
+		return;
+	}
+
 	ibmvfc_gather_partition_info(vhost);
 	ibmvfc_set_login_info(vhost);
 	ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT);
@@ -5197,6 +5311,12 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *vhost)
 	struct ibmvfc_event *evt;
 
 	evt = ibmvfc_get_event(&vhost->crq);
+	if (!evt) {
+		ibmvfc_dbg(vhost, "NPIV Logout failed: no available events\n");
+		ibmvfc_hard_reset_host(vhost);
+		return;
+	}
+
 	ibmvfc_init_event(evt, ibmvfc_npiv_logout_done, IBMVFC_MAD_FORMAT);
 
 	mad = &evt->iu.npiv_logout;
Signature · 1 line
2.42.0
author maintainer
#87 lore raw

PATCH 87/491 fs/jfs: Add check for negative db_l2nbperpage

In reply to Greg Kroah-Hartman

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

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

From: Juntong Deng <[email protected]>

[ Upstream commit 525b861a008143048535011f3816d407940f4bfa ]

l2nbperpage is log2(number of blks per page), and the minimum legal value should be 0, not negative.

In the case of l2nbperpage being negative, an error will occur when subsequently used as shift exponent.

Syzbot reported this bug:

UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:799:12

shift exponent -16777216 is negative

---
 fs/jfs/jfs_dmap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +2 -1
index 88afd108c2dd2..3a1842348112d 100644
@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap)
 	bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
 
 	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
-	if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) {
+	if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE ||
+		bmp->db_l2nbperpage < 0) {
 		err = -EINVAL;
 		goto err_release_metapage;
 	}
Signature · 1 line
2.42.0
author maintainer
#88 lore raw

PATCH 88/491 fs/jfs: Add validity check for db_maxag and db_agpref

In reply to Greg Kroah-Hartman

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

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

From: Juntong Deng <[email protected]>

[ Upstream commit 64933ab7b04881c6c18b21ff206c12278341c72e ]

Both db_maxag and db_agpref are used as the index of the db_agfree array, but there is currently no validity check for db_maxag and db_agpref, which can lead to errors.

The following is related bug reported by Syzbot:

UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:639:20

index 7936 is out of range for type 'atomic_t[128]'

Add checking that the values of db_maxag and db_agpref are valid indexes for the db_agfree array.

---
 fs/jfs/jfs_dmap.c | 6 ++++++
 1 file changed, 6 insertions(+)
fs/jfs/jfs_dmap.c +6 -0
index 3a1842348112d..4d59373f9e6c9 100644
@@ -195,6 +195,12 @@ int dbMount(struct inode *ipbmap)
 	bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
 	bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
 	bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
+	if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 ||
+		bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) {
+		err = -EINVAL;
+		goto err_release_metapage;
+	}
+
 	bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
 	bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
 	bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
Signature · 1 line
2.42.0
author maintainer
#89 lore raw

PATCH 89/491 jfs: fix array-index-out-of-bounds in dbFindLeaf

In reply to Greg Kroah-Hartman

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

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

From: Manas Ghandat <[email protected]>

[ Upstream commit 22cad8bc1d36547cdae0eef316c47d917ce3147c ]

Currently while searching for dmtree_t for sufficient free blocks there is an array out of bounds while getting element in tp->dm_stree. To add the required check for out of bound we first need to determine the type of dmtree. Thus added an extra parameter to dbFindLeaf so that the type of tree can be determined and the required check can be applied.

---
 fs/jfs/jfs_dmap.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
fs/jfs/jfs_dmap.c +10 -4
index 4d59373f9e6c9..11c77757ead9e 100644
@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno,
 static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
 static int dbFindBits(u32 word, int l2nb);
 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
+static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl);
 static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		      int nblocks);
 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
@@ -1717,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 		 * dbFindLeaf() returns the index of the leaf at which
 		 * free space was found.
 		 */
-		rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx);
+		rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true);
 
 		/* release the buffer.
 		 */
@@ -1964,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp,
 	 * free space.  if sufficient free space is found, dbFindLeaf()
 	 * returns the index of the leaf at which free space was found.
 	 */
-	if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
+	if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false))
 		return -ENOSPC;
 
 	if (leafidx < 0)
@@ -2928,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
  *	leafidx	- return pointer to be set to the index of the leaf
  *		  describing at least l2nb free blocks if sufficient
  *		  free blocks are found.
+ *	is_ctl	- determines if the tree is of type ctl
  *
  * RETURN VALUES:
  *	0	- success
  *	-ENOSPC	- insufficient free blocks.
  */
-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
+static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
 {
 	int ti, n = 0, k, x = 0;
+	int max_size;
+
+	max_size = is_ctl ? CTLTREESIZE : TREESIZE;
 
 	/* first check the root of the tree to see if there is
 	 * sufficient free space.
@@ -2956,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 			/* sufficient free space found.  move to the next
 			 * level (or quit if this is the last level).
 			 */
+			if (x + n > max_size)
+				return -ENOSPC;
 			if (l2nb <= tp->dmt_stree[x + n])
 				break;
 		}
Signature · 1 line
2.42.0
author maintainer
#90 lore raw

PATCH 90/491 jfs: fix array-index-out-of-bounds in diAlloc

In reply to Greg Kroah-Hartman

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

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

From: Manas Ghandat <[email protected]>

[ Upstream commit 05d9ea1ceb62a55af6727a69269a4fd310edf483 ]

Currently there is not check against the agno of the iag while allocating new inodes to avoid fragmentation problem. Added the check which is required.

---
 fs/jfs/jfs_imap.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/jfs/jfs_imap.c +4 -1
index 6fb28572cb2c6..34f1358264e23 100644
@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
 int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 {
 	int rc, ino, iagno, addext, extno, bitno, sword;
-	int nwords, rem, i, agno;
+	int nwords, rem, i, agno, dn_numag;
 	u32 mask, inosmap, extsmap;
 	struct inode *ipimap;
 	struct metapage *mp;
@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 
 	/* get the ag number of this iag */
 	agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb));
+	dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag;
+	if (agno < 0 || agno > dn_numag)
+		return -EIO;
 
 	if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
 		/*
Signature · 1 line
2.42.0
author maintainer
#91 lore raw

PATCH 91/491 HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround

In reply to Greg Kroah-Hartman

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

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

From: Mikhail Khvainitski <[email protected]>

[ Upstream commit 46a0a2c96f0f47628190f122c2e3d879e590bcbe ]

Built-in firmware of cptkbd handles scrolling by itself (when middle button is pressed) but with issues: it does not support horizontal and hi-res scrolling and upon middle button release it sends middle button click even if there was a scrolling event. Commit 3cb5ff0220e3 ("HID:
lenovo: Hide middle-button press until release") workarounds last issue but it's impossible to workaround scrolling-related issues without firmware modification.

Likely, Dennis Schneider has reverse engineered the firmware and provided an instruction on how to patch it [1]. However, aforementioned workaround prevents userspace (libinput) from knowing exact moment when middle button has been pressed down and performing "On-Button scrolling". This commit detects correctly-behaving patched firmware if cursor movement events has been received during middle button being pressed and stops applying workaround for this device.

---
 drivers/hid/hid-lenovo.c | 68 ++++++++++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 23 deletions(-)
drivers/hid/hid-lenovo.c +45 -23
index 44763c0da4441..9c1181313e44d 100644
@@ -51,7 +51,12 @@ struct lenovo_drvdata {
 	int select_right;
 	int sensitivity;
 	int press_speed;
-	u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */
+	/* 0: Up
+	 * 1: Down (undecided)
+	 * 2: Scrolling
+	 * 3: Patched firmware, disable workaround
+	 */
+	u8 middlebutton_state;
 	bool fn_lock;
 };
 
@@ -668,31 +673,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
 {
 	struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
 
-	/* "wheel" scroll events */
-	if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
-			usage->code == REL_HWHEEL)) {
-		/* Scroll events disable middle-click event */
-		cptkbd_data->middlebutton_state = 2;
-		return 0;
-	}
+	if (cptkbd_data->middlebutton_state != 3) {
+		/* REL_X and REL_Y events during middle button pressed
+		 * are only possible on patched, bug-free firmware
+		 * so set middlebutton_state to 3
+		 * to never apply workaround anymore
+		 */
+		if (cptkbd_data->middlebutton_state == 1 &&
+				usage->type == EV_REL &&
+				(usage->code == REL_X || usage->code == REL_Y)) {
+			cptkbd_data->middlebutton_state = 3;
+			/* send middle button press which was hold before */
+			input_event(field->hidinput->input,
+				EV_KEY, BTN_MIDDLE, 1);
+			input_sync(field->hidinput->input);
+		}
 
-	/* Middle click events */
-	if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) {
-		if (value == 1) {
-			cptkbd_data->middlebutton_state = 1;
-		} else if (value == 0) {
-			if (cptkbd_data->middlebutton_state == 1) {
-				/* No scrolling inbetween, send middle-click */
-				input_event(field->hidinput->input,
-					EV_KEY, BTN_MIDDLE, 1);
-				input_sync(field->hidinput->input);
-				input_event(field->hidinput->input,
-					EV_KEY, BTN_MIDDLE, 0);
-				input_sync(field->hidinput->input);
+		/* "wheel" scroll events */
+		if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
+				usage->code == REL_HWHEEL)) {
+			/* Scroll events disable middle-click event */
+			cptkbd_data->middlebutton_state = 2;
+			return 0;
+		}
+
+		/* Middle click events */
+		if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) {
+			if (value == 1) {
+				cptkbd_data->middlebutton_state = 1;
+			} else if (value == 0) {
+				if (cptkbd_data->middlebutton_state == 1) {
+					/* No scrolling inbetween, send middle-click */
+					input_event(field->hidinput->input,
+						EV_KEY, BTN_MIDDLE, 1);
+					input_sync(field->hidinput->input);
+					input_event(field->hidinput->input,
+						EV_KEY, BTN_MIDDLE, 0);
+					input_sync(field->hidinput->input);
+				}
+				cptkbd_data->middlebutton_state = 0;
 			}
-			cptkbd_data->middlebutton_state = 0;
+			return 1;
 		}
-		return 1;
 	}
 
 	if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) {
Signature · 1 line
2.42.0
author maintainer
#92 lore raw

PATCH 92/491 ARM: 9320/1: fix stack depot IRQ stack filter

In reply to Greg Kroah-Hartman

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

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

From: Vincent Whitchurch <[email protected]>

[ Upstream commit b0150014878c32197cfa66e3e2f79e57f66babc0 ]

Place IRQ handlers such as gic_handle_irq() in the irqentry section even if FUNCTION_GRAPH_TRACER is not enabled. Without this, the stack depot's filter_irq_stacks() does not correctly filter out IRQ stacks in those configurations, which hampers deduplication and eventually leads to "Stack depot reached limit capacity" splats with KASAN.

A similar fix was done for arm64 in commit f6794950f0e5ba37e3bbed ("arm64: set __exception_irq_entry with __irq_entry as a default").

---
 arch/arm/include/asm/exception.h | 4 ----
 1 file changed, 4 deletions(-)
arch/arm/include/asm/exception.h +0 -4
index 58e039a851af0..3c82975d46db3 100644
@@ -10,10 +10,6 @@
 
 #include <linux/interrupt.h>
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 #define __exception_irq_entry	__irq_entry
-#else
-#define __exception_irq_entry
-#endif
 
 #endif /* __ASM_ARM_EXCEPTION_H */
Signature · 1 line
2.42.0
author maintainer
#93 lore raw

PATCH 93/491 ALSA: hda: Fix possible null-ptr-deref when assigning a stream

In reply to Greg Kroah-Hartman

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

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

From: Cezary Rojewski <[email protected]>

[ Upstream commit f93dc90c2e8ed664985e366aa6459ac83cdab236 ]

While AudioDSP drivers assign streams exclusively of HOST or LINK type, nothing blocks a user to attempt to assign a COUPLED stream. As supplied substream instance may be a stub, what is the case when code-loading, such scenario ends with null-ptr-deref.

---
 sound/hda/hdac_stream.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
sound/hda/hdac_stream.c +4 -2
index 2633a4bb1d85d..214a0680524b0 100644
@@ -354,8 +354,10 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
 	struct hdac_stream *res = NULL;
 
 	/* make a non-zero unique key for the substream */
-	int key = (substream->pcm->device << 16) | (substream->number << 2) |
-		(substream->stream + 1);
+	int key = (substream->number << 2) | (substream->stream + 1);
+
+	if (substream->pcm)
+		key |= (substream->pcm->device << 16);
 
 	spin_lock_irq(&bus->reg_lock);
 	list_for_each_entry(azx_dev, &bus->stream_list, list) {
Signature · 1 line
2.42.0
author maintainer
#94 lore raw

PATCH 94/491 gpiolib: of: Add quirk for mt2701-cs42448 ASoC sound

In reply to Greg Kroah-Hartman

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

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

From: Linus Walleij <[email protected]>

[ Upstream commit 9e189e80dcb68528dea9e061d9704993f98cb84f ]

These gpio names are due to old DT bindings not following the "-gpio"/"-gpios" conventions. Handle it using a quirk so the driver can just look up the GPIOs.

---
 drivers/gpio/gpiolib-of.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpio/gpiolib-of.c +4 -0
index 1436cdb5fa268..219bf8a82d8f9 100644
@@ -496,6 +496,10 @@ static struct gpio_desc *of_find_gpio_rename(struct device_node *np,
 #if IS_ENABLED(CONFIG_SND_SOC_CS42L56)
 		{ "reset",	"cirrus,gpio-nreset",	"cirrus,cs42l56" },
 #endif
+#if IS_ENABLED(CONFIG_SND_SOC_MT2701_CS42448)
+		{ "i2s1-in-sel-gpio1",	NULL,	"mediatek,mt2701-cs42448-machine" },
+		{ "i2s1-in-sel-gpio2",	NULL,	"mediatek,mt2701-cs42448-machine" },
+#endif
 #if IS_ENABLED(CONFIG_SND_SOC_TLV320AIC3X)
 		{ "reset",	"gpio-reset",	"ti,tlv320aic3x" },
 		{ "reset",	"gpio-reset",	"ti,tlv320aic33" },
Signature · 1 line
2.42.0
author maintainer
#95 lore raw

PATCH 95/491 PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit 759574abd78e3b47ec45bbd31a64e8832cf73f97 ]

Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of custom masking and shifting.

Similarly, change custom code that misleadingly used PCI_EXP_LNKSTA_NLW_SHIFT to prepare value for PCI_EXP_LNKCAP write to use FIELD_PREP() with correct field define (PCI_EXP_LNKCAP_MLW).

---
 drivers/pci/controller/dwc/pcie-tegra194.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/pci/controller/dwc/pcie-tegra194.c +4 -5
index ccff8cde5cff6..07cb0818a5138 100644
@@ -9,6 +9,7 @@
  * Author: Vidya Sagar <[email protected]>
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
@@ -347,8 +348,7 @@ static void apply_bad_link_workaround(struct dw_pcie_rp *pp)
 	 */
 	val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA);
 	if (val & PCI_EXP_LNKSTA_LBMS) {
-		current_link_width = (val & PCI_EXP_LNKSTA_NLW) >>
-				     PCI_EXP_LNKSTA_NLW_SHIFT;
+		current_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val);
 		if (pcie->init_link_width > current_link_width) {
 			dev_warn(pci->dev, "PCIe link is bad, width reduced\n");
 			val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base +
@@ -761,8 +761,7 @@ static void tegra_pcie_enable_system_interrupts(struct dw_pcie_rp *pp)
 
 	val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base +
 				  PCI_EXP_LNKSTA);
-	pcie->init_link_width = (val_w & PCI_EXP_LNKSTA_NLW) >>
-				PCI_EXP_LNKSTA_NLW_SHIFT;
+	pcie->init_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val_w);
 
 	val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base +
 				  PCI_EXP_LNKCTL);
@@ -921,7 +920,7 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp)
 	/* Configure Max lane width from DT */
 	val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP);
 	val &= ~PCI_EXP_LNKCAP_MLW;
-	val |= (pcie->num_lanes << PCI_EXP_LNKSTA_NLW_SHIFT);
+	val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, pcie->num_lanes);
 	dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, val);
 
 	/* Clear Slot Clock Configuration bit if SRNS configuration */
Signature · 1 line
2.42.0
author maintainer
#96 lore raw

PATCH 96/491 PCI: mvebu: Use FIELD_PREP() with Link Width

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit 408599ec561ad5862cda4f107626009f6fa97a74 ]

mvebu_pcie_setup_hw() setups the Maximum Link Width field in the Link Capabilities registers using an open-coded variant of FIELD_PREP() with a literal in shift. Improve readability by using FIELD_PREP(PCI_EXP_LNKCAP_MLW, ...).

---
 drivers/pci/controller/pci-mvebu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/pci-mvebu.c +1 -1
index c931b1b07b1d8..0cacd58f6c05e 100644
@@ -265,7 +265,7 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	 */
 	lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
 	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
-	lnkcap |= (port->is_x4 ? 4 : 1) << 4;
+	lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, port->is_x4 ? 4 : 1);
 	mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
 
 	/* Disable Root Bridge I/O space, memory space and bus mastering. */
Signature · 1 line
2.42.0
author maintainer
#97 lore raw

PATCH 97/491 atm: iphase: Do PCI error checks on own line

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit c28742447ca9879b52fbaf022ad844f0ffcd749c ]

In get_esi() PCI errors are checked inside line-split "if" conditions (in addition to the file not following the coding style). To make the code in get_esi() more readable, fix the coding style and use the usual error handling pattern with a separate variable.

In addition, initialization of 'error' variable at declaration is not needed.

No functional changes intended.

---
 drivers/atm/iphase.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/atm/iphase.c +11 -9
index 3241486869530..9bba8f280a4d4 100644
@@ -2291,19 +2291,21 @@ static int get_esi(struct atm_dev *dev)
 static int reset_sar(struct atm_dev *dev)  
 {  
 	IADEV *iadev;  
-	int i, error = 1;  
+	int i, error;
 	unsigned int pci[64];  
 	  
 	iadev = INPH_IA_DEV(dev);  
-	for(i=0; i<64; i++)  
-	  if ((error = pci_read_config_dword(iadev->pci,  
-				i*4, &pci[i])) != PCIBIOS_SUCCESSFUL)  
-  	      return error;  
+	for (i = 0; i < 64; i++) {
+		error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]);
+		if (error != PCIBIOS_SUCCESSFUL)
+			return error;
+	}
 	writel(0, iadev->reg+IPHASE5575_EXT_RESET);  
-	for(i=0; i<64; i++)  
-	  if ((error = pci_write_config_dword(iadev->pci,  
-					i*4, pci[i])) != PCIBIOS_SUCCESSFUL)  
-	    return error;  
+	for (i = 0; i < 64; i++) {
+		error = pci_write_config_dword(iadev->pci, i * 4, pci[i]);
+		if (error != PCIBIOS_SUCCESSFUL)
+			return error;
+	}
 	udelay(5);  
 	return 0;  
 }  
Signature · 1 line
2.42.0
author maintainer
#98 lore raw

PATCH 98/491 PCI: Do error check on own line to split long "if" conditions

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit d15f18053e5cc5576af9e7eef0b2a91169b6326d ]

Placing PCI error code check inside "if" condition usually results in need to split lines. Combined with additional conditions the "if" condition becomes messy.

Convert to the usual error handling pattern with an additional variable to improve code readability. In addition, reverse the logic in pci_find_vsec_capability() to get rid of &&.

No functional changes intended.

---
 drivers/pci/pci.c    | 9 ++++++---
 drivers/pci/probe.c  | 6 +++---
 drivers/pci/quirks.c | 6 +++---
 3 files changed, 12 insertions(+), 9 deletions(-)
drivers/pci/pci.c +6 -3
index 702fe577089b4..3cd907eb67b74 100644
@@ -732,15 +732,18 @@ u16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap)
 {
 	u16 vsec = 0;
 	u32 header;
+	int ret;
 
 	if (vendor != dev->vendor)
 		return 0;
 
 	while ((vsec = pci_find_next_ext_capability(dev, vsec,
 						     PCI_EXT_CAP_ID_VNDR))) {
-		if (pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER,
-					  &header) == PCIBIOS_SUCCESSFUL &&
-		    PCI_VNDR_HEADER_ID(header) == cap)
+		ret = pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header);
+		if (ret != PCIBIOS_SUCCESSFUL)
+			continue;
+
+		if (PCI_VNDR_HEADER_ID(header) == cap)
 			return vsec;
 	}
 
drivers/pci/probe.c +3 -3
index 24a83cf5ace8c..cd08d39fdb1ff 100644
@@ -1653,15 +1653,15 @@ static void pci_set_removable(struct pci_dev *dev)
 static bool pci_ext_cfg_is_aliased(struct pci_dev *dev)
 {
 #ifdef CONFIG_PCI_QUIRKS
-	int pos;
+	int pos, ret;
 	u32 header, tmp;
 
 	pci_read_config_dword(dev, PCI_VENDOR_ID, &header);
 
 	for (pos = PCI_CFG_SPACE_SIZE;
 	     pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) {
-		if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL
-		    || header != tmp)
+		ret = pci_read_config_dword(dev, pos, &tmp);
+		if ((ret != PCIBIOS_SUCCESSFUL) || (header != tmp))
 			return false;
 	}
 
drivers/pci/quirks.c +3 -3
index eb65170b97ff0..e8a051e2d8140 100644
@@ -5383,7 +5383,7 @@ int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
  */
 static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
 {
-	int pos, i = 0;
+	int pos, i = 0, ret;
 	u8 next_cap;
 	u16 reg16, *cap;
 	struct pci_cap_saved_state *state;
@@ -5429,8 +5429,8 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
 		pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
 
 		pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE;
-		if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) !=
-		    PCIBIOS_SUCCESSFUL || (status == 0xffffffff))
+		ret = pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status);
+		if ((ret != PCIBIOS_SUCCESSFUL) || (PCI_POSSIBLE_ERROR(status)))
 			pdev->cfg_size = PCI_CFG_SPACE_SIZE;
 
 		if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP))
Signature · 1 line
2.42.0
author maintainer
#99 lore raw

PATCH 99/491 scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup()

In reply to Greg Kroah-Hartman

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

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

From: Wenchao Hao <[email protected]>

[ Upstream commit 4df105f0ce9f6f30cda4e99f577150d23f0c9c5f ]

fc_lport_ptp_setup() did not check the return value of fc_rport_create() which can return NULL and would cause a NULL pointer dereference. Address this issue by checking return value of fc_rport_create() and log error message on fc_rport_create() failed.

---
 drivers/scsi/libfc/fc_lport.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/scsi/libfc/fc_lport.c +6 -0
index 9c02c9523c4d4..ab06e9aeb613e 100644
@@ -241,6 +241,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
 	}
 	mutex_lock(&lport->disc.disc_mutex);
 	lport->ptp_rdata = fc_rport_create(lport, remote_fid);
+	if (!lport->ptp_rdata) {
+		printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n",
+			lport->port_id);
+		mutex_unlock(&lport->disc.disc_mutex);
+		return;
+	}
 	kref_get(&lport->ptp_rdata->kref);
 	lport->ptp_rdata->ids.port_name = remote_wwpn;
 	lport->ptp_rdata->ids.node_name = remote_wwnn;
Signature · 1 line
2.42.0
author maintainer
#100 lore raw

PATCH 100/491 PCI: Use FIELD_GET() to extract Link Width

In reply to Greg Kroah-Hartman

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

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

From: Ilpo Järvinen <[email protected]>

[ Upstream commit d1f9b39da4a5347150246871325190018cda8cb3 ]

Use FIELD_GET() to extract PCIe Negotiated and Maximum Link Width fields instead of custom masking and shifting.

---
 drivers/pci/pci-sysfs.c | 5 ++---
 drivers/pci/pci.c       | 5 ++---
 2 files changed, 4 insertions(+), 6 deletions(-)
drivers/pci/pci-sysfs.c +2 -3
index ab32a91f287b4..4473773dc2af4 100644
@@ -12,7 +12,7 @@
  * Modeled after usb's driverfs.c
  */
 
-
+#include <linux/bitfield.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
@@ -230,8 +230,7 @@ static ssize_t current_link_width_show(struct device *dev,
 	if (err)
 		return -EINVAL;
 
-	return sysfs_emit(buf, "%u\n",
-		(linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+	return sysfs_emit(buf, "%u\n", FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat));
 }
 static DEVICE_ATTR_RO(current_link_width);
 
drivers/pci/pci.c +2 -3
index 3cd907eb67b74..2c5662d43df1b 100644
@@ -6255,8 +6255,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
 		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
 
 		next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
-		next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
-			PCI_EXP_LNKSTA_NLW_SHIFT;
+		next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
 
 		next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);
 
@@ -6328,7 +6327,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev)
 
 	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
 	if (lnkcap)
-		return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4;
+		return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap);
 
 	return PCIE_LNK_WIDTH_UNKNOWN;
 }
Signature · 1 line
2.42.0
author maintainer
#101 lore raw

PATCH 101/491 PCI: Extract ATS disabling to a helper function

In reply to Greg Kroah-Hartman

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

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

From: Bartosz Pawlowski <[email protected]>

[ Upstream commit f18b1137d38c091cc8c16365219f0a1d4a30b3d1 ]

Introduce quirk_no_ats() helper function to provide a standard way to disable ATS capability in PCI quirks.

---
 drivers/pci/quirks.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/pci/quirks.c +9 -7
index e8a051e2d8140..b82f94af2fae4 100644
@@ -5507,6 +5507,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags);
 
 #ifdef CONFIG_PCI_ATS
+static void quirk_no_ats(struct pci_dev *pdev)
+{
+	pci_info(pdev, "disabling ATS\n");
+	pdev->ats_cap = 0;
+}
+
 /*
  * Some devices require additional driver setup to enable ATS.  Don't use
  * ATS for those devices as ATS will be enabled before the driver has had a
@@ -5520,14 +5526,10 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev)
 		    (pdev->subsystem_device == 0xce19 ||
 		     pdev->subsystem_device == 0xcc10 ||
 		     pdev->subsystem_device == 0xcc08))
-			goto no_ats;
-		else
-			return;
+			quirk_no_ats(pdev);
+	} else {
+		quirk_no_ats(pdev);
 	}
-
-no_ats:
-	pci_info(pdev, "disabling ATS\n");
-	pdev->ats_cap = 0;
 }
 
 /* AMD Stoney platform GPU */
Signature · 1 line
2.42.0
author maintainer
#102 lore raw

PATCH 102/491 PCI: Disable ATS for specific Intel IPU E2000 devices

In reply to Greg Kroah-Hartman

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

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

From: Bartosz Pawlowski <[email protected]>

[ Upstream commit a18615b1cfc04f00548c60eb9a77e0ce56e848fd ]

Due to a hardware issue in A and B steppings of Intel IPU E2000, it expects wrong endianness in ATS invalidation message body. This problem can lead to outdated translations being returned as valid and finally cause system instability.

To prevent such issues, add quirk_intel_e2000_no_ats() to disable ATS for vulnerable IPU E2000 devices.

---
 drivers/pci/quirks.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/pci/quirks.c +19 -0
index b82f94af2fae4..9fa3c9225bb30 100644
@@ -5552,6 +5552,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats);
 /* AMD Raven platform iGPU */
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats);
+
+/*
+ * Intel IPU E2000 revisions before C0 implement incorrect endianness
+ * in ATS Invalidate Request message body. Disable ATS for those devices.
+ */
+static void quirk_intel_e2000_no_ats(struct pci_dev *pdev)
+{
+	if (pdev->revision < 0x20)
+		quirk_no_ats(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
 #endif /* CONFIG_PCI_ATS */
 
 /* Freescale PCIe doesn't support MSI in RC mode */
Signature · 1 line
2.42.0
author maintainer
#103 lore raw

PATCH 103/491 PCI: dwc: Add dw_pcie_link_set_max_link_width()

In reply to Greg Kroah-Hartman

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

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

From: Yoshihiro Shimoda <[email protected]>

[ Upstream commit a9a1bcba90254975d4adbcca53f720318cf81c0c ]

This is a preparation before adding the Max-Link-width capability setup which would in its turn complete the max-link-width setup procedure defined by Synopsys in the HW-manual.

Seeing there is a max-link-speed setup method defined in the DW PCIe core driver it would be good to have a similar function for the link width setup.

That's why we need to define a dedicated function first from already implemented but incomplete link-width setting up code.

---
 drivers/pci/controller/dwc/pcie-designware.c | 86 ++++++++++----------
 1 file changed, 41 insertions(+), 45 deletions(-)
drivers/pci/controller/dwc/pcie-designware.c +41 -45
index 1f2ee71da4da2..d14b4da700eaf 100644
@@ -732,6 +732,46 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen)
 
 }
 
+static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
+{
+	u32 lwsc, plc;
+
+	if (!num_lanes)
+		return;
+
+	/* Set the number of lanes */
+	plc = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
+	plc &= ~PORT_LINK_FAST_LINK_MODE;
+	plc &= ~PORT_LINK_MODE_MASK;
+
+	/* Set link width speed control register */
+	lwsc = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+	lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK;
+	switch (num_lanes) {
+	case 1:
+		plc |= PORT_LINK_MODE_1_LANES;
+		lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES;
+		break;
+	case 2:
+		plc |= PORT_LINK_MODE_2_LANES;
+		lwsc |= PORT_LOGIC_LINK_WIDTH_2_LANES;
+		break;
+	case 4:
+		plc |= PORT_LINK_MODE_4_LANES;
+		lwsc |= PORT_LOGIC_LINK_WIDTH_4_LANES;
+		break;
+	case 8:
+		plc |= PORT_LINK_MODE_8_LANES;
+		lwsc |= PORT_LOGIC_LINK_WIDTH_8_LANES;
+		break;
+	default:
+		dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes);
+		return;
+	}
+	dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, plc);
+	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, lwsc);
+}
+
 void dw_pcie_iatu_detect(struct dw_pcie *pci)
 {
 	int max_region, ob, ib;
@@ -1013,49 +1053,5 @@ void dw_pcie_setup(struct dw_pcie *pci)
 	val |= PORT_LINK_DLL_LINK_EN;
 	dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
 
-	if (!pci->num_lanes) {
-		dev_dbg(pci->dev, "Using h/w default number of lanes\n");
-		return;
-	}
-
-	/* Set the number of lanes */
-	val &= ~PORT_LINK_FAST_LINK_MODE;
-	val &= ~PORT_LINK_MODE_MASK;
-	switch (pci->num_lanes) {
-	case 1:
-		val |= PORT_LINK_MODE_1_LANES;
-		break;
-	case 2:
-		val |= PORT_LINK_MODE_2_LANES;
-		break;
-	case 4:
-		val |= PORT_LINK_MODE_4_LANES;
-		break;
-	case 8:
-		val |= PORT_LINK_MODE_8_LANES;
-		break;
-	default:
-		dev_err(pci->dev, "num-lanes %u: invalid value\n", pci->num_lanes);
-		return;
-	}
-	dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
-
-	/* Set link width speed control register */
-	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
-	val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
-	switch (pci->num_lanes) {
-	case 1:
-		val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
-		break;
-	case 2:
-		val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
-		break;
-	case 4:
-		val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
-		break;
-	case 8:
-		val |= PORT_LOGIC_LINK_WIDTH_8_LANES;
-		break;
-	}
-	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+	dw_pcie_link_set_max_link_width(pci, pci->num_lanes);
 }
Signature · 1 line
2.42.0
author maintainer
#104 lore raw

PATCH 104/491 PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling

In reply to Greg Kroah-Hartman

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

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

From: Yoshihiro Shimoda <[email protected]>

[ Upstream commit 89db0793c9f2da265ecb6c1681f899d9af157f37 ]

Update dw_pcie_link_set_max_link_width() to set PCI_EXP_LNKCAP_MLW.

In accordance with the DW PCIe RC/EP HW manuals [1,2,3,...] aside with the PORT_LINK_CTRL_OFF.LINK_CAPABLE and GEN2_CTRL_OFF.NUM_OF_LANES[8:0] field there is another one which needs to be updated.

It's LINK_CAPABILITIES_REG.PCIE_CAP_MAX_LINK_WIDTH. If it isn't done at the very least the maximum link-width capability CSR won't expose the actual maximum capability.

[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,

    Version 4.60a, March 2015, p.1032
[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
    Version 4.70a, March 2016, p.1065
[3] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
    Version 4.90a, March 2016, p.1057
...
[X] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint,
      Version 5.40a, March 2019, p.1396
[X+1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
      Version 5.40a, March 2019, p.1266
---
 drivers/pci/controller/dwc/pcie-designware.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware.c +8 -1
index d14b4da700eaf..8e6f6ac42dc96 100644
@@ -734,7 +734,8 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen)
 
 static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
 {
-	u32 lwsc, plc;
+	u32 lnkcap, lwsc, plc;
+	u8 cap;
 
 	if (!num_lanes)
 		return;
@@ -770,6 +771,12 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
 	}
 	dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, plc);
 	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, lwsc);
+
+	cap = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+	lnkcap = dw_pcie_readl_dbi(pci, cap + PCI_EXP_LNKCAP);
+	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
+	lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, num_lanes);
+	dw_pcie_writel_dbi(pci, cap + PCI_EXP_LNKCAP, lnkcap);
 }
 
 void dw_pcie_iatu_detect(struct dw_pcie *pci)
Signature · 1 line
2.42.0
author maintainer
#105 lore raw

PATCH 105/491 misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller

In reply to Greg Kroah-Hartman

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

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

From: Yoshihiro Shimoda <[email protected]>

[ Upstream commit 6c4b39937f4e65688ea294725ae432b2565821ff ]

Add Renesas R8A779F0 in pci_device_id table so that pci-epf-test can be used for testing PCIe EP on R-Car S4-8.

---
 drivers/misc/pci_endpoint_test.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/misc/pci_endpoint_test.c +4 -0
index 7e1acc68d4359..af519088732d9 100644
@@ -82,6 +82,7 @@
 #define PCI_DEVICE_ID_RENESAS_R8A774B1		0x002b
 #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
 #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
+#define PCI_DEVICE_ID_RENESAS_R8A779F0		0x0031
 
 static DEFINE_IDA(pci_endpoint_test_ida);
 
@@ -991,6 +992,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1),},
 	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0),},
 	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1),},
+	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A779F0),
+	  .driver_data = (kernel_ulong_t)&default_data,
+	},
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
 	  .driver_data = (kernel_ulong_t)&j721e_data,
 	},
Signature · 1 line
2.42.0
author maintainer
#106 lore raw

PATCH 106/491 PCI: Use FIELD_GET() in Sapphire RX 5600 XT Pulse quirk

In reply to Greg Kroah-Hartman

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

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

From: Bjorn Helgaas <[email protected]>

[ Upstream commit 04e82fa5951ca66495d7b05665eff673aa3852b4 ]

Use FIELD_GET() to remove dependences on the field position, i.e., the shift value. No functional change intended.

Separate because this isn't as trivial as the other FIELD_GET() changes.

See 907830b0fc9e ("PCI: Add a REBAR size quirk for Sapphire RX 5600 XT Pulse")

---
 drivers/pci/pci.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pci/pci.c +4 -4
index 2c5662d43df1b..a7793abdd74ee 100644
@@ -3746,14 +3746,14 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
 		return 0;
 
 	pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
-	cap &= PCI_REBAR_CAP_SIZES;
+	cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap);
 
 	/* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
 	if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
-	    bar == 0 && cap == 0x7000)
-		cap = 0x3f000;
+	    bar == 0 && cap == 0x700)
+		return 0x3f00;
 
-	return cap >> 4;
+	return cap;
 }
 EXPORT_SYMBOL(pci_rebar_get_possible_sizes);
 
Signature · 1 line
2.42.0
author maintainer
#107 lore raw

PATCH 107/491 ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Tab 3 Pro YT3-X90 quirk

In reply to Greg Kroah-Hartman

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

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

From: Hans de Goede <[email protected]>

[ Upstream commit 2cb54788393134d8174ee594002baae3ce52c61e ]

The Lenovo Yoga Tab 3 Pro YT3-X90 x86 tablet, which ships with Android with a custom kernel as factory OS, does not list the used WM5102 codec inside its DSDT.

Workaround this with a new snd_soc_acpi_intel_baytrail_machines[] entry which matches on the SST id instead of the codec id like nocodec does, combined with using a machine_quirk callback which returns NULL on other machines to skip the new entry on other machines.

---
 .../intel/common/soc-acpi-intel-cht-match.c   | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)
sound/soc/intel/common/soc-acpi-intel-cht-match.c +43 -0
index cdcbf04b8832f..5e2ec60e2954b 100644
@@ -75,6 +75,39 @@ static struct snd_soc_acpi_mach *cht_ess8316_quirk(void *arg)
 	return arg;
 }
 
+/*
+ * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS has a buggy DSDT
+ * with the coded not being listed at all.
+ */
+static const struct dmi_system_id lenovo_yoga_tab3_x90[] = {
+	{
+		/* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
+		},
+	},
+	{ }
+};
+
+static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = {
+	.id = "10WM5102",
+	.drv_name = "bytcr_wm5102",
+	.fw_filename = "intel/fw_sst_22a8.bin",
+	.board = "bytcr_wm5102",
+	.sof_tplg_filename = "sof-cht-wm5102.tplg",
+};
+
+static struct snd_soc_acpi_mach *lenovo_yt3_x90_quirk(void *arg)
+{
+	if (dmi_check_system(lenovo_yoga_tab3_x90))
+		return &cht_lenovo_yoga_tab3_x90_mach;
+
+	/* Skip wildcard match snd_soc_acpi_intel_cherrytrail_machines[] entry */
+	return NULL;
+}
+
 static const struct snd_soc_acpi_codecs rt5640_comp_ids = {
 	.num_codecs = 2,
 	.codecs = { "10EC5640", "10EC3276" },
@@ -175,6 +208,16 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_cherrytrail_machines[] = {
 		.drv_name = "sof_pcm512x",
 		.sof_tplg_filename = "sof-cht-src-50khz-pcm512x.tplg",
 	},
+	/*
+	 * Special case for the Lenovo Yoga Tab 3 Pro YT3-X90 where the DSDT
+	 * misses the codec. Match on the SST id instead, lenovo_yt3_x90_quirk()
+	 * will return a YT3 specific mach or NULL when called on other hw,
+	 * skipping this entry.
+	 */
+	{
+		.id = "808622A8",
+		.machine_quirk = lenovo_yt3_x90_quirk,
+	},
 
 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
 	/*
Signature · 1 line
2.42.0
author maintainer
#108 lore raw

PATCH 108/491 crypto: hisilicon/qm - prevent soft lockup in receive loop

In reply to Greg Kroah-Hartman

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

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

From: Longfang Liu <[email protected]>

[ Upstream commit 33fc506d2ac514be1072499a263c3bff8c7c95a0 ]

In the scenario where the accelerator business is fully loaded. When the workqueue receiving messages and performing callback processing, there are a large number of messages that need to be received, and there are continuously messages that have been processed and need to be received.
This will cause the receive loop here to be locked for a long time. This scenario will cause watchdog timeout problems on OS with kernel preemption turned off.

The error logs:

watchdog: BUG: soft lockup - CPU#23 stuck for 23s! [kworker/u262:1:1407]
[ 1461.978428][   C23] Call trace:
[ 1461.981890][   C23]  complete+0x8c/0xf0
[ 1461.986031][   C23]  kcryptd_async_done+0x154/0x1f4 [dm_crypt]
[ 1461.992154][   C23]  sec_skcipher_callback+0x7c/0xf4 [hisi_sec2]
[ 1461.998446][   C23]  sec_req_cb+0x104/0x1f4 [hisi_sec2]
[ 1462.003950][   C23]  qm_poll_req_cb+0xcc/0x150 [hisi_qm]
[ 1462.009531][   C23]  qm_work_process+0x60/0xc0 [hisi_qm]
[ 1462.015101][   C23]  process_one_work+0x1c4/0x470
[ 1462.020052][   C23]  worker_thread+0x150/0x3c4
[ 1462.024735][   C23]  kthread+0x108/0x13c
[ 1462.028889][   C23]  ret_from_fork+0x10/0x18

Therefore, it is necessary to add an actively scheduled operation in the while loop to prevent this problem.
After adding it, no matter whether the OS turns on or off the kernel preemption function. Neither will cause watchdog timeout issues.

---
 drivers/crypto/hisilicon/qm.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/crypto/hisilicon/qm.c +2 -0
index ba4852744c052..2aec118ba6775 100644
@@ -845,6 +845,8 @@ static void qm_poll_req_cb(struct hisi_qp *qp)
 		qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ,
 		      qp->qp_status.cq_head, 0);
 		atomic_dec(&qp->qp_status.used);
+
+		cond_resched();
 	}
 
 	/* set c_flag */
Signature · 1 line
2.42.0
author maintainer
#109 lore raw

PATCH 109/491 HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W

In reply to Greg Kroah-Hartman

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

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

From: Jiri Kosina <[email protected]>

[ Upstream commit 62cc9c3cb3ec1bf31cc116146185ed97b450836a ]

This device needs ALWAYS_POLL quirk, otherwise it keeps reconnecting indefinitely.

---
 drivers/hid/hid-ids.h    | 1 +
 drivers/hid/hid-quirks.c | 1 +
 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
index cc0d0186a0d95..fafc40ecfd200 100644
@@ -366,6 +366,7 @@
 
 #define USB_VENDOR_ID_DELL				0x413c
 #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE	0x301a
+#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W		0x4503
 
 #define USB_VENDOR_ID_DELORME		0x1163
 #define USB_DEVICE_ID_DELORME_EARTHMATE	0x0100
drivers/hid/hid-quirks.c +1 -0
index 3983b4f282f8f..5a48fcaa32f00 100644
@@ -66,6 +66,7 @@ static const struct hid_device_id hid_quirks[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT },
Signature · 1 line
2.42.0
author maintainer
#110 lore raw

PATCH 110/491 exfat: support handle zero-size directory

In reply to Greg Kroah-Hartman

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

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

From: Yuezhang Mo <[email protected]>

[ Upstream commit dab48b8f2fe7264d51ec9eed0adea0fe3c78830a ]

After repairing a corrupted file system with exfatprogs' fsck.exfat, zero-size directories may result. It is also possible to create zero-size directories in other exFAT implementation, such as Paragon ufsd dirver.

As described in the specification, the lower directory size limits is 0 bytes.

Without this commit, sub-directories and files cannot be created under a zero-size directory, and it cannot be removed.

---
 fs/exfat/namei.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)
fs/exfat/namei.c +22 -7
index e0ff9d156f6f5..43774693f65f5 100644
@@ -351,14 +351,20 @@ static int exfat_find_empty_entry(struct inode *inode,
 		if (exfat_check_max_dentries(inode))
 			return -ENOSPC;
 
-		/* we trust p_dir->size regardless of FAT type */
-		if (exfat_find_last_cluster(sb, p_dir, &last_clu))
-			return -EIO;
-
 		/*
 		 * Allocate new cluster to this directory
 		 */
-		exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags);
+		if (ei->start_clu != EXFAT_EOF_CLUSTER) {
+			/* we trust p_dir->size regardless of FAT type */
+			if (exfat_find_last_cluster(sb, p_dir, &last_clu))
+				return -EIO;
+
+			exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags);
+		} else {
+			/* This directory is empty */
+			exfat_chain_set(&clu, EXFAT_EOF_CLUSTER, 0,
+					ALLOC_NO_FAT_CHAIN);
+		}
 
 		/* allocate a cluster */
 		ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode));
@@ -368,6 +374,11 @@ static int exfat_find_empty_entry(struct inode *inode,
 		if (exfat_zeroed_cluster(inode, clu.dir))
 			return -EIO;
 
+		if (ei->start_clu == EXFAT_EOF_CLUSTER) {
+			ei->start_clu = clu.dir;
+			p_dir->dir = clu.dir;
+		}
+
 		/* append to the FAT chain */
 		if (clu.flags != p_dir->flags) {
 			/* no-fat-chain bit is disabled,
@@ -646,7 +657,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
 	info->type = exfat_get_entry_type(ep);
 	info->attr = le16_to_cpu(ep->dentry.file.attr);
 	info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
-	if ((info->type == TYPE_FILE) && (info->size == 0)) {
+	if (info->size == 0) {
 		info->flags = ALLOC_NO_FAT_CHAIN;
 		info->start_clu = EXFAT_EOF_CLUSTER;
 	} else {
@@ -890,6 +901,9 @@ static int exfat_check_dir_empty(struct super_block *sb,
 
 	dentries_per_clu = sbi->dentries_per_clu;
 
+	if (p_dir->dir == EXFAT_EOF_CLUSTER)
+		return 0;
+
 	exfat_chain_dup(&clu, p_dir);
 
 	while (clu.dir != EXFAT_EOF_CLUSTER) {
@@ -1257,7 +1271,8 @@ static int __exfat_rename(struct inode *old_parent_inode,
 		}
 
 		/* Free the clusters if new_inode is a dir(as if exfat_rmdir) */
-		if (new_entry_type == TYPE_DIR) {
+		if (new_entry_type == TYPE_DIR &&
+		    new_ei->start_clu != EXFAT_EOF_CLUSTER) {
 			/* new_ei, new_clu_to_free */
 			struct exfat_chain new_clu_to_free;
 
Signature · 1 line
2.42.0
author maintainer
#111 lore raw

PATCH 111/491 mfd: intel-lpss: Add Intel Lunar Lake-M PCI IDs

In reply to Greg Kroah-Hartman

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

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

From: Jarkko Nikula <[email protected]>

[ Upstream commit e53b22b10c6e0de0cf2a03a92b18fdad70f266c7 ]

Add Intel Lunar Lake-M SoC PCI IDs.

---
 drivers/mfd/intel-lpss-pci.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/mfd/intel-lpss-pci.c +13 -0
index 699f44ffff0e4..ae5759200622c 100644
@@ -561,6 +561,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
 	{ PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa3e3), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa3e6), (kernel_ulong_t)&spt_uart_info },
+	/* LNL-M */
+	{ PCI_VDEVICE(INTEL, 0xa825), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xa826), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0xa850), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa851), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa852), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xa878), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa879), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa87a), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa87b), (kernel_ulong_t)&ehl_i2c_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
Signature · 1 line
2.42.0
author maintainer
#112 lore raw

PATCH 112/491 iio: adc: stm32-adc: harden against NULL pointer deref in stm32_adc_probe()

In reply to Greg Kroah-Hartman

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

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

From: Zhang Shurong <[email protected]>

[ Upstream commit 3a23b384e7e3d64d5587ad10729a34d4f761517e ]

of_match_device() may fail and returns a NULL pointer.

In practice there is no known reasonable way to trigger this, but in case one is added in future, harden the code by adding the check

---
 drivers/iio/adc/stm32-adc-core.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/iio/adc/stm32-adc-core.c +7 -2
index 48f02dcc81c1b..70011fdbf5f63 100644
@@ -706,6 +706,8 @@ static int stm32_adc_probe(struct platform_device *pdev)
 	struct stm32_adc_priv *priv;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *of_id;
+
 	struct resource *res;
 	u32 max_rate;
 	int ret;
@@ -718,8 +720,11 @@ static int stm32_adc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, &priv->common);
 
-	priv->cfg = (const struct stm32_adc_priv_cfg *)
-		of_match_device(dev->driver->of_match_table, dev)->data;
+	of_id = of_match_device(dev->driver->of_match_table, dev);
+	if (!of_id)
+		return -ENODEV;
+
+	priv->cfg = (const struct stm32_adc_priv_cfg *)of_id->data;
 	priv->nb_adc_max = priv->cfg->num_adcs;
 	spin_lock_init(&priv->common.lock);
 
Signature · 1 line
2.42.0
author maintainer
#113 lore raw

PATCH 113/491 thunderbolt: Apply USB 3.x bandwidth quirk only in software connection manager

In reply to Greg Kroah-Hartman

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

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

From: Mika Westerberg <[email protected]>

[ Upstream commit 0c35ac18256942e66d8dab6ca049185812e60c69 ]

This is not needed when firmware connection manager is run so limit this to software connection manager.

---
 drivers/thunderbolt/quirks.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/thunderbolt/quirks.c +3 -0
index 488138a28ae13..e6bfa63b40aee 100644
@@ -31,6 +31,9 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw)
 {
 	struct tb_port *port;
 
+	if (tb_switch_is_icm(sw))
+		return;
+
 	tb_switch_for_each_port(sw, port) {
 		if (!tb_port_is_usb3_down(port))
 			continue;
Signature · 1 line
2.42.0
author maintainer
#114 lore raw

PATCH 114/491 tty: vcc: Add check for kstrdup() in vcc_probe()

In reply to Greg Kroah-Hartman

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

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

From: Yi Yang <[email protected]>

[ Upstream commit d81ffb87aaa75f842cd7aa57091810353755b3e6 ]

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

---
 drivers/tty/vcc.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/tty/vcc.c +13 -3
index 34ba6e54789a7..b8b832c75b856 100644
@@ -579,18 +579,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 		return -ENOMEM;
 
 	name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL);
+	if (!name) {
+		rv = -ENOMEM;
+		goto free_port;
+	}
 
 	rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions,
 			     ARRAY_SIZE(vcc_versions), NULL, name);
 	if (rv)
-		goto free_port;
+		goto free_name;
 
 	port->vio.debug = vcc_dbg_vio;
 	vcc_ldc_cfg.debug = vcc_dbg_ldc;
 
 	rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port);
 	if (rv)
-		goto free_port;
+		goto free_name;
 
 	spin_lock_init(&port->lock);
 
@@ -624,6 +628,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 		goto unreg_tty;
 	}
 	port->domain = kstrdup(domain, GFP_KERNEL);
+	if (!port->domain) {
+		rv = -ENOMEM;
+		goto unreg_tty;
+	}
+
 
 	mdesc_release(hp);
 
@@ -653,8 +662,9 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	vcc_table_remove(port->index);
 free_ldc:
 	vio_ldc_free(&port->vio);
-free_port:
+free_name:
 	kfree(name);
+free_port:
 	kfree(port);
 
 	return rv;
Signature · 1 line
2.42.0
author maintainer
#115 lore raw

PATCH 115/491 dt-bindings: phy: qcom,snps-eusb2-repeater: Add magic tuning overrides

In reply to Greg Kroah-Hartman

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

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

From: Konrad Dybcio <[email protected]>

[ Upstream commit c20b59b2996c89c4f072c3312e6210528a298330 ]

The EUSB2 repeater requires some alterations to its init sequence, depending on board design.

Add support for making the necessary changes to that sequence to make USB functional on SM8550-based Xperia 1 V.

They all have lackluster description due to lack of information.

---
 .../phy/qcom,snps-eusb2-repeater.yaml         | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)
Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml +21 -0
index 083fda530b484..828650d4c4b09 100644
@@ -27,6 +27,27 @@ properties:
 
   vdd3-supply: true
 
+  qcom,tune-usb2-disc-thres:
+    $ref: /schemas/types.yaml#/definitions/uint8
+    description: High-Speed disconnect threshold
+    minimum: 0
+    maximum: 7
+    default: 0
+
+  qcom,tune-usb2-amplitude:
+    $ref: /schemas/types.yaml#/definitions/uint8
+    description: High-Speed trasmit amplitude
+    minimum: 0
+    maximum: 15
+    default: 8
+
+  qcom,tune-usb2-preem:
+    $ref: /schemas/types.yaml#/definitions/uint8
+    description: High-Speed TX pre-emphasis tuning
+    minimum: 0
+    maximum: 7
+    default: 5
+
 required:
   - compatible
   - reg
Signature · 1 line
2.42.0
author maintainer
#116 lore raw

PATCH 116/491 phy: qualcomm: phy-qcom-eusb2-repeater: Use regmap_fields

In reply to Greg Kroah-Hartman

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

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

From: Konrad Dybcio <[email protected]>

[ Upstream commit 4ba2e52718c0ce4ece6a269bec84319c355c030f ]

Switch to regmap_fields, so that the values written into registers are sanitized by their explicit sizes and the different registers are structured in an iterable object to make external changes to the init sequence simpler.

---
 .../phy/qualcomm/phy-qcom-eusb2-repeater.c    | 91 +++++++++++++------
 1 file changed, 61 insertions(+), 30 deletions(-)
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +61 -30
index 90f8543ba265b..b20b805414a2a 100644
@@ -29,14 +29,42 @@
 #define EUSB2_TUNE_SQUELCH_U		0x54
 #define EUSB2_TUNE_USB2_PREEM		0x57
 
-#define QCOM_EUSB2_REPEATER_INIT_CFG(o, v)	\
+#define QCOM_EUSB2_REPEATER_INIT_CFG(r, v)	\
 	{					\
-		.offset = o,			\
+		.reg = r,			\
 		.val = v,			\
 	}
 
+enum reg_fields {
+	F_TUNE_USB2_PREEM,
+	F_TUNE_SQUELCH_U,
+	F_TUNE_IUSB2,
+	F_NUM_TUNE_FIELDS,
+
+	F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS,
+	F_FORCE_EN_5,
+
+	F_EN_CTL1,
+
+	F_RPTR_STATUS,
+	F_NUM_FIELDS,
+};
+
+static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = {
+	[F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2),
+	[F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2),
+	[F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3),
+
+	[F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7),
+	[F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7),
+
+	[F_EN_CTL1] = REG_FIELD(EUSB2_EN_CTL1, 0, 7),
+
+	[F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7),
+};
+
 struct eusb2_repeater_init_tbl {
-	unsigned int offset;
+	unsigned int reg;
 	unsigned int val;
 };
 
@@ -49,11 +77,10 @@ struct eusb2_repeater_cfg {
 
 struct eusb2_repeater {
 	struct device *dev;
-	struct regmap *regmap;
+	struct regmap_field *regs[F_NUM_FIELDS];
 	struct phy *phy;
 	struct regulator_bulk_data *vregs;
 	const struct eusb2_repeater_cfg *cfg;
-	u16 base;
 	enum phy_mode mode;
 };
 
@@ -62,9 +89,9 @@ static const char * const pm8550b_vreg_l[] = {
 };
 
 static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = {
-	QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_IUSB2, 0x8),
-	QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_SQUELCH_U, 0x3),
-	QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_USB2_PREEM, 0x5),
+	QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_IUSB2, 0x8),
+	QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_SQUELCH_U, 0x3),
+	QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_USB2_PREEM, 0x5),
 };
 
 static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = {
@@ -94,7 +121,6 @@ static int eusb2_repeater_init(struct phy *phy)
 {
 	struct eusb2_repeater *rptr = phy_get_drvdata(phy);
 	const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl;
-	int num = rptr->cfg->init_tbl_num;
 	u32 val;
 	int ret;
 	int i;
@@ -103,17 +129,14 @@ static int eusb2_repeater_init(struct phy *phy)
 	if (ret)
 		return ret;
 
-	regmap_update_bits(rptr->regmap, rptr->base + EUSB2_EN_CTL1,
-			   EUSB2_RPTR_EN, EUSB2_RPTR_EN);
+	regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN);
 
-	for (i = 0; i < num; i++)
-		regmap_update_bits(rptr->regmap,
-				   rptr->base + init_tbl[i].offset,
-				   init_tbl[i].val, init_tbl[i].val);
+	for (i = 0; i < rptr->cfg->init_tbl_num; i++)
+		regmap_field_update_bits(rptr->regs[init_tbl[i].reg],
+					 init_tbl[i].val, init_tbl[i].val);
 
-	ret = regmap_read_poll_timeout(rptr->regmap,
-				       rptr->base + EUSB2_RPTR_STATUS, val,
-				       val & RPTR_OK, 10, 5);
+	ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS],
+					     val, val & RPTR_OK, 10, 5);
 	if (ret)
 		dev_err(rptr->dev, "initialization timed-out\n");
 
@@ -132,10 +155,10 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 		 * per eUSB 1.2 Spec. Below implement software workaround until
 		 * PHY and controller is fixing seen observation.
 		 */
-		regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5,
-				   F_CLK_19P2M_EN, F_CLK_19P2M_EN);
-		regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5,
-				   V_CLK_19P2M_EN, V_CLK_19P2M_EN);
+		regmap_field_update_bits(rptr->regs[F_FORCE_EN_5],
+					 F_CLK_19P2M_EN, F_CLK_19P2M_EN);
+		regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5],
+					 V_CLK_19P2M_EN, V_CLK_19P2M_EN);
 		break;
 	case PHY_MODE_USB_DEVICE:
 		/*
@@ -144,10 +167,10 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 		 * repeater doesn't clear previous value due to shared
 		 * regulators (say host <-> device mode switch).
 		 */
-		regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5,
-				   F_CLK_19P2M_EN, 0);
-		regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5,
-				   V_CLK_19P2M_EN, 0);
+		regmap_field_update_bits(rptr->regs[F_FORCE_EN_5],
+					 F_CLK_19P2M_EN, 0);
+		regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5],
+					 V_CLK_19P2M_EN, 0);
 		break;
 	default:
 		return -EINVAL;
@@ -176,8 +199,9 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct device_node *np = dev->of_node;
+	struct regmap *regmap;
+	int i, ret;
 	u32 res;
-	int ret;
 
 	rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL);
 	if (!rptr)
@@ -190,15 +214,22 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	if (!rptr->cfg)
 		return -EINVAL;
 
-	rptr->regmap = dev_get_regmap(dev->parent, NULL);
-	if (!rptr->regmap)
+	regmap = dev_get_regmap(dev->parent, NULL);
+	if (!regmap)
 		return -ENODEV;
 
 	ret = of_property_read_u32(np, "reg", &res);
 	if (ret < 0)
 		return ret;
 
-	rptr->base = res;
+	for (i = 0; i < F_NUM_FIELDS; i++)
+		eusb2_repeater_tune_reg_fields[i].reg += res;
+
+	ret = devm_regmap_field_bulk_alloc(dev, regmap, rptr->regs,
+					   eusb2_repeater_tune_reg_fields,
+					   F_NUM_FIELDS);
+	if (ret)
+		return ret;
 
 	ret = eusb2_repeater_init_vregs(rptr);
 	if (ret < 0) {
Signature · 1 line
2.42.0