Skip to contentSkip to conversation

5.17.4-rc1 review

PATCH In review Greg Kroah-Hartman 12 participants 232 messages Apr 18, 2022 – Apr 20, 2022 Page 1 of 2

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.17.4-rc1 review

This is the start of the stable review cycle for the 5.17.4 release. There are 219 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 Wed, 20 Apr 2022 12:11:14 +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/v5.x/stable-review/patch-5.17.4-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-5.17.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 5.17.4-rc1

Duoming Zhou <[email protected]>
ax25: Fix UAF bugs in ax25 timers

Steven Price <[email protected]>
cpu/hotplug: Remove the 'cpu' member of cpuhp_cpu_state

Matt Roper <[email protected]>
drm/i915: Sunset igpu legacy mmap support based on GRAPHICS_VER_FULL

Marco Elver <[email protected]>
mm, kfence: support kmem_dump_obj() for KFENCE objects

Chao Gao <[email protected]>
dma-direct: avoid redundant memory sync for swiotlb

Anna-Maria Behnsen <[email protected]>
timers: Fix warning condition in __run_timers()

Dongjin Yang <[email protected]>
dt-bindings: net: snps: remove duplicate name

Martin Povišer <[email protected]>
i2c: pasemi: Wait for write xfers to finish

Sherry Sun <[email protected]>
dt-bindings: memory: snps,ddrc-3.80a compatible also need interrupts

Nadav Amit <[email protected]>
smp: Fix offline cpu check in flush_smp_call_function_queue()

Vladimir Oltean <[email protected]>
Revert "net: dsa: setup master before ports"

Andy Shevchenko <[email protected]>
i2c: dev: check return value when calling dev_set_name()

Mikulas Patocka <[email protected]>
dm integrity: fix memory corruption when tag_size is less than digest size

Alexander Sverdlin <[email protected]>
ep93xx: clock: Fix UAF in ep93xx_clk_register_gate()

Nathan Chancellor <[email protected]>
ARM: davinci: da850-evm: Avoid NULL pointer dereference

Paul Gortmaker <[email protected]>
tick/nohz: Use WARN_ON_ONCE() to prevent console saturation

Rei Yamamoto <[email protected]>
genirq/affinity: Consider that CPUs on nodes can be unbalanced

Pawan Gupta <[email protected]>
x86/tsx: Disable TSX development mode at boot

Pawan Gupta <[email protected]>
x86/tsx: Use MSR_TSX_CTRL to clear CPUID bits

Tomasz Moń <[email protected]>
drm/amdgpu: Enable gfxoff quirk on MacBook Pro

Melissa Wen <[email protected]>
drm/amd/display: don't ignore alpha property on pre-multiplied mode

Nicolas Dichtel <[email protected]>
ipv6: fix panic when forwarding a pkt with no in6 dev

Johannes Berg <[email protected]>

    nl80211: correctly check NL80211_ATTR_REG_ALPHA2 size

Fabio M. De Francesco <[email protected]>
ALSA: pcm: Test for "silence" field in struct "pcm_format_data"

Tao Jin <[email protected]>
ALSA: hda/realtek: add quirk for Lenovo Thinkpad X12 speakers

Tim Crawford <[email protected]>
ALSA: hda/realtek: Add quirk for Clevo PD50PNT

Naohiro Aota <[email protected]>
btrfs: mark resumed async balance as writing

Jia-Ju Bai <[email protected]>
btrfs: fix root ref counts in error handling in btrfs_get_root_ref

Naohiro Aota <[email protected]>
btrfs: zoned: activate block group only for extent allocation

Toke Høiland-Jørgensen <[email protected]>
ath9k: Fix usage of driver-private space in tx_info

Toke Høiland-Jørgensen <[email protected]>
ath9k: Properly clear TX status area before reporting to mac80211

Bartosz Golaszewski <[email protected]>
gpio: sim: fix setting and getting multiple lines

Ronnie Sahlberg <[email protected]>
cifs: verify that tcon is valid before dereference in cifs_kill_sb

Jason A. Donenfeld <[email protected]>
gcc-plugins: latent_entropy: use /dev/urandom

Johan Hovold <[email protected]>
memory: renesas-rpc-if: fix platform-device leak in error path

Chuck Lever <[email protected]>
SUNRPC: Fix NFSD's request deferral on RDMA transports

Oliver Upton <[email protected]>
KVM: Don't create VM debugfs files outside of the VM directory

Sean Christopherson <[email protected]>
KVM: x86/mmu: Resolve nx_huge_pages when kvm.ko is loaded

Andrew Morton <[email protected]>
revert "fs/binfmt_elf: use PT_LOAD p_align values for static PIE"

Andrew Morton <[email protected]>
revert "fs/binfmt_elf: fix PT_LOAD p_align values for loaders"

Mike Kravetz <[email protected]>
hugetlb: do not demote poisoned hugetlb pages

Patrick Wang <[email protected]>
mm: kmemleak: take a full lowmem check in kmemleak_*_phys()

Minchan Kim <[email protected]>
mm: fix unexpected zeroed page mapping with zram swap

Juergen Gross <[email protected]>
mm, page_alloc: fix build_zonerefs_node()

Axel Rasmussen <[email protected]>
mm/secretmem: fix panic when growing a memfd_secret

Borislav Petkov <[email protected]>
perf/imx_ddr: Fix undefined behavior due to shift overflowing the constant

Pavel Begunkov <[email protected]>
io_uring: use nospec annotation for more indexes

Pavel Begunkov <[email protected]>
io_uring: zero tag on rsrc removal

Peter Zijlstra <[email protected]>
x86,bpf: Avoid IBT objtool warning

Duoming Zhou <[email protected]>
drivers: net: slip: fix NPD bug in sl_tx_timeout()

Chandrakanth patil <[email protected]>
scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan

Alexey Galakhov <[email protected]>
scsi: mvsas: Add PCI ID of RocketRaid 2640

Sreekanth Reddy <[email protected]>
scsi: mpt3sas: Fail reset operation if config request timed out

Christoph Böhmwalder <[email protected]>
drbd: set QUEUE_FLAG_STABLE_WRITES

Roman Li <[email protected]>
drm/amd/display: Fix allocate_mst_payload assert on resume

Martin Leung <[email protected]>
drm/amd/display: Revert FEC check in validation

Roman Li <[email protected]>
drm/amd/display: Enable power gating before init_pipes

Chris Park <[email protected]>
drm/amd/display: Correct Slice reset calculation

Matthias Schiffer <[email protected]>
spi: cadence-quadspi: fix protocol setup for non-1-1-X operations

Xiaomeng Tong <[email protected]>
myri10ge: fix an incorrect free for skb in myri10ge_sw_tso

Marcin Kozlowski <[email protected]>
net: usb: aqc111: Fix out-of-bounds accesses in RX fixup

Boqun Feng <[email protected]>
Drivers: hv: balloon: Disable balloon and hot-add accordingly

Andy Chiu <[email protected]>
net: axienet: setup mdio unconditionally

Steve Capper <[email protected]>
tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry

Joey Gouly <[email protected]>
arm64: alternatives: mark patch_alternative() as noinstr

Christophe Leroy <[email protected]>
static_call: Properly initialise DEFINE_STATIC_CALL_RET0()

Jonathan Bakker <[email protected]>
regulator: wm8994: Add an off-on delay for WM8994 variant

Leo Ruan <[email protected]>
gpu: ipu-v3: Fix dev_dbg frequency output

Christian Lamparter <[email protected]>
ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs

Randy Dunlap <[email protected]>
net: micrel: fix KS8851_MLL Kconfig

Tyrel Datwyler <[email protected]>
scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024

James Smart <[email protected]>
scsi: lpfc: Fix queue failures when recovering from PCI parity error

James Smart <[email protected]>
scsi: lpfc: Fix unload hang after back to back PCI EEH faults

James Smart <[email protected]>
scsi: lpfc: Improve PCI EEH Error and Recovery Handling

Xiaoguang Wang <[email protected]>
scsi: target: tcmu: Fix possible page UAF

Michael Kelley <[email protected]>
Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer

Michael Kelley <[email protected]>
PCI: hv: Propagate coherence from VMbus device to PCI device

Michael Kelley <[email protected]>
Drivers: hv: vmbus: Propagate VMbus coherence to each VMbus device

Andrea Parri (Microsoft) <[email protected]>
Drivers: hv: vmbus: Deactivate sysctl_record_panic_msg by default in isolated guests

QintaoShen <[email protected]>
drm/amdkfd: Check for potential null return of kmalloc_array()

Tianci Yin <[email protected]>
drm/amdgpu/vcn: improve vcn dpg stop procedure

Tushar Patel <[email protected]>
drm/amdkfd: Fix Incorrect VMIDs passed to HWS

Leo (Hanghong) Ma <[email protected]>
drm/amd/display: Update VTEM Infopacket definition

Chiawen Huang <[email protected]>
drm/amd/display: FEC check in timing validation

Charlene Liu <[email protected]>
drm/amd/display: fix audio format not updated after edid updated

Alex Deucher <[email protected]>
drm/amdgpu/gmc: use PCI BARs for APUs in passthrough

Guchun Chen <[email protected]>
drm/amdgpu: conduct a proper cleanup of PDB bo

Josef Bacik <[email protected]>
btrfs: do not warn for free space inode in cow_file_range

Darrick J. Wong <[email protected]>
btrfs: fix fallocate to use file_modified to update permissions consistently

Aurabindo Pillai <[email protected]>
drm/amd: Add USBC connector ID

Nicholas Piggin <[email protected]>
KVM: PPC: Book3S HV P9: Fix "lost kick" race

Jens Axboe <[email protected]>
io_uring: abort file assignment prior to assigning creds

Ming Lei <[email protected]>
block: null_blk: end timed out poll request

Ming Lei <[email protected]>
block: fix offset/size check in bio_trim()

Jeremy Linton <[email protected]>
net: bcmgenet: Revert "Use stronger register read/writes to assure ordering"

Vladimir Oltean <[email protected]>
net: dsa: felix: fix tagging protocol changes with multiple CPU ports

Antoine Tenart <[email protected]>

    tun: annotate access to queue->trans_start

Jason Gunthorpe <[email protected]>
vfio/pci: Fix vf_token mechanism when device-specific VF drivers are used

Khazhismel Kumykov <[email protected]>
dm mpath: only use ktime_get_ns() in historical selector

Harshit Mogalapalli <[email protected]>
cifs: potential buffer overflow in handling symlinks

Lin Ma <[email protected]>
nfc: nci: add flush_workqueue to prevent uaf

Dylan Hung <[email protected]>
net: ftgmac100: access hardware register after clock ready

Martin Willi <[email protected]>
macvlan: Fix leaking skb in source mode with nodst option

Adrian Hunter <[email protected]>
perf tools: Fix misleading add event PMU debug message

Takashi Iwai <[email protected]>
ALSA: usb-audio: Limit max buffer and period sizes per time

Takashi Iwai <[email protected]>
ALSA: usb-audio: Increase max buffer size

Athira Rajeev <[email protected]>
testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu set

Dylan Yudaken <[email protected]>
io_uring: verify pad field is 0 in io_get_ext_arg

Dylan Yudaken <[email protected]>
io_uring: verify that resv2 is 0 in io_uring_rsrc_update2

Dylan Yudaken <[email protected]>
io_uring: move io_uring_rsrc_update2 validation

Takashi Iwai <[email protected]>
ALSA: mtpav: Don't call card private_free at probe error path

Takashi Iwai <[email protected]>
ALSA: ad1889: Fix the missing snd_card_free() call at probe error

Pavel Begunkov <[email protected]>
io_uring: fix assign file locking issue

Antoine Tenart <[email protected]>
netfilter: nf_tables: nft_parse_register can return a negative value

Horatiu Vultur <[email protected]>
net: lan966x: Stop processing the MAC entry is port is wrong.

Horatiu Vultur <[email protected]>
net: lan966x: Fix when a port's upper is changed.

Petr Malat <[email protected]>
sctp: Initialize daddr on peeled off socket

Mike Christie <[email protected]>
scsi: iscsi: Fix unbound endpoint error handling

Mike Christie <[email protected]>
scsi: iscsi: Fix conn cleanup and stop race during iscsid restart

Mike Christie <[email protected]>
scsi: iscsi: Fix endpoint reuse regression

Mike Christie <[email protected]>
scsi: iscsi: Fix offload conn cleanup when iscsid restarts

Mike Christie <[email protected]>
scsi: iscsi: Move iscsi_ep_disconnect()

Ajish Koshy <[email protected]>

    scsi: pm80xx: Enable upper inbound, outbound queues

Ajish Koshy <[email protected]>

    scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63

Karsten Graul <[email protected]>
net/smc: Fix NULL pointer dereference in smc_pnet_find_ib()

Karsten Graul <[email protected]>
net/smc: use memcpy instead of snprintf to avoid out of bounds read

Jens Axboe <[email protected]>
io_uring: stop using io_wq_work as an fd placeholder

Kuogee Hsieh <[email protected]>
drm/msm/dp: add fail safe mode outside of event_mutex context

Stephen Boyd <[email protected]>
drm/msm/dsi: Use connector directly in msm_dsi_manager_connector_init()

Rob Clark <[email protected]>
drm/msm: Fix range size vs end confusion

Florian Westphal <[email protected]>
netfilter: nft_socket: make cgroup match work in input too

Ben Greear <[email protected]>
mac80211: fix ht_capa printout in debugfs

Rameshkumar Sundaram <[email protected]>
cfg80211: hold bss_lock while updating nontrans_list

Benedikt Spranger <[email protected]>
net/sched: taprio: Check if socket flags are valid

Dinh Nguyen <[email protected]>
net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link

Jens Axboe <[email protected]>
io_uring: flag the fact that linked file assignment is sane

Heiko Stuebner <[email protected]>
RISC-V: KVM: include missing hwcap.h into vcpu_fp

Anup Patel <[email protected]>
KVM: selftests: riscv: Fix alignment of the guest_hang() function

Anup Patel <[email protected]>
KVM: selftests: riscv: Set PTE A and D bits in VS-stage page table

Michael Walle <[email protected]>
net: dsa: felix: suppress -EPROBE_DEFER errors

Dave Wysochanski <[email protected]>
cachefiles: Fix KASAN slab-out-of-bounds in cachefiles_set_volume_xattr

Jeffle Xu <[email protected]>
cachefiles: unmark inode in use in error path

Marcelo Ricardo Leitner <[email protected]>
net/sched: fix initialization order when updating chain 0 head

Xin Long <[email protected]>
sctp: use the correct skb for security_sctp_assoc_request

Vadim Pasternak <[email protected]>
mlxsw: i2c: Fix initialization error flow

Vladimir Oltean <[email protected]>
net: mdio: don't defer probe forever if PHY IRQ provider is missing

Mateusz Palczewski <[email protected]>
Revert "iavf: Fix deadlock occurrence during resetting VF interface"

Alexander Lobakin <[email protected]>
ice: arfs: fix use-after-free when freeing @rx_cpu_rmap

Shyam Prasad N <[email protected]>
cifs: release cached dentries only if mount is complete

Linus Torvalds <[email protected]>
gpiolib: acpi: use correct format characters

Guillaume Nault <[email protected]>
veth: Ensure eth header is in skb's linear part

Vlad Buslov <[email protected]>
net/sched: flower: fix parsing of ethertype following VLAN header

Chuck Lever <[email protected]>
SUNRPC: Fix the svc_deferred_event trace class

Reiji Watanabe <[email protected]>
KVM: arm64: mixed-width check should be skipped for uninitialized vCPUs

Marc Zyngier <[email protected]>
KVM: arm64: Generalise VM features into a set of flags

Kyle Copperfield <[email protected]>
media: rockchip/rga: do proper error checking in probe

Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix sorting of retrieved clock rates

Anilkumar Kolli <[email protected]>
Revert "ath11k: mesh: add support for 256 bitmap in blockack frames in 11ax"

Miaoqian Lin <[email protected]>
memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe

Cristian Marussi <[email protected]>
firmware: arm_scmi: Remove clear channel call on the TX channel

Trond Myklebust <[email protected]>
nfsd: Fix a write performance regression

Rob Clark <[email protected]>
drm/msm: Add missing put_task_struct() in debugfs path

Takashi Iwai <[email protected]>
ALSA: nm256: Don't call card private_free at probe error path

Takashi Iwai <[email protected]>
ALSA: memalloc: Add fallback SG-buffer allocations for x86

Takashi Iwai <[email protected]>
ALSA: usb-audio: Cap upper limits of buffer/period bytes for implicit fb

Takashi Iwai <[email protected]>
ALSA: via82xx: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: sonicvibes: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: sc6000: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: rme96: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: rme9652: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: rme32: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: riptide: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: oxygen: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: maestro3: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: lx6464es: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: lola: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: korg1212: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: intel_hdmi: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: intel8x0: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: ice1724: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: hdspm: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: hdsp: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: galaxy: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: fm801: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: es1968: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: es1938: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: ens137x: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: emu10k1x: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: echoaudio: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: cs5535audio: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: cs4281: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: cmipci: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: ca0106: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: bt87x: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: azt3328: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: aw2: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: au88x0: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: atiixp: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: als4000: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: als300: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: ali5451: Fix the missing snd_card_free() call at probe error

Takashi Iwai <[email protected]>
ALSA: sis7019: Fix the missing error handling

Takashi Iwai <[email protected]>
ALSA: core: Add snd_card_free_on_error() helper

Naohiro Aota <[email protected]>
btrfs: return allocated block group from do_chunk_alloc()

Dennis Zhou <[email protected]>
btrfs: fix btrfs_submit_compressed_write cgroup attribution

Naohiro Aota <[email protected]>
btrfs: release correct delalloc amount in direct IO write path

Kai-Heng Feng <[email protected]>
drm/amdgpu: Ensure HDA function is suspended before ASIC reset

Tadeusz Struk <[email protected]>
uapi/linux/stddef.h: Add include guards

Piotr Chmura <[email protected]>

    media: si2157: unknown chip version Si2147-A30 ROM 0x50

Anup Patel <[email protected]>
RISC-V: KVM: Don't clear hgatp CSR in kvm_arch_vcpu_put()

Nathan Chancellor <[email protected]>
btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups()

Filipe Manana <[email protected]>
btrfs: remove no longer used counter when reading data page

Alvin Šipraga <[email protected]>
net: dsa: realtek: make interface drivers depend on OF

Alvin Šipraga <[email protected]>
net: dsa: realtek: rtl8365mb: serialize indirect PHY register access

Alvin Šipraga <[email protected]>
net: dsa: realtek: allow subdrivers to externally lock regmap

Mario Limonciello <[email protected]>
ACPI: processor idle: Check for architectural support for LPI

Mario Limonciello <[email protected]>
cpuidle: PSCI: Move the has_lpi check to the beginning of the function

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Fix p-state allow debug index on dcn31

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Add pstate verification and recovery for DCN31

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

Diffstat:

 .../memory-controllers/synopsys,ddrc-ecc.yaml      |   6 +-
 .../devicetree/bindings/net/snps,dwmac.yaml        |   6 +-
 Makefile                                           |   4 +-
 arch/arm/mach-davinci/board-da850-evm.c            |   4 +-
 arch/arm/mach-ep93xx/clock.c                       |   4 +-
 arch/arm64/include/asm/kvm_emulate.h               |  27 +++-
 arch/arm64/include/asm/kvm_host.h                  |  25 ++-
 arch/arm64/kernel/alternative.c                    |   6 +-
 arch/arm64/kernel/cpuidle.c                        |   6 +-
 arch/arm64/kvm/arm.c                               |   7 +-
 arch/arm64/kvm/mmio.c                              |   3 +-
 arch/arm64/kvm/pmu-emul.c                          |   2 +-
 arch/arm64/kvm/reset.c                             |  65 +++++---
 arch/powerpc/include/asm/static_call.h             |   1 +
 arch/powerpc/kvm/book3s_hv.c                       |  41 ++++-
 arch/riscv/kvm/vcpu.c                              |   2 -
 arch/riscv/kvm/vcpu_fp.c                           |   1 +
 arch/x86/include/asm/kvm_host.h                    |   5 +-
 arch/x86/include/asm/msr-index.h                   |   4 +-
 arch/x86/include/asm/static_call.h                 |   2 +
 arch/x86/kernel/cpu/common.c                       |   2 +
 arch/x86/kernel/cpu/cpu.h                          |   5 +-
 arch/x86/kernel/cpu/intel.c                        |   7 -
 arch/x86/kernel/cpu/tsx.c                          | 104 +++++++++++--
 arch/x86/kvm/mmu/mmu.c                             |  20 ++-
 arch/x86/kvm/x86.c                                 |  20 ++-
 arch/x86/net/bpf_jit_comp.c                        |   1 +
 block/bio.c                                        |   2 +-
 drivers/acpi/processor_idle.c                      |  15 +-
 drivers/ata/libata-core.c                          |   3 +
 drivers/base/dd.c                                  |   1 +
 drivers/block/drbd/drbd_main.c                     |   1 +
 drivers/block/null_blk/main.c                      |   2 +-
 drivers/firmware/arm_scmi/clock.c                  |   3 +-
 drivers/firmware/arm_scmi/driver.c                 |   3 +-
 drivers/gpio/gpio-sim.c                            |   4 +-
 drivers/gpio/gpiolib-acpi.c                        |   4 +-
 drivers/gpu/drm/amd/amdgpu/ObjectID.h              |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |  20 ++-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c              |   2 +
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c             |   2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c              |   5 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c              |   2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c              |   3 +
 drivers/gpu/drm/amd/amdkfd/kfd_device.c            |  11 +-
 drivers/gpu/drm/amd/amdkfd/kfd_events.c            |   2 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   3 +-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c  |   4 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c    |   1 +
 .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  |  29 ++--
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |  14 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c    |   1 +
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c |   5 +-
 .../gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c  |   1 +
 .../gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c    |  62 ++++++++
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |   5 +-
 .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c        |   4 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h   |   2 +
 .../amd/display/modules/info_packet/info_packet.c  |   5 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c           |   2 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |   2 +-
 drivers/gpu/drm/msm/dp/dp_display.c                |   6 +
 drivers/gpu/drm/msm/dp/dp_panel.c                  |  20 +--
 drivers/gpu/drm/msm/dp/dp_panel.h                  |   1 +
 drivers/gpu/drm/msm/dsi/dsi_manager.c              |   2 +-
 drivers/gpu/drm/msm/msm_gem.c                      |   1 +
 drivers/gpu/ipu-v3/ipu-di.c                        |   5 +-
 drivers/hv/hv_balloon.c                            |  36 ++++-
 drivers/hv/hv_common.c                             |  11 ++
 drivers/hv/ring_buffer.c                           |  11 +-
 drivers/hv/vmbus_drv.c                             |  49 +++++-
 drivers/i2c/busses/i2c-pasemi-core.c               |   6 +
 drivers/i2c/i2c-dev.c                              |  15 +-
 drivers/md/dm-integrity.c                          |   7 +-
 drivers/md/dm-ps-historical-service-time.c         |  11 +-
 drivers/media/platform/rockchip/rga/rga.c          |   2 +-
 drivers/media/tuners/si2157.c                      |  22 +--
 drivers/memory/atmel-ebi.c                         |  23 ++-
 drivers/memory/renesas-rpc-if.c                    |  10 +-
 drivers/net/dsa/ocelot/felix.c                     |  23 +++
 drivers/net/dsa/ocelot/felix_vsc9959.c             |   2 +-
 drivers/net/dsa/realtek/Kconfig                    |   1 +
 drivers/net/dsa/realtek/realtek-smi-core.c         |  48 +++++-
 drivers/net/dsa/realtek/realtek-smi-core.h         |   2 +
 drivers/net/dsa/realtek/rtl8365mb.c                |  54 ++++---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     |   4 +-
 drivers/net/ethernet/faraday/ftgmac100.c           |  10 +-
 drivers/net/ethernet/intel/iavf/iavf_main.c        |   7 +-
 drivers/net/ethernet/intel/ice/ice_arfs.c          |   9 +-
 drivers/net/ethernet/intel/ice/ice_lib.c           |   5 +-
 drivers/net/ethernet/intel/ice/ice_main.c          |  18 +--
 drivers/net/ethernet/mellanox/mlxsw/i2c.c          |   1 +
 drivers/net/ethernet/micrel/Kconfig                |   1 +
 .../net/ethernet/microchip/lan966x/lan966x_mac.c   |   6 +-
 .../ethernet/microchip/lan966x/lan966x_switchdev.c |   3 +-
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c |   8 -
 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h |   4 +
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  13 +-
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c  |  13 +-
 drivers/net/macvlan.c                              |   8 +-
 drivers/net/mdio/fwnode_mdio.c                     |   5 +
 drivers/net/slip/slip.c                            |   2 +-
 drivers/net/tun.c                                  |   2 +-
 drivers/net/usb/aqc111.c                           |   9 +-
 drivers/net/veth.c                                 |   2 +-
 drivers/net/wireless/ath/ath11k/mac.c              |  22 ++-
 drivers/net/wireless/ath/ath9k/main.c              |   2 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |  33 ++--
 drivers/pci/controller/pci-hyperv.c                |   9 ++
 drivers/perf/fsl_imx8_ddr_perf.c                   |   2 +-
 drivers/regulator/wm8994-regulator.c               |  42 +++++-
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c           |   2 +-
 drivers/scsi/lpfc/lpfc.h                           |   7 +-
 drivers/scsi/lpfc/lpfc_crtn.h                      |   3 +
 drivers/scsi/lpfc/lpfc_hbadisc.c                   | 120 ++++++++++++---
 drivers/scsi/lpfc/lpfc_init.c                      |  88 ++++++++---
 drivers/scsi/lpfc/lpfc_nvme.c                      |  27 ++--
 drivers/scsi/lpfc/lpfc_sli.c                       |  65 +++++---
 drivers/scsi/megaraid/megaraid_sas.h               |   3 +
 drivers/scsi/megaraid/megaraid_sas_base.c          |   7 +
 drivers/scsi/mpt3sas/mpt3sas_config.c              |   9 +-
 drivers/scsi/mvsas/mv_init.c                       |   1 +
 drivers/scsi/pm8001/pm80xx_hwi.c                   |  33 ++--
 drivers/scsi/scsi_transport_iscsi.c                | 168 +++++++++++++--------
 drivers/spi/spi-cadence-quadspi.c                  |  46 ++----
 drivers/target/target_core_user.c                  |   3 +-
 drivers/vfio/pci/vfio_pci_core.c                   | 124 +++++++++------
 fs/binfmt_elf.c                                    |   4 +-
 fs/btrfs/block-group.c                             |  40 +++--
 fs/btrfs/block-group.h                             |   4 +
 fs/btrfs/compression.c                             |   8 +
 fs/btrfs/disk-io.c                                 |   5 +-
 fs/btrfs/extent-tree.c                             |   2 +-
 fs/btrfs/extent_io.c                               |   5 +-
 fs/btrfs/file.c                                    |  13 +-
 fs/btrfs/inode.c                                   |   7 +-
 fs/btrfs/volumes.c                                 |   2 +
 fs/cachefiles/namei.c                              |  33 ++--
 fs/cachefiles/xattr.c                              |   2 +-
 fs/cifs/cifsfs.c                                   |  28 ++--
 fs/cifs/link.c                                     |   3 +
 fs/io-wq.h                                         |   1 -
 fs/io_uring.c                                      |  54 ++++---
 fs/nfsd/filecache.c                                |  18 ++-
 include/asm-generic/mshyperv.h                     |   1 +
 include/asm-generic/tlb.h                          |  10 +-
 include/linux/kfence.h                             |  24 +++
 include/linux/static_call.h                        |  20 ++-
 include/linux/sunrpc/svc.h                         |   1 +
 include/linux/vfio_pci_core.h                      |   2 +
 include/net/flow_dissector.h                       |   2 +
 include/scsi/scsi_transport_iscsi.h                |   2 +
 include/sound/core.h                               |   1 +
 include/sound/memalloc.h                           |   5 +
 include/trace/events/sunrpc.h                      |   7 +-
 include/uapi/linux/io_uring.h                      |   1 +
 include/uapi/linux/stddef.h                        |   4 +
 kernel/cpu.c                                       |  36 ++---
 kernel/dma/direct.h                                |   3 +-
 kernel/irq/affinity.c                              |   5 +-
 kernel/smp.c                                       |   2 +-
 kernel/time/tick-sched.c                           |   2 +-
 kernel/time/timer.c                                |  11 +-
 mm/hugetlb.c                                       |  17 ++-
 mm/kfence/core.c                                   |  21 ---
 mm/kfence/kfence.h                                 |  21 +++
 mm/kfence/report.c                                 |  47 ++++++
 mm/kmemleak.c                                      |   8 +-
 mm/page_alloc.c                                    |   2 +-
 mm/page_io.c                                       |  54 -------
 mm/secretmem.c                                     |  17 +++
 mm/slab.c                                          |   2 +-
 mm/slab.h                                          |   2 +-
 mm/slab_common.c                                   |   9 ++
 mm/slob.c                                          |   2 +-
 mm/slub.c                                          |   2 +-
 net/ax25/af_ax25.c                                 |   5 +
 net/core/flow_dissector.c                          |   1 +
 net/dsa/dsa2.c                                     |  23 ++-
 net/ipv6/ip6_output.c                              |   2 +-
 net/mac80211/debugfs_sta.c                         |   2 +-
 net/netfilter/nf_tables_api.c                      |   2 +-
 net/netfilter/nft_socket.c                         |   7 +-
 net/nfc/nci/core.c                                 |   4 +
 net/sched/cls_api.c                                |   2 +-
 net/sched/cls_flower.c                             |  18 ++-
 net/sched/sch_taprio.c                             |   3 +-
 net/sctp/sm_statefuns.c                            |   6 +-
 net/sctp/socket.c                                  |   2 +-
 net/smc/smc_clc.c                                  |   6 +-
 net/smc/smc_pnet.c                                 |   5 +-
 net/sunrpc/svc_xprt.c                              |   3 +
 net/sunrpc/xprtrdma/svc_rdma_recvfrom.c            |   2 +-
 net/wireless/nl80211.c                             |   3 +-
 net/wireless/scan.c                                |   2 +
 scripts/gcc-plugins/latent_entropy_plugin.c        |  44 +++---
 sound/core/init.c                                  |  28 ++++
 sound/core/memalloc.c                              | 111 +++++++++++++-
 sound/core/pcm_misc.c                              |   2 +-
 sound/drivers/mtpav.c                              |   4 +-
 sound/isa/galaxy/galaxy.c                          |   7 +-
 sound/isa/sc6000.c                                 |   7 +-
 sound/pci/ad1889.c                                 |  10 +-
 sound/pci/ali5451/ali5451.c                        |  10 +-
 sound/pci/als300.c                                 |   8 +-
 sound/pci/als4000.c                                |  10 +-
 sound/pci/atiixp.c                                 |  10 +-
 sound/pci/atiixp_modem.c                           |  10 +-
 sound/pci/au88x0/au88x0.c                          |   8 +-
 sound/pci/aw2/aw2-alsa.c                           |   8 +-
 sound/pci/azt3328.c                                |   8 +-
 sound/pci/bt87x.c                                  |  10 +-
 sound/pci/ca0106/ca0106_main.c                     |  10 +-
 sound/pci/cmipci.c                                 |   8 +-
 sound/pci/cs4281.c                                 |  10 +-
 sound/pci/cs5535audio/cs5535audio.c                |  10 +-
 sound/pci/echoaudio/echoaudio.c                    |   9 +-
 sound/pci/emu10k1/emu10k1x.c                       |  10 +-
 sound/pci/ens1370.c                                |  10 +-
 sound/pci/es1938.c                                 |  10 +-
 sound/pci/es1968.c                                 |  10 +-
 sound/pci/fm801.c                                  |  10 +-
 sound/pci/hda/patch_realtek.c                      |   2 +
 sound/pci/ice1712/ice1724.c                        |  10 +-
 sound/pci/intel8x0.c                               |  10 +-
 sound/pci/intel8x0m.c                              |  10 +-
 sound/pci/korg1212/korg1212.c                      |   8 +-
 sound/pci/lola/lola.c                              |  10 +-
 sound/pci/lx6464es/lx6464es.c                      |   8 +-
 sound/pci/maestro3.c                               |   8 +-
 sound/pci/nm256/nm256.c                            |   2 +-
 sound/pci/oxygen/oxygen_lib.c                      |  12 +-
 sound/pci/riptide/riptide.c                        |   8 +-
 sound/pci/rme32.c                                  |   8 +-
 sound/pci/rme96.c                                  |  10 +-
 sound/pci/rme9652/hdsp.c                           |   8 +-
 sound/pci/rme9652/hdspm.c                          |   8 +-
 sound/pci/rme9652/rme9652.c                        |   8 +-
 sound/pci/sis7019.c                                |  14 +-
 sound/pci/sonicvibes.c                             |  10 +-
 sound/pci/via82xx.c                                |  10 +-
 sound/pci/via82xx_modem.c                          |  10 +-
 sound/usb/pcm.c                                    |  16 +-
 sound/x86/intel_hdmi_audio.c                       |   7 +-
 tools/arch/x86/include/asm/msr-index.h             |   4 +-
 tools/perf/util/parse-events.c                     |   5 +-
 .../selftests/kvm/include/riscv/processor.h        |   4 +-
 tools/testing/selftests/kvm/lib/riscv/processor.c  |   2 +-
 tools/testing/selftests/mqueue/mq_perf_tests.c     |  25 ++-
 virt/kvm/kvm_main.c                                |  10 +-
 254 files changed, 2318 insertions(+), 927 deletions(-)
author maintainer
#1 lore raw

PATCH 1/219 drm/amd/display: Add pstate verification and recovery for DCN31

From: Nicholas Kazlauskas <[email protected]>

commit e7031d8258f1b4d6d50e5e5b5d92ba16f66eb8b4 upstream.

[Why]
To debug when p-state is being blocked and avoid PMFW hangs when it does occur.

[How]
Re-use the DCN10 hardware sequencer by adding a new interface for verifying p-state high on the hubbub. The interface is mostly the same as the DCN10 interface, but the bit definitions have changed for the debug bus.

---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c       |    1 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c |   10 +-
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c       |    1 
 drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c     |    1 
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c       |   60 ++++++++++++++
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c     |    2 
 drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h          |    2 
 7 files changed, 73 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +1 -0
@@ -940,6 +940,7 @@ static const struct hubbub_funcs hubbub1
 	.program_watermarks = hubbub1_program_watermarks,
 	.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
 	.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
+	.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
 };
 
 void hubbub1_construct(struct hubbub *hubbub,
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +7 -3
@@ -1112,9 +1112,13 @@ static bool dcn10_hw_wa_force_recovery(s
 
 void dcn10_verify_allow_pstate_change_high(struct dc *dc)
 {
+	struct hubbub *hubbub = dc->res_pool->hubbub;
 	static bool should_log_hw_state; /* prevent hw state log by default */
 
-	if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) {
+	if (!hubbub->funcs->verify_allow_pstate_change_high)
+		return;
+
+	if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
 		int i = 0;
 
 		if (should_log_hw_state)
@@ -1123,8 +1127,8 @@ void dcn10_verify_allow_pstate_change_hi
 		TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
 		BREAK_TO_DEBUGGER();
 		if (dcn10_hw_wa_force_recovery(dc)) {
-		/*check again*/
-			if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub))
+			/*check again*/
+			if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
 				BREAK_TO_DEBUGGER();
 		}
 	}
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c +1 -0
@@ -448,6 +448,7 @@ static const struct hubbub_funcs hubbub3
 	.program_watermarks = hubbub3_program_watermarks,
 	.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
 	.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+	.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
 	.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
 	.force_pstate_change_control = hubbub3_force_pstate_change_control,
 	.init_watermarks = hubbub3_init_watermarks,
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c +1 -0
@@ -60,6 +60,7 @@ static const struct hubbub_funcs hubbub3
 	.program_watermarks = hubbub3_program_watermarks,
 	.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
 	.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+	.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
 	.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
 	.force_pstate_change_control = hubbub3_force_pstate_change_control,
 	.hubbub_read_state = hubbub2_read_state,
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c +60 -0

72 lines not on this page · raw message

drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +1 -1
@@ -1011,7 +1011,7 @@ static const struct dc_debug_options deb
 	.max_downscale_src_width = 4096,/*upto true 4K*/
 	.disable_pplib_wm_range = false,
 	.scl_reset_length10 = true,
-	.sanity_checks = false,
+	.sanity_checks = true,
 	.underflow_assert_delay_us = 0xFFFFFFFF,
 	.dwb_fi_phase = -1, // -1 = disable,
 	.dmub_command_table = true,
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +2 -0
@@ -154,6 +154,8 @@ struct hubbub_funcs {
 	bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
 	void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
 
+	bool (*verify_allow_pstate_change_high)(struct hubbub *hubbub);
+
 	void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub);
 
 	void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub);
author maintainer
#2 lore raw

PATCH 2/219 drm/amd/display: Fix p-state allow debug index on dcn31

In reply to Greg Kroah-Hartman

From: Nicholas Kazlauskas <[email protected]>

commit 3107e1a7ae088ee94323fe9ab05dbefd65b3077f upstream.

[Why]
It changed since dcn30 but the hubbub31 constructor hasn't been modified to reflect this.

[How]
Update the value in the constructor to 0x6 so we're checking the right bits for p-state allow.

It worked before by accident, but can falsely assert 0 depending on HW state transitions. The most frequent of which appears to be when all pipes turn off during IGT tests.

Cc Harry Wentland <[email protected]>
Fixes e7031d8258f1b4 ("drm/amd/display: Add pstate verification and recovery for DCN31")
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c +2 -0
@@ -1042,5 +1042,7 @@ void hubbub31_construct(struct dcn20_hub
 	hubbub31->detile_buf_size = det_size_kb * 1024;
 	hubbub31->pixel_chunk_size = pixel_chunk_size_kb * 1024;
 	hubbub31->crb_size_segs = config_return_buffer_size_kb / DCN31_CRB_SEGMENT_SIZE_KB;
+
+	hubbub31->debug_test_index_pstate = 0x6;
 }
 
author maintainer
#3 lore raw

PATCH 3/219 cpuidle: PSCI: Move the `has_lpi` check to the beginning of the function

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

commit 01f6c7338ce267959975da65d86ba34f44d54220 upstream.

Currently the first thing checked is whether the PCSI cpu_suspend function has been initialized.

Another change will be overloading acpi_processor_ffh_lpi_probe and calling it sooner. So make the has_lpi check the first thing checked to prepare for that change.

---
 arch/arm64/kernel/cpuidle.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/kernel/cpuidle.c +3 -3
@@ -54,6 +54,9 @@ static int psci_acpi_cpu_init_idle(unsig
 	struct acpi_lpi_state *lpi;
 	struct acpi_processor *pr = per_cpu(processors, cpu);
 
+	if (unlikely(!pr || !pr->flags.has_lpi))
+		return -EINVAL;
+
 	/*
 	 * If the PSCI cpu_suspend function hook has not been initialized
 	 * idle states must not be enabled, so bail out
@@ -61,9 +64,6 @@ static int psci_acpi_cpu_init_idle(unsig
 	if (!psci_ops.cpu_suspend)
 		return -EOPNOTSUPP;
 
-	if (unlikely(!pr || !pr->flags.has_lpi))
-		return -EINVAL;
-
 	count = pr->power.count - 1;
 	if (count <= 0)
 		return -ENODEV;
author maintainer
#4 lore raw

PATCH 4/219 ACPI: processor idle: Check for architectural support for LPI

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

commit eb087f305919ee8169ad65665610313e74260463 upstream.

When osc_pc_lpi_support_confirmed is set through _OSC and _LPI is populated then the cpuidle driver assumes that LPI is fully functional.

However currently the kernel only provides architectural support for LPI on ARM. This leads to high power consumption on X86 platforms that otherwise try to enable LPI.

So probe whether or not LPI support is implemented before enabling LPI in the kernel. This is done by overloading acpi_processor_ffh_lpi_probe to check whether it returns -EOPNOTSUPP. It also means that all future implementations of acpi_processor_ffh_lpi_probe will need to follow these semantics as well.

---
 drivers/acpi/processor_idle.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/acpi/processor_idle.c +10 -5
@@ -1079,6 +1079,11 @@ static int flatten_lpi_states(struct acp
 	return 0;
 }
 
+int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+
 static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
 {
 	int ret, i;
@@ -1087,6 +1092,11 @@ static int acpi_processor_get_lpi_info(s
 	struct acpi_device *d = NULL;
 	struct acpi_lpi_states_array info[2], *tmp, *prev, *curr;
 
+	/* make sure our architecture has support */
+	ret = acpi_processor_ffh_lpi_probe(pr->id);
+	if (ret == -EOPNOTSUPP)
+		return ret;
+
 	if (!osc_pc_lpi_support_confirmed)
 		return -EOPNOTSUPP;
 
@@ -1138,11 +1148,6 @@ static int acpi_processor_get_lpi_info(s
 	return 0;
 }
 
-int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
-{
-	return -ENODEV;
-}
-
 int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
 	return -ENODEV;
author maintainer
#5 lore raw

PATCH 5/219 net: dsa: realtek: allow subdrivers to externally lock regmap

In reply to Greg Kroah-Hartman

From: Alvin Šipraga <[email protected]>

commit 907e772f6f6debb610ea28298ab57b31019a4edb upstream.

Currently there is no way for Realtek DSA subdrivers to serialize consecutive regmap accesses. In preparation for a bugfix relating to indirect PHY register access - which involves a series of regmap reads and writes - add a facility for subdrivers to serialize their regmap access.

Specifically, a mutex is added to the driver private data structure and the standard regmap is initialized with custom lock/unlock ops which use this mutex. Then, a "nolock" variant of the regmap is added, which is functionally equivalent to the existing regmap except that regmap locking is disabled. Functions that wish to serialize a sequence of regmap accesses may then lock the newly introduced driver-owned mutex before using the nolock regmap.

Doing things this way means that subdriver code that doesn't care about serialized register access - i.e. the vast majority of code - needn't worry about synchronizing register access with an external lock: it can just continue to use the original regmap.

Another advantage of this design is that, while regmaps with locking disabled do not expose a debugfs interface for obvious reasons, there still exists the original regmap which does expose this interface. This interface remains safe to use even combined with driver codepaths that use the nolock regmap, because said codepaths will use the same mutex to synchronize access.

With respect to disadvantages, it can be argued that having near-duplicate regmaps is confusing. However, the naming is rather explicit, and examples will abound.

Finally, while we are at it, rename realtek_smi_mdio_regmap_config to realtek_smi_regmap_config. This makes it consistent with the naming realtek_mdio_regmap_config in realtek-mdio.c.

[alsi: backport to 5.16: s/priv/smi/g and remove realtek-mdio changes]
---
 drivers/net/dsa/realtek/realtek-smi-core.c |   48 +++++++++++++++++++++++++++--
 drivers/net/dsa/realtek/realtek-smi-core.h |    2 +
 2 files changed, 47 insertions(+), 3 deletions(-)
drivers/net/dsa/realtek/realtek-smi-core.c +45 -3
@@ -315,7 +315,21 @@ static int realtek_smi_read(void *ctx, u
 	return realtek_smi_read_reg(smi, reg, val);
 }
 
-static const struct regmap_config realtek_smi_mdio_regmap_config = {
+static void realtek_smi_lock(void *ctx)
+{
+	struct realtek_smi *smi = ctx;
+
+	mutex_lock(&smi->map_lock);
+}
+
+static void realtek_smi_unlock(void *ctx)
+{
+	struct realtek_smi *smi = ctx;
+
+	mutex_unlock(&smi->map_lock);
+}
+
+static const struct regmap_config realtek_smi_regmap_config = {
 	.reg_bits = 10, /* A4..A0 R4..R0 */
 	.val_bits = 16,
 	.reg_stride = 1,
@@ -325,6 +339,21 @@ static const struct regmap_config realte
 	.reg_read = realtek_smi_read,
 	.reg_write = realtek_smi_write,
 	.cache_type = REGCACHE_NONE,
+	.lock = realtek_smi_lock,
+	.unlock = realtek_smi_unlock,
+};
+
+static const struct regmap_config realtek_smi_nolock_regmap_config = {
+	.reg_bits = 10, /* A4..A0 R4..R0 */
+	.val_bits = 16,
+	.reg_stride = 1,
+	/* PHY regs are at 0x8000 */
+	.max_register = 0xffff,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.reg_read = realtek_smi_read,
+	.reg_write = realtek_smi_write,
+	.cache_type = REGCACHE_NONE,
+	.disable_locking = true,
 };
 
 static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
@@ -388,6 +417,7 @@ static int realtek_smi_probe(struct plat
 	const struct realtek_smi_variant *var;
 	struct device *dev = &pdev->dev;
 	struct realtek_smi *smi;
+	struct regmap_config rc;
 	struct device_node *np;
 	int ret;
 
@@ -398,13 +428,25 @@ static int realtek_smi_probe(struct plat
 	if (!smi)
 		return -ENOMEM;
 	smi->chip_data = (void *)smi + sizeof(*smi);
-	smi->map = devm_regmap_init(dev, NULL, smi,
-				    &realtek_smi_mdio_regmap_config);
+
+	mutex_init(&smi->map_lock);
+
+	rc = realtek_smi_regmap_config;
+	rc.lock_arg = smi;
+	smi->map = devm_regmap_init(dev, NULL, smi, &rc);
 	if (IS_ERR(smi->map)) {
 		ret = PTR_ERR(smi->map);
 		dev_err(dev, "regmap init failed: %d\n", ret);
 		return ret;
 	}
+
+	rc = realtek_smi_nolock_regmap_config;
+	smi->map_nolock = devm_regmap_init(dev, NULL, smi, &rc);
+	if (IS_ERR(smi->map_nolock)) {
+		ret = PTR_ERR(smi->map_nolock);
+		dev_err(dev, "regmap init failed: %d\n", ret);
+		return ret;
+	}
 
 	/* Link forward and backward */
 	smi->dev = dev;
drivers/net/dsa/realtek/realtek-smi-core.h +2 -0
@@ -49,6 +49,8 @@ struct realtek_smi {
 	struct gpio_desc	*mdc;
 	struct gpio_desc	*mdio;
 	struct regmap		*map;
+	struct regmap		*map_nolock;
+	struct mutex		map_lock;
 	struct mii_bus		*slave_mii_bus;
 
 	unsigned int		clk_delay;
author maintainer
#6 lore raw

PATCH 6/219 net: dsa: realtek: rtl8365mb: serialize indirect PHY register access

In reply to Greg Kroah-Hartman

From: Alvin Šipraga <[email protected]>

commit 2796728460b822d549841e0341752b263dc265c4 upstream.

Realtek switches in the rtl8365mb family can access the PHY registers of the internal PHYs via the switch registers. This method is called indirect access. At a high level, the indirect PHY register access method involves reading and writing some special switch registers in a particular sequence. This works for both SMI and MDIO connected switches.

Currently the rtl8365mb driver does not take any care to serialize the aforementioned access to the switch registers. In particular, it is permitted for other driver code to access other switch registers while the indirect PHY register access is ongoing. Locking is only done at the regmap level. This, however, is a bug: concurrent register access, even to unrelated switch registers, risks corrupting the PHY register value read back via the indirect access method described above.

Arınç reported that the switch sometimes returns nonsense data when reading the PHY registers. In particular, a value of 0 causes the kernel's PHY subsystem to think that the link is down, but since most reads return correct data, the link then flip-flops between up and down over a period of time.

The aforementioned bug can be readily observed by:

1. Enabling ftrace events for regmap and mdio
2. Polling BSMR PHY register for a connected port;

    it should always read the same (e.g. 0x79ed)

3. Wait for step 2 to give a different value

Example command for step 2:

    while true; do phytool read swp2/2/0x01; done

On my i.MX8MM, the above steps will yield a bogus value for the BSMR PHY register within a matter of seconds. The interleaved register access it then evident in the trace log:

 kworker/3:4-70      [003] .......  1927.139849: regmap_reg_write: ethernet-switch reg=1004 val=bd
     phytool-16816   [002] .......  1927.139979: regmap_reg_read: ethernet-switch reg=1f01 val=0
 kworker/3:4-70      [003] .......  1927.140381: regmap_reg_read: ethernet-switch reg=1005 val=0
     phytool-16816   [002] .......  1927.140468: regmap_reg_read: ethernet-switch reg=1d15 val=a69
 kworker/3:4-70      [003] .......  1927.140864: regmap_reg_read: ethernet-switch reg=1003 val=0
     phytool-16816   [002] .......  1927.140955: regmap_reg_write: ethernet-switch reg=1f02 val=2041
 kworker/3:4-70      [003] .......  1927.141390: regmap_reg_read: ethernet-switch reg=1002 val=0
     phytool-16816   [002] .......  1927.141479: regmap_reg_write: ethernet-switch reg=1f00 val=1
 kworker/3:4-70      [003] .......  1927.142311: regmap_reg_write: ethernet-switch reg=1004 val=be
     phytool-16816   [002] .......  1927.142410: regmap_reg_read: ethernet-switch reg=1f01 val=0
 kworker/3:4-70      [003] .......  1927.142534: regmap_reg_read: ethernet-switch reg=1005 val=0
     phytool-16816   [002] .......  1927.142618: regmap_reg_read: ethernet-switch reg=1f04 val=0
     phytool-16816   [002] .......  1927.142641: mdio_access: SMI-0 read  phy:0x02 reg:0x01 val:0x0000 <- ?!
 kworker/3:4-70      [003] .......  1927.143037: regmap_reg_read: ethernet-switch reg=1001 val=0
 kworker/3:4-70      [003] .......  1927.143133: regmap_reg_read: ethernet-switch reg=1000 val=2d89
 kworker/3:4-70      [003] .......  1927.143213: regmap_reg_write: ethernet-switch reg=1004 val=be
 kworker/3:4-70      [003] .......  1927.143291: regmap_reg_read: ethernet-switch reg=1005 val=0
 kworker/3:4-70      [003] .......  1927.143368: regmap_reg_read: ethernet-switch reg=1003 val=0
 kworker/3:4-70      [003] .......  1927.143443: regmap_reg_read: ethernet-switch reg=1002 val=6

The kworker here is polling MIB counters for stats, as evidenced by the register 0x1004 that we are writing to (RTL8365MB_MIB_ADDRESS_REG). This polling is performed every 3 seconds, but is just one example of such unsynchronized access. In Arınç's case, the driver was not using the switch IRQ, so the PHY subsystem was itself doing polling analogous to phytool in the above example.

A test module was created [see second Link] to simulate such spurious switch register accesses while performing indirect PHY register reads and writes. Realtek was also consulted to confirm whether this is a known issue or not. The conclusion of these lines of inquiry is as follows:

1. Reading of PHY registers via indirect access will be aborted if, after executing the read operation (via a write to the INDIRECT_ACCESS_CTRL_REG), any register is accessed, other than INDIRECT_ACCESS_STATUS_REG.

2. The PHY register indirect read is only complete when INDIRECT_ACCESS_STATUS_REG reads zero.

3. The INDIRECT_ACCESS_DATA_REG, which is read to get the result of the PHY read, will contain the result of the last successful read operation. If there was spurious register access and the indirect read was aborted, then this register is not guaranteed to hold anything meaningful and the PHY read will silently fail.

4. PHY writes do not appear to be affected by this mechanism.

5. Other similar access routines, such as for MIB counters, although similar to the PHY indirect access method, are actually table access. Table access is not affected by spurious reads or writes of other registers. However, concurrent table access is not allowed. Currently this is protected via mib_lock, so there is nothing to fix.

The above statements are corroborated both via the test module and through consultation with Realtek. In particular, Realtek states that this is simply a property of the hardware design and is not a hardware bug.

To fix this problem, one must guard against regmap access while the PHY indirect register read is executing. Fix this by using the newly introduced "nolock" regmap in all PHY-related functions, and by aquiring the regmap mutex at the top level of the PHY register access callbacks. Although no issue has been observed with PHY register _writes_, this change also serializes the indirect access method there. This is done purely as a matter of convenience and for reasons of symmetry.

---
 drivers/net/dsa/realtek/rtl8365mb.c |   54 ++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 21 deletions(-)
drivers/net/dsa/realtek/rtl8365mb.c +33 -21
@@ -565,7 +565,7 @@ static int rtl8365mb_phy_poll_busy(struc
 {
 	u32 val;
 
-	return regmap_read_poll_timeout(smi->map,
+	return regmap_read_poll_timeout(smi->map_nolock,
 					RTL8365MB_INDIRECT_ACCESS_STATUS_REG,
 					val, !val, 10, 100);
 }
@@ -579,7 +579,7 @@ static int rtl8365mb_phy_ocp_prepare(str
 	/* Set OCP prefix */
 	val = FIELD_GET(RTL8365MB_PHY_OCP_ADDR_PREFIX_MASK, ocp_addr);
 	ret = regmap_update_bits(
-		smi->map, RTL8365MB_GPHY_OCP_MSB_0_REG,
+		smi->map_nolock, RTL8365MB_GPHY_OCP_MSB_0_REG,
 		RTL8365MB_GPHY_OCP_MSB_0_CFG_CPU_OCPADR_MASK,
 		FIELD_PREP(RTL8365MB_GPHY_OCP_MSB_0_CFG_CPU_OCPADR_MASK, val));
 	if (ret)
@@ -592,8 +592,8 @@ static int rtl8365mb_phy_ocp_prepare(str
 			  ocp_addr >> 1);
 	val |= FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK,
 			  ocp_addr >> 6);
-	ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG,
-			   val);
+	ret = regmap_write(smi->map_nolock,
+			   RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG, val);
 	if (ret)
 		return ret;
 
@@ -606,36 +606,42 @@ static int rtl8365mb_phy_ocp_read(struct
 	u32 val;
 	int ret;
 
+	mutex_lock(&smi->map_lock);
+
 	ret = rtl8365mb_phy_poll_busy(smi);
 	if (ret)
-		return ret;
+		goto out;
 
 	ret = rtl8365mb_phy_ocp_prepare(smi, phy, ocp_addr);
 	if (ret)
-		return ret;
+		goto out;
 
 	/* Execute read operation */
 	val = FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_MASK,
 			 RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_VALUE) |
 	      FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_RW_MASK,
 			 RTL8365MB_INDIRECT_ACCESS_CTRL_RW_READ);
-	ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_CTRL_REG, val);
+	ret = regmap_write(smi->map_nolock, RTL8365MB_INDIRECT_ACCESS_CTRL_REG,
+			   val);
 	if (ret)
-		return ret;
+		goto out;
 
 	ret = rtl8365mb_phy_poll_busy(smi);
 	if (ret)
-		return ret;
+		goto out;
 
 	/* Get PHY register data */
-	ret = regmap_read(smi->map, RTL8365MB_INDIRECT_ACCESS_READ_DATA_REG,
-			  &val);
+	ret = regmap_read(smi->map_nolock,
+			  RTL8365MB_INDIRECT_ACCESS_READ_DATA_REG, &val);
 	if (ret)
-		return ret;
+		goto out;
 
 	*data = val & 0xFFFF;
 
-	return 0;
+out:
+	mutex_unlock(&smi->map_lock);
+
+	return ret;
 }
 
 static int rtl8365mb_phy_ocp_write(struct realtek_smi *smi, int phy,
@@ -644,32 +650,38 @@ static int rtl8365mb_phy_ocp_write(struc
 	u32 val;
 	int ret;
 
+	mutex_lock(&smi->map_lock);
+
 	ret = rtl8365mb_phy_poll_busy(smi);
 	if (ret)
-		return ret;
+		goto out;
 
 	ret = rtl8365mb_phy_ocp_prepare(smi, phy, ocp_addr);
 	if (ret)
-		return ret;
+		goto out;
 
 	/* Set PHY register data */
-	ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG,
-			   data);
+	ret = regmap_write(smi->map_nolock,
+			   RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG, data);
 	if (ret)
-		return ret;
+		goto out;
 
 	/* Execute write operation */
 	val = FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_MASK,
 			 RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_VALUE) |
 	      FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_RW_MASK,
 			 RTL8365MB_INDIRECT_ACCESS_CTRL_RW_WRITE);
-	ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_CTRL_REG, val);
+	ret = regmap_write(smi->map_nolock, RTL8365MB_INDIRECT_ACCESS_CTRL_REG,
+			   val);
 	if (ret)
-		return ret;
+		goto out;
 
 	ret = rtl8365mb_phy_poll_busy(smi);
 	if (ret)
-		return ret;
+		goto out;
+
+out:
+	mutex_unlock(&smi->map_lock);
 
 	return 0;
 }
author maintainer
#7 lore raw

PATCH 7/219 net: dsa: realtek: make interface drivers depend on OF

In reply to Greg Kroah-Hartman

From: Alvin Šipraga <[email protected]>

commit 109d899452ba17996eccec7ae8249fb1f8900a16 upstream.

The kernel test robot reported build warnings with a randconfig that built realtek-{smi,mdio} without CONFIG_OF set. Since both interface drivers are using OF and will not probe without, add the corresponding dependency to Kconfig.

Fixes aac94001067d ("net: dsa: realtek: add new mdio interface for drivers")
Fixes 765c39a4fafe ("net: dsa: realtek: convert subdrivers into modules")
[alsi: backport to 5.16: remove mdio part]
Cc [email protected] # v5.16+
---
 drivers/net/dsa/realtek/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/net/dsa/realtek/Kconfig +1 -0
@@ -14,6 +14,7 @@ menuconfig NET_DSA_REALTEK
 config NET_DSA_REALTEK_SMI
 	tristate "Realtek SMI connected switch driver"
 	depends on NET_DSA_REALTEK
+	depends on OF
 	default y
 	help
 	  Select to enable support for registering switches connected
author maintainer
#8 lore raw

PATCH 8/219 btrfs: remove no longer used counter when reading data page

In reply to Greg Kroah-Hartman

From: Filipe Manana <[email protected]>

commit ad3fc7946b1829213bbdbb2b9ad0d124b31ae4a7 upstream.

After commit 92082d40976ed0 ("btrfs: integrate page status update for data read path into begin/end_page_read"), the 'nr' counter at btrfs_do_readpage() is no longer used, we increment it but we never read from it. So just remove it.

---
 fs/btrfs/extent_io.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
fs/btrfs/extent_io.c +1 -4
@@ -3562,7 +3562,6 @@ int btrfs_do_readpage(struct page *page,
 	u64 cur_end;
 	struct extent_map *em;
 	int ret = 0;
-	int nr = 0;
 	size_t pg_offset = 0;
 	size_t iosize;
 	size_t blocksize = inode->i_sb->s_blocksize;
@@ -3720,9 +3719,7 @@ int btrfs_do_readpage(struct page *page,
 					 end_bio_extent_readpage, 0,
 					 this_bio_flag,
 					 force_bio_submit);
-		if (!ret) {
-			nr++;
-		} else {
+		if (ret) {
 			unlock_extent(tree, cur, cur + iosize - 1);
 			end_page_read(page, false, cur, iosize);
 			goto out;
author maintainer
#9 lore raw

PATCH 9/219 btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups()

In reply to Greg Kroah-Hartman

From: Nathan Chancellor <[email protected]>

commit 6d4a6b515c39f1f8763093e0f828959b2fbc2f45 upstream.

Clang's version of -Wunused-but-set-variable recently gained support for unary operations, which reveals two unused variables:

fs/btrfs/block-group.c:2949:6: error: variable 'num_started' set but not used [-Werror,-Wunused-but-set-variable]

          int num_started = 0;
              ^
  fs/btrfs/block-group.c:3116:6: error: variable 'num_started' set but not used [-Werror,-Wunused-but-set-variable]
          int num_started = 0;
              ^

2 errors generated.

These variables appear to be unused from their introduction, so just remove them to silence the warnings.

Fixes c9dc4c657850 ("Btrfs: two stage dirty block group writeout")
Fixes 1bbc621ef284 ("Btrfs: allow block group cache writeout outside critical section in commit")
---
 fs/btrfs/block-group.c |    4 ----
 1 file changed, 4 deletions(-)
fs/btrfs/block-group.c +0 -4
@@ -2922,7 +2922,6 @@ int btrfs_start_dirty_block_groups(struc
 	struct btrfs_path *path = NULL;
 	LIST_HEAD(dirty);
 	struct list_head *io = &cur_trans->io_bgs;
-	int num_started = 0;
 	int loops = 0;
 
 	spin_lock(&cur_trans->dirty_bgs_lock);
@@ -2988,7 +2987,6 @@ again:
 			cache->io_ctl.inode = NULL;
 			ret = btrfs_write_out_cache(trans, cache, path);
 			if (ret == 0 && cache->io_ctl.inode) {
-				num_started++;
 				should_put = 0;
 
 				/*
@@ -3089,7 +3087,6 @@ int btrfs_write_dirty_block_groups(struc
 	int should_put;
 	struct btrfs_path *path;
 	struct list_head *io = &cur_trans->io_bgs;
-	int num_started = 0;
 
 	path = btrfs_alloc_path();
 	if (!path)
@@ -3147,7 +3144,6 @@ int btrfs_write_dirty_block_groups(struc
 			cache->io_ctl.inode = NULL;
 			ret = btrfs_write_out_cache(trans, cache, path);
 			if (ret == 0 && cache->io_ctl.inode) {
-				num_started++;
 				should_put = 0;
 				list_add_tail(&cache->io_list, io);
 			} else {
author maintainer
#10 lore raw

PATCH 10/219 RISC-V: KVM: Dont clear hgatp CSR in kvm_arch_vcpu_put()

In reply to Greg Kroah-Hartman

From: Anup Patel <[email protected]>

commit 8c3ce496bd612bd21679e445f75fcabb6be997b2 upstream.

We might have RISC-V systems (such as QEMU) where VMID is not part of the TLB entry tag so these systems will have to flush all TLB entries upon any change in hgatp.VMID.

Currently, we zero-out hgatp CSR in kvm_arch_vcpu_put() and we re-program hgatp CSR in kvm_arch_vcpu_load(). For above described systems, this will flush all TLB entries whenever VCPU exits to user-space hence reducing performance.

This patch fixes above described performance issue by not clearing hgatp CSR in kvm_arch_vcpu_put().

Fixes 34bde9d8b9e6 ("RISC-V: KVM: Implement VCPU world-switch")
---
 arch/riscv/kvm/vcpu.c |    2 --
 1 file changed, 2 deletions(-)
arch/riscv/kvm/vcpu.c +0 -2
@@ -653,8 +653,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
 				     vcpu->arch.isa);
 	kvm_riscv_vcpu_host_fp_restore(&vcpu->arch.host_context);
 
-	csr_write(CSR_HGATP, 0);
-
 	csr->vsstatus = csr_read(CSR_VSSTATUS);
 	csr->vsie = csr_read(CSR_VSIE);
 	csr->vstvec = csr_read(CSR_VSTVEC);
author maintainer
#11 lore raw

PATCH 11/219 media: si2157: unknown chip version Si2147-A30 ROM 0x50

In reply to Greg Kroah-Hartman

From: Piotr Chmura <[email protected]>

commit 3ae87d2f25c0e998da2721ce332e2b80d3d53c39 upstream.

Fix firmware file names assignment in si2157 tuner, allow for running devices without firmware files needed.

modprobe gives error: unknown chip version Si2147-A30 ROM 0x50 Device initialization is interrupted.

Caused by:
1. table si2157_tuners has swapped fields rom_id and required vs struct si2157_tuner_info.
2. both firmware file names can be null for devices with required == false - device uses build-in firmware in this case

Tested on this device:

	m07ca:1871 AVerMedia Technologies, Inc. TD310 DVB-T/T2/C dongle
---
 drivers/media/tuners/si2157.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/media/tuners/si2157.c +11 -11
@@ -77,16 +77,16 @@ err_mutex_unlock:
 }
 
 static const struct si2157_tuner_info si2157_tuners[] = {
-	{ SI2141, false, 0x60, SI2141_60_FIRMWARE, SI2141_A10_FIRMWARE },
-	{ SI2141, false, 0x61, SI2141_61_FIRMWARE, SI2141_A10_FIRMWARE },
-	{ SI2146, false, 0x11, SI2146_11_FIRMWARE, NULL },
-	{ SI2147, false, 0x50, SI2147_50_FIRMWARE, NULL },
-	{ SI2148, true,  0x32, SI2148_32_FIRMWARE, SI2158_A20_FIRMWARE },
-	{ SI2148, true,  0x33, SI2148_33_FIRMWARE, SI2158_A20_FIRMWARE },
-	{ SI2157, false, 0x50, SI2157_50_FIRMWARE, SI2157_A30_FIRMWARE },
-	{ SI2158, false, 0x50, SI2158_50_FIRMWARE, SI2158_A20_FIRMWARE },
-	{ SI2158, false, 0x51, SI2158_51_FIRMWARE, SI2158_A20_FIRMWARE },
-	{ SI2177, false, 0x50, SI2177_50_FIRMWARE, SI2157_A30_FIRMWARE },
+	{ SI2141, 0x60, false, SI2141_60_FIRMWARE, SI2141_A10_FIRMWARE },
+	{ SI2141, 0x61, false, SI2141_61_FIRMWARE, SI2141_A10_FIRMWARE },
+	{ SI2146, 0x11, false, SI2146_11_FIRMWARE, NULL },
+	{ SI2147, 0x50, false, SI2147_50_FIRMWARE, NULL },
+	{ SI2148, 0x32, true,  SI2148_32_FIRMWARE, SI2158_A20_FIRMWARE },
+	{ SI2148, 0x33, true,  SI2148_33_FIRMWARE, SI2158_A20_FIRMWARE },
+	{ SI2157, 0x50, false, SI2157_50_FIRMWARE, SI2157_A30_FIRMWARE },
+	{ SI2158, 0x50, false, SI2158_50_FIRMWARE, SI2158_A20_FIRMWARE },
+	{ SI2158, 0x51, false, SI2158_51_FIRMWARE, SI2158_A20_FIRMWARE },
+	{ SI2177, 0x50, false, SI2177_50_FIRMWARE, SI2157_A30_FIRMWARE },
 };
 
 static int si2157_load_firmware(struct dvb_frontend *fe,
@@ -178,7 +178,7 @@ static int si2157_find_and_load_firmware
 		}
 	}
 
-	if (!fw_name && !fw_alt_name) {
+	if (required && !fw_name && !fw_alt_name) {
 		dev_err(&client->dev,
 			"unknown chip version Si21%d-%c%c%c ROM 0x%02x\n",
 			part_id, cmd.args[1], cmd.args[3], cmd.args[4], rom_id);
author maintainer
#12 lore raw

PATCH 12/219 uapi/linux/stddef.h: Add include guards

In reply to Greg Kroah-Hartman

From: Tadeusz Struk <[email protected]>

commit 55037ed7bdc62151a726f5685f88afa6a82959b1 upstream.

Add include guard wrapper define to uapi/linux/stddef.h to prevent macro redefinition errors when stddef.h is included more than once. This was not needed before since the only contents already used a redefinition test.

Fixes 50d7bd38c3aa ("stddef: Introduce struct_group() helper macro")
---
 include/uapi/linux/stddef.h | 4 ++++
 1 file changed, 4 insertions(+)
include/uapi/linux/stddef.h +4 -0
index 3021ea25a284..7837ba4fe728 100644
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_STDDEF_H
+#define _UAPI_LINUX_STDDEF_H
+
 #include <linux/compiler_types.h>
 
 #ifndef __always_inline
@@ -41,3 +44,4 @@
 		struct { } __empty_ ## NAME; \
 		TYPE NAME[]; \
 	}
+#endif
Signature · 1 line
2.35.2
author maintainer
#13 lore raw

PATCH 13/219 drm/amdgpu: Ensure HDA function is suspended before ASIC reset

In reply to Greg Kroah-Hartman

From: Kai-Heng Feng <[email protected]>

commit 887f75cfd0da44c19dda93b2ff9e70ca8792cdc1 upstream.

DP/HDMI audio on AMD PRO VII stops working after S3:

[  149.450391] amdgpu 0000:63:00.0: amdgpu: MODE1 reset
[  149.450395] amdgpu 0000:63:00.0: amdgpu: GPU mode1 reset
[  149.450494] amdgpu 0000:63:00.0: amdgpu: GPU psp mode1 reset
[  149.983693] snd_hda_intel 0000:63:00.1: refused to change power state from D0 to D3hot
[  150.003439] amdgpu 0000:63:00.0: refused to change power state from D0 to D3hot
...
[  155.432975] snd_hda_intel 0000:63:00.1: CORB reset timeout#2, CORBRP = 65535

The offending commit is daf8de0874ab5b ("drm/amdgpu: always reset the asic in suspend (v2)"). Commit 34452ac3038a7 ("drm/amdgpu: don't use BACO for reset in S3 ") doesn't help, so the issue is something different.

Assuming that to make HDA resume to D0 fully realized, it needs to be successfully put to D3 first. And this guesswork proves working, by moving amdgpu_asic_reset() to noirq callback, so it's called after HDA function is in D3.

Fixes daf8de0874ab5b ("drm/amdgpu: always reset the asic in suspend (v2)")
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +12 -6
@@ -2276,18 +2276,23 @@ static int amdgpu_pmops_suspend(struct d
 {
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct amdgpu_device *adev = drm_to_adev(drm_dev);
-	int r;
 
 	if (amdgpu_acpi_is_s0ix_active(adev))
 		adev->in_s0ix = true;
 	else
 		adev->in_s3 = true;
-	r = amdgpu_device_suspend(drm_dev, true);
-	if (r)
-		return r;
+	return amdgpu_device_suspend(drm_dev, true);
+}
+
+static int amdgpu_pmops_suspend_noirq(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = drm_to_adev(drm_dev);
+
 	if (!adev->in_s0ix)
-		r = amdgpu_asic_reset(adev);
-	return r;
+		return amdgpu_asic_reset(adev);
+
+	return 0;
 }
 
 static int amdgpu_pmops_resume(struct device *dev)
@@ -2528,6 +2533,7 @@ static const struct dev_pm_ops amdgpu_pm
 	.prepare = amdgpu_pmops_prepare,
 	.complete = amdgpu_pmops_complete,
 	.suspend = amdgpu_pmops_suspend,
+	.suspend_noirq = amdgpu_pmops_suspend_noirq,
 	.resume = amdgpu_pmops_resume,
 	.freeze = amdgpu_pmops_freeze,
 	.thaw = amdgpu_pmops_thaw,
author maintainer
#14 lore raw

PATCH 14/219 btrfs: release correct delalloc amount in direct IO write path

In reply to Greg Kroah-Hartman

From: Naohiro Aota <[email protected]>

commit 6d82ad13c4110e73c7b0392f00534a1502a1b520 upstream.

Running generic/406 causes the following WARNING in btrfs_destroy_inode() which tells there are outstanding extents left.

In btrfs_get_blocks_direct_write(), we reserve a temporary outstanding extents with btrfs_delalloc_reserve_metadata() (or indirectly from btrfs_delalloc_reserve_space(()). We then release the outstanding extents with btrfs_delalloc_release_extents(). However, the "len" can be modified in the COW case, which releases fewer outstanding extents than expected.

Fix it by calling btrfs_delalloc_release_extents() for the original length.

To reproduce the warning, the filesystem should be 1 GiB. It's triggering a short-write, due to not being able to allocate a large extent and instead allocating a smaller one.

  WARNING: CPU: 0 PID: 757 at fs/btrfs/inode.c:8848 btrfs_destroy_inode+0x1e6/0x210 [btrfs]
  Modules linked in: btrfs blake2b_generic xor lzo_compress
  lzo_decompress raid6_pq zstd zstd_decompress zstd_compress xxhash zram
  zsmalloc
  CPU: 0 PID: 757 Comm: umount Not tainted 5.17.0-rc8+ #101
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS d55cb5a 04/01/2014
  RIP: 0010:btrfs_destroy_inode+0x1e6/0x210 [btrfs]
  RSP: 0018:ffffc9000327bda8 EFLAGS: 00010206
  RAX: 0000000000000000 RBX: ffff888100548b78 RCX: 0000000000000000
  RDX: 0000000000026900 RSI: 0000000000000000 RDI: ffff888100548b78
  RBP: ffff888100548940 R08: 0000000000000000 R09: ffff88810b48aba8
  R10: 0000000000000001 R11: ffff8881004eb240 R12: ffff88810b48a800
  R13: ffff88810b48ec08 R14: ffff88810b48ed00 R15: ffff888100490c68
  FS:  00007f8549ea0b80(0000) GS:ffff888237c00000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00007f854a09e733 CR3: 000000010a2e9003 CR4: 0000000000370eb0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  Call Trace:
   <TASK>
   destroy_inode+0x33/0x70
   dispose_list+0x43/0x60
   evict_inodes+0x161/0x1b0
   generic_shutdown_super+0x2d/0x110
   kill_anon_super+0xf/0x20
   btrfs_kill_super+0xd/0x20 [btrfs]
   deactivate_locked_super+0x27/0x90
   cleanup_mnt+0x12c/0x180
   task_work_run+0x54/0x80
   exit_to_user_mode_prepare+0x152/0x160
   syscall_exit_to_user_mode+0x12/0x30
   do_syscall_64+0x42/0x80
   entry_SYSCALL_64_after_hwframe+0x44/0xae
   RIP: 0033:0x7f854a000fb7
Fixes f0bfa76a11e9 ("btrfs: fix ENOSPC failure when attempting direct IO write into NOCOW range")
---
 fs/btrfs/inode.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +3 -3
@@ -7423,6 +7423,7 @@ static int btrfs_get_blocks_direct_write
 	u64 block_start, orig_start, orig_block_len, ram_bytes;
 	bool can_nocow = false;
 	bool space_reserved = false;
+	u64 prev_len;
 	int ret = 0;
 
 	/*
@@ -7450,6 +7451,7 @@ static int btrfs_get_blocks_direct_write
 			can_nocow = true;
 	}
 
+	prev_len = len;
 	if (can_nocow) {
 		struct extent_map *em2;
 
@@ -7479,8 +7481,6 @@ static int btrfs_get_blocks_direct_write
 			goto out;
 		}
 	} else {
-		const u64 prev_len = len;
-
 		/* Our caller expects us to free the input extent map. */
 		free_extent_map(em);
 		*map = NULL;
@@ -7511,7 +7511,7 @@ static int btrfs_get_blocks_direct_write
 	 * We have created our ordered extent, so we can now release our reservation
 	 * for an outstanding extent.
 	 */
-	btrfs_delalloc_release_extents(BTRFS_I(inode), len);
+	btrfs_delalloc_release_extents(BTRFS_I(inode), prev_len);
 
 	/*
 	 * Need to update the i_size under the extent lock so buffered
author maintainer
#15 lore raw

PATCH 15/219 btrfs: fix btrfs_submit_compressed_write cgroup attribution

In reply to Greg Kroah-Hartman

From: Dennis Zhou <[email protected]>

commit acee08aaf6d158d03668dc82b0a0eef41100531b upstream.

This restores the logic from commit 46bcff2bfc5e ("btrfs: fix compressed write bio blkcg attribution") which added cgroup attribution to btrfs writeback. It also adds back the REQ_CGROUP_PUNT flag for these ios.

Fixes 91507240482e ("btrfs: determine stripe boundary at bio allocation time in btrfs_submit_compressed_write")
---
 fs/btrfs/compression.c |    8 ++++++++
 1 file changed, 8 insertions(+)
fs/btrfs/compression.c +8 -0
@@ -534,6 +534,9 @@ blk_status_t btrfs_submit_compressed_wri
 	cb->orig_bio = NULL;
 	cb->nr_pages = nr_pages;
 
+	if (blkcg_css)
+		kthread_associate_blkcg(blkcg_css);
+
 	while (cur_disk_bytenr < disk_start + compressed_len) {
 		u64 offset = cur_disk_bytenr - disk_start;
 		unsigned int index = offset >> PAGE_SHIFT;
@@ -552,6 +555,8 @@ blk_status_t btrfs_submit_compressed_wri
 				bio = NULL;
 				goto finish_cb;
 			}
+			if (blkcg_css)
+				bio->bi_opf |= REQ_CGROUP_PUNT;
 		}
 		/*
 		 * We should never reach next_stripe_start start as we will
@@ -609,6 +614,9 @@ blk_status_t btrfs_submit_compressed_wri
 	return 0;
 
 finish_cb:
+	if (blkcg_css)
+		kthread_associate_blkcg(NULL);
+
 	if (bio) {
 		bio->bi_status = ret;
 		bio_endio(bio);
author maintainer
#16 lore raw

PATCH 16/219 btrfs: return allocated block group from do_chunk_alloc()

In reply to Greg Kroah-Hartman

From: Naohiro Aota <[email protected]>

commit 820c363bd526ec8e133e4b84e6ad1fda12023b4b upstream.

Return the allocated block group from do_chunk_alloc(). This is a preparation patch for the next patch.

---
 fs/btrfs/block-group.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
fs/btrfs/block-group.c +13 -3
@@ -3427,7 +3427,7 @@ int btrfs_force_chunk_alloc(struct btrfs
 	return btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
 }
 
-static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
+static struct btrfs_block_group *do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
 {
 	struct btrfs_block_group *bg;
 	int ret;
@@ -3514,7 +3514,11 @@ static int do_chunk_alloc(struct btrfs_t
 out:
 	btrfs_trans_release_chunk_metadata(trans);
 
-	return ret;
+	if (ret)
+		return ERR_PTR(ret);
+
+	btrfs_get_block_group(bg);
+	return bg;
 }
 
 /*
@@ -3629,6 +3633,7 @@ int btrfs_chunk_alloc(struct btrfs_trans
 {
 	struct btrfs_fs_info *fs_info = trans->fs_info;
 	struct btrfs_space_info *space_info;
+	struct btrfs_block_group *ret_bg;
 	bool wait_for_alloc = false;
 	bool should_alloc = false;
 	int ret = 0;
@@ -3722,9 +3727,14 @@ int btrfs_chunk_alloc(struct btrfs_trans
 			force_metadata_allocation(fs_info);
 	}
 
-	ret = do_chunk_alloc(trans, flags);
+	ret_bg = do_chunk_alloc(trans, flags);
 	trans->allocating_chunk = false;
 
+	if (IS_ERR(ret_bg))
+		ret = PTR_ERR(ret_bg);
+	else
+		btrfs_put_block_group(ret_bg);
+
 	spin_lock(&space_info->lock);
 	if (ret < 0) {
 		if (ret == -ENOSPC)
author maintainer
#17 lore raw

PATCH 17/219 ALSA: core: Add snd_card_free_on_error() helper

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit fee2b871d8d6389c9b4bdf9346a99ccc1c98c9b8 upstream.

This is a small helper function to handle the error path more easily when an error happens during the probe for the device with the device-managed card. Since devres releases in the reverser order of the creations, usually snd_card_free() gets called at the last in the probe error path unless it already reached snd_card_register() calls. Due to this nature, when a driver expects the resource releases in card->private_free, this might be called too lately.

As a workaround, one should call the probe like:

static int __some_probe(...) { // do real probe.... }

static int some_probe(...)

 {
	return snd_card_free_on_error(dev, __some_probe(dev, ...));

}

so that the snd_card_free() is called explicitly at the beginning of the error path from the probe.

This function will be used in the upcoming fixes to address the regressions by devres usages.

Fixes e8ad415b7a55 ("ALSA: core: Add managed card creation")
---
 include/sound/core.h |    1 +
 sound/core/init.c    |   28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)
include/sound/core.h +1 -0
@@ -284,6 +284,7 @@ int snd_card_disconnect(struct snd_card
 void snd_card_disconnect_sync(struct snd_card *card);
 int snd_card_free(struct snd_card *card);
 int snd_card_free_when_closed(struct snd_card *card);
+int snd_card_free_on_error(struct device *dev, int ret);
 void snd_card_set_id(struct snd_card *card, const char *id);
 int snd_card_register(struct snd_card *card);
 int snd_card_info_init(void);
sound/core/init.c +28 -0
@@ -209,6 +209,12 @@ static void __snd_card_release(struct de
  * snd_card_register(), the very first devres action to call snd_card_free()
  * is added automatically.  In that way, the resource disconnection is assured
  * at first, then released in the expected order.
+ *
+ * If an error happens at the probe before snd_card_register() is called and
+ * there have been other devres resources, you'd need to free the card manually
+ * via snd_card_free() call in the error; otherwise it may lead to UAF due to
+ * devres call orders.  You can use snd_card_free_on_error() helper for
+ * handling it more easily.
  */
 int snd_devm_card_new(struct device *parent, int idx, const char *xid,
 		      struct module *module, size_t extra_size,
@@ -235,6 +241,28 @@ int snd_devm_card_new(struct device *par
 }
 EXPORT_SYMBOL_GPL(snd_devm_card_new);
 
+/**
+ * snd_card_free_on_error - a small helper for handling devm probe errors
+ * @dev: the managed device object
+ * @ret: the return code from the probe callback
+ *
+ * This function handles the explicit snd_card_free() call at the error from
+ * the probe callback.  It's just a small helper for simplifying the error
+ * handling with the managed devices.
+ */
+int snd_card_free_on_error(struct device *dev, int ret)
+{
+	struct snd_card *card;
+
+	if (!ret)
+		return 0;
+	card = devres_find(dev, __snd_card_release, NULL, NULL);
+	if (card)
+		snd_card_free(card);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_card_free_on_error);
+
 static int snd_card_init(struct snd_card *card, struct device *parent,
 			 int idx, const char *xid, struct module *module,
 			 size_t extra_size)
author maintainer
#18 lore raw

PATCH 18/219 ALSA: sis7019: Fix the missing error handling

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 2236a3243ff8291e97c70097dd11a0fdb8904380 upstream.

The previous cleanup with devres forgot to replace the snd_card_free() call with the devm version. Moreover, it still needs the manual call of snd_card_free() at the probe error path, otherwise the reverse order of the releases may happen. This patch addresses those issues.

Fixes 499ddc16394c ("ALSA: sis7019: Allocate resources with device-managed APIs")
---
 sound/pci/sis7019.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
sound/pci/sis7019.c +10 -4
@@ -1331,8 +1331,8 @@ static int sis_chip_create(struct snd_ca
 	return 0;
 }
 
-static int snd_sis7019_probe(struct pci_dev *pci,
-			     const struct pci_device_id *pci_id)
+static int __snd_sis7019_probe(struct pci_dev *pci,
+			       const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct sis7019 *sis;
@@ -1352,8 +1352,8 @@ static int snd_sis7019_probe(struct pci_
 	if (!codecs)
 		codecs = SIS_PRIMARY_CODEC_PRESENT;
 
-	rc = snd_card_new(&pci->dev, index, id, THIS_MODULE,
-			  sizeof(*sis), &card);
+	rc = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE,
+			       sizeof(*sis), &card);
 	if (rc < 0)
 		return rc;
 
@@ -1386,6 +1386,12 @@ static int snd_sis7019_probe(struct pci_
 	return 0;
 }
 
+static int snd_sis7019_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_sis7019_probe(pci, pci_id));
+}
+
 static struct pci_driver sis7019_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_sis7019_ids,
author maintainer
#19 lore raw

PATCH 19/219 ALSA: ali5451: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 19401a9441236cfbbbeb1bef4ef4c8668db45dfc upstream.

The recent cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 1f0819979248 ("ALSA: ali5451: Allocate resources with device-managed APIs")
---
 sound/pci/ali5451/ali5451.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/ali5451/ali5451.c +8 -2
@@ -2124,8 +2124,8 @@ static int snd_ali_create(struct snd_car
 	return 0;
 }
 
-static int snd_ali_probe(struct pci_dev *pci,
-			 const struct pci_device_id *pci_id)
+static int __snd_ali_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct snd_ali *codec;
@@ -2170,6 +2170,12 @@ static int snd_ali_probe(struct pci_dev
 	return 0;
 }
 
+static int snd_ali_probe(struct pci_dev *pci,
+			 const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_ali_probe(pci, pci_id));
+}
+
 static struct pci_driver ali5451_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ali_ids,
author maintainer
#20 lore raw

PATCH 20/219 ALSA: als300: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit ab8bce9da6102c575c473c053672547589bc4c59 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes 21a9314cf93b ("ALSA: als300: Allocate resources with device-managed APIs")
---
 sound/pci/als300.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/als300.c +6 -2
@@ -708,7 +708,7 @@ static int snd_als300_probe(struct pci_d
 
 	err = snd_als300_create(card, pci, chip_type);
 	if (err < 0)
-		return err;
+		goto error;
 
 	strcpy(card->driver, "ALS300");
 	if (chip->chip_type == DEVICE_ALS300_PLUS)
@@ -723,11 +723,15 @@ static int snd_als300_probe(struct pci_d
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver als300_driver = {
author maintainer
#21 lore raw

PATCH 21/219 ALSA: als4000: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit d616a0246da88d811f9f4c3aa83003c05efd3af0 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 0e175f665960 ("ALSA: als4000: Allocate resources with device-managed APIs")
---
 sound/pci/als4000.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/als4000.c +8 -2
@@ -806,8 +806,8 @@ static void snd_card_als4000_free( struc
 	snd_als4000_free_gameport(acard);
 }
 
-static int snd_card_als4000_probe(struct pci_dev *pci,
-				  const struct pci_device_id *pci_id)
+static int __snd_card_als4000_probe(struct pci_dev *pci,
+				    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -930,6 +930,12 @@ static int snd_card_als4000_probe(struct
 	return 0;
 }
 
+static int snd_card_als4000_probe(struct pci_dev *pci,
+				  const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_card_als4000_probe(pci, pci_id));
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int snd_als4000_suspend(struct device *dev)
 {
author maintainer
#22 lore raw

PATCH 22/219 ALSA: atiixp: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 48e8adde8d1c586c799dab123fc1ebc8b8db620f upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 86bde74dbf09 ("ALSA: atiixp: Allocate resources with device-managed APIs")
---
 sound/pci/atiixp.c       |   10 ++++++++--
 sound/pci/atiixp_modem.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)
sound/pci/atiixp.c +8 -2
@@ -1572,8 +1572,8 @@ static int snd_atiixp_init(struct snd_ca
 }
 
 
-static int snd_atiixp_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_atiixp_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct atiixp *chip;
@@ -1623,6 +1623,12 @@ static int snd_atiixp_probe(struct pci_d
 	return 0;
 }
 
+static int snd_atiixp_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_atiixp_probe(pci, pci_id));
+}
+
 static struct pci_driver atiixp_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
sound/pci/atiixp_modem.c +8 -2
@@ -1201,8 +1201,8 @@ static int snd_atiixp_init(struct snd_ca
 }
 
 
-static int snd_atiixp_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_atiixp_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct atiixp_modem *chip;
@@ -1247,6 +1247,12 @@ static int snd_atiixp_probe(struct pci_d
 	return 0;
 }
 
+static int snd_atiixp_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_atiixp_probe(pci, pci_id));
+}
+
 static struct pci_driver atiixp_modem_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
author maintainer
#23 lore raw

PATCH 23/219 ALSA: au88x0: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit b093de145bc8769c6e9207947afad9efe102f4f6 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes e44b5b440609 ("ALSA: au88x0: Allocate resources with device-managed APIs")
---
 sound/pci/au88x0/au88x0.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/au88x0/au88x0.c +7 -1
@@ -193,7 +193,7 @@ snd_vortex_create(struct snd_card *card,
 
 // constructor -- see "Constructor" sub-section
 static int
-snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -310,6 +310,12 @@ snd_vortex_probe(struct pci_dev *pci, co
 	return 0;
 }
 
+static int
+snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_vortex_probe(pci, pci_id));
+}
+
 // pci_driver definition
 static struct pci_driver vortex_driver = {
 	.name = KBUILD_MODNAME,
author maintainer
#24 lore raw

PATCH 24/219 ALSA: aw2: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit bf4067e8a19eae67c45659a956c361d59251ba57 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes 33631012cd06 ("ALSA: aw2: Allocate resources with device-managed APIs")
---
 sound/pci/aw2/aw2-alsa.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/aw2/aw2-alsa.c +6 -2
@@ -275,7 +275,7 @@ static int snd_aw2_probe(struct pci_dev
 	/* (3) Create main component */
 	err = snd_aw2_create(card, pci);
 	if (err < 0)
-		return err;
+		goto error;
 
 	/* initialize mutex */
 	mutex_init(&chip->mtx);
@@ -294,13 +294,17 @@ static int snd_aw2_probe(struct pci_dev
 	/* (6) Register card instance */
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	/* (7) Set PCI driver data */
 	pci_set_drvdata(pci, card);
 
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 /* open callback */
author maintainer
#25 lore raw

PATCH 25/219 ALSA: azt3328: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 49fe36e1c02cb06f66689c888e4e767c31cd259d upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 8c5823ef31e1 ("ALSA: azt3328: Allocate resources with device-managed APIs")
---
 sound/pci/azt3328.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/azt3328.c +7 -1
@@ -2427,7 +2427,7 @@ snd_azf3328_create(struct snd_card *card
 }
 
 static int
-snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2520,6 +2520,12 @@ snd_azf3328_probe(struct pci_dev *pci, c
 	return 0;
 }
 
+static int
+snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_azf3328_probe(pci, pci_id));
+}
+
 #ifdef CONFIG_PM_SLEEP
 static inline void
 snd_azf3328_suspend_regs(const struct snd_azf3328 *chip,
author maintainer
#26 lore raw

PATCH 26/219 ALSA: bt87x: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit f0438155273f057fec9818bc9d1b782ba35cf6a1 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 9e80ed64a006 ("ALSA: bt87x: Allocate resources with device-managed APIs")
---
 sound/pci/bt87x.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/bt87x.c +8 -2
@@ -805,8 +805,8 @@ static int snd_bt87x_detect_card(struct
 	return SND_BT87X_BOARD_UNKNOWN;
 }
 
-static int snd_bt87x_probe(struct pci_dev *pci,
-			   const struct pci_device_id *pci_id)
+static int __snd_bt87x_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -889,6 +889,12 @@ static int snd_bt87x_probe(struct pci_de
 	return 0;
 }
 
+static int snd_bt87x_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_bt87x_probe(pci, pci_id));
+}
+
 /* default entries for all Bt87x cards - it's not exported */
 /* driver_data is set to 0 to call detection */
 static const struct pci_device_id snd_bt87x_default_ids[] = {
author maintainer
#27 lore raw

PATCH 27/219 ALSA: ca0106: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit c79442cc5a38e46597bc647128c8f1de62d80020 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 1656fa6ea258 ("ALSA: ca0106: Allocate resources with device-managed APIs")
---
 sound/pci/ca0106/ca0106_main.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/ca0106/ca0106_main.c +8 -2
@@ -1725,8 +1725,8 @@ static int snd_ca0106_midi(struct snd_ca
 }
 
 
-static int snd_ca0106_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int __snd_ca0106_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1786,6 +1786,12 @@ static int snd_ca0106_probe(struct pci_d
 	return 0;
 }
 
+static int snd_ca0106_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_ca0106_probe(pci, pci_id));
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int snd_ca0106_suspend(struct device *dev)
 {
author maintainer
#28 lore raw

PATCH 28/219 ALSA: cmipci: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit a59396b1c11823c69c31621198c04def17f3a869 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes 87e082ad84a7 ("ALSA: cmipci: Allocate resources with device-managed APIs")
---
 sound/pci/cmipci.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/cmipci.c +6 -2
@@ -3247,15 +3247,19 @@ static int snd_cmipci_probe(struct pci_d
 
 	err = snd_cmipci_create(card, pci, dev);
 	if (err < 0)
-		return err;
+		goto error;
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 #ifdef CONFIG_PM_SLEEP
author maintainer
#29 lore raw

PATCH 29/219 ALSA: cs4281: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 9bf5ed9a4e623583f15202d99f4521bc39050f61 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 99041fea70d0 ("ALSA: cs4281: Allocate resources with device-managed APIs")
---
 sound/pci/cs4281.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/cs4281.c +8 -2
@@ -1827,8 +1827,8 @@ static void snd_cs4281_opl3_command(stru
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-static int snd_cs4281_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_cs4281_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1888,6 +1888,12 @@ static int snd_cs4281_probe(struct pci_d
 	return 0;
 }
 
+static int snd_cs4281_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_cs4281_probe(pci, pci_id));
+}
+
 /*
  * Power Management
  */
author maintainer
#30 lore raw

PATCH 30/219 ALSA: cs5535audio: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 2a56314798e0227cf51e3d1d184a419dc07bc173 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

Fixes 5eba4c646dfe ("ALSA: cs5535audio: Allocate resources with device-managed APIs")
---
 sound/pci/cs5535audio/cs5535audio.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/cs5535audio/cs5535audio.c +8 -2
@@ -281,8 +281,8 @@ static int snd_cs5535audio_create(struct
 	return 0;
 }
 
-static int snd_cs5535audio_probe(struct pci_dev *pci,
-				 const struct pci_device_id *pci_id)
+static int __snd_cs5535audio_probe(struct pci_dev *pci,
+				   const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -331,6 +331,12 @@ static int snd_cs5535audio_probe(struct
 	return 0;
 }
 
+static int snd_cs5535audio_probe(struct pci_dev *pci,
+				 const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_cs5535audio_probe(pci, pci_id));
+}
+
 static struct pci_driver cs5535audio_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cs5535audio_ids,
author maintainer
#31 lore raw

PATCH 31/219 ALSA: echoaudio: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 313c7e57035125cb7533b53ddd0bc7aa562b433c upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

---
 sound/pci/echoaudio/echoaudio.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
sound/pci/echoaudio/echoaudio.c +7 -2
@@ -1970,8 +1970,8 @@ static int snd_echo_create(struct snd_ca
 }
 
 /* constructor */
-static int snd_echo_probe(struct pci_dev *pci,
-			  const struct pci_device_id *pci_id)
+static int __snd_echo_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2139,6 +2139,11 @@ static int snd_echo_probe(struct pci_dev
 	return 0;
 }
 
+static int snd_echo_probe(struct pci_dev *pci,
+			  const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_echo_probe(pci, pci_id));
+}
 
 
 #if defined(CONFIG_PM_SLEEP)
author maintainer
#32 lore raw

PATCH 32/219 ALSA: emu10k1x: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit f37019b6bfe2e13cc536af0e6a42ed62005392ae upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 2b377c6b6012 ("ALSA: emu10k1x: Allocate resources with device-managed APIs")
---
 sound/pci/emu10k1/emu10k1x.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/emu10k1/emu10k1x.c +8 -2
@@ -1491,8 +1491,8 @@ static int snd_emu10k1x_midi(struct emu1
 	return 0;
 }
 
-static int snd_emu10k1x_probe(struct pci_dev *pci,
-			      const struct pci_device_id *pci_id)
+static int __snd_emu10k1x_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1554,6 +1554,12 @@ static int snd_emu10k1x_probe(struct pci
 	return 0;
 }
 
+static int snd_emu10k1x_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_emu10k1x_probe(pci, pci_id));
+}
+
 // PCI IDs
 static const struct pci_device_id snd_emu10k1x_ids[] = {
 	{ PCI_VDEVICE(CREATIVE, 0x0006), 0 },	/* Dell OEM version (EMU10K1) */
author maintainer
#33 lore raw

PATCH 33/219 ALSA: ens137x: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit c2dc46932d117a1505f589ad1db3095aa6789058 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 10ed6eaf9d72 ("ALSA: ens137x: Allocate resources with device-managed APIs")
---
 sound/pci/ens1370.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/ens1370.c +8 -2
@@ -2304,8 +2304,8 @@ static irqreturn_t snd_audiopci_interrup
 	return IRQ_HANDLED;
 }
 
-static int snd_audiopci_probe(struct pci_dev *pci,
-			      const struct pci_device_id *pci_id)
+static int __snd_audiopci_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2369,6 +2369,12 @@ static int snd_audiopci_probe(struct pci
 	return 0;
 }
 
+static int snd_audiopci_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_audiopci_probe(pci, pci_id));
+}
+
 static struct pci_driver ens137x_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_audiopci_ids,
author maintainer
#34 lore raw

PATCH 34/219 ALSA: es1938: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit bc22628591e5913e67edb3c2a89b97849e30a8f8 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 08e9d3ab4cc1 ("ALSA: es1938: Allocate resources with device-managed APIs")
---
 sound/pci/es1938.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/es1938.c +8 -2
@@ -1716,8 +1716,8 @@ static int snd_es1938_mixer(struct es193
 }
        
 
-static int snd_es1938_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_es1938_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1796,6 +1796,12 @@ static int snd_es1938_probe(struct pci_d
 	return 0;
 }
 
+static int snd_es1938_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_es1938_probe(pci, pci_id));
+}
+
 static struct pci_driver es1938_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_es1938_ids,
author maintainer
#35 lore raw

PATCH 35/219 ALSA: es1968: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit de9a01bc95a9e5e36d0659521bb04579053d8566 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes a7b4cbfdc701 ("ALSA: es1968: Allocate resources with device-managed APIs")
---
 sound/pci/es1968.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/es1968.c +8 -2
@@ -2741,8 +2741,8 @@ static int snd_es1968_create(struct snd_
 
 /*
  */
-static int snd_es1968_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_es1968_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2848,6 +2848,12 @@ static int snd_es1968_probe(struct pci_d
 	return 0;
 }
 
+static int snd_es1968_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_es1968_probe(pci, pci_id));
+}
+
 static struct pci_driver es1968_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_es1968_ids,
author maintainer
#36 lore raw

PATCH 36/219 ALSA: fm801: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 7f611274a3d1657a67b3fa8cd0cec1dee00e02b4 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 47c413395376 ("ALSA: fm801: Allocate resources with device-managed APIs")
---
 sound/pci/fm801.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/fm801.c +8 -2
@@ -1268,8 +1268,8 @@ static int snd_fm801_create(struct snd_c
 	return 0;
 }
 
-static int snd_card_fm801_probe(struct pci_dev *pci,
-				const struct pci_device_id *pci_id)
+static int __snd_card_fm801_probe(struct pci_dev *pci,
+				  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1333,6 +1333,12 @@ static int snd_card_fm801_probe(struct p
 	return 0;
 }
 
+static int snd_card_fm801_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_card_fm801_probe(pci, pci_id));
+}
+
 #ifdef CONFIG_PM_SLEEP
 static const unsigned char saved_regs[] = {
 	FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
author maintainer
#37 lore raw

PATCH 37/219 ALSA: galaxy: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 10b1881a97be240126891cb384bd3bc1869f52d8 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 35a245ec0619 ("ALSA: galaxy: Allocate resources with device-managed APIs")
---
 sound/isa/galaxy/galaxy.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
sound/isa/galaxy/galaxy.c +6 -1
@@ -478,7 +478,7 @@ static void snd_galaxy_free(struct snd_c
 		galaxy_set_config(galaxy, galaxy->config);
 }
 
-static int snd_galaxy_probe(struct device *dev, unsigned int n)
+static int __snd_galaxy_probe(struct device *dev, unsigned int n)
 {
 	struct snd_galaxy *galaxy;
 	struct snd_wss *chip;
@@ -598,6 +598,11 @@ static int snd_galaxy_probe(struct devic
 	return 0;
 }
 
+static int snd_galaxy_probe(struct device *dev, unsigned int n)
+{
+	return snd_card_free_on_error(dev, __snd_galaxy_probe(dev, n));
+}
+
 static struct isa_driver snd_galaxy_driver = {
 	.match		= snd_galaxy_match,
 	.probe		= snd_galaxy_probe,
author maintainer
#38 lore raw

PATCH 38/219 ALSA: hdsp: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit e2263f0bf7443a200a5c1c418baefd92f1674600 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes d136b8e54f92 ("ALSA: hdsp: Allocate resources with device-managed APIs")
---
 sound/pci/rme9652/hdsp.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/rme9652/hdsp.c +6 -2
@@ -5444,17 +5444,21 @@ static int snd_hdsp_probe(struct pci_dev
 	hdsp->pci = pci;
 	err = snd_hdsp_create(card, hdsp);
 	if (err)
-		return err;
+		goto error;
 
 	strcpy(card->shortname, "Hammerfall DSP");
 	sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
 		hdsp->port, hdsp->irq);
 	err = snd_card_register(card);
 	if (err)
-		return err;
+		goto error;
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver hdsp_driver = {
author maintainer
#39 lore raw

PATCH 39/219 ALSA: hdspm: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit eab521aebcdeb1c801009503e3a7f8989e3c6b36 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes 0195ca5fd1f4 ("ALSA: hdspm: Allocate resources with device-managed APIs")
---
 sound/pci/rme9652/hdspm.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/rme9652/hdspm.c +6 -2
@@ -6895,7 +6895,7 @@ static int snd_hdspm_probe(struct pci_de
 
 	err = snd_hdspm_create(card, hdspm);
 	if (err < 0)
-		return err;
+		goto error;
 
 	if (hdspm->io_type != MADIface) {
 		snprintf(card->shortname, sizeof(card->shortname), "%s_%x",
@@ -6914,12 +6914,16 @@ static int snd_hdspm_probe(struct pci_de
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	pci_set_drvdata(pci, card);
 
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver hdspm_driver = {
author maintainer
#40 lore raw

PATCH 40/219 ALSA: ice1724: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 4a850a0079ce601c0c4016f4edb7d618e811ed7d upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 314f6dbb1f33 ("ALSA: ice1724: Allocate resources with device-managed APIs")
---
 sound/pci/ice1712/ice1724.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/ice1712/ice1724.c +8 -2
@@ -2519,8 +2519,8 @@ static int snd_vt1724_create(struct snd_
  *
  */
 
-static int snd_vt1724_probe(struct pci_dev *pci,
-			    const struct pci_device_id *pci_id)
+static int __snd_vt1724_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2662,6 +2662,12 @@ static int snd_vt1724_probe(struct pci_d
 	return 0;
 }
 
+static int snd_vt1724_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_vt1724_probe(pci, pci_id));
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int snd_vt1724_suspend(struct device *dev)
 {
author maintainer
#41 lore raw

PATCH 41/219 ALSA: intel8x0: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 71b21f5f8970a87f034138454ebeff0608d24875 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 7835e0901e24 ("ALSA: intel8x0: Allocate resources with device-managed APIs")
---
 sound/pci/intel8x0.c  |   10 ++++++++--
 sound/pci/intel8x0m.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)
sound/pci/intel8x0.c +8 -2
@@ -3109,8 +3109,8 @@ static int check_default_spdif_aclink(st
 	return 0;
 }
 
-static int snd_intel8x0_probe(struct pci_dev *pci,
-			      const struct pci_device_id *pci_id)
+static int __snd_intel8x0_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct intel8x0 *chip;
@@ -3189,6 +3189,12 @@ static int snd_intel8x0_probe(struct pci
 	return 0;
 }
 
+static int snd_intel8x0_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_intel8x0_probe(pci, pci_id));
+}
+
 static struct pci_driver intel8x0_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0_ids,
sound/pci/intel8x0m.c +8 -2
@@ -1178,8 +1178,8 @@ static struct shortname_table {
 	{ 0 },
 };
 
-static int snd_intel8x0m_probe(struct pci_dev *pci,
-			       const struct pci_device_id *pci_id)
+static int __snd_intel8x0m_probe(struct pci_dev *pci,
+				 const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct intel8x0m *chip;
@@ -1225,6 +1225,12 @@ static int snd_intel8x0m_probe(struct pc
 	return 0;
 }
 
+static int snd_intel8x0m_probe(struct pci_dev *pci,
+			       const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_intel8x0m_probe(pci, pci_id));
+}
+
 static struct pci_driver intel8x0m_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0m_ids,
author maintainer
#42 lore raw

PATCH 42/219 ALSA: intel_hdmi: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 5e154dfb4f9995096aa6d342df75040ae802c17e upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 854577ac2aea ("ALSA: x86: Allocate resources with device-managed APIs")
---
 sound/x86/intel_hdmi_audio.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
sound/x86/intel_hdmi_audio.c +6 -1
@@ -1665,7 +1665,7 @@ static void hdmi_lpe_audio_free(struct s
  * This function is called when the i915 driver creates the
  * hdmi-lpe-audio platform device.
  */
-static int hdmi_lpe_audio_probe(struct platform_device *pdev)
+static int __hdmi_lpe_audio_probe(struct platform_device *pdev)
 {
 	struct snd_card *card;
 	struct snd_intelhad_card *card_ctx;
@@ -1828,6 +1828,11 @@ static int hdmi_lpe_audio_probe(struct p
 	return 0;
 }
 
+static int hdmi_lpe_audio_probe(struct platform_device *pdev)
+{
+	return snd_card_free_on_error(&pdev->dev, __hdmi_lpe_audio_probe(pdev));
+}
+
 static const struct dev_pm_ops hdmi_lpe_audio_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume)
 };
author maintainer
#43 lore raw

PATCH 43/219 ALSA: korg1212: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit c01b723a56ce18ae66ff18c5803942badc15fbcd upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes b5cde369b618 ("ALSA: korg1212: Allocate resources with device-managed APIs")
---
 sound/pci/korg1212/korg1212.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/korg1212/korg1212.c +6 -2
@@ -2355,7 +2355,7 @@ snd_korg1212_probe(struct pci_dev *pci,
 
 	err = snd_korg1212_create(card, pci);
 	if (err < 0)
-		return err;
+		goto error;
 
 	strcpy(card->driver, "korg1212");
 	strcpy(card->shortname, "korg1212");
@@ -2366,10 +2366,14 @@ snd_korg1212_probe(struct pci_dev *pci,
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver korg1212_driver = {
author maintainer
#44 lore raw

PATCH 44/219 ALSA: lola: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit d04e84b9817c652002f0ee9b42059d41493e9118 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 098fe3d6e775 ("ALSA: lola: Allocate resources with device-managed APIs")
---
 sound/pci/lola/lola.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/lola/lola.c +8 -2
@@ -637,8 +637,8 @@ static int lola_create(struct snd_card *
 	return 0;
 }
 
-static int lola_probe(struct pci_dev *pci,
-		      const struct pci_device_id *pci_id)
+static int __lola_probe(struct pci_dev *pci,
+			const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -687,6 +687,12 @@ static int lola_probe(struct pci_dev *pc
 	return 0;
 }
 
+static int lola_probe(struct pci_dev *pci,
+		      const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __lola_probe(pci, pci_id));
+}
+
 /* PCI IDs */
 static const struct pci_device_id lola_ids[] = {
 	{ PCI_VDEVICE(DIGIGRAM, 0x0001) },
author maintainer
#45 lore raw

PATCH 45/219 ALSA: lx6464es: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 60797a21dd8360a99ba797f8ca587087c07bb54c upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes 6f16c19b115e ("ALSA: lx6464es: Allocate resources with device-managed APIs")
---
 sound/pci/lx6464es/lx6464es.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/lx6464es/lx6464es.c +6 -2
@@ -1019,7 +1019,7 @@ static int snd_lx6464es_probe(struct pci
 	err = snd_lx6464es_create(card, pci);
 	if (err < 0) {
 		dev_err(card->dev, "error during snd_lx6464es_create\n");
-		return err;
+		goto error;
 	}
 
 	strcpy(card->driver, "LX6464ES");
@@ -1036,12 +1036,16 @@ static int snd_lx6464es_probe(struct pci
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	dev_dbg(chip->card->dev, "initialization successful\n");
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver lx6464es_driver = {
author maintainer
#46 lore raw

PATCH 46/219 ALSA: maestro3: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit ae86bf5c2a8d81418eadf1c31dd9253b609e3093 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 5c0939253c3c ("ALSA: maestro3: Allocate resources with device-managed APIs")
---
 sound/pci/maestro3.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/maestro3.c +7 -1
@@ -2637,7 +2637,7 @@ snd_m3_create(struct snd_card *card, str
 /*
  */
 static int
-snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2702,6 +2702,12 @@ snd_m3_probe(struct pci_dev *pci, const
 	return 0;
 }
 
+static int
+snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_m3_probe(pci, pci_id));
+}
+
 static struct pci_driver m3_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_m3_ids,
author maintainer
#47 lore raw

PATCH 47/219 ALSA: oxygen: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 6ebc16e206aa82ddb0450c907865c55bcb7c0f43 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 596ae97ab0ce ("ALSA: oxygen: Allocate resources with device-managed APIs")
---
 sound/pci/oxygen/oxygen_lib.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
sound/pci/oxygen/oxygen_lib.c +11 -1
@@ -576,7 +576,7 @@ static void oxygen_card_free(struct snd_
 	mutex_destroy(&chip->mutex);
 }
 
-int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
+static int __oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
 		     struct module *owner,
 		     const struct pci_device_id *ids,
 		     int (*get_model)(struct oxygen *chip,
@@ -701,6 +701,16 @@ int oxygen_pci_probe(struct pci_dev *pci
 	pci_set_drvdata(pci, card);
 	return 0;
 }
+
+int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
+		     struct module *owner,
+		     const struct pci_device_id *ids,
+		     int (*get_model)(struct oxygen *chip,
+				      const struct pci_device_id *id))
+{
+	return snd_card_free_on_error(&pci->dev,
+				      __oxygen_pci_probe(pci, index, id, owner, ids, get_model));
+}
 EXPORT_SYMBOL(oxygen_pci_probe);
 
 #ifdef CONFIG_PM_SLEEP
author maintainer
#48 lore raw

PATCH 48/219 ALSA: riptide: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 348f08de55b149e41a05111d1a713c4484e5a426 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 546c201a891e ("ALSA: riptide: Allocate resources with device-managed APIs")
---
 sound/pci/riptide/riptide.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/riptide/riptide.c +7 -1
@@ -2023,7 +2023,7 @@ static void snd_riptide_joystick_remove(
 #endif
 
 static int
-snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2124,6 +2124,12 @@ snd_card_riptide_probe(struct pci_dev *p
 	return 0;
 }
 
+static int
+snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_card_riptide_probe(pci, pci_id));
+}
+
 static struct pci_driver driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_riptide_ids,
author maintainer
#49 lore raw

PATCH 49/219 ALSA: rme32: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 55d2d046b23b9bcb907f6b3e38e52113d55085eb upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 102e6156ded2 ("ALSA: rme32: Allocate resources with device-managed APIs")
---
 sound/pci/rme32.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/rme32.c +7 -1
@@ -1875,7 +1875,7 @@ static void snd_rme32_card_free(struct s
 }
 
 static int
-snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct rme32 *rme32;
@@ -1927,6 +1927,12 @@ snd_rme32_probe(struct pci_dev *pci, con
 	return 0;
 }
 
+static int
+snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_rme32_probe(pci, pci_id));
+}
+
 static struct pci_driver rme32_driver = {
 	.name =		KBUILD_MODNAME,
 	.id_table =	snd_rme32_ids,
author maintainer
#50 lore raw

PATCH 50/219 ALSA: rme9652: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit b2aa4f80693b7841e5ac4eadbd2d8cec56b10a51 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() manually on the error from the probe callback.

Fixes b1002b2d41c5 ("ALSA: rme9652: Allocate resources with device-managed APIs")
---
 sound/pci/rme9652/rme9652.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/rme9652/rme9652.c +6 -2
@@ -2572,7 +2572,7 @@ static int snd_rme9652_probe(struct pci_
 	rme9652->pci = pci;
 	err = snd_rme9652_create(card, rme9652, precise_ptr[dev]);
 	if (err)
-		return err;
+		goto error;
 
 	strcpy(card->shortname, rme9652->card_name);
 
@@ -2580,10 +2580,14 @@ static int snd_rme9652_probe(struct pci_
 		card->shortname, rme9652->port, rme9652->irq);
 	err = snd_card_register(card);
 	if (err)
-		return err;
+		goto error;
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver rme9652_driver = {
author maintainer
#51 lore raw

PATCH 51/219 ALSA: rme96: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 93b884f8d82f08c7af542703a724cc23cd2d5bfc upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes df06df7cc997 ("ALSA: rme96: Allocate resources with device-managed APIs")
---
 sound/pci/rme96.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/rme96.c +8 -2
@@ -2430,8 +2430,8 @@ static void snd_rme96_card_free(struct s
 }
 
 static int
-snd_rme96_probe(struct pci_dev *pci,
-		const struct pci_device_id *pci_id)
+__snd_rme96_probe(struct pci_dev *pci,
+		  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct rme96 *rme96;
@@ -2498,6 +2498,12 @@ snd_rme96_probe(struct pci_dev *pci,
 	return 0;
 }
 
+static int snd_rme96_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_rme96_probe(pci, pci_id));
+}
+
 static struct pci_driver rme96_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_rme96_ids,
author maintainer
#52 lore raw

PATCH 52/219 ALSA: sc6000: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit d72458071150b802940204950d0d462ea3c913b1 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 111601ff76e9 ("ALSA: sc6000: Allocate resources with device-managed APIs")
---
 sound/isa/sc6000.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
sound/isa/sc6000.c +6 -1
@@ -537,7 +537,7 @@ static void snd_sc6000_free(struct snd_c
 		sc6000_setup_board(vport, 0);
 }
 
-static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
+static int __snd_sc6000_probe(struct device *devptr, unsigned int dev)
 {
 	static const int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
 	static const int possible_dmas[] = { 1, 3, 0, -1 };
@@ -662,6 +662,11 @@ static int snd_sc6000_probe(struct devic
 	return 0;
 }
 
+static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
+{
+	return snd_card_free_on_error(devptr, __snd_sc6000_probe(devptr, dev));
+}
+
 static struct isa_driver snd_sc6000_driver = {
 	.match		= snd_sc6000_match,
 	.probe		= snd_sc6000_probe,
author maintainer
#53 lore raw

PATCH 53/219 ALSA: sonicvibes: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit b087a381d7386ec95803222d0d9b1ac499550713 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 2ca6cbde6ad7 ("ALSA: sonicvibes: Allocate resources with device-managed APIs")
---
 sound/pci/sonicvibes.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/sonicvibes.c +8 -2
@@ -1387,8 +1387,8 @@ static int snd_sonicvibes_midi(struct so
 	return 0;
 }
 
-static int snd_sonic_probe(struct pci_dev *pci,
-			   const struct pci_device_id *pci_id)
+static int __snd_sonic_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1459,6 +1459,12 @@ static int snd_sonic_probe(struct pci_de
 	return 0;
 }
 
+static int snd_sonic_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_sonic_probe(pci, pci_id));
+}
+
 static struct pci_driver sonicvibes_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_sonic_ids,
author maintainer
#54 lore raw

PATCH 54/219 ALSA: via82xx: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 27a0963f9cea5be3c68281f07fe82cdf712ef333 upstream.

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes afaf99751d0c ("ALSA: via82xx: Allocate resources with device-managed APIs")
---
 sound/pci/via82xx.c       |   10 ++++++++--
 sound/pci/via82xx_modem.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)
sound/pci/via82xx.c +8 -2
@@ -2458,8 +2458,8 @@ static int check_dxs_list(struct pci_dev
 	return VIA_DXS_48K;
 };
 
-static int snd_via82xx_probe(struct pci_dev *pci,
-			     const struct pci_device_id *pci_id)
+static int __snd_via82xx_probe(struct pci_dev *pci,
+			       const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct via82xx *chip;
@@ -2569,6 +2569,12 @@ static int snd_via82xx_probe(struct pci_
 	return 0;
 }
 
+static int snd_via82xx_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_via82xx_probe(pci, pci_id));
+}
+
 static struct pci_driver via82xx_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_ids,
sound/pci/via82xx_modem.c +8 -2
@@ -1103,8 +1103,8 @@ static int snd_via82xx_create(struct snd
 }
 
 
-static int snd_via82xx_probe(struct pci_dev *pci,
-			     const struct pci_device_id *pci_id)
+static int __snd_via82xx_probe(struct pci_dev *pci,
+			       const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct via82xx_modem *chip;
@@ -1157,6 +1157,12 @@ static int snd_via82xx_probe(struct pci_
 	return 0;
 }
 
+static int snd_via82xx_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_via82xx_probe(pci, pci_id));
+}
+
 static struct pci_driver via82xx_modem_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_modem_ids,
author maintainer
#55 lore raw

PATCH 55/219 ALSA: usb-audio: Cap upper limits of buffer/period bytes for implicit fb

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 98c27add5d96485db731a92dac31567b0486cae8 upstream.

In the implicit feedback mode, some parameters are tied between both playback and capture streams. One of the tied parameters is the period size, and this can be a problem if the device has different number of channels to both streams. Assume that an application opens a playback stream that has an implicit feedback from a capture stream, and it allocates up to the max period and buffer size as much as possible. When the capture device supports only more channels than the playback, the minimum period and buffer sizes become larger than the sizes the playback stream took. That is, the minimum size will be over the max size the driver limits, and PCM core sees as if no available configuration is found, returning -EINVAL mercilessly.

For avoiding this problem, we have to look through the counter part of audioformat list for each sync ep, and checks the channels. If more channels are found there, we reduce the max period and buffer sizes accordingly.

You may wonder that the patch adds only the evaluation of channels between streams, and what about other parameters? Both the format and the rate are tied in the implicit fb mode, hence they are always identical.

---
 sound/usb/pcm.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 87 insertions(+), 2 deletions(-)
sound/usb/pcm.c +87 -2
@@ -659,6 +659,9 @@ static int snd_usb_pcm_prepare(struct sn
 #define hwc_debug(fmt, args...) do { } while(0)
 #endif
 
+#define MAX_BUFFER_BYTES	(1024 * 1024)
+#define MAX_PERIOD_BYTES	(512 * 1024)
+
 static const struct snd_pcm_hardware snd_usb_hardware =
 {
 	.info =			SNDRV_PCM_INFO_MMAP |
@@ -669,9 +672,9 @@ static const struct snd_pcm_hardware snd
 				SNDRV_PCM_INFO_PAUSE,
 	.channels_min =		1,
 	.channels_max =		256,
-	.buffer_bytes_max =	1024 * 1024,
+	.buffer_bytes_max =	MAX_BUFFER_BYTES,
 	.period_bytes_min =	64,
-	.period_bytes_max =	512 * 1024,
+	.period_bytes_max =	MAX_PERIOD_BYTES,
 	.periods_min =		2,
 	.periods_max =		1024,
 };
@@ -971,6 +974,78 @@ static int hw_rule_periods_implicit_fb(s
 				      ep->cur_buffer_periods);
 }
 
+/* get the adjusted max buffer (or period) bytes that can fit with the
+ * paired format for implicit fb
+ */
+static unsigned int
+get_adjusted_max_bytes(struct snd_usb_substream *subs,
+		       struct snd_usb_substream *pair,
+		       struct snd_pcm_hw_params *params,
+		       unsigned int max_bytes,
+		       bool reverse_map)
+{
+	const struct audioformat *fp, *pp;
+	unsigned int rmax = 0, r;
+
+	list_for_each_entry(fp, &subs->fmt_list, list) {
+		if (!fp->implicit_fb)
+			continue;
+		if (!reverse_map &&
+		    !hw_check_valid_format(subs, params, fp))
+			continue;
+		list_for_each_entry(pp, &pair->fmt_list, list) {
+			if (pp->iface != fp->sync_iface ||
+			    pp->altsetting != fp->sync_altsetting ||
+			    pp->ep_idx != fp->sync_ep_idx)
+				continue;
+			if (reverse_map &&
+			    !hw_check_valid_format(pair, params, pp))
+				break;
+			if (!reverse_map && pp->channels > fp->channels)
+				r = max_bytes * fp->channels / pp->channels;
+			else if (reverse_map && pp->channels < fp->channels)
+				r = max_bytes * pp->channels / fp->channels;
+			else
+				r = max_bytes;
+			rmax = max(rmax, r);
+			break;
+		}
+	}
+	return rmax;
+}
+
+/* Reduce the period or buffer bytes depending on the paired substream;
+ * when a paired configuration for implicit fb has a higher number of channels,
+ * we need to reduce the max size accordingly, otherwise it may become unusable
+ */
+static int hw_rule_bytes_implicit_fb(struct snd_pcm_hw_params *params,
+				     struct snd_pcm_hw_rule *rule)
+{
+	struct snd_usb_substream *subs = rule->private;
+	struct snd_usb_substream *pair;
+	struct snd_interval *it;
+	unsigned int max_bytes;
+	unsigned int rmax;
+
+	pair = &subs->stream->substream[!subs->direction];
+	if (!pair->ep_num)
+		return 0;
+
+	if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_BYTES)
+		max_bytes = MAX_PERIOD_BYTES;
+	else
+		max_bytes = MAX_BUFFER_BYTES;
+
+	rmax = get_adjusted_max_bytes(subs, pair, params, max_bytes, false);
+	if (!rmax)
+		rmax = get_adjusted_max_bytes(pair, subs, params, max_bytes, true);
+	if (!rmax)
+		return 0;
+
+	it = hw_param_interval(params, rule->var);
+	return apply_hw_params_minmax(it, 0, rmax);
+}
+
 /*
  * set up the runtime hardware information.
  */
@@ -1085,6 +1160,16 @@ static int setup_hw_info(struct snd_pcm_
 				  SNDRV_PCM_HW_PARAM_PERIODS, -1);
 	if (err < 0)
 		return err;
+	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+				  hw_rule_bytes_implicit_fb, subs,
+				  SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
+	if (err < 0)
+		return err;
+	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+				  hw_rule_bytes_implicit_fb, subs,
+				  SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
+	if (err < 0)
+		return err;
 
 	list_for_each_entry(fp, &subs->fmt_list, list) {
 		if (fp->implicit_fb) {
author maintainer
#56 lore raw

PATCH 56/219 ALSA: memalloc: Add fallback SG-buffer allocations for x86

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 925ca893b4a65177394581737b95d03fea2660f2 upstream.

The recent change for memory allocator replaced the SG-buffer handling helper for x86 with the standard non-contiguous page handler. This works for most cases, but there is a corner case I obviously overlooked, namely, the fallback of non-contiguous handler without IOMMU. When the system runs without IOMMU, the core handler tries to use the continuous pages with a single SGL entry. It works nicely for most cases, but when the system memory gets fragmented, the large allocation may fail frequently.

Ideally the non-contig handler could deal with the proper SG pages, it's cumbersome to extend for now. As a workaround, here we add new types for (minimalistic) SG allocations, instead, so that the allocator falls back to those types automatically when the allocation with the standard API failed.

BTW, one better (but pretty minor) improvement from the previous SG-buffer code is that this provides the proper mmap support without the PCM's page fault handling.

---
 include/sound/memalloc.h |   5 ++
 sound/core/memalloc.c    | 111 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 115 insertions(+), 1 deletion(-)
include/sound/memalloc.h +5 -0
index 653dfffb3ac8..8d79cebf95f3 100644
@@ -51,6 +51,11 @@ struct snd_dma_device {
 #define SNDRV_DMA_TYPE_DEV_SG	SNDRV_DMA_TYPE_DEV /* no SG-buf support */
 #define SNDRV_DMA_TYPE_DEV_WC_SG	SNDRV_DMA_TYPE_DEV_WC
 #endif
+/* fallback types, don't use those directly */
+#ifdef CONFIG_SND_DMA_SGBUF
+#define SNDRV_DMA_TYPE_DEV_SG_FALLBACK		10
+#define SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK	11
+#endif
 
 /*
  * info for buffer allocation
sound/core/memalloc.c +110 -1

142 lines not on this page · raw message

Signature · 1 line
2.35.2
author maintainer
#57 lore raw

PATCH 57/219 ALSA: nm256: Dont call card private_free at probe error path

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit f20ae5074dfb38f23b0c07c62bdf8e7254a0acf8 upstream.

The card destructor of nm256 driver does merely stopping the running streams, and it's superfluous for the probe error handling. Moreover, calling this via the previous devres change would lead to another problem due to the reverse call order.

This patch moves the setup of the private_free callback after the card registration, so that it can be used only after fully set up.

Fixes c19935f04784 ("ALSA: nm256: Allocate resources with device-managed APIs")
---
 sound/pci/nm256/nm256.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/nm256/nm256.c +1 -1
@@ -1573,7 +1573,6 @@ snd_nm256_create(struct snd_card *card,
 	chip->coeffs_current = 0;
 
 	snd_nm256_init_chip(chip);
-	card->private_free = snd_nm256_free;
 
 	// pci_set_master(pci); /* needed? */
 	return 0;
@@ -1680,6 +1679,7 @@ static int snd_nm256_probe(struct pci_de
 	err = snd_card_register(card);
 	if (err < 0)
 		return err;
+	card->private_free = snd_nm256_free;
 
 	pci_set_drvdata(pci, card);
 	return 0;
author maintainer
#58 lore raw

PATCH 58/219 drm/msm: Add missing put_task_struct() in debugfs path

In reply to Greg Kroah-Hartman

From: Rob Clark <[email protected]>

[ Upstream commit ac3e4f42d5ec459f701743debd9c1ad2f2247402 ]

Fixes 25faf2f2e065 ("drm/msm: Show process names in gem_describe")
---
 drivers/gpu/drm/msm/msm_gem.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/msm/msm_gem.c +1 -0
index 02b9ae65a96a..a4f61972667b 100644
@@ -926,6 +926,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m,
 					get_pid_task(aspace->pid, PIDTYPE_PID);
 				if (task) {
 					comm = kstrdup(task->comm, GFP_KERNEL);
+					put_task_struct(task);
 				} else {
 					comm = NULL;
 				}
Signature · 1 line
2.35.1
author maintainer
#59 lore raw

PATCH 59/219 nfsd: Fix a write performance regression

In reply to Greg Kroah-Hartman

From: Trond Myklebust <[email protected]>

[ Upstream commit 6b8a94332ee4f7d9a8ae0cbac7609f79c212f06c ]

The call to filemap_flush() in nfsd_file_put() is there to ensure that we clear out any writes belonging to a NFSv3 client relatively quickly and avoid situations where the file can't be evicted by the garbage collector. It also ensures that we detect write errors quickly.

The problem is this causes a regression in performance for some workloads.

So try to improve matters by deferring writeback until we're ready to close the file, and need to detect errors so that we can force the client to resend.

Fixes b6669305d35a ("nfsd: Reduce the number of calls to nfsd_file_gc()")
---
 fs/nfsd/filecache.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
fs/nfsd/filecache.c +15 -3
index cc2831cec669..496f7b3f7523 100644
@@ -235,6 +235,13 @@ nfsd_file_check_write_error(struct nfsd_file *nf)
 	return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err));
 }
 
+static void
+nfsd_file_flush(struct nfsd_file *nf)
+{
+	if (nf->nf_file && vfs_fsync(nf->nf_file, 1) != 0)
+		nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
+}
+
 static void
 nfsd_file_do_unhash(struct nfsd_file *nf)
 {
@@ -302,11 +309,14 @@ nfsd_file_put(struct nfsd_file *nf)
 		return;
 	}
 
-	filemap_flush(nf->nf_file->f_mapping);
 	is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
-	nfsd_file_put_noref(nf);
-	if (is_hashed)
+	if (!is_hashed) {
+		nfsd_file_flush(nf);
+		nfsd_file_put_noref(nf);
+	} else {
+		nfsd_file_put_noref(nf);
 		nfsd_file_schedule_laundrette();
+	}
 	if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
 		nfsd_file_gc();
 }
@@ -327,6 +337,7 @@ nfsd_file_dispose_list(struct list_head *dispose)
 	while(!list_empty(dispose)) {
 		nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
 		list_del(&nf->nf_lru);
+		nfsd_file_flush(nf);
 		nfsd_file_put_noref(nf);
 	}
 }
@@ -340,6 +351,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
 	while(!list_empty(dispose)) {
 		nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
 		list_del(&nf->nf_lru);
+		nfsd_file_flush(nf);
 		if (!refcount_dec_and_test(&nf->nf_ref))
 			continue;
 		if (nfsd_file_free(nf))
Signature · 1 line
2.35.1
author maintainer
#60 lore raw

PATCH 60/219 firmware: arm_scmi: Remove clear channel call on the TX channel

In reply to Greg Kroah-Hartman

From: Cristian Marussi <[email protected]>

[ Upstream commit 98f0d68f94ea21541e0050cc64fa108ade779839 ]

On SCMI transports whose channels are based on a shared resource the TX channel area has to be acquired by the agent before placing the desired command into the channel and it will be then relinquished by the platform once the related reply has been made available into the channel. On an RX channel the logic is reversed with the platform acquiring the channel area and the agent reliquishing it once done by calling the scmi_clear_channel() helper.

As a consequence, even in case of error, the agent must never try to clear a TX channel from its side: restrict the existing clear channel call on the the reply path only to delayed responses since they are indeed coming from the RX channel.

Fixes e9b21c96181c ("firmware: arm_scmi: Make .clear_channel optional")
---
 drivers/firmware/arm_scmi/driver.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/firmware/arm_scmi/driver.c +2 -1
index d76bab3aaac4..e815b8f98739 100644
@@ -652,7 +652,8 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
 
 	xfer = scmi_xfer_command_acquire(cinfo, msg_hdr);
 	if (IS_ERR(xfer)) {
-		scmi_clear_channel(info, cinfo);
+		if (MSG_XTRACT_TYPE(msg_hdr) == MSG_TYPE_DELAYED_RESP)
+			scmi_clear_channel(info, cinfo);
 		return;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#61 lore raw

PATCH 61/219 memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe

In reply to Greg Kroah-Hartman

From: Miaoqian Lin <[email protected]>

[ Upstream commit 6f296a9665ba5ac68937bf11f96214eb9de81baa ]

The device_node pointer is returned by of_parse_phandle() with refcount incremented. We should use of_node_put() on it when done.

Fixes 87108dc78eb8 ("memory: atmel-ebi: Enable the SMC clock if specified")
---
 drivers/memory/atmel-ebi.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/memory/atmel-ebi.c +17 -6
index c267283b01fd..e749dcb3ddea 100644
@@ -544,20 +544,27 @@ static int atmel_ebi_probe(struct platform_device *pdev)
 	smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
 
 	ebi->smc.regmap = syscon_node_to_regmap(smc_np);
-	if (IS_ERR(ebi->smc.regmap))
-		return PTR_ERR(ebi->smc.regmap);
+	if (IS_ERR(ebi->smc.regmap)) {
+		ret = PTR_ERR(ebi->smc.regmap);
+		goto put_node;
+	}
 
 	ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np);
-	if (IS_ERR(ebi->smc.layout))
-		return PTR_ERR(ebi->smc.layout);
+	if (IS_ERR(ebi->smc.layout)) {
+		ret = PTR_ERR(ebi->smc.layout);
+		goto put_node;
+	}
 
 	ebi->smc.clk = of_clk_get(smc_np, 0);
 	if (IS_ERR(ebi->smc.clk)) {
-		if (PTR_ERR(ebi->smc.clk) != -ENOENT)
-			return PTR_ERR(ebi->smc.clk);
+		if (PTR_ERR(ebi->smc.clk) != -ENOENT) {
+			ret = PTR_ERR(ebi->smc.clk);
+			goto put_node;
+		}
 
 		ebi->smc.clk = NULL;
 	}
+	of_node_put(smc_np);
 	ret = clk_prepare_enable(ebi->smc.clk);
 	if (ret)
 		return ret;
@@ -608,6 +615,10 @@ static int atmel_ebi_probe(struct platform_device *pdev)
 	}
 
 	return of_platform_populate(np, NULL, NULL, dev);
+
+put_node:
+	of_node_put(smc_np);
+	return ret;
 }
 
 static __maybe_unused int atmel_ebi_resume(struct device *dev)
Signature · 1 line
2.35.1
author maintainer
#62 lore raw

PATCH 62/219 Revert "ath11k: mesh: add support for 256 bitmap in blockack frames in 11ax"

In reply to Greg Kroah-Hartman

From: Anilkumar Kolli <[email protected]>

[ Upstream commit 10cb21f4ff3f9cb36d1e1c39bf80426f02f4986a ]

This reverts commit 743b9065fe6348a5f8f5ce04869ce2d701e5e1bc.

The original commit breaks the 256 bitmap in blockack frames in AP mode. After reverting the commit the feature works again in both AP and mesh modes

Tested-on: IPQ8074 hw2.0 PCI WLAN.HK.2.6.0.1-00786-QCAHKSWPL_SILICONZ-1

Fixes 743b9065fe63 ("ath11k: mesh: add support for 256 bitmap in blockack frames in 11ax")
---
 drivers/net/wireless/ath/ath11k/mac.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +14 -8
index 28de877ad6c4..f54d5819477a 100644
@@ -3131,6 +3131,20 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
 			arvif->do_not_send_tmpl = true;
 		else
 			arvif->do_not_send_tmpl = false;
+
+		if (vif->bss_conf.he_support) {
+			ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+							    WMI_VDEV_PARAM_BA_MODE,
+							    WMI_BA_MODE_BUFFER_SIZE_256);
+			if (ret)
+				ath11k_warn(ar->ab,
+					    "failed to set BA BUFFER SIZE 256 for vdev: %d\n",
+					    arvif->vdev_id);
+			else
+				ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+					   "Set BA BUFFER SIZE 256 for VDEV: %d\n",
+					   arvif->vdev_id);
+		}
 	}
 
 	if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
@@ -3166,14 +3180,6 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
 
 		if (arvif->is_up && vif->bss_conf.he_support &&
 		    vif->bss_conf.he_oper.params) {
-			ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
-							    WMI_VDEV_PARAM_BA_MODE,
-							    WMI_BA_MODE_BUFFER_SIZE_256);
-			if (ret)
-				ath11k_warn(ar->ab,
-					    "failed to set BA BUFFER SIZE 256 for vdev: %d\n",
-					    arvif->vdev_id);
-
 			param_id = WMI_VDEV_PARAM_HEOPS_0_31;
 			param_value = vif->bss_conf.he_oper.params;
 			ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
Signature · 1 line
2.35.1
author maintainer
#63 lore raw

PATCH 63/219 firmware: arm_scmi: Fix sorting of retrieved clock rates

In reply to Greg Kroah-Hartman

From: Cristian Marussi <[email protected]>

[ Upstream commit 23274739a5b6166f74d8d9cb5243d7bf6b46aab9 ]

During SCMI Clock protocol initialization, after having retrieved from the SCMI platform all the available discrete rates for a specific clock, the clock rates array is sorted, unfortunately using a pointer to its end as a base instead of its start, so that sorting does not work.

Fix invocation of sort() passing as base a pointer to the start of the retrieved clock rates array.

Fixes dccec73de91d ("firmware: arm_scmi: Keep the discrete clock rates sorted")
---
 drivers/firmware/arm_scmi/clock.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/firmware/arm_scmi/clock.c +2 -1
index 35b56c8ba0c0..492f3a9197ec 100644
@@ -204,7 +204,8 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
 
 	if (rate_discrete && rate) {
 		clk->list.num_rates = tot_rate_cnt;
-		sort(rate, tot_rate_cnt, sizeof(*rate), rate_cmp_func, NULL);
+		sort(clk->list.rates, tot_rate_cnt, sizeof(*rate),
+		     rate_cmp_func, NULL);
 	}
 
 	clk->rate_discrete = rate_discrete;
Signature · 1 line
2.35.1
author maintainer
#64 lore raw

PATCH 64/219 media: rockchip/rga: do proper error checking in probe

In reply to Greg Kroah-Hartman

From: Kyle Copperfield <[email protected]>

[ Upstream commit 6150f276073a1480030242a7e006a89e161d6cd6 ]

The latest fix for probe error handling contained a typo that causes probing to fail with the following message:

rockchip-rga: probe of ff680000.rga failed with error -12

This patch fixes the typo.

---
 drivers/media/platform/rockchip/rga/rga.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/rockchip/rga/rga.c +1 -1
index 4de5e8d2b261..3d3d1062e212 100644
@@ -892,7 +892,7 @@ static int rga_probe(struct platform_device *pdev)
 	}
 	rga->dst_mmu_pages =
 		(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
-	if (rga->dst_mmu_pages) {
+	if (!rga->dst_mmu_pages) {
 		ret = -ENOMEM;
 		goto free_src_pages;
 	}
Signature · 1 line
2.35.1
author maintainer
#65 lore raw

PATCH 65/219 KVM: arm64: Generalise VM features into a set of flags

In reply to Greg Kroah-Hartman

From: Marc Zyngier <[email protected]>

[ Upstream commit 06394531b425794dc56f3d525b7994d25b8072f7 ]

We currently deal with a set of booleans for VM features, while they could be better represented as set of flags contained in an unsigned long, similarily to what we are doing on the CPU side.

---
 arch/arm64/include/asm/kvm_host.h | 15 +++++++++------
 arch/arm64/kvm/arm.c              |  7 ++++---
 arch/arm64/kvm/mmio.c             |  3 ++-
 arch/arm64/kvm/pmu-emul.c         |  2 +-
 4 files changed, 16 insertions(+), 11 deletions(-)
arch/arm64/include/asm/kvm_host.h +9 -6
index 8234626a945a..2619fda42ca2 100644
@@ -122,7 +122,12 @@ struct kvm_arch {
 	 * should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
 	 * supported.
 	 */
-	bool return_nisv_io_abort_to_user;
+#define KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER	0
+	/* Memory Tagging Extension enabled for the guest */
+#define KVM_ARCH_FLAG_MTE_ENABLED			1
+	/* At least one vCPU has ran in the VM */
+#define KVM_ARCH_FLAG_HAS_RAN_ONCE			2
+	unsigned long flags;
 
 	/*
 	 * VM-wide PMU filter, implemented as a bitmap and big enough for
@@ -133,10 +138,6 @@ struct kvm_arch {
 
 	u8 pfr0_csv2;
 	u8 pfr0_csv3;
-
-	/* Memory Tagging Extension enabled for the guest */
-	bool mte_enabled;
-	bool ran_once;
 };
 
 struct kvm_vcpu_fault_info {
@@ -792,7 +793,9 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 #define kvm_arm_vcpu_sve_finalized(vcpu) \
 	((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED)
 
-#define kvm_has_mte(kvm) (system_supports_mte() && (kvm)->arch.mte_enabled)
+#define kvm_has_mte(kvm)					\
+	(system_supports_mte() &&				\
+	 test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags))
 #define kvm_vcpu_has_pmu(vcpu)					\
 	(test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features))
 
arch/arm64/kvm/arm.c +4 -3
index 85a2a75f4498..25d8aff273a1 100644
@@ -89,7 +89,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 	switch (cap->cap) {
 	case KVM_CAP_ARM_NISV_TO_USER:
 		r = 0;
-		kvm->arch.return_nisv_io_abort_to_user = true;
+		set_bit(KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
+			&kvm->arch.flags);
 		break;
 	case KVM_CAP_ARM_MTE:
 		mutex_lock(&kvm->lock);
@@ -97,7 +98,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			r = -EINVAL;
 		} else {
 			r = 0;
-			kvm->arch.mte_enabled = true;
+			set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags);
 		}
 		mutex_unlock(&kvm->lock);
 		break;
@@ -635,7 +636,7 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 		kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
 
 	mutex_lock(&kvm->lock);
-	kvm->arch.ran_once = true;
+	set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
 	mutex_unlock(&kvm->lock);
 
 	return ret;
arch/arm64/kvm/mmio.c +2 -1
index 3e2d8ba11a02..3dd38a151d2a 100644
@@ -135,7 +135,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 	 * volunteered to do so, and bail out otherwise.
 	 */
 	if (!kvm_vcpu_dabt_isvalid(vcpu)) {
-		if (vcpu->kvm->arch.return_nisv_io_abort_to_user) {
+		if (test_bit(KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
+			     &vcpu->kvm->arch.flags)) {
 			run->exit_reason = KVM_EXIT_ARM_NISV;
 			run->arm_nisv.esr_iss = kvm_vcpu_dabt_iss_nisv_sanitized(vcpu);
 			run->arm_nisv.fault_ipa = fault_ipa;
arch/arm64/kvm/pmu-emul.c +1 -1
index bc771bc1a041..fc6ee6f02fec 100644
@@ -982,7 +982,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 		mutex_lock(&kvm->lock);
 
-		if (kvm->arch.ran_once) {
+		if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags)) {
 			mutex_unlock(&kvm->lock);
 			return -EBUSY;
 		}
Signature · 1 line
2.35.1
author maintainer
#66 lore raw

PATCH 66/219 KVM: arm64: mixed-width check should be skipped for uninitialized vCPUs

In reply to Greg Kroah-Hartman

From: Reiji Watanabe <[email protected]>

[ Upstream commit 26bf74bd9f6ff0f1545b4f0c92a37c232d076014 ]

KVM allows userspace to configure either all EL1 32bit or 64bit vCPUs for a guest. At vCPU reset, vcpu_allowed_register_width() checks if the vcpu's register width is consistent with all other vCPUs'. Since the checking is done even against vCPUs that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet, the uninitialized vCPUs are erroneously treated as 64bit vCPU, which causes the function to incorrectly detect a mixed-width VM.

Introduce KVM_ARCH_FLAG_EL1_32BIT and KVM_ARCH_FLAG_REG_WIDTH_CONFIGURED bits for kvm->arch.flags. A value of the EL1_32BIT bit indicates that the guest needs to be configured with all 32bit or 64bit vCPUs, and a value of the REG_WIDTH_CONFIGURED bit indicates if a value of the EL1_32BIT bit is valid (already set up). Values in those bits are set at the first KVM_ARM_VCPU_INIT for the guest based on KVM_ARM_VCPU_EL1_32BIT configuration for the vCPU.

Check vcpu's register width against those new bits at the vcpu's KVM_ARM_VCPU_INIT (instead of against other vCPUs' register width).

Fixes 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
---
 arch/arm64/include/asm/kvm_emulate.h | 27 ++++++++----
 arch/arm64/include/asm/kvm_host.h    | 10 +++++
 arch/arm64/kvm/reset.c               | 65 +++++++++++++++++++---------
 3 files changed, 74 insertions(+), 28 deletions(-)
arch/arm64/include/asm/kvm_emulate.h +19 -8
index d62405ce3e6d..7496deab025a 100644
@@ -43,10 +43,22 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
 void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
 
+#if defined(__KVM_VHE_HYPERVISOR__) || defined(__KVM_NVHE_HYPERVISOR__)
 static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
 {
 	return !(vcpu->arch.hcr_el2 & HCR_RW);
 }
+#else
+static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	WARN_ON_ONCE(!test_bit(KVM_ARCH_FLAG_REG_WIDTH_CONFIGURED,
+			       &kvm->arch.flags));
+
+	return test_bit(KVM_ARCH_FLAG_EL1_32BIT, &kvm->arch.flags);
+}
+#endif
 
 static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 {
@@ -72,15 +84,14 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 		vcpu->arch.hcr_el2 |= HCR_TVM;
 	}
 
-	if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
+	if (vcpu_el1_is_32bit(vcpu))
 		vcpu->arch.hcr_el2 &= ~HCR_RW;
-
-	/*
-	 * TID3: trap feature register accesses that we virtualise.
-	 * For now this is conditional, since no AArch32 feature regs
-	 * are currently virtualised.
-	 */
-	if (!vcpu_el1_is_32bit(vcpu))
+	else
+		/*
+		 * TID3: trap feature register accesses that we virtualise.
+		 * For now this is conditional, since no AArch32 feature regs
+		 * are currently virtualised.
+		 */
 		vcpu->arch.hcr_el2 |= HCR_TID3;
 
 	if (cpus_have_const_cap(ARM64_MISMATCHED_CACHE_TYPE) ||
arch/arm64/include/asm/kvm_host.h +10 -0
index 2619fda42ca2..b5ae92f77c61 100644
@@ -127,6 +127,16 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_MTE_ENABLED			1
 	/* At least one vCPU has ran in the VM */
 #define KVM_ARCH_FLAG_HAS_RAN_ONCE			2
+	/*
+	 * The following two bits are used to indicate the guest's EL1
+	 * register width configuration. A value of KVM_ARCH_FLAG_EL1_32BIT
+	 * bit is valid only when KVM_ARCH_FLAG_REG_WIDTH_CONFIGURED is set.
+	 * Otherwise, the guest's EL1 register width has not yet been
+	 * determined yet.
+	 */
+#define KVM_ARCH_FLAG_REG_WIDTH_CONFIGURED		3
+#define KVM_ARCH_FLAG_EL1_32BIT				4
+
 	unsigned long flags;
 
 	/*
arch/arm64/kvm/reset.c +45 -20

96 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#67 lore raw

PATCH 67/219 SUNRPC: Fix the svc_deferred_event trace class

In reply to Greg Kroah-Hartman

From: Chuck Lever <[email protected]>

[ Upstream commit 4d5004451ab2218eab94a30e1841462c9316ba19 ]

Fix a NULL deref crash that occurs when an svc_rqst is deferred while the sunrpc tracing subsystem is enabled. svc_revisit() sets dr->xprt to NULL, so it can't be relied upon in the tracepoint to provide the remote's address.

Unfortunately we can't revert the "svc_deferred_class" hunk in commit ece200ddd54b ("sunrpc: Save remote presentation address in svc_xprt for trace events") because there is now a specific check of event format specifiers for unsafe dereferences. The warning that check emits is:

event svc_defer_recv has unsafe dereference of argument 1

A "%pISpc" format specifier with a "struct sockaddr *" is indeed flagged by this check.

Instead, take the brute-force approach used by the svcrdma_qp_error tracepoint. Convert the dr::addr field into a presentation address in the TP_fast_assign() arm of the trace event, and store that as a string. This fix can be backported to -stable kernels.

In the meantime, commit c6ced22997ad ("tracing: Update print fmt check to handle new __get_sockaddr() macro") is now in v5.18, so this wonky fix can be replaced with __sockaddr() and friends properly during the v5.19 merge window.

Fixes ece200ddd54b ("sunrpc: Save remote presentation address in svc_xprt for trace events")
---
 include/trace/events/sunrpc.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
include/trace/events/sunrpc.h +4 -3
index 5be3faf88c1a..06fe47fb3686 100644
@@ -1956,17 +1956,18 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
 	TP_STRUCT__entry(
 		__field(const void *, dr)
 		__field(u32, xid)
-		__string(addr, dr->xprt->xpt_remotebuf)
+		__array(__u8, addr, INET6_ADDRSTRLEN + 10)
 	),
 
 	TP_fast_assign(
 		__entry->dr = dr;
 		__entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
 						       (dr->xprt_hlen>>2)));
-		__assign_str(addr, dr->xprt->xpt_remotebuf);
+		snprintf(__entry->addr, sizeof(__entry->addr) - 1,
+			 "%pISpc", (struct sockaddr *)&dr->addr);
 	),
 
-	TP_printk("addr=%s dr=%p xid=0x%08x", __get_str(addr), __entry->dr,
+	TP_printk("addr=%s dr=%p xid=0x%08x", __entry->addr, __entry->dr,
 		__entry->xid)
 );
 
Signature · 1 line
2.35.1
author maintainer
#68 lore raw

PATCH 68/219 net/sched: flower: fix parsing of ethertype following VLAN header

In reply to Greg Kroah-Hartman

From: Vlad Buslov <[email protected]>

[ Upstream commit 2105f700b53c24aa48b65c15652acc386044d26a ]

A tc flower filter matching TCA_FLOWER_KEY_VLAN_ETH_TYPE is expected to match the L2 ethertype following the first VLAN header, as confirmed by linked discussion with the maintainer. However, such rule also matches packets that have additional second VLAN header, even though filter has both eth_type and vlan_ethtype set to "ipv4". Looking at the code this seems to be mostly an artifact of the way flower uses flow dissector. First, even though looking at the uAPI eth_type and vlan_ethtype appear like a distinct fields, in flower they are all mapped to the same key->basic.n_proto. Second, flow dissector skips following VLAN header as no keys for FLOW_DISSECTOR_KEY_CVLAN are set and eventually assigns the value of n_proto to last parsed header. With these, such filters ignore any headers present between first VLAN header and first "non magic" header (ipv4 in this case) that doesn't result FLOW_DISSECT_RET_PROTO_AGAIN.

Fix the issue by extending flow dissector VLAN key structure with new 'vlan_eth_type' field that matches first ethertype following previously parsed VLAN header. Modify flower classifier to set the new flow_dissector_key_vlan->vlan_eth_type with value obtained from TCA_FLOWER_KEY_VLAN_ETH_TYPE/TCA_FLOWER_KEY_CVLAN_ETH_TYPE uAPIs.

Fixes 9399ae9a6cb2 ("net_sched: flower: Add vlan support")
Fixes d64efd0926ba ("net/sched: flower: Add supprt for matching on QinQ vlan headers")
---
 include/net/flow_dissector.h |  2 ++
 net/core/flow_dissector.c    |  1 +
 net/sched/cls_flower.c       | 18 +++++++++++++-----
 3 files changed, 16 insertions(+), 5 deletions(-)
include/net/flow_dissector.h +2 -0
index aa33e1092e2c..9f65f1bfbd24 100644
@@ -59,6 +59,8 @@ struct flow_dissector_key_vlan {
 		__be16	vlan_tci;
 	};
 	__be16	vlan_tpid;
+	__be16	vlan_eth_type;
+	u16	padding;
 };
 
 struct flow_dissector_mpls_lse {
net/core/flow_dissector.c +1 -0
index 15833e1d6ea1..544d2028ccf5 100644
@@ -1182,6 +1182,7 @@ bool __skb_flow_dissect(const struct net *net,
 					 VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
 			}
 			key_vlan->vlan_tpid = saved_vlan_tpid;
+			key_vlan->vlan_eth_type = proto;
 		}
 
 		fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
net/sched/cls_flower.c +13 -5
index 1a9b1f140f9e..ef5b3452254a 100644
@@ -1005,6 +1005,7 @@ static int fl_set_key_mpls(struct nlattr **tb,
 static void fl_set_key_vlan(struct nlattr **tb,
 			    __be16 ethertype,
 			    int vlan_id_key, int vlan_prio_key,
+			    int vlan_next_eth_type_key,
 			    struct flow_dissector_key_vlan *key_val,
 			    struct flow_dissector_key_vlan *key_mask)
 {
@@ -1023,6 +1024,11 @@ static void fl_set_key_vlan(struct nlattr **tb,
 	}
 	key_val->vlan_tpid = ethertype;
 	key_mask->vlan_tpid = cpu_to_be16(~0);
+	if (tb[vlan_next_eth_type_key]) {
+		key_val->vlan_eth_type =
+			nla_get_be16(tb[vlan_next_eth_type_key]);
+		key_mask->vlan_eth_type = cpu_to_be16(~0);
+	}
 }
 
 static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
@@ -1519,8 +1525,9 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
 
 		if (eth_type_vlan(ethertype)) {
 			fl_set_key_vlan(tb, ethertype, TCA_FLOWER_KEY_VLAN_ID,
-					TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan,
-					&mask->vlan);
+					TCA_FLOWER_KEY_VLAN_PRIO,
+					TCA_FLOWER_KEY_VLAN_ETH_TYPE,
+					&key->vlan, &mask->vlan);
 
 			if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
 				ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
@@ -1528,6 +1535,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
 					fl_set_key_vlan(tb, ethertype,
 							TCA_FLOWER_KEY_CVLAN_ID,
 							TCA_FLOWER_KEY_CVLAN_PRIO,
+							TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
 							&key->cvlan, &mask->cvlan);
 					fl_set_key_val(tb, &key->basic.n_proto,
 						       TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
@@ -2886,13 +2894,13 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net,
 		goto nla_put_failure;
 
 	if (mask->basic.n_proto) {
-		if (mask->cvlan.vlan_tpid) {
+		if (mask->cvlan.vlan_eth_type) {
 			if (nla_put_be16(skb, TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
 					 key->basic.n_proto))
 				goto nla_put_failure;
-		} else if (mask->vlan.vlan_tpid) {
+		} else if (mask->vlan.vlan_eth_type) {
 			if (nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
-					 key->basic.n_proto))
+					 key->vlan.vlan_eth_type))
 				goto nla_put_failure;
 		}
 	}
Signature · 1 line
2.35.1
author maintainer
#69 lore raw

PATCH 69/219 veth: Ensure eth header is in skbs linear part

In reply to Greg Kroah-Hartman

From: Guillaume Nault <[email protected]>

[ Upstream commit 726e2c5929de841fdcef4e2bf995680688ae1b87 ]

After feeding a decapsulated packet to a veth device with act_mirred, skb_headlen() may be 0. But veth_xmit() calls __dev_forward_skb(), which expects at least ETH_HLEN byte of linear data (as __dev_forward_skb2() calls eth_type_trans(), which pulls ETH_HLEN bytes unconditionally).

Use pskb_may_pull() to ensure veth_xmit() respects this constraint.

kernel BUG at include/linux/skbuff.h:2328!

RIP: 0010:eth_type_trans+0xcf/0x140
Call Trace:
 <IRQ>
 __dev_forward_skb2+0xe3/0x160
 veth_xmit+0x6e/0x250 [veth]
 dev_hard_start_xmit+0xc7/0x200
 __dev_queue_xmit+0x47f/0x520
 ? skb_ensure_writable+0x85/0xa0
 ? skb_mpls_pop+0x98/0x1c0
 tcf_mirred_act+0x442/0x47e [act_mirred]
 tcf_action_exec+0x86/0x140
 fl_classify+0x1d8/0x1e0 [cls_flower]
 ? dma_pte_clear_level+0x129/0x1a0
 ? dma_pte_clear_level+0x129/0x1a0
 ? prb_fill_curr_block+0x2f/0xc0
 ? skb_copy_bits+0x11a/0x220
 __tcf_classify+0x58/0x110
 tcf_classify_ingress+0x6b/0x140
 __netif_receive_skb_core.constprop.0+0x47d/0xfd0
 ? __iommu_dma_unmap_swiotlb+0x44/0x90
 __netif_receive_skb_one_core+0x3d/0xa0
 netif_receive_skb+0x116/0x170
 be_process_rx+0x22f/0x330 [be2net]
 be_poll+0x13c/0x370 [be2net]
 __napi_poll+0x2a/0x170
 net_rx_action+0x22f/0x2f0
 __do_softirq+0xca/0x2a8
 __irq_exit_rcu+0xc1/0xe0
 common_interrupt+0x83/0xa0
Fixes e314dbdc1c0d ("[NET]: Virtual ethernet device driver.")
---
 drivers/net/veth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/veth.c +1 -1
index d29fb9759cc9..6c8f4f4dfc8a 100644
@@ -320,7 +320,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	rcu_read_lock();
 	rcv = rcu_dereference(priv->peer);
-	if (unlikely(!rcv)) {
+	if (unlikely(!rcv) || !pskb_may_pull(skb, ETH_HLEN)) {
 		kfree_skb(skb);
 		goto drop;
 	}
Signature · 1 line
2.35.1
author maintainer
#70 lore raw

PATCH 70/219 gpiolib: acpi: use correct format characters

In reply to Greg Kroah-Hartman

From: Linus Torvalds <[email protected]>

[ Upstream commit 213d266ebfb1621aab79cfe63388facc520a1381 ]

When compiling with -Wformat, clang emits the following warning:

gpiolib-acpi.c:393:4: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat]

                        pin);
                        ^~~

So warning that '%hhX' is paired with an 'int' is all just completely mindless and wrong. Sadly, I can see a different bogus warning reason why people would want to use '%02hhX'.

Again, the *sane* thing from a human perspective is to use '%02X. But if the compiler doesn't do any range analysis at all, it could decide that "Oh, that print format could need up to 8 bytes of space in the result". Using '%02hhX' would cut that down to two.

And since we use

        char ev_name[5];

and currently use "_%c%02hhX" as the format string, even a compiler that doesn't notice that "pin <= 255" test that guards this all will go "OK, that's at most 4 bytes and the final NUL termination, so it's fine".

While a compiler - like gcc - that only sees that the original source of the 'pin' value is a 'unsigned short' array, and then doesn't take the "pin <= 255" into account, will warn like this:

gpiolib-acpi.c: In function 'acpi_gpiochip_request_interrupt':
gpiolib-acpi.c:206:24: warning: '%02X' directive writing between 2 and 4 bytes into a region of size 3 [-Wformat-overflow=]

       sprintf(ev_name, "_%c%02X",
                            ^~~~

gpiolib-acpi.c:206:20: note: directive argument in the range [0, 65535]

because gcc isn't being very good at that argument range analysis either.

In other words, the original use of 'hhx' was bogus to begin with, and due to *another* compiler warning being bad, and we had that bad code being written back in 2016 to work around _that_ compiler warning (commit e40a3ae1f794: "gpio: acpi: work around false-positive -Wstring-overflow warning").

Sadly, two different bad compiler warnings together does not make for one good one.

It just makes for even more pain.

End result: I think the simplest and cleanest option is simply the proposed change which undoes that '%hhX' change for gcc, and replaces it with just using a slightly bigger stack allocation. It's not like a 5-byte allocation is in any way likely to have saved any actual stack, since all the other variables in that function are 'int' or bigger.

False-positive compiler warnings really do make people write worse code, and that's a problem. But on a scale of bad code, I feel that extending the buffer trivially is better than adding a pointless cast that literally makes no sense.

At least in this case the end result isn't unreadable or buggy. We've had several cases of bad compiler warnings that caused changes that were actually horrendously wrong.

Fixes e40a3ae1f794 ("gpio: acpi: work around false-positive -Wstring-overflow warning")
---
 drivers/gpio/gpiolib-acpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpiolib-acpi.c +2 -2
index a5495ad31c9c..b7c2f2af1dee 100644
@@ -387,8 +387,8 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
 	pin = agpio->pin_table[0];
 
 	if (pin <= 255) {
-		char ev_name[5];
-		sprintf(ev_name, "_%c%02hhX",
+		char ev_name[8];
+		sprintf(ev_name, "_%c%02X",
 			agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
 			pin);
 		if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
Signature · 1 line
2.35.1
author maintainer
#71 lore raw

PATCH 71/219 cifs: release cached dentries only if mount is complete

In reply to Greg Kroah-Hartman

From: Shyam Prasad N <[email protected]>

[ Upstream commit d788e51636462e61c6883f7d96b07b06bc291650 ]

During cifs_kill_sb, we first dput all the dentries that we have cached. However this function can also get called for mount failures. So dput the cached dentries only if the filesystem mount is complete. i.e. cifs_sb->root is populated.

Fixes 5e9c89d43fa6 ("cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache")
---
 fs/cifs/cifsfs.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
fs/cifs/cifsfs.c +15 -13
index 6e5246122ee2..9f0f6bdb3a4d 100644
@@ -266,22 +266,24 @@ static void cifs_kill_sb(struct super_block *sb)
 	 * before we kill the sb.
 	 */
 	if (cifs_sb->root) {
+		node = rb_first(root);
+		while (node != NULL) {
+			tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+			tcon = tlink_tcon(tlink);
+			cfid = &tcon->crfid;
+			mutex_lock(&cfid->fid_mutex);
+			if (cfid->dentry) {
+				dput(cfid->dentry);
+				cfid->dentry = NULL;
+			}
+			mutex_unlock(&cfid->fid_mutex);
+			node = rb_next(node);
+		}
+
+		/* finally release root dentry */
 		dput(cifs_sb->root);
 		cifs_sb->root = NULL;
 	}
-	node = rb_first(root);
-	while (node != NULL) {
-		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
-		tcon = tlink_tcon(tlink);
-		cfid = &tcon->crfid;
-		mutex_lock(&cfid->fid_mutex);
-		if (cfid->dentry) {
-			dput(cfid->dentry);
-			cfid->dentry = NULL;
-		}
-		mutex_unlock(&cfid->fid_mutex);
-		node = rb_next(node);
-	}
 
 	kill_anon_super(sb);
 	cifs_umount(cifs_sb);
Signature · 1 line
2.35.1
author maintainer
#72 lore raw

PATCH 72/219 ice: arfs: fix use-after-free when freeing @rx_cpu_rmap

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

[ Upstream commit d7442f512b71fc63a99c8a801422dde4fbbf9f93 ]

The CI testing bots triggered the following splat:

[  718.203054] BUG: KASAN: use-after-free in free_irq_cpu_rmap+0x53/0x80
[  718.206349] Read of size 4 at addr ffff8881bd127e00 by task sh/20834
[  718.212852] CPU: 28 PID: 20834 Comm: sh Kdump: loaded Tainted: G S      W IOE     5.17.0-rc8_nextqueue-devqueue-02643-g23f3121aca93 #1
[  718.219695] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0012.070720200218 07/07/2020
[  718.223418] Call Trace:
[  718.227139]
[  718.230783]  dump_stack_lvl+0x33/0x42
[  718.234431]  print_address_description.constprop.9+0x21/0x170
[  718.238177]  ? free_irq_cpu_rmap+0x53/0x80
[  718.241885]  ? free_irq_cpu_rmap+0x53/0x80
[  718.245539]  kasan_report.cold.18+0x7f/0x11b
[  718.249197]  ? free_irq_cpu_rmap+0x53/0x80
[  718.252852]  free_irq_cpu_rmap+0x53/0x80
[  718.256471]  ice_free_cpu_rx_rmap.part.11+0x37/0x50 [ice]
[  718.260174]  ice_remove_arfs+0x5f/0x70 [ice]
[  718.263810]  ice_rebuild_arfs+0x3b/0x70 [ice]
[  718.267419]  ice_rebuild+0x39c/0xb60 [ice]
[  718.270974]  ? asm_sysvec_apic_timer_interrupt+0x12/0x20
[  718.274472]  ? ice_init_phy_user_cfg+0x360/0x360 [ice]
[  718.278033]  ? delay_tsc+0x4a/0xb0
[  718.281513]  ? preempt_count_sub+0x14/0xc0
[  718.284984]  ? delay_tsc+0x8f/0xb0
[  718.288463]  ice_do_reset+0x92/0xf0 [ice]
[  718.292014]  ice_pci_err_resume+0x91/0xf0 [ice]
[  718.295561]  pci_reset_function+0x53/0x80
<...>
[  718.393035] Allocated by task 690:
[  718.433497] Freed by task 20834:
[  718.495688] Last potentially related work creation:
[  718.568966] The buggy address belongs to the object at ffff8881bd127e00
                which belongs to the cache kmalloc-96 of size 96
[  718.574085] The buggy address is located 0 bytes inside of
                96-byte region [ffff8881bd127e00, ffff8881bd127e60)
[  718.579265] The buggy address belongs to the page:
[  718.598905] Memory state around the buggy address:
[  718.601809]  ffff8881bd127d00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
[  718.604796]  ffff8881bd127d80: 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc
[  718.607794] >ffff8881bd127e00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
[  718.610811]                    ^
[  718.613819]  ffff8881bd127e80: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc
[  718.617107]  ffff8881bd127f00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc

This is due to that free_irq_cpu_rmap() is always being called *after* (devm_)free_irq() and thus it tries to work with IRQ descs already freed. For example, on device reset the driver frees the rmap right before allocating a new one (the splat above). Make rmap creation and freeing function symmetrical with {request,free}_irq() calls i.e. do that on ifup/ifdown instead of device probe/remove/resume. These operations can be performed independently from the actual device aRFS configuration. Also, make sure ice_vsi_free_irq() clears IRQ affinity notifiers only when aRFS is disabled -- otherwise, CPU rmap sets and clears its own and they must not be touched manually.

---
 drivers/net/ethernet/intel/ice/ice_arfs.c |  9 ++-------
 drivers/net/ethernet/intel/ice/ice_lib.c  |  5 ++++-
 drivers/net/ethernet/intel/ice/ice_main.c | 18 ++++++++----------
 3 files changed, 14 insertions(+), 18 deletions(-)
drivers/net/ethernet/intel/ice/ice_arfs.c +2 -7
index 5daade32ea62..fba178e07600 100644
@@ -577,7 +577,7 @@ void ice_free_cpu_rx_rmap(struct ice_vsi *vsi)
 {
 	struct net_device *netdev;
 
-	if (!vsi || vsi->type != ICE_VSI_PF || !vsi->arfs_fltr_list)
+	if (!vsi || vsi->type != ICE_VSI_PF)
 		return;
 
 	netdev = vsi->netdev;
@@ -599,7 +599,7 @@ int ice_set_cpu_rx_rmap(struct ice_vsi *vsi)
 	int base_idx, i;
 
 	if (!vsi || vsi->type != ICE_VSI_PF)
-		return -EINVAL;
+		return 0;
 
 	pf = vsi->back;
 	netdev = vsi->netdev;
@@ -636,7 +636,6 @@ void ice_remove_arfs(struct ice_pf *pf)
 	if (!pf_vsi)
 		return;
 
-	ice_free_cpu_rx_rmap(pf_vsi);
 	ice_clear_arfs(pf_vsi);
 }
 
@@ -653,9 +652,5 @@ void ice_rebuild_arfs(struct ice_pf *pf)
 		return;
 
 	ice_remove_arfs(pf);
-	if (ice_set_cpu_rx_rmap(pf_vsi)) {
-		dev_err(ice_pf_to_dev(pf), "Failed to rebuild aRFS\n");
-		return;
-	}
 	ice_init_arfs(pf_vsi);
 }
drivers/net/ethernet/intel/ice/ice_lib.c +4 -1
index 5fd2bbeab2d1..15bb6f001a04 100644
@@ -2869,6 +2869,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
 		return;
 
 	vsi->irqs_ready = false;
+	ice_free_cpu_rx_rmap(vsi);
+
 	ice_for_each_q_vector(vsi, i) {
 		u16 vector = i + base;
 		int irq_num;
@@ -2882,7 +2884,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
 			continue;
 
 		/* clear the affinity notifier in the IRQ descriptor */
-		irq_set_affinity_notifier(irq_num, NULL);
+		if (!IS_ENABLED(CONFIG_RFS_ACCEL))
+			irq_set_affinity_notifier(irq_num, NULL);
 
 		/* clear the affinity_mask in the IRQ descriptor */
 		irq_set_affinity_hint(irq_num, NULL);
drivers/net/ethernet/intel/ice/ice_main.c +8 -10
index db2e02e673a7..2de2bbbca1e9 100644
@@ -2494,6 +2494,13 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename)
 		irq_set_affinity_hint(irq_num, &q_vector->affinity_mask);
 	}
 
+	err = ice_set_cpu_rx_rmap(vsi);
+	if (err) {
+		netdev_err(vsi->netdev, "Failed to setup CPU RMAP on VSI %u: %pe\n",
+			   vsi->vsi_num, ERR_PTR(err));
+		goto free_q_irqs;
+	}
+
 	vsi->irqs_ready = true;
 	return 0;
 
@@ -3605,20 +3612,12 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 	 */
 	ice_napi_add(vsi);
 
-	status = ice_set_cpu_rx_rmap(vsi);
-	if (status) {
-		dev_err(dev, "Failed to set CPU Rx map VSI %d error %d\n",
-			vsi->vsi_num, status);
-		goto unroll_napi_add;
-	}
 	status = ice_init_mac_fltr(pf);
 	if (status)
-		goto free_cpu_rx_map;
+		goto unroll_napi_add;
 
 	return 0;
 
-free_cpu_rx_map:
-	ice_free_cpu_rx_rmap(vsi);
 unroll_napi_add:
 	ice_tc_indir_block_unregister(vsi);
 unroll_cfg_netdev:
@@ -5076,7 +5075,6 @@ static int __maybe_unused ice_suspend(struct device *dev)
 			continue;
 		ice_vsi_free_q_vectors(pf->vsi[v]);
 	}
-	ice_free_cpu_rx_rmap(ice_get_main_vsi(pf));
 	ice_clear_interrupt_scheme(pf);
 
 	pci_save_state(pdev);
Signature · 1 line
2.35.1
author maintainer
#73 lore raw

PATCH 73/219 Revert "iavf: Fix deadlock occurrence during resetting VF interface"

In reply to Greg Kroah-Hartman

From: Mateusz Palczewski <[email protected]>

[ Upstream commit 7d59706dbef8de83b3662026766507bc494223d7 ]

This change caused a regression with resetting while changing network namespaces. By clearing the IFF_UP flag, the kernel now thinks it has fully closed the device.

This reverts commit 0cc318d2e8408bc0ffb4662a0c3e5e57005ac6ff.

Fixes 0cc318d2e840 ("iavf: Fix deadlock occurrence during resetting VF interface")
---
 drivers/net/ethernet/intel/iavf/iavf_main.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +2 -5
index d10e9a8e8011..f55ecb672768 100644
@@ -2817,7 +2817,6 @@ static void iavf_reset_task(struct work_struct *work)
 	running = adapter->state == __IAVF_RUNNING;
 
 	if (running) {
-		netdev->flags &= ~IFF_UP;
 		netif_carrier_off(netdev);
 		netif_tx_stop_all_queues(netdev);
 		adapter->link_up = false;
@@ -2934,7 +2933,7 @@ static void iavf_reset_task(struct work_struct *work)
 		 * to __IAVF_RUNNING
 		 */
 		iavf_up_complete(adapter);
-		netdev->flags |= IFF_UP;
+
 		iavf_irq_enable(adapter, true);
 	} else {
 		iavf_change_state(adapter, __IAVF_DOWN);
@@ -2950,10 +2949,8 @@ static void iavf_reset_task(struct work_struct *work)
 reset_err:
 	mutex_unlock(&adapter->client_lock);
 	mutex_unlock(&adapter->crit_lock);
-	if (running) {
+	if (running)
 		iavf_change_state(adapter, __IAVF_RUNNING);
-		netdev->flags |= IFF_UP;
-	}
 	dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
 	iavf_close(netdev);
 }
Signature · 1 line
2.35.1
author maintainer
#74 lore raw

PATCH 74/219 net: mdio: dont defer probe forever if PHY IRQ provider is missing

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 74befa447e6839cdd90ed541159ec783726946f9 ]

When a driver for an interrupt controller is missing, of_irq_get() returns -EPROBE_DEFER ad infinitum, causing fwnode_mdiobus_phy_device_register(), and ultimately, the entire of_mdiobus_register() call, to fail. In turn, any phy_connect() call towards a PHY on this MDIO bus will also fail.

This is not what is expected to happen, because the PHY library falls back to poll mode when of_irq_get() returns a hard error code, and the MDIO bus, PHY and attached Ethernet controller work fine, albeit suboptimally, when the PHY library polls for link status. However, -EPROBE_DEFER has special handling given the assumption that at some point probe deferral will stop, and the driver for the supplier will kick in and create the IRQ domain.

Reasons for which the interrupt controller may be missing:

- It is not yet written. This may happen if a more recent DT blob (with an interrupt-parent for the PHY) is used to boot an old kernel where the driver didn't exist, and that kernel worked with the vintage-correct DT blob using poll mode.

- It is compiled out. Behavior is the same as above.

- It is compiled as a module. The kernel will wait for a number of seconds specified in the "deferred_probe_timeout" boot parameter for user space to load the required module. The current default is 0, which times out at the end of initcalls. It is possible that this might cause regressions unless users adjust this boot parameter.

The proposed solution is to use the driver_deferred_probe_check_state() helper function provided by the driver core, which gives up after some -EPROBE_DEFER attempts, taking "deferred_probe_timeout" into consideration. The return code is changed from -EPROBE_DEFER into -ENODEV or -ETIMEDOUT, depending on whether the kernel is compiled with support for modules or not.

---
 drivers/base/dd.c              | 1 +
 drivers/net/mdio/fwnode_mdio.c | 5 +++++
 2 files changed, 6 insertions(+)
drivers/base/dd.c +1 -0
index 752a11d16e26..7e079fa3795b 100644
@@ -296,6 +296,7 @@ int driver_deferred_probe_check_state(struct device *dev)
 
 	return -EPROBE_DEFER;
 }
+EXPORT_SYMBOL_GPL(driver_deferred_probe_check_state);
 
 static void deferred_probe_timeout_work_func(struct work_struct *work)
 {
drivers/net/mdio/fwnode_mdio.c +5 -0
index 1becb1a731f6..1c1584fca632 100644
@@ -43,6 +43,11 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
 	int rc;
 
 	rc = fwnode_irq_get(child, 0);
+	/* Don't wait forever if the IRQ provider doesn't become available,
+	 * just fall back to poll mode
+	 */
+	if (rc == -EPROBE_DEFER)
+		rc = driver_deferred_probe_check_state(&phy->mdio.dev);
 	if (rc == -EPROBE_DEFER)
 		return rc;
 
Signature · 1 line
2.35.1
author maintainer
#75 lore raw

PATCH 75/219 mlxsw: i2c: Fix initialization error flow

In reply to Greg Kroah-Hartman

From: Vadim Pasternak <[email protected]>

[ Upstream commit d452088cdfd5a4ad9d96d847d2273fe958d6339b ]

Add mutex_destroy() call in driver initialization error flow.

---
 drivers/net/ethernet/mellanox/mlxsw/i2c.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlxsw/i2c.c +1 -0
index 939b692ffc33..ce843ea91464 100644
@@ -650,6 +650,7 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
 	return 0;
 
 errout:
+	mutex_destroy(&mlxsw_i2c->cmd.lock);
 	i2c_set_clientdata(client, NULL);
 
 	return err;
Signature · 1 line
2.35.1
author maintainer
#76 lore raw

PATCH 76/219 sctp: use the correct skb for security_sctp_assoc_request

In reply to Greg Kroah-Hartman

From: Xin Long <[email protected]>

[ Upstream commit e2d88f9ce678cd33763826ae2f0412f181251314 ]

Yi Chen reported an unexpected sctp connection abort, and it occurred when COOKIE_ECHO is bundled with DATA Fragment by SCTP HW GSO. As the IP header is included in chunk->head_skb instead of chunk->skb, it failed to check IP header version in security_sctp_assoc_request().

According to Ondrej, SELinux only looks at IP header (address and IPsec options) and XFRM state data, and these are all included in head_skb for SCTP HW GSO packets. So fix it by using head_skb when calling security_sctp_assoc_request() in processing COOKIE_ECHO.

v1->v2:
- As Ondrej noticed, chunk->head_skb should also be used for

    security_sctp_assoc_established() in sctp_sf_do_5_1E_ca().
---
 net/sctp/sm_statefuns.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/sctp/sm_statefuns.c +3 -3
index 7f342bc12735..52edee1322fc 100644
@@ -781,7 +781,7 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
 		}
 	}
 
-	if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
+	if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: chunk->skb)) {
 		sctp_association_free(new_asoc);
 		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 	}
@@ -932,7 +932,7 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
 
 	/* Set peer label for connection. */
 	if (security_sctp_assoc_established((struct sctp_association *)asoc,
-					    chunk->skb))
+					    chunk->head_skb ?: chunk->skb))
 		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 
 	/* Verify that the chunk length for the COOKIE-ACK is OK.
@@ -2262,7 +2262,7 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
 	}
 
 	/* Update socket peer label if first association. */
-	if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
+	if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: chunk->skb)) {
 		sctp_association_free(new_asoc);
 		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 	}
Signature · 1 line
2.35.1
author maintainer
#77 lore raw

PATCH 77/219 net/sched: fix initialization order when updating chain 0 head

In reply to Greg Kroah-Hartman

From: Marcelo Ricardo Leitner <[email protected]>

[ Upstream commit e65812fd22eba32f11abe28cb377cbd64cfb1ba0 ]

Currently, when inserting a new filter that needs to sit at the head of chain 0, it will first update the heads pointer on all devices using the (shared) block, and only then complete the initialization of the new element so that it has a "next" element.

This can lead to a situation that the chain 0 head is propagated to another CPU before the "next" initialization is done. When this race condition is triggered, packets being matched on that CPU will simply miss all other filters, and will flow through the stack as if there were no other filters installed. If the system is using OVS + TC, such packets will get handled by vswitchd via upcall, which results in much higher latency and reordering. For other applications it may result in packet drops.

This is reproducible with a tc only setup, but it varies from system to system. It could be reproduced with a shared block amongst 10 veth tunnels, and an ingress filter mirroring packets to another veth. That's because using the last added veth tunnel to the shared block to do the actual traffic, it makes the race window bigger and easier to trigger.

The fix is rather simple, to just initialize the next pointer of the new filter instance (tp) before propagating the head change.

The fixes tag is pointing to the original code though this issue should only be observed when using it unlocked.

---
 net/sched/cls_api.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/cls_api.c +1 -1
index 5ce1208a6ea3..130b5fda9c51 100644
@@ -1653,10 +1653,10 @@ static int tcf_chain_tp_insert(struct tcf_chain *chain,
 	if (chain->flushing)
 		return -EAGAIN;
 
+	RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info));
 	if (*chain_info->pprev == chain->filter_chain)
 		tcf_chain0_head_change(chain, tp);
 	tcf_proto_get(tp);
-	RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info));
 	rcu_assign_pointer(*chain_info->pprev, tp);
 
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#78 lore raw

PATCH 78/219 cachefiles: unmark inode in use in error path

In reply to Greg Kroah-Hartman

From: Jeffle Xu <[email protected]>

[ Upstream commit ea5dc046127e857a7873ae55fd57c866e9e86fb2 ]

Unmark inode in use if error encountered. If the in-use flag leakage occurs in cachefiles_open_file(), Cachefiles will complain "Inode already in use" when later another cookie with the same index key is looked up.

If the in-use flag leakage occurs in cachefiles_create_tmpfile(), though the "Inode already in use" warning won't be triggered, fix the leakage anyway.

---
 fs/cachefiles/namei.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)
fs/cachefiles/namei.c +24 -9
index f256c8aff7bb..ca9f3e4ec4b3 100644
@@ -57,6 +57,16 @@ static void __cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
 	trace_cachefiles_mark_inactive(object, inode);
 }
 
+static void cachefiles_do_unmark_inode_in_use(struct cachefiles_object *object,
+					      struct dentry *dentry)
+{
+	struct inode *inode = d_backing_inode(dentry);
+
+	inode_lock(inode);
+	__cachefiles_unmark_inode_in_use(object, dentry);
+	inode_unlock(inode);
+}
+
 /*
  * Unmark a backing inode and tell cachefilesd that there's something that can
  * be culled.
@@ -68,9 +78,7 @@ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
 	struct inode *inode = file_inode(file);
 
 	if (inode) {
-		inode_lock(inode);
-		__cachefiles_unmark_inode_in_use(object, file->f_path.dentry);
-		inode_unlock(inode);
+		cachefiles_do_unmark_inode_in_use(object, file->f_path.dentry);
 
 		if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
 			atomic_long_add(inode->i_blocks, &cache->b_released);
@@ -484,7 +492,7 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 				object, d_backing_inode(path.dentry), ret,
 				cachefiles_trace_trunc_error);
 			file = ERR_PTR(ret);
-			goto out_dput;
+			goto out_unuse;
 		}
 	}
 
@@ -494,15 +502,20 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 		trace_cachefiles_vfs_error(object, d_backing_inode(path.dentry),
 					   PTR_ERR(file),
 					   cachefiles_trace_open_error);
-		goto out_dput;
+		goto out_unuse;
 	}
 	if (unlikely(!file->f_op->read_iter) ||
 	    unlikely(!file->f_op->write_iter)) {
 		fput(file);
 		pr_notice("Cache does not support read_iter and write_iter\n");
 		file = ERR_PTR(-EINVAL);
+		goto out_unuse;
 	}
 
+	goto out_dput;
+
+out_unuse:
+	cachefiles_do_unmark_inode_in_use(object, path.dentry);
 out_dput:
 	dput(path.dentry);
 out:
@@ -590,14 +603,16 @@ static bool cachefiles_open_file(struct cachefiles_object *object,
 check_failed:
 	fscache_cookie_lookup_negative(object->cookie);
 	cachefiles_unmark_inode_in_use(object, file);
-	if (ret == -ESTALE) {
-		fput(file);
-		dput(dentry);
+	fput(file);
+	dput(dentry);
+	if (ret == -ESTALE)
 		return cachefiles_create_file(object);
-	}
+	return false;
+
 error_fput:
 	fput(file);
 error:
+	cachefiles_do_unmark_inode_in_use(object, dentry);
 	dput(dentry);
 	return false;
 }
Signature · 1 line
2.35.1
author maintainer
#79 lore raw

PATCH 79/219 cachefiles: Fix KASAN slab-out-of-bounds in cachefiles_set_volume_xattr

In reply to Greg Kroah-Hartman

From: Dave Wysochanski <[email protected]>

[ Upstream commit 7b2f6c306601240635c72caa61f682e74d4591b2 ]

Use the actual length of volume coherency data when setting the xattr to avoid the following KASAN report.

 BUG: KASAN: slab-out-of-bounds in cachefiles_set_volume_xattr+0xa0/0x350 [cachefiles]
 Write of size 4 at addr ffff888101e02af4 by task kworker/6:0/1347

 CPU: 6 PID: 1347 Comm: kworker/6:0 Kdump: loaded Not tainted 5.18.0-rc1-nfs-fscache-netfs+ #13
 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-4.fc34 04/01/2014
 Workqueue: events fscache_create_volume_work [fscache]
 Call Trace:
  <TASK>
  dump_stack_lvl+0x45/0x5a
  print_report.cold+0x5e/0x5db
  ? __lock_text_start+0x8/0x8
  ? cachefiles_set_volume_xattr+0xa0/0x350 [cachefiles]
  kasan_report+0xab/0x120
  ? cachefiles_set_volume_xattr+0xa0/0x350 [cachefiles]
  kasan_check_range+0xf5/0x1d0
  memcpy+0x39/0x60
  cachefiles_set_volume_xattr+0xa0/0x350 [cachefiles]
  cachefiles_acquire_volume+0x2be/0x500 [cachefiles]
  ? __cachefiles_free_volume+0x90/0x90 [cachefiles]
  fscache_create_volume_work+0x68/0x160 [fscache]
  process_one_work+0x3b7/0x6a0
  worker_thread+0x2c4/0x650
  ? process_one_work+0x6a0/0x6a0
  kthread+0x16c/0x1a0
  ? kthread_complete_and_exit+0x20/0x20
  ret_from_fork+0x22/0x30
  </TASK>

 Allocated by task 1347:
  kasan_save_stack+0x1e/0x40
  __kasan_kmalloc+0x81/0xa0
  cachefiles_set_volume_xattr+0x76/0x350 [cachefiles]
  cachefiles_acquire_volume+0x2be/0x500 [cachefiles]
  fscache_create_volume_work+0x68/0x160 [fscache]
  process_one_work+0x3b7/0x6a0
  worker_thread+0x2c4/0x650
  kthread+0x16c/0x1a0
  ret_from_fork+0x22/0x30

 The buggy address belongs to the object at ffff888101e02af0
 which belongs to the cache kmalloc-8 of size 8
 The buggy address is located 4 bytes inside of
 8-byte region [ffff888101e02af0, ffff888101e02af8)

 The buggy address belongs to the physical page:
 page:00000000a2292d70 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x101e02
 flags: 0x17ffffc0000200(slab|node=0|zone=2|lastcpupid=0x1fffff)
 raw: 0017ffffc0000200 0000000000000000 dead000000000001 ffff888100042280
 raw: 0000000000000000 0000000080660066 00000001ffffffff 0000000000000000
 page dumped because: kasan: bad access detected

 Memory state around the buggy address:
 ffff888101e02980: fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc fc fc
 ffff888101e02a00: 00 fc fc fc fc 00 fc fc fc fc 00 fc fc fc fc 00
 >ffff888101e02a80: fc fc fc fc 00 fc fc fc fc 00 fc fc fc fc 04 fc
                                                            ^
 ffff888101e02b00: fc fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc
 ffff888101e02b80: fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc fc
 ==================================================================
---
 fs/cachefiles/xattr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cachefiles/xattr.c +1 -1
index 35465109d9c4..00b087c14995 100644
@@ -203,7 +203,7 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
 	if (!buf)
 		return false;
 	buf->reserved = cpu_to_be32(0);
-	memcpy(buf->data, p, len);
+	memcpy(buf->data, p, volume->vcookie->coherency_len);
 
 	ret = cachefiles_inject_write_error();
 	if (ret == 0)
Signature · 1 line
2.35.1
author maintainer
#80 lore raw

PATCH 80/219 net: dsa: felix: suppress -EPROBE_DEFER errors

In reply to Greg Kroah-Hartman

From: Michael Walle <[email protected]>

[ Upstream commit e6934e4048c91502efcb21da92b7ae37cd8fa741 ]

The DSA master might not have been probed yet in which case the probe of the felix switch fails with -EPROBE_DEFER:

[    4.435305] mscc_felix 0000:00:00.5: Failed to register DSA switch: -517

It is not an error. Use dev_err_probe() to demote this particular error to a debug message.

Fixes 56051948773e ("net: dsa: ocelot: add driver for Felix switch family")
---
 drivers/net/dsa/ocelot/felix_vsc9959.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/ocelot/felix_vsc9959.c +1 -1
index 2875b5250856..443d34ce2853 100644
@@ -2328,7 +2328,7 @@ static int felix_pci_probe(struct pci_dev *pdev,
 
 	err = dsa_register_switch(ds);
 	if (err) {
-		dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
+		dev_err_probe(&pdev->dev, err, "Failed to register DSA switch\n");
 		goto err_register_ds;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#81 lore raw

PATCH 81/219 KVM: selftests: riscv: Set PTE A and D bits in VS-stage page table

In reply to Greg Kroah-Hartman

From: Anup Patel <[email protected]>

[ Upstream commit fac3725364397f9a40a101f089b86ea655a58d06 ]

Supporting hardware updates of PTE A and D bits is optional for any RISC-V implementation so current software strategy is to always set these bits in both G-stage (hypervisor) and VS-stage (guest kernel).

If PTE A and D bits are not set by software (hypervisor or guest) then RISC-V implementations not supporting hardware updates of these bits will cause traps even for perfectly valid PTEs.

Based on above explanation, the VS-stage page table created by various KVM selftest applications is not correct because PTE A and D bits are not set. This patch fixes VS-stage page table programming of PTE A and D bits for KVM selftests.

Fixes 3e06cdf10520 ("KVM: selftests: Add initial support for RISC-V

64-bit")

---
 tools/testing/selftests/kvm/include/riscv/processor.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
tools/testing/selftests/kvm/include/riscv/processor.h +3 -1
index dc284c6bdbc3..eca5c622efd2 100644
@@ -101,7 +101,9 @@ static inline void set_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t id,
 #define PGTBL_PTE_WRITE_SHIFT			2
 #define PGTBL_PTE_READ_MASK			0x0000000000000002ULL
 #define PGTBL_PTE_READ_SHIFT			1
-#define PGTBL_PTE_PERM_MASK			(PGTBL_PTE_EXECUTE_MASK | \
+#define PGTBL_PTE_PERM_MASK			(PGTBL_PTE_ACCESSED_MASK | \
+						 PGTBL_PTE_DIRTY_MASK | \
+						 PGTBL_PTE_EXECUTE_MASK | \
 						 PGTBL_PTE_WRITE_MASK | \
 						 PGTBL_PTE_READ_MASK)
 #define PGTBL_PTE_VALID_MASK			0x0000000000000001ULL
Signature · 1 line
2.35.1
author maintainer
#82 lore raw

PATCH 82/219 KVM: selftests: riscv: Fix alignment of the guest_hang() function

In reply to Greg Kroah-Hartman

From: Anup Patel <[email protected]>

[ Upstream commit ebdef0de2dbc40e697adaa6b3408130f7a7b8351 ]

The guest_hang() function is used as the default exception handler for various KVM selftests applications by setting it's address in the vstvec CSR. The vstvec CSR requires exception handler base address to be at least 4-byte aligned so this patch fixes alignment of the guest_hang() function.

Fixes 3e06cdf10520 ("KVM: selftests: Add initial support for RISC-V

64-bit")

---
 tools/testing/selftests/kvm/lib/riscv/processor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/kvm/lib/riscv/processor.c +1 -1
index d377f2603d98..3961487a4870 100644
@@ -268,7 +268,7 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent)
 		core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6);
 }
 
-static void guest_hang(void)
+static void __aligned(16) guest_hang(void)
 {
 	while (1)
 		;
Signature · 1 line
2.35.1
author maintainer
#83 lore raw

PATCH 83/219 RISC-V: KVM: include missing hwcap.h into vcpu_fp

In reply to Greg Kroah-Hartman

From: Heiko Stuebner <[email protected]>

[ Upstream commit 4054eee9290248bf66c5eacb58879c9aaad37f71 ]

vcpu_fp uses the riscv_isa_extension mechanism which gets defined in hwcap.h but doesn't include that head file.

While it seems to work in most cases, in certain conditions this can lead to build failures like

../arch/riscv/kvm/vcpu_fp.c: In function ‘kvm_riscv_vcpu_fp_reset’:
../arch/riscv/kvm/vcpu_fp.c:22:13: error: implicit declaration of function ‘riscv_isa_extension_available’ [-Werror=implicit-function-declaration]
22 | if (riscv_isa_extension_available(&isa, f) ||

      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

../arch/riscv/kvm/vcpu_fp.c:22:49: error: ‘f’ undeclared (first use in this function)
22 | if (riscv_isa_extension_available(&isa, f) ||

Fix this by simply including the necessary header.

Fixes 0a86512dc113 ("RISC-V: KVM: Factor-out FP virtualization into separate

sources")

---
 arch/riscv/kvm/vcpu_fp.c | 1 +
 1 file changed, 1 insertion(+)
arch/riscv/kvm/vcpu_fp.c +1 -0
index 4449a976e5a6..d4308c512007 100644
@@ -11,6 +11,7 @@
 #include <linux/err.h>
 #include <linux/kvm_host.h>
 #include <linux/uaccess.h>
+#include <asm/hwcap.h>
 
 #ifdef CONFIG_FPU
 void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
Signature · 1 line
2.35.1
author maintainer
#84 lore raw

PATCH 84/219 io_uring: flag the fact that linked file assignment is sane

In reply to Greg Kroah-Hartman

From: Jens Axboe <[email protected]>

[ Upstream commit c4212f3eb89fd5654f0a6ed2ee1d13fcb86cb664 ]

Give applications a way to tell if the kernel supports sane linked files, as in files being assigned at the right time to be able to reliably do <open file direct into slot X><read file from slot X> while using IOSQE_IO_LINK to order them.

Not really a bug fix, but flag it as such so that it gets pulled in with backports of the deferred file assignment.

Fixes 6bf9c47a3989 ("io_uring: defer file assignment")
---
 fs/io_uring.c                 | 3 ++-
 include/uapi/linux/io_uring.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)
fs/io_uring.c +2 -1
index 1a9630dc5361..d13f142793f2 100644
@@ -10566,7 +10566,8 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p,
 			IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL |
 			IORING_FEAT_POLL_32BITS | IORING_FEAT_SQPOLL_NONFIXED |
 			IORING_FEAT_EXT_ARG | IORING_FEAT_NATIVE_WORKERS |
-			IORING_FEAT_RSRC_TAGS | IORING_FEAT_CQE_SKIP;
+			IORING_FEAT_RSRC_TAGS | IORING_FEAT_CQE_SKIP |
+			IORING_FEAT_LINKED_FILE;
 
 	if (copy_to_user(params, p, sizeof(*p))) {
 		ret = -EFAULT;
include/uapi/linux/io_uring.h +1 -0
index 787f491f0d2a..1e45368ad33f 100644
@@ -293,6 +293,7 @@ struct io_uring_params {
 #define IORING_FEAT_NATIVE_WORKERS	(1U << 9)
 #define IORING_FEAT_RSRC_TAGS		(1U << 10)
 #define IORING_FEAT_CQE_SKIP		(1U << 11)
+#define IORING_FEAT_LINKED_FILE		(1U << 12)
 
 /*
  * io_uring_register(2) opcodes and arguments
Signature · 1 line
2.35.1
author maintainer
#85 lore raw

PATCH 85/219 net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link

In reply to Greg Kroah-Hartman

From: Dinh Nguyen <[email protected]>

[ Upstream commit a6aaa00324240967272b451bfa772547bd576ee6 ]

When using a fixed-link, the altr_tse_pcs driver crashes due to null-pointer dereference as no phy_device is provided to tse_pcs_fix_mac_speed function. Fix this by adding a check for phy_dev before calling the tse_pcs_fix_mac_speed() function.

Also clean up the tse_pcs_fix_mac_speed function a bit. There is no need to check for splitter_base and sgmii_adapter_base because the driver will fail if these 2 variables are not derived from the device tree.

Fixes fb3bbdb85989 ("net: ethernet: Add TSE PCS support to dwmac-socfpga")
---
 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c  |  8 --------
 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h  |  4 ++++
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 13 +++++--------
 3 files changed, 9 insertions(+), 16 deletions(-)
drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +0 -8
index cd478d2cd871..00f6d347eaf7 100644
@@ -57,10 +57,6 @@
 #define TSE_PCS_USE_SGMII_ENA				BIT(0)
 #define TSE_PCS_IF_USE_SGMII				0x03
 
-#define SGMII_ADAPTER_CTRL_REG				0x00
-#define SGMII_ADAPTER_DISABLE				0x0001
-#define SGMII_ADAPTER_ENABLE				0x0000
-
 #define AUTONEGO_LINK_TIMER				20
 
 static int tse_pcs_reset(void __iomem *base, struct tse_pcs *pcs)
@@ -202,12 +198,8 @@ void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev,
 			   unsigned int speed)
 {
 	void __iomem *tse_pcs_base = pcs->tse_pcs_base;
-	void __iomem *sgmii_adapter_base = pcs->sgmii_adapter_base;
 	u32 val;
 
-	writew(SGMII_ADAPTER_ENABLE,
-	       sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
-
 	pcs->autoneg = phy_dev->autoneg;
 
 	if (phy_dev->autoneg == AUTONEG_ENABLE) {
drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h +4 -0
index 442812c0a4bd..694ac25ef426 100644
@@ -10,6 +10,10 @@
 #include <linux/phy.h>
 #include <linux/timer.h>
 
+#define SGMII_ADAPTER_CTRL_REG		0x00
+#define SGMII_ADAPTER_ENABLE		0x0000
+#define SGMII_ADAPTER_DISABLE		0x0001
+
 struct tse_pcs {
 	struct device *dev;
 	void __iomem *tse_pcs_base;
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +5 -8
index b7c2579c963b..ac9e6c7a33b5 100644
@@ -18,9 +18,6 @@
 
 #include "altr_tse_pcs.h"
 
-#define SGMII_ADAPTER_CTRL_REG                          0x00
-#define SGMII_ADAPTER_DISABLE                           0x0001
-
 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
@@ -62,16 +59,14 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
 {
 	struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv;
 	void __iomem *splitter_base = dwmac->splitter_base;
-	void __iomem *tse_pcs_base = dwmac->pcs.tse_pcs_base;
 	void __iomem *sgmii_adapter_base = dwmac->pcs.sgmii_adapter_base;
 	struct device *dev = dwmac->dev;
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct phy_device *phy_dev = ndev->phydev;
 	u32 val;
 
-	if ((tse_pcs_base) && (sgmii_adapter_base))
-		writew(SGMII_ADAPTER_DISABLE,
-		       sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
+	writew(SGMII_ADAPTER_DISABLE,
+	       sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
 
 	if (splitter_base) {
 		val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
@@ -93,7 +88,9 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
 		writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
 	}
 
-	if (tse_pcs_base && sgmii_adapter_base)
+	writew(SGMII_ADAPTER_ENABLE,
+	       sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
+	if (phy_dev)
 		tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed);
 }
 
Signature · 1 line
2.35.1
author maintainer
#86 lore raw

PATCH 86/219 net/sched: taprio: Check if socket flags are valid

In reply to Greg Kroah-Hartman

From: Benedikt Spranger <[email protected]>

[ Upstream commit e8a64bbaaad1f6548cec5508297bc6d45e8ab69e ]

A user may set the SO_TXTIME socket option to ensure a packet is send at a given time. The taprio scheduler has to confirm, that it is allowed to send a packet at that given time, by a check against the packet time schedule. The scheduler drop the packet, if the gates are closed at the given send time.

The check, if SO_TXTIME is set, may fail since sk_flags are part of an union and the union is used otherwise. This happen, if a socket is not a full socket, like a request socket for example.

Add a check to verify, if the union is used for sk_flags.

Fixes 4cfd5779bd6e ("taprio: Add support for txtime-assist mode")
---
 net/sched/sch_taprio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/sched/sch_taprio.c +2 -1
index 377f896bdedc..b9c71a304d39 100644
@@ -417,7 +417,8 @@ static int taprio_enqueue_one(struct sk_buff *skb, struct Qdisc *sch,
 {
 	struct taprio_sched *q = qdisc_priv(sch);
 
-	if (skb->sk && sock_flag(skb->sk, SOCK_TXTIME)) {
+	/* sk_flags are only safe to use on full sockets. */
+	if (skb->sk && sk_fullsock(skb->sk) && sock_flag(skb->sk, SOCK_TXTIME)) {
 		if (!is_valid_interval(skb, sch))
 			return qdisc_drop(skb, sch, to_free);
 	} else if (TXTIME_ASSIST_IS_ENABLED(q->flags)) {
Signature · 1 line
2.35.1
author maintainer
#87 lore raw

PATCH 87/219 cfg80211: hold bss_lock while updating nontrans_list

In reply to Greg Kroah-Hartman

From: Rameshkumar Sundaram <[email protected]>

[ Upstream commit a5199b5626cd6913cf8776a835bc63d40e0686ad ]

Synchronize additions to nontrans_list of transmitting BSS with bss_lock to avoid races. Also when cfg80211_add_nontrans_list() fails __cfg80211_unlink_bss() needs bss_lock to be held (has lockdep assert on bss_lock). So protect the whole block with bss_lock to avoid races and warnings. Found during code review.

Fixes 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
---
 net/wireless/scan.c | 2 ++
 1 file changed, 2 insertions(+)
net/wireless/scan.c +2 -0
index b2fdac96bab0..4a6d86432910 100644
@@ -2018,11 +2018,13 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
 		/* this is a nontransmitting bss, we need to add it to
 		 * transmitting bss' list if it is not there
 		 */
+		spin_lock_bh(&rdev->bss_lock);
 		if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
 					       &res->pub)) {
 			if (__cfg80211_unlink_bss(rdev, res))
 				rdev->bss_generation++;
 		}
+		spin_unlock_bh(&rdev->bss_lock);
 	}
 
 	trace_cfg80211_return_bss(&res->pub);
Signature · 1 line
2.35.1
author maintainer
#88 lore raw

PATCH 88/219 mac80211: fix ht_capa printout in debugfs

In reply to Greg Kroah-Hartman

From: Ben Greear <[email protected]>

[ Upstream commit fb4bccd863ccccd36ad000601856609e259a1859 ]

Don't use sizeof(pointer) when calculating scnprintf offset.

Fixes 01f84f0ed3b4 ("mac80211: reduce stack usage in debugfs")
[correct the Fixes tag]
---
 net/mac80211/debugfs_sta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/debugfs_sta.c +1 -1
index 9479f2787ea7..88d9cc945a21 100644
@@ -441,7 +441,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
 #define PRINT_HT_CAP(_cond, _str) \
 	do { \
 	if (_cond) \
-			p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \
+			p += scnprintf(p, bufsz + buf - p, "\t" _str "\n"); \
 	} while (0)
 	char *buf, *p;
 	int i;
Signature · 1 line
2.35.1
author maintainer
#89 lore raw

PATCH 89/219 netfilter: nft_socket: make cgroup match work in input too

In reply to Greg Kroah-Hartman

From: Florian Westphal <[email protected]>

[ Upstream commit 05ae2fba821c4d122ab4ba3e52144e21586c4010 ]

cgroupv2 helper function ignores the already-looked up sk and uses skb->sk instead.

Just pass sk from the calling function instead; this will make cgroup matching work for udp and tcp in input even when edemux did not set skb->sk already.

Fixes e0bb96db96f8 ("netfilter: nft_socket: add support for cgroupsv2")
---
 net/netfilter/nft_socket.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
net/netfilter/nft_socket.c +3 -4
index d601974c9d2e..b8f011145765 100644
@@ -36,12 +36,11 @@ static void nft_socket_wildcard(const struct nft_pktinfo *pkt,
 
 #ifdef CONFIG_SOCK_CGROUP_DATA
 static noinline bool
-nft_sock_get_eval_cgroupv2(u32 *dest, const struct nft_pktinfo *pkt, u32 level)
+nft_sock_get_eval_cgroupv2(u32 *dest, struct sock *sk, const struct nft_pktinfo *pkt, u32 level)
 {
-	struct sock *sk = skb_to_full_sk(pkt->skb);
 	struct cgroup *cgrp;
 
-	if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
+	if (!sk_fullsock(sk))
 		return false;
 
 	cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
@@ -108,7 +107,7 @@ static void nft_socket_eval(const struct nft_expr *expr,
 		break;
 #ifdef CONFIG_SOCK_CGROUP_DATA
 	case NFT_SOCKET_CGROUPV2:
-		if (!nft_sock_get_eval_cgroupv2(dest, pkt, priv->level)) {
+		if (!nft_sock_get_eval_cgroupv2(dest, sk, pkt, priv->level)) {
 			regs->verdict.code = NFT_BREAK;
 			return;
 		}
Signature · 1 line
2.35.1
author maintainer
#90 lore raw

PATCH 90/219 drm/msm: Fix range size vs end confusion

In reply to Greg Kroah-Hartman

From: Rob Clark <[email protected]>

[ Upstream commit 537fef808be5ea56f6fc06932162550819a3b3c3 ]

The fourth param is size, rather than range_end.

Note that we could increase the address space size if we had a way to prevent buffers from spanning a 4G split, mostly just to avoid fw bugs with 64b math.

Fixes 84c31ee16f90 ("drm/msm/a6xx: Add support for per-instance pagetables")
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +1 -1
index 616be7265da4..19622fb1fa35 100644
@@ -1714,7 +1714,7 @@ a6xx_create_private_address_space(struct msm_gpu *gpu)
 		return ERR_CAST(mmu);
 
 	return msm_gem_address_space_create(mmu,
-		"gpu", 0x100000000ULL, 0x1ffffffffULL);
+		"gpu", 0x100000000ULL, SZ_4G);
 }
 
 static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
Signature · 1 line
2.35.1
author maintainer
#91 lore raw

PATCH 91/219 drm/msm/dsi: Use connector directly in msm_dsi_manager_connector_init()

In reply to Greg Kroah-Hartman

From: Stephen Boyd <[email protected]>

[ Upstream commit 47b7de6b88b962ef339a2427a023d2a23d161654 ]

The member 'msm_dsi->connector' isn't assigned until msm_dsi_manager_connector_init() returns (see msm_dsi_modeset_init() and how it assigns the return value). Therefore this pointer is going to be NULL here. Let's use 'connector' which is what was intended.

Cc Dmitry Baryshkov <[email protected]>
Cc Sean Paul <[email protected]>
Fixes 6d5e78406991 ("drm/msm/dsi: Move dsi panel init into modeset init path")

Patchwork: https://patchwork.freedesktop.org/patch/478693/

---
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/dsi/dsi_manager.c +1 -1
index f19bae475c96..cd7b41b7d518 100644
@@ -641,7 +641,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id)
 	return connector;
 
 fail:
-	connector->funcs->destroy(msm_dsi->connector);
+	connector->funcs->destroy(connector);
 	return ERR_PTR(ret);
 }
 
Signature · 1 line
2.35.1
author maintainer
#92 lore raw

PATCH 92/219 drm/msm/dp: add fail safe mode outside of event_mutex context

In reply to Greg Kroah-Hartman

From: Kuogee Hsieh <[email protected]>

[ Upstream commit 8b2c181e3dcf7562445af6702ee94aaedcbe13c8 ]

There is possible circular locking dependency detected on event_mutex (see below logs). This is due to set fail safe mode is done at dp_panel_read_sink_caps() within event_mutex scope. To break this possible circular locking, this patch move setting fail safe mode out of event_mutex scope.

[   23.958078] ======================================================
[   23.964430] WARNING: possible circular locking dependency detected
[   23.970777] 5.17.0-rc2-lockdep-00088-g05241de1f69e #148 Not tainted
[   23.977219] ------------------------------------------------------
[   23.983570] DrmThread/1574 is trying to acquire lock:
[   23.988763] ffffff808423aab0 (&dp->event_mutex){+.+.}-{3:3}, at: msm_dp_displ                                                                             ay_enable+0x58/0x164
[   23.997895]
[   23.997895] but task is already holding lock:
[   24.003895] ffffff808420b280 (&kms->commit_lock[i]/1){+.+.}-{3:3}, at: lock_c                                                                             rtcs+0x80/0x8c
[   24.012495]
[   24.012495] which lock already depends on the new lock.
[   24.012495]
[   24.020886]
[   24.020886] the existing dependency chain (in reverse order) is:
[   24.028570]
[   24.028570] -> #5 (&kms->commit_lock[i]/1){+.+.}-{3:3}:
[   24.035472]        __mutex_lock+0xc8/0x384
[   24.039695]        mutex_lock_nested+0x54/0x74
[   24.044272]        lock_crtcs+0x80/0x8c
[   24.048222]        msm_atomic_commit_tail+0x1e8/0x3d0
[   24.053413]        commit_tail+0x7c/0xfc
[   24.057452]        drm_atomic_helper_commit+0x158/0x15c
[   24.062826]        drm_atomic_commit+0x60/0x74
[   24.067403]        drm_mode_atomic_ioctl+0x6b0/0x908
[   24.072508]        drm_ioctl_kernel+0xe8/0x168
[   24.077086]        drm_ioctl+0x320/0x370
[   24.081123]        drm_compat_ioctl+0x40/0xdc
[   24.085602]        __arm64_compat_sys_ioctl+0xe0/0x150
[   24.090895]        invoke_syscall+0x80/0x114
[   24.095294]        el0_svc_common.constprop.3+0xc4/0xf8
[   24.100668]        do_el0_svc_compat+0x2c/0x54
[   24.105242]        el0_svc_compat+0x4c/0xe4
[   24.109548]        el0t_32_sync_handler+0xc4/0xf4
[   24.114381]        el0t_32_sync+0x178
[   24.118688]
[   24.118688] -> #4 (&kms->commit_lock[i]){+.+.}-{3:3}:
[   24.125408]        __mutex_lock+0xc8/0x384
[   24.129628]        mutex_lock_nested+0x54/0x74
[   24.134204]        lock_crtcs+0x80/0x8c
[   24.138155]        msm_atomic_commit_tail+0x1e8/0x3d0
[   24.143345]        commit_tail+0x7c/0xfc
[   24.147382]        drm_atomic_helper_commit+0x158/0x15c
[   24.152755]        drm_atomic_commit+0x60/0x74
[   24.157323]        drm_atomic_helper_set_config+0x68/0x90
[   24.162869]        drm_mode_setcrtc+0x394/0x648
[   24.167535]        drm_ioctl_kernel+0xe8/0x168
[   24.172102]        drm_ioctl+0x320/0x370
[   24.176135]        drm_compat_ioctl+0x40/0xdc
[   24.180621]        __arm64_compat_sys_ioctl+0xe0/0x150
[   24.185904]        invoke_syscall+0x80/0x114
[   24.190302]        el0_svc_common.constprop.3+0xc4/0xf8
[   24.195673]        do_el0_svc_compat+0x2c/0x54
[   24.200241]        el0_svc_compat+0x4c/0xe4
[   24.204544]        el0t_32_sync_handler+0xc4/0xf4
[   24.209378]        el0t_32_sync+0x174/0x178
[   24.213680] -> #3 (crtc_ww_class_mutex){+.+.}-{3:3}:
[   24.220308]        __ww_mutex_lock.constprop.20+0xe8/0x878
[   24.225951]        ww_mutex_lock+0x60/0xd0
[   24.230166]        modeset_lock+0x190/0x19c
[   24.234467]        drm_modeset_lock+0x34/0x54
[   24.238953]        drmm_mode_config_init+0x550/0x764
[   24.244065]        msm_drm_bind+0x170/0x59c
[   24.248374]        try_to_bring_up_master+0x244/0x294
[   24.253572]        __component_add+0xf4/0x14c
[   24.258057]        component_add+0x2c/0x38
[   24.262273]        dsi_dev_attach+0x2c/0x38
[   24.266575]        dsi_host_attach+0xc4/0x120
[   24.271060]        mipi_dsi_attach+0x34/0x48
[   24.275456]        devm_mipi_dsi_attach+0x28/0x68
[   24.280298]        ti_sn_bridge_probe+0x2b4/0x2dc
[   24.285137]        auxiliary_bus_probe+0x78/0x90
[   24.289893]        really_probe+0x1e4/0x3d8
[   24.294194]        __driver_probe_device+0x14c/0x164
[   24.299298]        driver_probe_device+0x54/0xf8
[   24.304043]        __device_attach_driver+0xb4/0x118
[   24.309145]        bus_for_each_drv+0xb0/0xd4
[   24.313628]        __device_attach+0xcc/0x158
[   24.318112]        device_initial_probe+0x24/0x30
[   24.322954]        bus_probe_device+0x38/0x9c
[   24.327439]        deferred_probe_work_func+0xd4/0xf0
[   24.332628]        process_one_work+0x2f0/0x498
[   24.337289]        process_scheduled_works+0x44/0x48
[   24.342391]        worker_thread+0x1e4/0x26c
[   24.346788]        kthread+0xe4/0xf4
[   24.350470]        ret_from_fork+0x10/0x20
[   24.354683]
[   24.354683]
[   24.354683] -> #2 (crtc_ww_class_acquire){+.+.}-{0:0}:
[   24.361489]        drm_modeset_acquire_init+0xe4/0x138
[   24.366777]        drm_helper_probe_detect_ctx+0x44/0x114
[   24.372327]        check_connector_changed+0xbc/0x198
[   24.377517]        drm_helper_hpd_irq_event+0xcc/0x11c
[   24.382804]        dsi_hpd_worker+0x24/0x30
[   24.387104]        process_one_work+0x2f0/0x498
[   24.391762]        worker_thread+0x1d0/0x26c
[   24.396158]        kthread+0xe4/0xf4
[   24.399840]        ret_from_fork+0x10/0x20
[   24.404053]
[   24.404053] -> #1 (&dev->mode_config.mutex){+.+.}-{3:3}:
[   24.411032]        __mutex_lock+0xc8/0x384
[   24.415247]        mutex_lock_nested+0x54/0x74
[   24.419819]        dp_panel_read_sink_caps+0x23c/0x26c
[   24.425108]        dp_display_process_hpd_high+0x34/0xd4
[   24.430570]        dp_display_usbpd_configure_cb+0x30/0x3c
[   24.436205]        hpd_event_thread+0x2ac/0x550
[   24.440864]        kthread+0xe4/0xf4
[   24.444544]        ret_from_fork+0x10/0x20
[   24.448757]
[   24.448757] -> #0 (&dp->event_mutex){+.+.}-{3:3}:
[   24.455116]        __lock_acquire+0xe2c/0x10d8
[   24.459690]        lock_acquire+0x1ac/0x2d0
[   24.463988]        __mutex_lock+0xc8/0x384
[   24.468201]        mutex_lock_nested+0x54/0x74
[   24.472773]        msm_dp_display_enable+0x58/0x164
[   24.477789]        dp_bridge_enable+0x24/0x30
[   24.482273]        drm_atomic_bridge_chain_enable+0x78/0x9c
[   24.488006]        drm_atomic_helper_commit_modeset_enables+0x1bc/0x244
[   24.494801]        msm_atomic_commit_tail+0x248/0x3d0
[   24.499992]        commit_tail+0x7c/0xfc
[   24.504031]        drm_atomic_helper_commit+0x158/0x15c
[   24.509404]        drm_atomic_commit+0x60/0x74
[   24.513976]        drm_mode_atomic_ioctl+0x6b0/0x908
[   24.519079]        drm_ioctl_kernel+0xe8/0x168
[   24.523650]        drm_ioctl+0x320/0x370
[   24.527689]        drm_compat_ioctl+0x40/0xdc
[   24.532175]        __arm64_compat_sys_ioctl+0xe0/0x150
[   24.537463]        invoke_syscall+0x80/0x114
[   24.541861]        el0_svc_common.constprop.3+0xc4/0xf8
[   24.547235]        do_el0_svc_compat+0x2c/0x54
[   24.551806]        el0_svc_compat+0x4c/0xe4
[   24.556106]        el0t_32_sync_handler+0xc4/0xf4
[   24.560948]        el0t_32_sync+0x174/0x178

Changes in v2:
-- add circular lockiing trace

Fixes d4aca422539c ("drm/msm/dp: always add fail-safe mode into connector mode list")

Patchwork: https://patchwork.freedesktop.org/patch/481396/

---
 drivers/gpu/drm/msm/dp/dp_display.c |  6 ++++++
 drivers/gpu/drm/msm/dp/dp_panel.c   | 20 ++++++++++----------
 drivers/gpu/drm/msm/dp/dp_panel.h   |  1 +
 3 files changed, 17 insertions(+), 10 deletions(-)
drivers/gpu/drm/msm/dp/dp_display.c +6 -0
index 1d7f82e6eafe..af9c09c30860 100644
@@ -551,6 +551,12 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
 
 	mutex_unlock(&dp->event_mutex);
 
+	/*
+	 * add fail safe mode outside event_mutex scope
+	 * to avoid potiential circular lock with drm thread
+	 */
+	dp_panel_add_fail_safe_mode(dp->dp_display.connector);
+
 	/* uevent will complete connection part */
 	return 0;
 };
drivers/gpu/drm/msm/dp/dp_panel.c +10 -10
index f1418722c549..26c3653c99ec 100644
@@ -151,6 +151,15 @@ static int dp_panel_update_modes(struct drm_connector *connector,
 	return rc;
 }
 
+void dp_panel_add_fail_safe_mode(struct drm_connector *connector)
+{
+	/* fail safe edid */
+	mutex_lock(&connector->dev->mode_config.mutex);
+	if (drm_add_modes_noedid(connector, 640, 480))
+		drm_set_preferred_mode(connector, 640, 480);
+	mutex_unlock(&connector->dev->mode_config.mutex);
+}
+
 int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
 	struct drm_connector *connector)
 {
@@ -207,16 +216,7 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
 			goto end;
 		}
 
-		/* fail safe edid */
-		mutex_lock(&connector->dev->mode_config.mutex);
-		if (drm_add_modes_noedid(connector, 640, 480))
-			drm_set_preferred_mode(connector, 640, 480);
-		mutex_unlock(&connector->dev->mode_config.mutex);
-	} else {
-		/* always add fail-safe mode as backup mode */
-		mutex_lock(&connector->dev->mode_config.mutex);
-		drm_add_modes_noedid(connector, 640, 480);
-		mutex_unlock(&connector->dev->mode_config.mutex);
+		dp_panel_add_fail_safe_mode(connector);
 	}
 
 	if (panel->aux_cfg_update_done) {
drivers/gpu/drm/msm/dp/dp_panel.h +1 -0
index 9023e5bb4b8b..99739ea679a7 100644
@@ -59,6 +59,7 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel);
 int dp_panel_deinit(struct dp_panel *dp_panel);
 int dp_panel_timing_cfg(struct dp_panel *dp_panel);
 void dp_panel_dump_regs(struct dp_panel *dp_panel);
+void dp_panel_add_fail_safe_mode(struct drm_connector *connector);
 int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
 		struct drm_connector *connector);
 u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel, u32 mode_max_bpp,
Signature · 1 line
2.35.1
author maintainer
#93 lore raw

PATCH 93/219 io_uring: stop using io_wq_work as an fd placeholder

In reply to Greg Kroah-Hartman

From: Jens Axboe <[email protected]>

[ Upstream commit 82733d168cbd3fe9dab603f05894316b99008924 ]

There are two reasons why this isn't the best idea:

- It's an odd area to grab a bit of storage space, hence it's an odd area to grab storage from.
- It puts the 3rd io_kiocb cacheline into the hot path, where normal hot path just needs the first two.

Use 'cflags' for joint fd/cflags storage. We only need fd until we successfully issue, and we only need cflags once a request is done and is completed.

Fixes 6bf9c47a3989 ("io_uring: defer file assignment")
---
 fs/io-wq.h    |  1 -
 fs/io_uring.c | 12 ++++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)
fs/io-wq.h +0 -1
index 04d374e65e54..dbecd27656c7 100644
@@ -155,7 +155,6 @@ struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack)
 struct io_wq_work {
 	struct io_wq_work_node list;
 	unsigned flags;
-	int fd;
 };
 
 static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
fs/io_uring.c +8 -4
index d13f142793f2..d05394b0c1e6 100644
@@ -864,7 +864,11 @@ struct io_kiocb {
 
 	u64				user_data;
 	u32				result;
-	u32				cflags;
+	/* fd initially, then cflags for completion */
+	union {
+		u32			cflags;
+		int			fd;
+	};
 
 	struct io_ring_ctx		*ctx;
 	struct task_struct		*task;
@@ -6708,9 +6712,9 @@ static bool io_assign_file(struct io_kiocb *req, unsigned int issue_flags)
 		return true;
 
 	if (req->flags & REQ_F_FIXED_FILE)
-		req->file = io_file_get_fixed(req, req->work.fd, issue_flags);
+		req->file = io_file_get_fixed(req, req->fd, issue_flags);
 	else
-		req->file = io_file_get_normal(req, req->work.fd);
+		req->file = io_file_get_normal(req, req->fd);
 	if (req->file)
 		return true;
 
@@ -7243,7 +7247,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
 	if (io_op_defs[opcode].needs_file) {
 		struct io_submit_state *state = &ctx->submit_state;
 
-		req->work.fd = READ_ONCE(sqe->fd);
+		req->fd = READ_ONCE(sqe->fd);
 
 		/*
 		 * Plug now if we have more than 2 IO left after this, and the
Signature · 1 line
2.35.1
author maintainer
#94 lore raw

PATCH 94/219 net/smc: use memcpy instead of snprintf to avoid out of bounds read

In reply to Greg Kroah-Hartman

From: Karsten Graul <[email protected]>

[ Upstream commit b1871fd48efc567650dbdc974e5a2342a03fe0d2 ]

Using snprintf() to convert not null-terminated strings to null terminated strings may cause out of bounds read in the source string. Therefore use memcpy() and terminate the target string with a null afterwards.

Fixes fa0866625543 ("net/smc: add support for user defined EIDs")
Fixes 3c572145c24e ("net/smc: add generic netlink support for system EID")
---
 net/smc/smc_clc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/smc/smc_clc.c +4 -2
index ce27399b38b1..f9f3f59c79de 100644
@@ -191,7 +191,8 @@ static int smc_nl_ueid_dumpinfo(struct sk_buff *skb, u32 portid, u32 seq,
 			  flags, SMC_NETLINK_DUMP_UEID);
 	if (!hdr)
 		return -ENOMEM;
-	snprintf(ueid_str, sizeof(ueid_str), "%s", ueid);
+	memcpy(ueid_str, ueid, SMC_MAX_EID_LEN);
+	ueid_str[SMC_MAX_EID_LEN] = 0;
 	if (nla_put_string(skb, SMC_NLA_EID_TABLE_ENTRY, ueid_str)) {
 		genlmsg_cancel(skb, hdr);
 		return -EMSGSIZE;
@@ -252,7 +253,8 @@ int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
 		goto end;
 
 	smc_ism_get_system_eid(&seid);
-	snprintf(seid_str, sizeof(seid_str), "%s", seid);
+	memcpy(seid_str, seid, SMC_MAX_EID_LEN);
+	seid_str[SMC_MAX_EID_LEN] = 0;
 	if (nla_put_string(skb, SMC_NLA_SEID_ENTRY, seid_str))
 		goto err;
 	read_lock(&smc_clc_eid_table.lock);
Signature · 1 line
2.35.1
author maintainer
#95 lore raw

PATCH 95/219 net/smc: Fix NULL pointer dereference in smc_pnet_find_ib()

In reply to Greg Kroah-Hartman

From: Karsten Graul <[email protected]>

[ Upstream commit d22f4f977236f97e01255a80bca2ea93a8094fc8 ]

dev_name() was called with dev.parent as argument but without to NULL-check it before.
Solve this by checking the pointer before the call to dev_name().

Fixes af5f60c7e3d5 ("net/smc: allow PCI IDs as ib device names in the pnet table")
Reported-by [email protected]
---
 net/smc/smc_pnet.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
net/smc/smc_pnet.c +3 -2
index 29f0a559d884..4769f76505af 100644
@@ -311,8 +311,9 @@ static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
 	list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
 		if (!strncmp(ibdev->ibdev->name, ib_name,
 			     sizeof(ibdev->ibdev->name)) ||
-		    !strncmp(dev_name(ibdev->ibdev->dev.parent), ib_name,
-			     IB_DEVICE_NAME_MAX - 1)) {
+		    (ibdev->ibdev->dev.parent &&
+		     !strncmp(dev_name(ibdev->ibdev->dev.parent), ib_name,
+			     IB_DEVICE_NAME_MAX - 1))) {
 			goto out;
 		}
 	}
Signature · 1 line
2.35.1
author maintainer
#96 lore raw

PATCH 96/219 scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63

In reply to Greg Kroah-Hartman

From: Ajish Koshy <[email protected]>

[ Upstream commit 294080eacf92a0781e6d43663448a55001ec8c64 ]

When upper inbound and outbound queues 32-63 are enabled, we see upper vectors 32-63 in interrupt service routine. We need corresponding registers to handle masking and unmasking of these upper interrupts.

To achieve this, we use registers MSGU_ODMR_U(0x34) to mask and MSGU_ODMR_CLR_U(0x3C) to unmask the interrupts. In these registers bit 0-31 represents interrupt vectors 32-63.

---
 drivers/scsi/pm8001/pm80xx_hwi.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/scsi/pm8001/pm80xx_hwi.c +13 -9
index 55163469030d..2dea48933ef9 100644
@@ -1734,10 +1734,11 @@ static void
 pm80xx_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec)
 {
 #ifdef PM8001_USE_MSIX
-	u32 mask;
-	mask = (u32)(1 << vec);
-
-	pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, (u32)(mask & 0xFFFFFFFF));
+	if (vec < 32)
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, 1U << vec);
+	else
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR_U,
+			    1U << (vec - 32));
 	return;
 #endif
 	pm80xx_chip_intx_interrupt_enable(pm8001_ha);
@@ -1753,12 +1754,15 @@ static void
 pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)
 {
 #ifdef PM8001_USE_MSIX
-	u32 mask;
-	if (vec == 0xFF)
-		mask = 0xFFFFFFFF;
+	if (vec == 0xFF) {
+		/* disable all vectors 0-31, 32-63 */
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, 0xFFFFFFFF);
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_U, 0xFFFFFFFF);
+	} else if (vec < 32)
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, 1U << vec);
 	else
-		mask = (u32)(1 << vec);
-	pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, (u32)(mask & 0xFFFFFFFF));
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_U,
+			    1U << (vec - 32));
 	return;
 #endif
 	pm80xx_chip_intx_interrupt_disable(pm8001_ha);
Signature · 1 line
2.35.1
author maintainer
#97 lore raw

PATCH 97/219 scsi: pm80xx: Enable upper inbound, outbound queues

In reply to Greg Kroah-Hartman

From: Ajish Koshy <[email protected]>

[ Upstream commit bcd8a45223470e00b5f254018174d64a75db4bbe ]

Executing driver on servers with more than 32 CPUs were faced with command timeouts. This is because we were not geting completions for commands submitted on IQ32 - IQ63.

Set E64Q bit to enable upper inbound and outbound queues 32 to 63 in the MPI main configuration table.

Added 500ms delay after successful MPI initialization as mentioned in controller datasheet.

---
 drivers/scsi/pm8001/pm80xx_hwi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/scsi/pm8001/pm80xx_hwi.c +11 -0
index 2dea48933ef9..5853b3c0d76d 100644
@@ -766,6 +766,10 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity	= 0x01;
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt		= 0x01;
 
+	/* Enable higher IQs and OQs, 32 to 63, bit 16 */
+	if (pm8001_ha->max_q_num > 32)
+		pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt |=
+							1 << 16;
 	/* Disable end to end CRC checking */
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump = (0x1 << 16);
 
@@ -1027,6 +1031,13 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
 	if (0x0000 != gst_len_mpistate)
 		return -EBUSY;
 
+	/*
+	 *  As per controller datasheet, after successful MPI
+	 *  initialization minimum 500ms delay is required before
+	 *  issuing commands.
+	 */
+	msleep(500);
+
 	return 0;
 }
 
Signature · 1 line
2.35.1
author maintainer
#98 lore raw

PATCH 98/219 scsi: iscsi: Move iscsi_ep_disconnect()

In reply to Greg Kroah-Hartman

From: Mike Christie <[email protected]>

[ Upstream commit c34f95e98d8fb750eefd4f3fe58b4f8b5e89253b ]

This patch moves iscsi_ep_disconnect() so it can be called earlier in the next patch.

---
 drivers/scsi/scsi_transport_iscsi.c | 38 ++++++++++++++---------------
 1 file changed, 19 insertions(+), 19 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +19 -19
index 554b6f784223..126f6f23bffa 100644
@@ -2236,6 +2236,25 @@ static void iscsi_stop_conn(struct iscsi_cls_conn *conn, int flag)
 	ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n");
 }
 
+static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
+{
+	struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
+	struct iscsi_endpoint *ep;
+
+	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
+	conn->state = ISCSI_CONN_FAILED;
+
+	if (!conn->ep || !session->transport->ep_disconnect)
+		return;
+
+	ep = conn->ep;
+	conn->ep = NULL;
+
+	session->transport->unbind_conn(conn, is_active);
+	session->transport->ep_disconnect(ep);
+	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 			      struct iscsi_uevent *ev)
 {
@@ -2276,25 +2295,6 @@ static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 	return 0;
 }
 
-static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
-{
-	struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
-	struct iscsi_endpoint *ep;
-
-	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
-	conn->state = ISCSI_CONN_FAILED;
-
-	if (!conn->ep || !session->transport->ep_disconnect)
-		return;
-
-	ep = conn->ep;
-	conn->ep = NULL;
-
-	session->transport->unbind_conn(conn, is_active);
-	session->transport->ep_disconnect(ep);
-	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
-}
-
 static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 {
 	struct iscsi_cls_conn *conn = container_of(work, struct iscsi_cls_conn,
Signature · 1 line
2.35.1
author maintainer
#99 lore raw

PATCH 99/219 scsi: iscsi: Fix offload conn cleanup when iscsid restarts

In reply to Greg Kroah-Hartman

From: Mike Christie <[email protected]>

[ Upstream commit cbd2283aaf47fef4ded4b29124b1ef3beb515f3a ]

When userspace restarts during boot or upgrades it won't know about the offload driver's endpoint and connection mappings. iscsid will start by cleaning up the old session by doing a stop_conn call. Later, if we are able to create a new connection, we clean up the old endpoint during the binding stage. The problem is that if we do stop_conn before doing the ep_disconnect call offload, drivers can still be executing I/O. We then might free tasks from the under the card/driver.

This moves the ep_disconnect call to before we do the stop_conn call for this case. It will then work and look like a normal recovery/cleanup procedure from the driver's point of view.

---
 drivers/scsi/scsi_transport_iscsi.c | 48 +++++++++++++++++------------
 1 file changed, 28 insertions(+), 20 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +28 -20
index 126f6f23bffa..03cda2da80ef 100644
@@ -2255,6 +2255,23 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
 	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
 }
 
+static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
+					 struct iscsi_endpoint *ep,
+					 bool is_active)
+{
+	/* Check if this was a conn error and the kernel took ownership */
+	if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
+		iscsi_ep_disconnect(conn, is_active);
+	} else {
+		ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
+		mutex_unlock(&conn->ep_mutex);
+
+		flush_work(&conn->cleanup_work);
+
+		mutex_lock(&conn->ep_mutex);
+	}
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 			      struct iscsi_uevent *ev)
 {
@@ -2275,6 +2292,16 @@ static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 		cancel_work_sync(&conn->cleanup_work);
 		iscsi_stop_conn(conn, flag);
 	} else {
+		/*
+		 * For offload, when iscsid is restarted it won't know about
+		 * existing endpoints so it can't do a ep_disconnect. We clean
+		 * it up here for userspace.
+		 */
+		mutex_lock(&conn->ep_mutex);
+		if (conn->ep)
+			iscsi_if_disconnect_bound_ep(conn, conn->ep, true);
+		mutex_unlock(&conn->ep_mutex);
+
 		/*
 		 * Figure out if it was the kernel or userspace initiating this.
 		 */
@@ -3003,16 +3030,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
 	}
 
 	mutex_lock(&conn->ep_mutex);
-	/* Check if this was a conn error and the kernel took ownership */
-	if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
-		ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
-		mutex_unlock(&conn->ep_mutex);
-
-		flush_work(&conn->cleanup_work);
-		goto put_ep;
-	}
-
-	iscsi_ep_disconnect(conn, false);
+	iscsi_if_disconnect_bound_ep(conn, ep, false);
 	mutex_unlock(&conn->ep_mutex);
 put_ep:
 	iscsi_put_endpoint(ep);
@@ -3723,16 +3741,6 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
 
 	switch (nlh->nlmsg_type) {
 	case ISCSI_UEVENT_BIND_CONN:
-		if (conn->ep) {
-			/*
-			 * For offload boot support where iscsid is restarted
-			 * during the pivot root stage, the ep will be intact
-			 * here when the new iscsid instance starts up and
-			 * reconnects.
-			 */
-			iscsi_ep_disconnect(conn, true);
-		}
-
 		session = iscsi_session_lookup(ev->u.b_conn.sid);
 		if (!session) {
 			err = -EINVAL;
Signature · 1 line
2.35.1
author maintainer
#100 lore raw

PATCH 100/219 scsi: iscsi: Fix endpoint reuse regression

In reply to Greg Kroah-Hartman

From: Mike Christie <[email protected]>

[ Upstream commit 0aadafb5c34403a7cced1a8d61877048dc059f70 ]

This patch fixes a bug where when using iSCSI offload we can free an endpoint while userspace still thinks it's active. That then causes the endpoint ID to be reused for a new connection's endpoint while userspace still thinks the ID is for the original connection. Userspace will then end up disconnecting a running connection's endpoint or trying to bind to another connection's endpoint.

This bug is a regression added in:

Commit 23d6fefbb3f6 ("scsi: iscsi: Fix in-kernel conn failure handling")

where we added a in kernel ep_disconnect call to fix a bug in:

Commit 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in kernel space")

where we would call stop_conn without having done ep_disconnect. This early ep_disconnect call will then free the endpoint and it's ID while userspace still thinks the ID is valid.

Fix the early release of the ID by having the in kernel recovery code keep a reference to the endpoint until userspace has called into the kernel to finish cleaning up the endpoint/connection. It requires the previous commit "scsi: iscsi: Release endpoint ID when its freed" which moved the freeing of the ID until when the endpoint is released.

---
 drivers/scsi/scsi_transport_iscsi.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/scsi/scsi_transport_iscsi.c +11 -1
index 03cda2da80ef..4fa2fd7f4c72 100644
@@ -2267,7 +2267,11 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
 		mutex_unlock(&conn->ep_mutex);
 
 		flush_work(&conn->cleanup_work);
-
+		/*
+		 * Userspace is now done with the EP so we can release the ref
+		 * iscsi_cleanup_conn_work_fn took.
+		 */
+		iscsi_put_endpoint(ep);
 		mutex_lock(&conn->ep_mutex);
 	}
 }
@@ -2342,6 +2346,12 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 		return;
 	}
 
+	/*
+	 * Get a ref to the ep, so we don't release its ID until after
+	 * userspace is done referencing it in iscsi_if_disconnect_bound_ep.
+	 */
+	if (conn->ep)
+		get_device(&conn->ep->dev);
 	iscsi_ep_disconnect(conn, false);
 
 	if (system_state != SYSTEM_RUNNING) {
Signature · 1 line
2.35.1
author maintainer
#101 lore raw

PATCH 101/219 scsi: iscsi: Fix conn cleanup and stop race during iscsid restart

In reply to Greg Kroah-Hartman

From: Mike Christie <[email protected]>

[ Upstream commit 7c6e99c18167ed89729bf167ccb4a7e3ab3115ba ]

If iscsid is doing a stop_conn at the same time the kernel is starting error recovery we can hit a race that allows the cleanup work to run on a valid connection. In the race, iscsi_if_stop_conn sees the cleanup bit set, but it calls flush_work on the clean_work before iscsi_conn_error_event has queued it. The flush then returns before the queueing and so the cleanup_work can run later and disconnect/stop a conn while it's in a connected state.

The patch:

Commit 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in kernel space")

added the late stop_conn call bug originally, and the patch:

Commit 23d6fefbb3f6 ("scsi: iscsi: Fix in-kernel conn failure handling")

attempted to fix it but only fixed the normal EH case and left the above race for the iscsid restart case. For the normal EH case we don't hit the race because we only signal userspace to start recovery after we have done the queueing, so the flush will always catch the queued work or see it completed.

For iscsid restart cases like boot, we can hit the race because iscsid will call down to the kernel before the kernel has signaled any error, so both code paths can be running at the same time. This adds a lock around the setting of the cleanup bit and queueing so they happen together.

---
 drivers/scsi/scsi_transport_iscsi.c | 17 +++++++++++++++++
 include/scsi/scsi_transport_iscsi.h |  2 ++
 2 files changed, 19 insertions(+)
drivers/scsi/scsi_transport_iscsi.c +17 -0
index 4fa2fd7f4c72..ed289e1242c9 100644
@@ -2260,9 +2260,12 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
 					 bool is_active)
 {
 	/* Check if this was a conn error and the kernel took ownership */
+	spin_lock_irq(&conn->lock);
 	if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
+		spin_unlock_irq(&conn->lock);
 		iscsi_ep_disconnect(conn, is_active);
 	} else {
+		spin_unlock_irq(&conn->lock);
 		ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
 		mutex_unlock(&conn->ep_mutex);
 
@@ -2309,9 +2312,12 @@ static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 		/*
 		 * Figure out if it was the kernel or userspace initiating this.
 		 */
+		spin_lock_irq(&conn->lock);
 		if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
+			spin_unlock_irq(&conn->lock);
 			iscsi_stop_conn(conn, flag);
 		} else {
+			spin_unlock_irq(&conn->lock);
 			ISCSI_DBG_TRANS_CONN(conn,
 					     "flush kernel conn cleanup.\n");
 			flush_work(&conn->cleanup_work);
@@ -2320,7 +2326,9 @@ static int iscsi_if_stop_conn(struct iscsi_transport *transport,
 		 * Only clear for recovery to avoid extra cleanup runs during
 		 * termination.
 		 */
+		spin_lock_irq(&conn->lock);
 		clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
+		spin_unlock_irq(&conn->lock);
 	}
 	ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop done.\n");
 	return 0;
@@ -2341,7 +2349,9 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 	 */
 	if (conn->state != ISCSI_CONN_BOUND && conn->state != ISCSI_CONN_UP) {
 		ISCSI_DBG_TRANS_CONN(conn, "Got error while conn is already failed. Ignoring.\n");
+		spin_lock_irq(&conn->lock);
 		clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
+		spin_unlock_irq(&conn->lock);
 		mutex_unlock(&conn->ep_mutex);
 		return;
 	}
@@ -2407,6 +2417,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
 		conn->dd_data = &conn[1];
 
 	mutex_init(&conn->ep_mutex);
+	spin_lock_init(&conn->lock);
 	INIT_LIST_HEAD(&conn->conn_list);
 	INIT_WORK(&conn->cleanup_work, iscsi_cleanup_conn_work_fn);
 	conn->transport = transport;
@@ -2598,9 +2609,12 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
 	struct iscsi_uevent *ev;
 	struct iscsi_internal *priv;
 	int len = nlmsg_total_size(sizeof(*ev));
+	unsigned long flags;
 
+	spin_lock_irqsave(&conn->lock, flags);
 	if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags))
 		queue_work(iscsi_conn_cleanup_workq, &conn->cleanup_work);
+	spin_unlock_irqrestore(&conn->lock, flags);
 
 	priv = iscsi_if_transport_lookup(conn->transport);
 	if (!priv)
@@ -3743,11 +3757,14 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
 		return -EINVAL;
 
 	mutex_lock(&conn->ep_mutex);
+	spin_lock_irq(&conn->lock);
 	if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
+		spin_unlock_irq(&conn->lock);
 		mutex_unlock(&conn->ep_mutex);
 		ev->r.retcode = -ENOTCONN;
 		return 0;
 	}
+	spin_unlock_irq(&conn->lock);
 
 	switch (nlh->nlmsg_type) {
 	case ISCSI_UEVENT_BIND_CONN:
include/scsi/scsi_transport_iscsi.h +2 -0
index c5d7810fd792..037c77fb5dc5 100644
@@ -211,6 +211,8 @@ struct iscsi_cls_conn {
 	struct mutex ep_mutex;
 	struct iscsi_endpoint *ep;
 
+	/* Used when accessing flags and queueing work. */
+	spinlock_t lock;
 	unsigned long flags;
 	struct work_struct cleanup_work;
 
Signature · 1 line
2.35.1
author maintainer
#102 lore raw

PATCH 102/219 scsi: iscsi: Fix unbound endpoint error handling

In reply to Greg Kroah-Hartman

From: Mike Christie <[email protected]>

[ Upstream commit 03690d81974535f228e892a14f0d2d44404fe555 ]

If a driver raises a connection error before the connection is bound, we can leave a cleanup_work queued that can later run and disconnect/stop a connection that is logged in. The problem is that drivers can call iscsi_conn_error_event for endpoints that are connected but not yet bound when something like the network port they are using is brought down. iscsi_cleanup_conn_work_fn will check for this and exit early, but if the cleanup_work is stuck behind other works, it might not get run until after userspace has done ep_disconnect. Because the endpoint is not yet bound there was no way for ep_disconnect to flush the work.

The bug of leaving stop_conns queued was added in:

Commit 23d6fefbb3f6 ("scsi: iscsi: Fix in-kernel conn failure handling")

and:

Commit 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in kernel space")

was supposed to fix it, but left this case.

This patch moves the conn state check to before we even queue the work so we can avoid queueing.

---
 drivers/scsi/scsi_transport_iscsi.c | 65 ++++++++++++++++-------------
 1 file changed, 36 insertions(+), 29 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +36 -29
index ed289e1242c9..c7b1b2e8bb02 100644
@@ -2221,10 +2221,10 @@ static void iscsi_stop_conn(struct iscsi_cls_conn *conn, int flag)
 
 	switch (flag) {
 	case STOP_CONN_RECOVER:
-		conn->state = ISCSI_CONN_FAILED;
+		WRITE_ONCE(conn->state, ISCSI_CONN_FAILED);
 		break;
 	case STOP_CONN_TERM:
-		conn->state = ISCSI_CONN_DOWN;
+		WRITE_ONCE(conn->state, ISCSI_CONN_DOWN);
 		break;
 	default:
 		iscsi_cls_conn_printk(KERN_ERR, conn, "invalid stop flag %d\n",
@@ -2242,7 +2242,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
 	struct iscsi_endpoint *ep;
 
 	ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
-	conn->state = ISCSI_CONN_FAILED;
+	WRITE_ONCE(conn->state, ISCSI_CONN_FAILED);
 
 	if (!conn->ep || !session->transport->ep_disconnect)
 		return;
@@ -2341,21 +2341,6 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 	struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
 
 	mutex_lock(&conn->ep_mutex);
-	/*
-	 * If we are not at least bound there is nothing for us to do. Userspace
-	 * will do a ep_disconnect call if offload is used, but will not be
-	 * doing a stop since there is nothing to clean up, so we have to clear
-	 * the cleanup bit here.
-	 */
-	if (conn->state != ISCSI_CONN_BOUND && conn->state != ISCSI_CONN_UP) {
-		ISCSI_DBG_TRANS_CONN(conn, "Got error while conn is already failed. Ignoring.\n");
-		spin_lock_irq(&conn->lock);
-		clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
-		spin_unlock_irq(&conn->lock);
-		mutex_unlock(&conn->ep_mutex);
-		return;
-	}
-
 	/*
 	 * Get a ref to the ep, so we don't release its ID until after
 	 * userspace is done referencing it in iscsi_if_disconnect_bound_ep.
@@ -2422,7 +2407,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
 	INIT_WORK(&conn->cleanup_work, iscsi_cleanup_conn_work_fn);
 	conn->transport = transport;
 	conn->cid = cid;
-	conn->state = ISCSI_CONN_DOWN;
+	WRITE_ONCE(conn->state, ISCSI_CONN_DOWN);
 
 	/* this is released in the dev's release function */
 	if (!get_device(&session->dev))
@@ -2610,10 +2595,30 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
 	struct iscsi_internal *priv;
 	int len = nlmsg_total_size(sizeof(*ev));
 	unsigned long flags;
+	int state;
 
 	spin_lock_irqsave(&conn->lock, flags);
-	if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags))
-		queue_work(iscsi_conn_cleanup_workq, &conn->cleanup_work);
+	/*
+	 * Userspace will only do a stop call if we are at least bound. And, we
+	 * only need to do the in kernel cleanup if in the UP state so cmds can
+	 * be released to upper layers. If in other states just wait for
+	 * userspace to avoid races that can leave the cleanup_work queued.
+	 */
+	state = READ_ONCE(conn->state);
+	switch (state) {
+	case ISCSI_CONN_BOUND:
+	case ISCSI_CONN_UP:
+		if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP,
+				      &conn->flags)) {
+			queue_work(iscsi_conn_cleanup_workq,
+				   &conn->cleanup_work);
+		}
+		break;
+	default:
+		ISCSI_DBG_TRANS_CONN(conn, "Got conn error in state %d\n",
+				     state);
+		break;
+	}
 	spin_unlock_irqrestore(&conn->lock, flags);
 
 	priv = iscsi_if_transport_lookup(conn->transport);
@@ -2964,7 +2969,7 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
 	char *data = (char*)ev + sizeof(*ev);
 	struct iscsi_cls_conn *conn;
 	struct iscsi_cls_session *session;
-	int err = 0, value = 0;
+	int err = 0, value = 0, state;
 
 	if (ev->u.set_param.len > PAGE_SIZE)
 		return -EINVAL;
@@ -2981,8 +2986,8 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
 			session->recovery_tmo = value;
 		break;
 	default:
-		if ((conn->state == ISCSI_CONN_BOUND) ||
-			(conn->state == ISCSI_CONN_UP)) {
+		state = READ_ONCE(conn->state);
+		if (state == ISCSI_CONN_BOUND || state == ISCSI_CONN_UP) {
 			err = transport->set_param(conn, ev->u.set_param.param,
 					data, ev->u.set_param.len);
 		} else {
@@ -3778,7 +3783,7 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
 						ev->u.b_conn.transport_eph,
 						ev->u.b_conn.is_leading);
 		if (!ev->r.retcode)
-			conn->state = ISCSI_CONN_BOUND;
+			WRITE_ONCE(conn->state, ISCSI_CONN_BOUND);
 
 		if (ev->r.retcode || !transport->ep_connect)
 			break;
@@ -3797,7 +3802,8 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
 	case ISCSI_UEVENT_START_CONN:
 		ev->r.retcode = transport->start_conn(conn);
 		if (!ev->r.retcode)
-			conn->state = ISCSI_CONN_UP;
+			WRITE_ONCE(conn->state, ISCSI_CONN_UP);
+
 		break;
 	case ISCSI_UEVENT_SEND_PDU:
 		pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
@@ -4105,10 +4111,11 @@ static ssize_t show_conn_state(struct device *dev,
 {
 	struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent);
 	const char *state = "unknown";
+	int conn_state = READ_ONCE(conn->state);
 
-	if (conn->state >= 0 &&
-	    conn->state < ARRAY_SIZE(connection_state_names))
-		state = connection_state_names[conn->state];
+	if (conn_state >= 0 &&
+	    conn_state < ARRAY_SIZE(connection_state_names))
+		state = connection_state_names[conn_state];
 
 	return sysfs_emit(buf, "%s\n", state);
 }
Signature · 1 line
2.35.1
author maintainer
#103 lore raw

PATCH 103/219 sctp: Initialize daddr on peeled off socket

In reply to Greg Kroah-Hartman

From: Petr Malat <[email protected]>

[ Upstream commit 8467dda0c26583547731e7f3ea73fc3856bae3bf ]

Function sctp_do_peeloff() wrongly initializes daddr of the original socket instead of the peeled off socket, which makes getpeername() return zeroes instead of the primary address. Initialize the new socket instead.

Fixes d570ee490fb1 ("[SCTP]: Correctly set daddr for IPv6 sockets during peeloff")
---
 net/sctp/socket.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/socket.c +1 -1
index 3e1a9600be5e..7b0427658056 100644
@@ -5636,7 +5636,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
 	 * Set the daddr and initialize id to something more random and also
 	 * copy over any ip options.
 	 */
-	sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk);
+	sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sock->sk);
 	sp->pf->copy_ip_options(sk, sock->sk);
 
 	/* Populate the fields of the newsk from the oldsk and migrate the
Signature · 1 line
2.35.1
author maintainer
#104 lore raw

PATCH 104/219 net: lan966x: Fix when a ports upper is changed.

In reply to Greg Kroah-Hartman

From: Horatiu Vultur <[email protected]>

[ Upstream commit d7a947d289dc205fc717c004dcebe33b15305afd ]

On lan966x it is not allowed to have foreign interfaces under a bridge which already contains lan966x ports. So when a port leaves the bridge it would call switchdev_bridge_port_unoffload which eventually will notify the other ports that bridge left the vlan group but that is not true because the bridge is still part of the vlan group.

Therefore when a port leaves the bridge, stop generating replays because already the HW cleared after itself and the other ports don't need to do anything else.

Fixes cf2f60897e921e ("net: lan966x: Add support to offload the forwarding.")
---
 drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c +1 -2
index 7de55f6a4da8..3c987fd6b9e2 100644
@@ -261,8 +261,7 @@ static int lan966x_port_prechangeupper(struct net_device *dev,
 
 	if (netif_is_bridge_master(info->upper_dev) && !info->linking)
 		switchdev_bridge_port_unoffload(port->dev, port,
-						&lan966x_switchdev_nb,
-						&lan966x_switchdev_blocking_nb);
+						NULL, NULL);
 
 	return NOTIFY_DONE;
 }
Signature · 1 line
2.35.1
author maintainer
#105 lore raw

PATCH 105/219 net: lan966x: Stop processing the MAC entry is port is wrong.

In reply to Greg Kroah-Hartman

From: Horatiu Vultur <[email protected]>

[ Upstream commit 269219321eb7d7645a3122cf40a420c5dc655eb9 ]

Currently when getting a new MAC is learn, the HW generates an interrupt. So then the SW will check the new entry and checks if it arrived on a correct port. If it didn't just generate a warning. But this could still crash the system. Therefore stop processing that entry when an issue is seen.

Fixes 5ccd66e01cbef8 ("net: lan966x: add support for interrupts from analyzer")
---
 drivers/net/ethernet/microchip/lan966x/lan966x_mac.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/microchip/lan966x/lan966x_mac.c +4 -2
index ce5970bdcc6a..2679111ef669 100644
@@ -346,7 +346,8 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
 
 			lan966x_mac_process_raw_entry(&raw_entries[column],
 						      mac, &vid, &dest_idx);
-			WARN_ON(dest_idx > lan966x->num_phys_ports);
+			if (WARN_ON(dest_idx > lan966x->num_phys_ports))
+				continue;
 
 			/* If the entry in SW is found, then there is nothing
 			 * to do
@@ -392,7 +393,8 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
 
 		lan966x_mac_process_raw_entry(&raw_entries[column],
 					      mac, &vid, &dest_idx);
-		WARN_ON(dest_idx > lan966x->num_phys_ports);
+		if (WARN_ON(dest_idx > lan966x->num_phys_ports))
+			continue;
 
 		mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx);
 		if (!mac_entry)
Signature · 1 line
2.35.1
author maintainer
#106 lore raw

PATCH 106/219 netfilter: nf_tables: nft_parse_register can return a negative value

In reply to Greg Kroah-Hartman

From: Antoine Tenart <[email protected]>

[ Upstream commit 6c6f9f31ecd47dce1d0dafca4bec8805f9bc97cd ]

Since commit 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.") nft_parse_register can return a negative value, but the function prototype is still returning an unsigned int.

Fixes 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.")
---
 net/netfilter/nf_tables_api.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
index 1f5a0eece0d1..30d29d038d09 100644
@@ -9275,7 +9275,7 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
 }
 EXPORT_SYMBOL_GPL(nft_parse_u32_check);
 
-static unsigned int nft_parse_register(const struct nlattr *attr, u32 *preg)
+static int nft_parse_register(const struct nlattr *attr, u32 *preg)
 {
 	unsigned int reg;
 
Signature · 1 line
2.35.1
author maintainer
#107 lore raw

PATCH 107/219 io_uring: fix assign file locking issue

In reply to Greg Kroah-Hartman

From: Pavel Begunkov <[email protected]>

[ Upstream commit 0f8da75b51ac863b9435368bd50691718cc454b0 ]

io-wq work cancellation path can't take uring_lock as how it's done on file assignment, we have to handle IO_WQ_WORK_CANCEL first, this fixes encountered hangs.

---
 fs/io_uring.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
fs/io_uring.c +6 -4
index d05394b0c1e6..e3d1fc954933 100644
@@ -6892,16 +6892,18 @@ static void io_wq_submit_work(struct io_wq_work *work)
 	if (timeout)
 		io_queue_linked_timeout(timeout);
 
-	if (!io_assign_file(req, issue_flags)) {
-		err = -EBADF;
-		work->flags |= IO_WQ_WORK_CANCEL;
-	}
 
 	/* either cancelled or io-wq is dying, so don't touch tctx->iowq */
 	if (work->flags & IO_WQ_WORK_CANCEL) {
+fail:
 		io_req_task_queue_fail(req, err);
 		return;
 	}
+	if (!io_assign_file(req, issue_flags)) {
+		err = -EBADF;
+		work->flags |= IO_WQ_WORK_CANCEL;
+		goto fail;
+	}
 
 	if (req->flags & REQ_F_FORCE_ASYNC) {
 		bool opcode_poll = def->pollin || def->pollout;
Signature · 1 line
2.35.1
author maintainer
#108 lore raw

PATCH 108/219 ALSA: ad1889: Fix the missing snd_card_free() call at probe error

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

[ Upstream commit a8e84a5da18e6d786540aa4ceb6f969d5f1a441d ]

The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free().

This patch fixes it by calling snd_card_free() on the error from the probe callback using a new helper function.

Fixes 567f58754109 ("ALSA: ad1889: Allocate resources with device-managed APIs")
---
 sound/pci/ad1889.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
sound/pci/ad1889.c +8 -2
index bba4dae8dcc7..50e30704bf6f 100644
@@ -844,8 +844,8 @@ snd_ad1889_create(struct snd_card *card, struct pci_dev *pci)
 }
 
 static int
-snd_ad1889_probe(struct pci_dev *pci,
-		 const struct pci_device_id *pci_id)
+__snd_ad1889_probe(struct pci_dev *pci,
+		   const struct pci_device_id *pci_id)
 {
 	int err;
 	static int devno;
@@ -904,6 +904,12 @@ snd_ad1889_probe(struct pci_dev *pci,
 	return 0;
 }
 
+static int snd_ad1889_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
+{
+	return snd_card_free_on_error(&pci->dev, __snd_ad1889_probe(pci, pci_id));
+}
+
 static const struct pci_device_id snd_ad1889_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
 	{ 0, },
Signature · 1 line
2.35.1
author maintainer
#109 lore raw

PATCH 109/219 ALSA: mtpav: Dont call card private_free at probe error path

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

[ Upstream commit 4fb27190879b82e48ce89a56e9d6c04437dbc065 ]

The card destructor of nm256 driver does merely stopping the running timer, and it's superfluous for the probe error handling. Moreover, calling this via the previous devres change would lead to another problem due to the reverse call order.

This patch moves the setup of the private_free callback after the card registration, so that it can be used only after fully set up.

Fixes aa92050f10f0 ("ALSA: mtpav: Allocate resources with device-managed APIs")
---
 sound/drivers/mtpav.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/drivers/mtpav.c +2 -2
index 11235baaf6fa..f212f233ea61 100644
@@ -693,8 +693,6 @@ static int snd_mtpav_probe(struct platform_device *dev)
 	mtp_card->outmidihwport = 0xffffffff;
 	timer_setup(&mtp_card->timer, snd_mtpav_output_timer, 0);
 
-	card->private_free = snd_mtpav_free;
-
 	err = snd_mtpav_get_RAWMIDI(mtp_card);
 	if (err < 0)
 		return err;
@@ -716,6 +714,8 @@ static int snd_mtpav_probe(struct platform_device *dev)
 	if (err < 0)
 		return err;
 
+	card->private_free = snd_mtpav_free;
+
 	platform_set_drvdata(dev, card);
 	printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#110 lore raw

PATCH 110/219 io_uring: move io_uring_rsrc_update2 validation

In reply to Greg Kroah-Hartman

From: Dylan Yudaken <[email protected]>

[ Upstream commit 565c5e616e8061b40a2e1d786c418a7ac3503a8d ]

Move validation to be more consistently straight after copy_from_user. This is already done in io_register_rsrc_update and so this removes that redundant check.

---
 fs/io_uring.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/io_uring.c +2 -2
index e3d1fc954933..7da6fddaef4d 100644
@@ -10784,8 +10784,6 @@ static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
 	__u32 tmp;
 	int err;
 
-	if (up->resv)
-		return -EINVAL;
 	if (check_add_overflow(up->offset, nr_args, &tmp))
 		return -EOVERFLOW;
 	err = io_rsrc_node_switch_start(ctx);
@@ -10811,6 +10809,8 @@ static int io_register_files_update(struct io_ring_ctx *ctx, void __user *arg,
 	memset(&up, 0, sizeof(up));
 	if (copy_from_user(&up, arg, sizeof(struct io_uring_rsrc_update)))
 		return -EFAULT;
+	if (up.resv)
+		return -EINVAL;
 	return __io_register_rsrc_update(ctx, IORING_RSRC_FILE, &up, nr_args);
 }
 
Signature · 1 line
2.35.1
author maintainer
#111 lore raw

PATCH 111/219 io_uring: verify that resv2 is 0 in io_uring_rsrc_update2

In reply to Greg Kroah-Hartman

From: Dylan Yudaken <[email protected]>

[ Upstream commit d8a3ba9c143bf89c032deced8a686ffa53b46098 ]

Verify that the user does not pass in anything but 0 for this field.

Fixes 992da01aa932 ("io_uring: change registration/upd/rsrc tagging ABI")
---
 fs/io_uring.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
fs/io_uring.c +3 -2
index 7da6fddaef4d..2838bc6cdbc8 100644
@@ -6466,6 +6466,7 @@ static int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
 	up.nr = 0;
 	up.tags = 0;
 	up.resv = 0;
+	up.resv2 = 0;
 
 	io_ring_submit_lock(ctx, needs_lock);
 	ret = __io_register_rsrc_update(ctx, IORING_RSRC_FILE,
@@ -10809,7 +10810,7 @@ static int io_register_files_update(struct io_ring_ctx *ctx, void __user *arg,
 	memset(&up, 0, sizeof(up));
 	if (copy_from_user(&up, arg, sizeof(struct io_uring_rsrc_update)))
 		return -EFAULT;
-	if (up.resv)
+	if (up.resv || up.resv2)
 		return -EINVAL;
 	return __io_register_rsrc_update(ctx, IORING_RSRC_FILE, &up, nr_args);
 }
@@ -10823,7 +10824,7 @@ static int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
 		return -EINVAL;
 	if (copy_from_user(&up, arg, sizeof(up)))
 		return -EFAULT;
-	if (!up.nr || up.resv)
+	if (!up.nr || up.resv || up.resv2)
 		return -EINVAL;
 	return __io_register_rsrc_update(ctx, type, &up, up.nr);
 }
Signature · 1 line
2.35.1
author maintainer
#112 lore raw

PATCH 112/219 io_uring: verify pad field is 0 in io_get_ext_arg

In reply to Greg Kroah-Hartman

From: Dylan Yudaken <[email protected]>

[ Upstream commit d2347b9695dafe5c388a5f9aeb70e27a7a4d29cf ]

Ensure that only 0 is passed for pad here.

Fixes c73ebb685fb6 ("io_uring: add timeout support for io_uring_enter()")
---
 fs/io_uring.c | 2 ++
 1 file changed, 2 insertions(+)
fs/io_uring.c +2 -0
index 2838bc6cdbc8..7a652c8eeed2 100644
@@ -10109,6 +10109,8 @@ static int io_get_ext_arg(unsigned flags, const void __user *argp, size_t *argsz
 		return -EINVAL;
 	if (copy_from_user(&arg, argp, sizeof(arg)))
 		return -EFAULT;
+	if (arg.pad)
+		return -EINVAL;
 	*sig = u64_to_user_ptr(arg.sigmask);
 	*argsz = arg.sigmask_sz;
 	*ts = u64_to_user_ptr(arg.ts);
Signature · 1 line
2.35.1
author maintainer
#113 lore raw

PATCH 113/219 testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu set

In reply to Greg Kroah-Hartman

From: Athira Rajeev <[email protected]>

[ Upstream commit ce64763c63854b4079f2e036638aa881a1fb3fbc ]

The selftest "mqueue/mq_perf_tests.c" use CPU_ALLOC to allocate CPU set. This cpu set is used further in pthread_attr_setaffinity_np and by pthread_create in the code. But in current code, allocated cpu set is not freed.

Fix this issue by adding CPU_FREE in the "shutdown" function which is called in most of the error/exit path for the cleanup. There are few error paths which exit without using shutdown. Add a common goto error path with CPU_FREE for these cases.

Fixes 7820b0715b6f ("tools/selftests: add mq_perf_tests")
---
 .../testing/selftests/mqueue/mq_perf_tests.c  | 25 +++++++++++++------
 1 file changed, 17 insertions(+), 8 deletions(-)
tools/testing/selftests/mqueue/mq_perf_tests.c +17 -8
index b019e0b8221c..84fda3b49073 100644
@@ -180,6 +180,9 @@ void shutdown(int exit_val, char *err_cause, int line_no)
 	if (in_shutdown++)
 		return;
 
+	/* Free the cpu_set allocated using CPU_ALLOC in main function */
+	CPU_FREE(cpu_set);
+
 	for (i = 0; i < num_cpus_to_pin; i++)
 		if (cpu_threads[i]) {
 			pthread_kill(cpu_threads[i], SIGUSR1);
@@ -551,6 +554,12 @@ int main(int argc, char *argv[])
 		perror("sysconf(_SC_NPROCESSORS_ONLN)");
 		exit(1);
 	}
+
+	if (getuid() != 0)
+		ksft_exit_skip("Not running as root, but almost all tests "
+			"require root in order to modify\nsystem settings.  "
+			"Exiting.\n");
+
 	cpus_online = min(MAX_CPUS, sysconf(_SC_NPROCESSORS_ONLN));
 	cpu_set = CPU_ALLOC(cpus_online);
 	if (cpu_set == NULL) {
@@ -589,7 +598,7 @@ int main(int argc, char *argv[])
 						cpu_set)) {
 					fprintf(stderr, "Any given CPU may "
 						"only be given once.\n");
-					exit(1);
+					goto err_code;
 				} else
 					CPU_SET_S(cpus_to_pin[cpu],
 						  cpu_set_size, cpu_set);
@@ -607,7 +616,7 @@ int main(int argc, char *argv[])
 				queue_path = malloc(strlen(option) + 2);
 				if (!queue_path) {
 					perror("malloc()");
-					exit(1);
+					goto err_code;
 				}
 				queue_path[0] = '/';
 				queue_path[1] = 0;
@@ -622,17 +631,12 @@ int main(int argc, char *argv[])
 		fprintf(stderr, "Must pass at least one CPU to continuous "
 			"mode.\n");
 		poptPrintUsage(popt_context, stderr, 0);
-		exit(1);
+		goto err_code;
 	} else if (!continuous_mode) {
 		num_cpus_to_pin = 1;
 		cpus_to_pin[0] = cpus_online - 1;
 	}
 
-	if (getuid() != 0)
-		ksft_exit_skip("Not running as root, but almost all tests "
-			"require root in order to modify\nsystem settings.  "
-			"Exiting.\n");
-
 	max_msgs = fopen(MAX_MSGS, "r+");
 	max_msgsize = fopen(MAX_MSGSIZE, "r+");
 	if (!max_msgs)
@@ -740,4 +744,9 @@ int main(int argc, char *argv[])
 			sleep(1);
 	}
 	shutdown(0, "", 0);
+
+err_code:
+	CPU_FREE(cpu_set);
+	exit(1);
+
 }
Signature · 1 line
2.35.1
author maintainer
#114 lore raw

PATCH 114/219 ALSA: usb-audio: Increase max buffer size

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

[ Upstream commit fee2ec8cceb33b8886bc5894fb07e0b2e34148af ]

The current limit of max buffer size 1MB seems too small for modern devices with lots of channels and high sample rates. Let's make bigger, 4MB.

---
 sound/usb/pcm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/pcm.c +1 -1
index 6a460225f2e3..37ee6df8b15a 100644
@@ -659,7 +659,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
 #define hwc_debug(fmt, args...) do { } while(0)
 #endif
 
-#define MAX_BUFFER_BYTES	(1024 * 1024)
+#define MAX_BUFFER_BYTES	(4 * 1024 * 1024)
 #define MAX_PERIOD_BYTES	(512 * 1024)
 
 static const struct snd_pcm_hardware snd_usb_hardware =
Signature · 1 line
2.35.1
author maintainer
#115 lore raw

PATCH 115/219 ALSA: usb-audio: Limit max buffer and period sizes per time

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

[ Upstream commit 24d0c9f0e7de95fe3e3e0067cbea1cd5d413244b ]

In the previous fix, we increased the max buffer bytes from 1MB to 4MB so that we can use bigger buffers for the modern HiFi devices with higher rates, more channels and wider formats. OTOH, extending this has a concern that too big buffer is allowed for the lower rates, less channels and narrower formats; when an application tries to allocate as big buffer as possible, it'll lead to unexpectedly too huge size.

Also, we had a problem about the inconsistent max buffer and period bytes for the implicit feedback mode when both streams have different channels. This was fixed by the (relatively complex) patch to reduce the max buffer and period bytes accordingly.

This is an alternative fix for those, a patch to kill two birds with one stone (*): instead of increasing the max buffer bytes blindly and applying the reduction per channels, we simply use the hw constraints for the buffer and period "time". Meanwhile the max buffer and period bytes are set unlimited instead.

Since the inconsistency of buffer (and period) bytes comes from the difference of the channels in the tied streams, as long as we care only about the buffer (and period) time, it doesn't matter; the buffer time is same for different channels, although we still allow higher buffer size. Similarly, this will allow more buffer bytes for HiFi devices while it also keeps the reasonable size for the legacy devices, too.

As of this patch, the max period and buffer time are set to 1 and 2 seconds, which should be large enough for all possible use cases.

(*) No animals were harmed in the making of this patch.

Fixes 98c27add5d96 ("ALSA: usb-audio: Cap upper limits of buffer/period bytes for implicit fb")
Fixes fee2ec8cceb3 ("ALSA: usb-audio: Increase max buffer size")
---
 sound/usb/pcm.c | 101 +++++++-----------------------------------------
 1 file changed, 14 insertions(+), 87 deletions(-)
sound/usb/pcm.c +14 -87
index 37ee6df8b15a..6d699065e81a 100644
@@ -659,9 +659,6 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
 #define hwc_debug(fmt, args...) do { } while(0)
 #endif
 
-#define MAX_BUFFER_BYTES	(4 * 1024 * 1024)
-#define MAX_PERIOD_BYTES	(512 * 1024)
-
 static const struct snd_pcm_hardware snd_usb_hardware =
 {
 	.info =			SNDRV_PCM_INFO_MMAP |
@@ -672,9 +669,9 @@ static const struct snd_pcm_hardware snd_usb_hardware =
 				SNDRV_PCM_INFO_PAUSE,
 	.channels_min =		1,
 	.channels_max =		256,
-	.buffer_bytes_max =	MAX_BUFFER_BYTES,
+	.buffer_bytes_max =	INT_MAX, /* limited by BUFFER_TIME later */
 	.period_bytes_min =	64,
-	.period_bytes_max =	MAX_PERIOD_BYTES,
+	.period_bytes_max =	INT_MAX, /* limited by PERIOD_TIME later */
 	.periods_min =		2,
 	.periods_max =		1024,
 };
@@ -974,78 +971,6 @@ static int hw_rule_periods_implicit_fb(struct snd_pcm_hw_params *params,
 				      ep->cur_buffer_periods);
 }
 
-/* get the adjusted max buffer (or period) bytes that can fit with the
- * paired format for implicit fb
- */
-static unsigned int
-get_adjusted_max_bytes(struct snd_usb_substream *subs,
-		       struct snd_usb_substream *pair,
-		       struct snd_pcm_hw_params *params,
-		       unsigned int max_bytes,
-		       bool reverse_map)
-{
-	const struct audioformat *fp, *pp;
-	unsigned int rmax = 0, r;
-
-	list_for_each_entry(fp, &subs->fmt_list, list) {
-		if (!fp->implicit_fb)
-			continue;
-		if (!reverse_map &&
-		    !hw_check_valid_format(subs, params, fp))
-			continue;
-		list_for_each_entry(pp, &pair->fmt_list, list) {
-			if (pp->iface != fp->sync_iface ||
-			    pp->altsetting != fp->sync_altsetting ||
-			    pp->ep_idx != fp->sync_ep_idx)
-				continue;
-			if (reverse_map &&
-			    !hw_check_valid_format(pair, params, pp))
-				break;
-			if (!reverse_map && pp->channels > fp->channels)
-				r = max_bytes * fp->channels / pp->channels;
-			else if (reverse_map && pp->channels < fp->channels)
-				r = max_bytes * pp->channels / fp->channels;
-			else
-				r = max_bytes;
-			rmax = max(rmax, r);
-			break;
-		}
-	}
-	return rmax;
-}
-
-/* Reduce the period or buffer bytes depending on the paired substream;
- * when a paired configuration for implicit fb has a higher number of channels,
- * we need to reduce the max size accordingly, otherwise it may become unusable
- */
-static int hw_rule_bytes_implicit_fb(struct snd_pcm_hw_params *params,
-				     struct snd_pcm_hw_rule *rule)
-{
-	struct snd_usb_substream *subs = rule->private;
-	struct snd_usb_substream *pair;
-	struct snd_interval *it;
-	unsigned int max_bytes;
-	unsigned int rmax;
-
-	pair = &subs->stream->substream[!subs->direction];
-	if (!pair->ep_num)
-		return 0;
-
-	if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_BYTES)
-		max_bytes = MAX_PERIOD_BYTES;
-	else
-		max_bytes = MAX_BUFFER_BYTES;
-
-	rmax = get_adjusted_max_bytes(subs, pair, params, max_bytes, false);
-	if (!rmax)
-		rmax = get_adjusted_max_bytes(pair, subs, params, max_bytes, true);
-	if (!rmax)
-		return 0;
-
-	it = hw_param_interval(params, rule->var);
-	return apply_hw_params_minmax(it, 0, rmax);
-}
-
 /*
  * set up the runtime hardware information.
  */
@@ -1139,6 +1064,18 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
 			return err;
 	}
 
+	/* set max period and buffer sizes for 1 and 2 seconds, respectively */
+	err = snd_pcm_hw_constraint_minmax(runtime,
+					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
+					   0, 1000000);
+	if (err < 0)
+		return err;
+	err = snd_pcm_hw_constraint_minmax(runtime,
+					   SNDRV_PCM_HW_PARAM_BUFFER_TIME,
+					   0, 2000000);
+	if (err < 0)
+		return err;
+
 	/* additional hw constraints for implicit fb */
 	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
 				  hw_rule_format_implicit_fb, subs,
@@ -1160,16 +1097,6 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
 				  SNDRV_PCM_HW_PARAM_PERIODS, -1);
 	if (err < 0)
 		return err;
-	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-				  hw_rule_bytes_implicit_fb, subs,
-				  SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
-	if (err < 0)
-		return err;
-	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
-				  hw_rule_bytes_implicit_fb, subs,
-				  SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
-	if (err < 0)
-		return err;
 
 	list_for_each_entry(fp, &subs->fmt_list, list) {
 		if (fp->implicit_fb) {
Signature · 1 line
2.35.1
author maintainer
#116 lore raw

PATCH 116/219 perf tools: Fix misleading add event PMU debug message

In reply to Greg Kroah-Hartman

From: Adrian Hunter <[email protected]>

[ Upstream commit f034fc50d3c7d9385c20d505ab4cf56b8fd18ac7 ]

Fix incorrect debug message:

Attempting to add event pmu 'intel_pt' with '' that may result in non-fatal errors

which always appears with perf record -vv and intel_pt e.g.

perf record -vv -e intel_pt//u uname

The message is incorrect because there will never be non-fatal errors.

Suppress the message if the PMU is 'selectable' i.e. meant to be selected directly as an event.

Fixes 4ac22b484d4c79e8 ("perf parse-events: Make add PMU verbose output clearer")
Cc Ian Rogers <[email protected]>
Cc Jiri Olsa <[email protected]>
---
 tools/perf/util/parse-events.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/util/parse-events.c +3 -2
index 24997925ae00..dd84fed698a3 100644
@@ -1523,7 +1523,9 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
 	bool use_uncore_alias;
 	LIST_HEAD(config_terms);
 
-	if (verbose > 1) {
+	pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
+
+	if (verbose > 1 && !(pmu && pmu->selectable)) {
 		fprintf(stderr, "Attempting to add event pmu '%s' with '",
 			name);
 		if (head_config) {
@@ -1536,7 +1538,6 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
 		fprintf(stderr, "' that may result in non-fatal errors\n");
 	}
 
-	pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
 	if (!pmu) {
 		char *err_str;
 
Signature · 1 line
2.35.1
author maintainer
#117 lore raw

PATCH 117/219 macvlan: Fix leaking skb in source mode with nodst option

In reply to Greg Kroah-Hartman

From: Martin Willi <[email protected]>

[ Upstream commit e16b859872b87650bb55b12cca5a5fcdc49c1442 ]

The MACVLAN receive handler clones skbs to all matching source MACVLAN interfaces, before it passes the packet along to match on destination based MACVLANs.

When using the MACVLAN nodst mode, passing the packet to destination based MACVLANs is omitted and the handler returns with RX_HANDLER_CONSUMED. However, the passed skb is not freed, leaking for any packet processed with the nodst option.

Properly free the skb when consuming packets to fix that leak.

Fixes 427f0c8c194b ("macvlan: Add nodst option to macvlan type source")
---
 drivers/net/macvlan.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/macvlan.c +6 -2
index 6ef5f77be4d0..c83664b28d89 100644
@@ -460,8 +460,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
 			return RX_HANDLER_CONSUMED;
 		*pskb = skb;
 		eth = eth_hdr(skb);
-		if (macvlan_forward_source(skb, port, eth->h_source))
+		if (macvlan_forward_source(skb, port, eth->h_source)) {
+			kfree_skb(skb);
 			return RX_HANDLER_CONSUMED;
+		}
 		src = macvlan_hash_lookup(port, eth->h_source);
 		if (src && src->mode != MACVLAN_MODE_VEPA &&
 		    src->mode != MACVLAN_MODE_BRIDGE) {
@@ -480,8 +482,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
 		return RX_HANDLER_PASS;
 	}
 
-	if (macvlan_forward_source(skb, port, eth->h_source))
+	if (macvlan_forward_source(skb, port, eth->h_source)) {
+		kfree_skb(skb);
 		return RX_HANDLER_CONSUMED;
+	}
 	if (macvlan_passthru(port))
 		vlan = list_first_or_null_rcu(&port->vlans,
 					      struct macvlan_dev, list);
Signature · 1 line
2.35.1
author maintainer
#118 lore raw

PATCH 118/219 net: ftgmac100: access hardware register after clock ready

In reply to Greg Kroah-Hartman

From: Dylan Hung <[email protected]>

[ Upstream commit 3d2504524531990b32a0629cc984db44f399d161 ]

AST2600 MAC register 0x58 is writable only when the MAC clock is enabled. Usually, the MAC clock is enabled by the bootloader so register 0x58 is set normally when the bootloader is involved. To make ast2600 ftgmac100 work without the bootloader, postpone the register write until the clock is ready.

Fixes 137d23cea1c0 ("net: ftgmac100: Fix Aspeed ast2600 TX hang issue")
---
 drivers/net/ethernet/faraday/ftgmac100.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/faraday/ftgmac100.c +5 -5
index d5356db7539a..caf48023f8ea 100644
@@ -1835,11 +1835,6 @@ static int ftgmac100_probe(struct platform_device *pdev)
 		priv->rxdes0_edorr_mask = BIT(30);
 		priv->txdes0_edotr_mask = BIT(30);
 		priv->is_aspeed = true;
-		/* Disable ast2600 problematic HW arbitration */
-		if (of_device_is_compatible(np, "aspeed,ast2600-mac")) {
-			iowrite32(FTGMAC100_TM_DEFAULT,
-				  priv->base + FTGMAC100_OFFSET_TM);
-		}
 	} else {
 		priv->rxdes0_edorr_mask = BIT(15);
 		priv->txdes0_edotr_mask = BIT(15);
@@ -1911,6 +1906,11 @@ static int ftgmac100_probe(struct platform_device *pdev)
 		err = ftgmac100_setup_clk(priv);
 		if (err)
 			goto err_phy_connect;
+
+		/* Disable ast2600 problematic HW arbitration */
+		if (of_device_is_compatible(np, "aspeed,ast2600-mac"))
+			iowrite32(FTGMAC100_TM_DEFAULT,
+				  priv->base + FTGMAC100_OFFSET_TM);
 	}
 
 	/* Default ring sizes */
Signature · 1 line
2.35.1
author maintainer
#119 lore raw

PATCH 119/219 nfc: nci: add flush_workqueue to prevent uaf

In reply to Greg Kroah-Hartman

From: Lin Ma <[email protected]>

[ Upstream commit ef27324e2cb7bb24542d6cb2571740eefe6b00dc ]

Our detector found a concurrent use-after-free bug when detaching an NCI device. The main reason for this bug is the unexpected scheduling between the used delayed mechanism (timer and workqueue).

The race can be demonstrated below:

Thread-1 Thread-2

                                 | nci_dev_up()
                                 |   nci_open_device()
                                 |     __nci_request(nci_reset_req)
                                 |       nci_send_cmd
                                 |         queue_work(cmd_work)
nci_unregister_device()          |
  nci_close_device()             | ...
    del_timer_sync(cmd_timer)[1] |
...                              | Worker
nci_free_device()                | nci_cmd_work()
  kfree(ndev)[3]                 |   mod_timer(cmd_timer)[2]

In short, the cleanup routine thought that the cmd_timer has already been detached by [1] but the mod_timer can re-attach the timer [2], even it is already released [3], resulting in UAF.

This UAF is easy to trigger, crash trace by POC is like below

[   66.703713] ==================================================================
[   66.703974] BUG: KASAN: use-after-free in enqueue_timer+0x448/0x490
[   66.703974] Write of size 8 at addr ffff888009fb7058 by task kworker/u4:1/33
[   66.703974]
[   66.703974] CPU: 1 PID: 33 Comm: kworker/u4:1 Not tainted 5.18.0-rc2 #5
[   66.703974] Workqueue: nfc2_nci_cmd_wq nci_cmd_work
[   66.703974] Call Trace:
[   66.703974]  <TASK>
[   66.703974]  dump_stack_lvl+0x57/0x7d
[   66.703974]  print_report.cold+0x5e/0x5db
[   66.703974]  ? enqueue_timer+0x448/0x490
[   66.703974]  kasan_report+0xbe/0x1c0
[   66.703974]  ? enqueue_timer+0x448/0x490
[   66.703974]  enqueue_timer+0x448/0x490
[   66.703974]  __mod_timer+0x5e6/0xb80
[   66.703974]  ? mark_held_locks+0x9e/0xe0
[   66.703974]  ? try_to_del_timer_sync+0xf0/0xf0
[   66.703974]  ? lockdep_hardirqs_on_prepare+0x17b/0x410
[   66.703974]  ? queue_work_on+0x61/0x80
[   66.703974]  ? lockdep_hardirqs_on+0xbf/0x130
[   66.703974]  process_one_work+0x8bb/0x1510
[   66.703974]  ? lockdep_hardirqs_on_prepare+0x410/0x410
[   66.703974]  ? pwq_dec_nr_in_flight+0x230/0x230
[   66.703974]  ? rwlock_bug.part.0+0x90/0x90
[   66.703974]  ? _raw_spin_lock_irq+0x41/0x50
[   66.703974]  worker_thread+0x575/0x1190
[   66.703974]  ? process_one_work+0x1510/0x1510
[   66.703974]  kthread+0x2a0/0x340
[   66.703974]  ? kthread_complete_and_exit+0x20/0x20
[   66.703974]  ret_from_fork+0x22/0x30
[   66.703974]  </TASK>
[   66.703974]
[   66.703974] Allocated by task 267:
[   66.703974]  kasan_save_stack+0x1e/0x40
[   66.703974]  __kasan_kmalloc+0x81/0xa0
[   66.703974]  nci_allocate_device+0xd3/0x390
[   66.703974]  nfcmrvl_nci_register_dev+0x183/0x2c0
[   66.703974]  nfcmrvl_nci_uart_open+0xf2/0x1dd
[   66.703974]  nci_uart_tty_ioctl+0x2c3/0x4a0
[   66.703974]  tty_ioctl+0x764/0x1310
[   66.703974]  __x64_sys_ioctl+0x122/0x190
[   66.703974]  do_syscall_64+0x3b/0x90
[   66.703974]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   66.703974]
[   66.703974] Freed by task 406:
[   66.703974]  kasan_save_stack+0x1e/0x40
[   66.703974]  kasan_set_track+0x21/0x30
[   66.703974]  kasan_set_free_info+0x20/0x30
[   66.703974]  __kasan_slab_free+0x108/0x170
[   66.703974]  kfree+0xb0/0x330
[   66.703974]  nfcmrvl_nci_unregister_dev+0x90/0xd0
[   66.703974]  nci_uart_tty_close+0xdf/0x180
[   66.703974]  tty_ldisc_kill+0x73/0x110
[   66.703974]  tty_ldisc_hangup+0x281/0x5b0
[   66.703974]  __tty_hangup.part.0+0x431/0x890
[   66.703974]  tty_release+0x3a8/0xc80
[   66.703974]  __fput+0x1f0/0x8c0
[   66.703974]  task_work_run+0xc9/0x170
[   66.703974]  exit_to_user_mode_prepare+0x194/0x1a0
[   66.703974]  syscall_exit_to_user_mode+0x19/0x50
[   66.703974]  do_syscall_64+0x48/0x90
[   66.703974]  entry_SYSCALL_64_after_hwframe+0x44/0xae

To fix the UAF, this patch adds flush_workqueue() to ensure the nci_cmd_work is finished before the following del_timer_sync. This combination will promise the timer is actually detached.

Fixes 6a2968aaf50c ("NFC: basic NCI protocol implementation")
---
 net/nfc/nci/core.c | 4 ++++
 1 file changed, 4 insertions(+)
net/nfc/nci/core.c +4 -0
index d2537383a3e8..6a193cce2a75 100644
@@ -560,6 +560,10 @@ static int nci_close_device(struct nci_dev *ndev)
 	mutex_lock(&ndev->req_lock);
 
 	if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
+		/* Need to flush the cmd wq in case
+		 * there is a queued/running cmd_work
+		 */
+		flush_workqueue(ndev->cmd_wq);
 		del_timer_sync(&ndev->cmd_timer);
 		del_timer_sync(&ndev->data_timer);
 		mutex_unlock(&ndev->req_lock);
Signature · 1 line
2.35.1
author maintainer
#120 lore raw

PATCH 120/219 cifs: potential buffer overflow in handling symlinks

In reply to Greg Kroah-Hartman

From: Harshit Mogalapalli <[email protected]>

[ Upstream commit 64c4a37ac04eeb43c42d272f6e6c8c12bfcf4304 ]

Smatch printed a warning:

	arch/x86/crypto/poly1305_glue.c:198 poly1305_update_arch() error:
	__memcpy() 'dctx->buf' too small (16 vs u32max)

It's caused because Smatch marks 'link_len' as untrusted since it comes from sscanf(). Add a check to ensure that 'link_len' is not larger than the size of the 'link_str' buffer.

Fixes c69c1b6eaea1 ("cifs: implement CIFSParseMFSymlink()")
---
 fs/cifs/link.c | 3 +++
 1 file changed, 3 insertions(+)
fs/cifs/link.c +3 -0
index 852e54ee82c2..bbdf3281559c 100644
@@ -85,6 +85,9 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
 	if (rc != 1)
 		return -EINVAL;
 
+	if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
+		return -EINVAL;
+
 	rc = symlink_hash(link_len, link_str, md5_hash);
 	if (rc) {
 		cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
Signature · 1 line
2.35.1
author maintainer
#121 lore raw

PATCH 121/219 dm mpath: only use ktime_get_ns() in historical selector

In reply to Greg Kroah-Hartman

From: Khazhismel Kumykov <[email protected]>

[ Upstream commit ce40426fdc3c92acdba6b5ca74bc7277ffaa6a3d ]

Mixing sched_clock() and ktime_get_ns() usage will give bad results.

Switch hst_select_path() from using sched_clock() to ktime_get_ns(). Also rename path_service_time()'s 'sched_now' variable to 'now'.

Fixes 2613eab11996 ("dm mpath: add Historical Service Time Path Selector")
---
 drivers/md/dm-ps-historical-service-time.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/md/dm-ps-historical-service-time.c +5 -6
index 875bca30a0dd..82f2a06153dc 100644
@@ -27,7 +27,6 @@
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/sched/clock.h>
 
 
 #define DM_MSG_PREFIX	"multipath historical-service-time"
@@ -433,7 +432,7 @@ static struct dm_path *hst_select_path(struct path_selector *ps,
 {
 	struct selector *s = ps->context;
 	struct path_info *pi = NULL, *best = NULL;
-	u64 time_now = sched_clock();
+	u64 time_now = ktime_get_ns();
 	struct dm_path *ret = NULL;
 	unsigned long flags;
 
@@ -474,7 +473,7 @@ static int hst_start_io(struct path_selector *ps, struct dm_path *path,
 
 static u64 path_service_time(struct path_info *pi, u64 start_time)
 {
-	u64 sched_now = ktime_get_ns();
+	u64 now = ktime_get_ns();
 
 	/* if a previous disk request has finished after this IO was
 	 * sent to the hardware, pretend the submission happened
@@ -483,11 +482,11 @@ static u64 path_service_time(struct path_info *pi, u64 start_time)
 	if (time_after64(pi->last_finish, start_time))
 		start_time = pi->last_finish;
 
-	pi->last_finish = sched_now;
-	if (time_before64(sched_now, start_time))
+	pi->last_finish = now;
+	if (time_before64(now, start_time))
 		return 0;
 
-	return sched_now - start_time;
+	return now - start_time;
 }
 
 static int hst_end_io(struct path_selector *ps, struct dm_path *path,
Signature · 1 line
2.35.1
author maintainer
#122 lore raw

PATCH 122/219 vfio/pci: Fix vf_token mechanism when device-specific VF drivers are used

In reply to Greg Kroah-Hartman

From: Jason Gunthorpe <[email protected]>

[ Upstream commit 1ef3342a934e235aca72b4bcc0d6854d80a65077 ]

get_pf_vdev() tries to check if a PF is a VFIO PF by looking at the driver:

       if (pci_dev_driver(physfn) != pci_dev_driver(vdev->pdev)) {

However now that we have multiple VF and PF drivers this is no longer reliable.

This means that security tests realted to vf_token can be skipped by mixing and matching different VFIO PCI drivers.

Instead of trying to use the driver core to find the PF devices maintain a linked list of all PF vfio_pci_core_device's that we have called pci_enable_sriov() on.

When registering a VF just search the list to see if the PF is present and record the match permanently in the struct. PCI core locking prevents a PF from passing pci_disable_sriov() while VF drivers are attached so the VFIO owned PF becomes a static property of the VF.

In common cases where vfio does not own the PF the global list remains empty and the VF's pointer is statically NULL.

This also fixes a lockdep splat from recursive locking of the vfio_group::device_lock between vfio_device_get_from_name() and vfio_device_get_from_dev(). If the VF and PF share the same group this would deadlock.

Fixes ff53edf6d6ab ("vfio/pci: Split the pci_driver code out of vfio_pci_core.c")
---
 drivers/vfio/pci/vfio_pci_core.c | 124 ++++++++++++++++++-------------
 include/linux/vfio_pci_core.h    |   2 +
 2 files changed, 76 insertions(+), 50 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +74 -50
index 2e6409cc11ad..ef54ef11af55 100644
@@ -36,6 +36,10 @@ static bool nointxmask;
 static bool disable_vga;
 static bool disable_idle_d3;
 
+/* List of PF's that vfio_pci_core_sriov_configure() has been called on */
+static DEFINE_MUTEX(vfio_pci_sriov_pfs_mutex);
+static LIST_HEAD(vfio_pci_sriov_pfs);
+
 static inline bool vfio_vga_disabled(void)
 {
 #ifdef CONFIG_VFIO_PCI_VGA
@@ -434,47 +438,17 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_disable);
 
-static struct vfio_pci_core_device *get_pf_vdev(struct vfio_pci_core_device *vdev)
-{
-	struct pci_dev *physfn = pci_physfn(vdev->pdev);
-	struct vfio_device *pf_dev;
-
-	if (!vdev->pdev->is_virtfn)
-		return NULL;
-
-	pf_dev = vfio_device_get_from_dev(&physfn->dev);
-	if (!pf_dev)
-		return NULL;
-
-	if (pci_dev_driver(physfn) != pci_dev_driver(vdev->pdev)) {
-		vfio_device_put(pf_dev);
-		return NULL;
-	}
-
-	return container_of(pf_dev, struct vfio_pci_core_device, vdev);
-}
-
-static void vfio_pci_vf_token_user_add(struct vfio_pci_core_device *vdev, int val)
-{
-	struct vfio_pci_core_device *pf_vdev = get_pf_vdev(vdev);
-
-	if (!pf_vdev)
-		return;
-
-	mutex_lock(&pf_vdev->vf_token->lock);
-	pf_vdev->vf_token->users += val;
-	WARN_ON(pf_vdev->vf_token->users < 0);
-	mutex_unlock(&pf_vdev->vf_token->lock);
-
-	vfio_device_put(&pf_vdev->vdev);
-}
-
 void vfio_pci_core_close_device(struct vfio_device *core_vdev)
 {
 	struct vfio_pci_core_device *vdev =
 		container_of(core_vdev, struct vfio_pci_core_device, vdev);
 
-	vfio_pci_vf_token_user_add(vdev, -1);
+	if (vdev->sriov_pf_core_dev) {
+		mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock);
+		WARN_ON(!vdev->sriov_pf_core_dev->vf_token->users);
+		vdev->sriov_pf_core_dev->vf_token->users--;
+		mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock);
+	}
 	vfio_spapr_pci_eeh_release(vdev->pdev);
 	vfio_pci_core_disable(vdev);
 
@@ -495,7 +469,12 @@ void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev)
 {
 	vfio_pci_probe_mmaps(vdev);
 	vfio_spapr_pci_eeh_open(vdev->pdev);
-	vfio_pci_vf_token_user_add(vdev, 1);
+
+	if (vdev->sriov_pf_core_dev) {
+		mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock);
+		vdev->sriov_pf_core_dev->vf_token->users++;
+		mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock);
+	}
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable);
 
@@ -1603,11 +1582,8 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_core_device *vdev,
 	 *
 	 * If the VF token is provided but unused, an error is generated.
 	 */
-	if (!vdev->pdev->is_virtfn && !vdev->vf_token && !vf_token)
-		return 0; /* No VF token provided or required */
-
 	if (vdev->pdev->is_virtfn) {
-		struct vfio_pci_core_device *pf_vdev = get_pf_vdev(vdev);
+		struct vfio_pci_core_device *pf_vdev = vdev->sriov_pf_core_dev;
 		bool match;
 
 		if (!pf_vdev) {
@@ -1620,7 +1596,6 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_core_device *vdev,
 		}
 
 		if (!vf_token) {
-			vfio_device_put(&pf_vdev->vdev);
 			pci_info_ratelimited(vdev->pdev,
 				"VF token required to access device\n");
 			return -EACCES;
@@ -1630,8 +1605,6 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_core_device *vdev,
 		match = uuid_equal(uuid, &pf_vdev->vf_token->uuid);
 		mutex_unlock(&pf_vdev->vf_token->lock);
 
-		vfio_device_put(&pf_vdev->vdev);
-
 		if (!match) {
 			pci_info_ratelimited(vdev->pdev,
 				"Incorrect VF token provided for device\n");
@@ -1752,8 +1725,30 @@ static int vfio_pci_bus_notifier(struct notifier_block *nb,
 static int vfio_pci_vf_init(struct vfio_pci_core_device *vdev)
 {
 	struct pci_dev *pdev = vdev->pdev;
+	struct vfio_pci_core_device *cur;
+	struct pci_dev *physfn;
 	int ret;
 
+	if (pdev->is_virtfn) {
+		/*
+		 * If this VF was created by our vfio_pci_core_sriov_configure()
+		 * then we can find the PF vfio_pci_core_device now, and due to
+		 * the locking in pci_disable_sriov() it cannot change until
+		 * this VF device driver is removed.
+		 */
+		physfn = pci_physfn(vdev->pdev);
+		mutex_lock(&vfio_pci_sriov_pfs_mutex);
+		list_for_each_entry(cur, &vfio_pci_sriov_pfs, sriov_pfs_item) {
+			if (cur->pdev == physfn) {
+				vdev->sriov_pf_core_dev = cur;
+				break;
+			}
+		}
+		mutex_unlock(&vfio_pci_sriov_pfs_mutex);
+		return 0;
+	}
+
+	/* Not a SRIOV PF */
 	if (!pdev->is_physfn)
 		return 0;
 
@@ -1825,6 +1820,7 @@ void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev,
 	INIT_LIST_HEAD(&vdev->ioeventfds_list);
 	mutex_init(&vdev->vma_lock);
 	INIT_LIST_HEAD(&vdev->vma_list);
+	INIT_LIST_HEAD(&vdev->sriov_pfs_item);
 	init_rwsem(&vdev->memory_lock);
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_init_device);
@@ -1916,7 +1912,7 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev)
 {
 	struct pci_dev *pdev = vdev->pdev;
 
-	pci_disable_sriov(pdev);
+	vfio_pci_core_sriov_configure(pdev, 0);
 
 	vfio_unregister_group_dev(&vdev->vdev);
 
@@ -1954,21 +1950,49 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
 
 int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
 {
+	struct vfio_pci_core_device *vdev;
 	struct vfio_device *device;
 	int ret = 0;
 
+	device_lock_assert(&pdev->dev);
+
 	device = vfio_device_get_from_dev(&pdev->dev);
 	if (!device)
 		return -ENODEV;
 
-	if (nr_virtfn == 0)
-		pci_disable_sriov(pdev);
-	else
+	vdev = container_of(device, struct vfio_pci_core_device, vdev);
+
+	if (nr_virtfn) {
+		mutex_lock(&vfio_pci_sriov_pfs_mutex);
+		/*
+		 * The thread that adds the vdev to the list is the only thread
+		 * that gets to call pci_enable_sriov() and we will only allow
+		 * it to be called once without going through
+		 * pci_disable_sriov()
+		 */
+		if (!list_empty(&vdev->sriov_pfs_item)) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		list_add_tail(&vdev->sriov_pfs_item, &vfio_pci_sriov_pfs);
+		mutex_unlock(&vfio_pci_sriov_pfs_mutex);
 		ret = pci_enable_sriov(pdev, nr_virtfn);
+		if (ret)
+			goto out_del;
+		ret = nr_virtfn;
+		goto out_put;
+	}
 
-	vfio_device_put(device);
+	pci_disable_sriov(pdev);
 
-	return ret < 0 ? ret : nr_virtfn;
+out_del:
+	mutex_lock(&vfio_pci_sriov_pfs_mutex);
+	list_del_init(&vdev->sriov_pfs_item);
+out_unlock:
+	mutex_unlock(&vfio_pci_sriov_pfs_mutex);
+out_put:
+	vfio_device_put(device);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure);
 
include/linux/vfio_pci_core.h +2 -0
index ae6f4838ab75..6e5db4edc335 100644
@@ -133,6 +133,8 @@ struct vfio_pci_core_device {
 	struct mutex		ioeventfds_lock;
 	struct list_head	ioeventfds_list;
 	struct vfio_pci_vf_token	*vf_token;
+	struct list_head		sriov_pfs_item;
+	struct vfio_pci_core_device	*sriov_pf_core_dev;
 	struct notifier_block	nb;
 	struct mutex		vma_lock;
 	struct list_head	vma_list;
Signature · 1 line
2.35.1
author maintainer
#123 lore raw

PATCH 123/219 tun: annotate access to queue->trans_start

In reply to Greg Kroah-Hartman

From: Antoine Tenart <[email protected]>

[ Upstream commit 968a1a5d6541cd24e37dadc1926eab9c10aeb09b ]

Commit 5337824f4dc4 ("net: annotate accesses to queue->trans_start") introduced a new helper, txq_trans_cond_update, to update queue->trans_start using WRITE_ONCE. One snippet in drivers/net/tun.c was missed, as it was introduced roughly at the same time.

Fixes 5337824f4dc4 ("net: annotate accesses to queue->trans_start")
Cc Eric Dumazet <[email protected]>
---
 drivers/net/tun.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/tun.c +1 -1
index de999e0fedbc..aa78d7e00289 100644
@@ -1106,7 +1106,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* NETIF_F_LLTX requires to do our own update of trans_start */
 	queue = netdev_get_tx_queue(dev, txq);
-	queue->trans_start = jiffies;
+	txq_trans_cond_update(queue);
 
 	/* Notify and wake up reader process */
 	if (tfile->flags & TUN_FASYNC)
Signature · 1 line
2.35.1
author maintainer
#124 lore raw

PATCH 124/219 net: dsa: felix: fix tagging protocol changes with multiple CPU ports

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 00fa91bc9cc2a9d340f963af5e457610ad4b2f9c ]

When the device tree has 2 CPU ports defined, a single one is active (has any dp->cpu_dp pointers point to it). Yet the second one is still a CPU port, and DSA still calls ->change_tag_protocol on it.

On the NXP LS1028A, the CPU ports are ports 4 and 5. Port 4 is the active CPU port and port 5 is inactive.

After the following commands:

# Initial setting
cat /sys/class/net/eno2/dsa/tagging
ocelot
echo ocelot-8021q > /sys/class/net/eno2/dsa/tagging echo ocelot > /sys/class/net/eno2/dsa/tagging

traffic is now broken, because the driver has moved the NPI port from port 4 to port 5, unbeknown to DSA.

The problem can be avoided by detecting that the second CPU port is unused, and not doing anything for it. Further rework will be needed when proper support for multiple CPU ports is added.

Treat this as a bug and prepare current kernels to work in single-CPU mode with multiple-CPU DT blobs.

Fixes adb3dccf090b ("net: dsa: felix: convert to the new .change_tag_protocol DSA API")
---
 drivers/net/dsa/ocelot/felix.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
drivers/net/dsa/ocelot/felix.c +23 -0
index 9957772201d5..c414d9e9d7c0 100644
@@ -599,6 +599,8 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu,
 	struct ocelot *ocelot = ds->priv;
 	struct felix *felix = ocelot_to_felix(ocelot);
 	enum dsa_tag_protocol old_proto = felix->tag_proto;
+	bool cpu_port_active = false;
+	struct dsa_port *dp;
 	int err;
 
 	if (proto != DSA_TAG_PROTO_SEVILLE &&
@@ -606,6 +608,27 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu,
 	    proto != DSA_TAG_PROTO_OCELOT_8021Q)
 		return -EPROTONOSUPPORT;
 
+	/* We don't support multiple CPU ports, yet the DT blob may have
+	 * multiple CPU ports defined. The first CPU port is the active one,
+	 * the others are inactive. In this case, DSA will call
+	 * ->change_tag_protocol() multiple times, once per CPU port.
+	 * Since we implement the tagging protocol change towards "ocelot" or
+	 * "seville" as effectively initializing the NPI port, what we are
+	 * doing is effectively changing who the NPI port is to the last @cpu
+	 * argument passed, which is an unused DSA CPU port and not the one
+	 * that should actively pass traffic.
+	 * Suppress DSA's calls on CPU ports that are inactive.
+	 */
+	dsa_switch_for_each_user_port(dp, ds) {
+		if (dp->cpu_dp->index == cpu) {
+			cpu_port_active = true;
+			break;
+		}
+	}
+
+	if (!cpu_port_active)
+		return 0;
+
 	felix_del_tag_protocol(ds, cpu, old_proto);
 
 	err = felix_set_tag_protocol(ds, cpu, proto);
Signature · 1 line
2.35.1
author maintainer
#125 lore raw

PATCH 125/219 net: bcmgenet: Revert "Use stronger register read/writes to assure ordering"

In reply to Greg Kroah-Hartman

From: Jeremy Linton <[email protected]>

[ Upstream commit 2df3fc4a84e917a422935cc5bae18f43f9955d31 ]

It turns out after digging deeper into this bug, that it was being triggered by GCC12 failing to call the bcmgenet_enable_dma() routine. Given that a gcc12 fix has been merged [1] and the genet driver now works properly when built with gcc12, this commit should be reverted.

[1]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105160
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=aabb9a261ef060cf24fd626713f1d7d9df81aa57

Fixes 8d3ea3d402db ("net: bcmgenet: Use stronger register read/writes to assure ordering")
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +2 -2
index bd5998012a87..2da804f84b48 100644
@@ -76,7 +76,7 @@ static inline void bcmgenet_writel(u32 value, void __iomem *offset)
 	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		__raw_writel(value, offset);
 	else
-		writel(value, offset);
+		writel_relaxed(value, offset);
 }
 
 static inline u32 bcmgenet_readl(void __iomem *offset)
@@ -84,7 +84,7 @@ static inline u32 bcmgenet_readl(void __iomem *offset)
 	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		return __raw_readl(offset);
 	else
-		return readl(offset);
+		return readl_relaxed(offset);
 }
 
 static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv,
Signature · 1 line
2.35.1
author maintainer
#126 lore raw

PATCH 126/219 block: fix offset/size check in bio_trim()

In reply to Greg Kroah-Hartman

From: Ming Lei <[email protected]>

[ Upstream commit 8535c0185d14ea41f0efd6a357961b05daf6687e ]

Unit of bio->bi_iter.bi_size is bytes, but unit of offset/size is sector.

Fix the above issue in checking offset/size in bio_trim().

Fixes e83502ca5f1e ("block: fix argument type of bio_trim()")
Cc Chaitanya Kulkarni <[email protected]>
---
 block/bio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
block/bio.c +1 -1
index 1be1e360967d..342b1cf5d713 100644
@@ -1570,7 +1570,7 @@ EXPORT_SYMBOL(bio_split);
 void bio_trim(struct bio *bio, sector_t offset, sector_t size)
 {
 	if (WARN_ON_ONCE(offset > BIO_MAX_SECTORS || size > BIO_MAX_SECTORS ||
-			 offset + size > bio->bi_iter.bi_size))
+			 offset + size > bio_sectors(bio)))
 		return;
 
 	size <<= 9;
Signature · 1 line
2.35.1
author maintainer
#127 lore raw

PATCH 127/219 block: null_blk: end timed out poll request

In reply to Greg Kroah-Hartman

From: Ming Lei <[email protected]>

[ Upstream commit 3e3876d322aef82416ecc496a4d4a587e0fdf7a3 ]

When poll request is timed out, it is removed from the poll list, but not completed, so the request is leaked, and never get chance to complete.

Fix the issue by ending it in timeout handler.

Fixes 0a593fbbc245 ("null_blk: poll queue support")
---
 drivers/block/null_blk/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/null_blk/main.c +1 -1
index 13004beb48ca..233577b14141 100644
@@ -1606,7 +1606,7 @@ static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res)
 	 * Only fake timeouts need to execute blk_mq_complete_request() here.
 	 */
 	cmd->error = BLK_STS_TIMEOUT;
-	if (cmd->fake_timeout)
+	if (cmd->fake_timeout || hctx->type == HCTX_TYPE_POLL)
 		blk_mq_complete_request(rq);
 	return BLK_EH_DONE;
 }
Signature · 1 line
2.35.1
author maintainer
#128 lore raw

PATCH 128/219 io_uring: abort file assignment prior to assigning creds

In reply to Greg Kroah-Hartman

From: Jens Axboe <[email protected]>

[ Upstream commit 701521403cfb228536b3947035c8a6eca40d8e58 ]

We need to either restore creds properly if we fail on the file assignment, or just do the file assignment first instead. Let's do the latter as it's simpler, should make no difference here for file assignment.

Reported-by [email protected]
Fixes 6bf9c47a3989 ("io_uring: defer file assignment")
---
 fs/io_uring.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
fs/io_uring.c +3 -2
index 7a652c8eeed2..6f93bff7633c 100644
@@ -6729,13 +6729,14 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
 	const struct cred *creds = NULL;
 	int ret;
 
+	if (unlikely(!io_assign_file(req, issue_flags)))
+		return -EBADF;
+
 	if (unlikely((req->flags & REQ_F_CREDS) && req->creds != current_cred()))
 		creds = override_creds(req->creds);
 
 	if (!io_op_defs[req->opcode].audit_skip)
 		audit_uring_entry(req->opcode);
-	if (unlikely(!io_assign_file(req, issue_flags)))
-		return -EBADF;
 
 	switch (req->opcode) {
 	case IORING_OP_NOP:
Signature · 1 line
2.35.1
author maintainer
#129 lore raw

PATCH 129/219 KVM: PPC: Book3S HV P9: Fix "lost kick" race

In reply to Greg Kroah-Hartman

From: Nicholas Piggin <[email protected]>

[ Upstream commit c7fa848ff01dad9ed3146a6b1a7d3622131bcedd ]

When new work is created that requires attention from the hypervisor (e.g., to inject an interrupt into the guest), fast_vcpu_kick is used to pull the target vcpu out of the guest if it may have been running.

Therefore the work creation side looks like this:

  vcpu->arch.doorbell_request = 1;
  kvmppc_fast_vcpu_kick_hv(vcpu) {
    smp_mb();
    cpu = vcpu->cpu;
    if (cpu != -1)
        send_ipi(cpu);
  }

And the guest entry side *should* look like this:

  vcpu->cpu = smp_processor_id();
  smp_mb();
  if (vcpu->arch.doorbell_request) {
    // do something (abort entry or inject doorbell etc)
  }

But currently the store and load are flipped, so it is possible for the entry to see no doorbell pending, and the doorbell creation misses the store to set cpu, resulting lost work (or at least delayed until the next guest exit).

Fix this by reordering the entry operations and adding a smp_mb between them. The P8 path appears to have a similar race which is commented but not addressed yet.

---
 arch/powerpc/kvm/book3s_hv.c | 41 +++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)
arch/powerpc/kvm/book3s_hv.c +33 -8
index 791db769080d..316f61a4cb59 100644
@@ -225,6 +225,13 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
 	int cpu;
 	struct rcuwait *waitp;
 
+	/*
+	 * rcuwait_wake_up contains smp_mb() which orders prior stores that
+	 * create pending work vs below loads of cpu fields. The other side
+	 * is the barrier in vcpu run that orders setting the cpu fields vs
+	 * testing for pending work.
+	 */
+
 	waitp = kvm_arch_vcpu_get_wait(vcpu);
 	if (rcuwait_wake_up(waitp))
 		++vcpu->stat.generic.halt_wakeup;
@@ -1089,7 +1096,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
 			break;
 		}
 		tvcpu->arch.prodded = 1;
-		smp_mb();
+		smp_mb(); /* This orders prodded store vs ceded load */
 		if (tvcpu->arch.ceded)
 			kvmppc_fast_vcpu_kick_hv(tvcpu);
 		break;
@@ -3771,6 +3778,14 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 		pvc = core_info.vc[sub];
 		pvc->pcpu = pcpu + thr;
 		for_each_runnable_thread(i, vcpu, pvc) {
+			/*
+			 * XXX: is kvmppc_start_thread called too late here?
+			 * It updates vcpu->cpu and vcpu->arch.thread_cpu
+			 * which are used by kvmppc_fast_vcpu_kick_hv(), but
+			 * kick is called after new exceptions become available
+			 * and exceptions are checked earlier than here, by
+			 * kvmppc_core_prepare_to_enter.
+			 */
 			kvmppc_start_thread(vcpu, pvc);
 			kvmppc_create_dtl_entry(vcpu, pvc);
 			trace_kvm_guest_enter(vcpu);
@@ -4492,6 +4507,21 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
 	if (need_resched() || !kvm->arch.mmu_ready)
 		goto out;
 
+	vcpu->cpu = pcpu;
+	vcpu->arch.thread_cpu = pcpu;
+	vc->pcpu = pcpu;
+	local_paca->kvm_hstate.kvm_vcpu = vcpu;
+	local_paca->kvm_hstate.ptid = 0;
+	local_paca->kvm_hstate.fake_suspend = 0;
+
+	/*
+	 * Orders set cpu/thread_cpu vs testing for pending interrupts and
+	 * doorbells below. The other side is when these fields are set vs
+	 * kvmppc_fast_vcpu_kick_hv reading the cpu/thread_cpu fields to
+	 * kick a vCPU to notice the pending interrupt.
+	 */
+	smp_mb();
+
 	if (!nested) {
 		kvmppc_core_prepare_to_enter(vcpu);
 		if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
@@ -4511,13 +4541,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
 
 	tb = mftb();
 
-	vcpu->cpu = pcpu;
-	vcpu->arch.thread_cpu = pcpu;
-	vc->pcpu = pcpu;
-	local_paca->kvm_hstate.kvm_vcpu = vcpu;
-	local_paca->kvm_hstate.ptid = 0;
-	local_paca->kvm_hstate.fake_suspend = 0;
-
 	__kvmppc_create_dtl_entry(vcpu, pcpu, tb + vc->tb_offset, 0);
 
 	trace_kvm_guest_enter(vcpu);
@@ -4619,6 +4642,8 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
 	run->exit_reason = KVM_EXIT_INTR;
 	vcpu->arch.ret = -EINTR;
  out:
+	vcpu->cpu = -1;
+	vcpu->arch.thread_cpu = -1;
 	powerpc_local_irq_pmu_restore(flags);
 	preempt_enable();
 	goto done;
Signature · 1 line
2.35.1
author maintainer
#130 lore raw

PATCH 130/219 drm/amd: Add USBC connector ID

In reply to Greg Kroah-Hartman

From: Aurabindo Pillai <[email protected]>

[ Upstream commit c5c948aa894a831f96fccd025e47186b1ee41615 ]

[Why&How] Add a dedicated AMDGPU specific ID for use with newer ASICs that support USB-C output

---
 drivers/gpu/drm/amd/amdgpu/ObjectID.h | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/ObjectID.h +1 -0
index 5b393622f592..a0f0a17e224f 100644
@@ -119,6 +119,7 @@
 #define CONNECTOR_OBJECT_ID_eDP                   0x14
 #define CONNECTOR_OBJECT_ID_MXM                   0x15
 #define CONNECTOR_OBJECT_ID_LVDS_eDP              0x16
+#define CONNECTOR_OBJECT_ID_USBC                  0x17
 
 /* deleted */
 
Signature · 1 line
2.35.1
author maintainer
#131 lore raw

PATCH 131/219 btrfs: fix fallocate to use file_modified to update permissions consistently

In reply to Greg Kroah-Hartman

From: Darrick J. Wong <[email protected]>

[ Upstream commit 05fd9564e9faf0f23b4676385e27d9405cef6637 ]

Since the initial introduction of (posix) fallocate back at the turn of the century, it has been possible to use this syscall to change the user-visible contents of files. This can happen by extending the file size during a preallocation, or through any of the newer modes (punch, zero range). Because the call can be used to change file contents, we should treat it like we do any other modification to a file -- update the mtime, and drop set[ug]id privileges/capabilities.

The VFS function file_modified() does all this for us if pass it a locked inode, so let's make fallocate drop permissions correctly.

---
 fs/btrfs/file.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
fs/btrfs/file.c +11 -2
index a0179cc62913..28ddd9cf2069 100644
@@ -2918,8 +2918,9 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
 	return ret;
 }
 
-static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+static int btrfs_punch_hole(struct file *file, loff_t offset, loff_t len)
 {
+	struct inode *inode = file_inode(file);
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_state *cached_state = NULL;
@@ -2951,6 +2952,10 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
 		goto out_only_mutex;
 	}
 
+	ret = file_modified(file);
+	if (ret)
+		goto out_only_mutex;
+
 	lockstart = round_up(offset, btrfs_inode_sectorsize(BTRFS_I(inode)));
 	lockend = round_down(offset + len,
 			     btrfs_inode_sectorsize(BTRFS_I(inode))) - 1;
@@ -3391,7 +3396,7 @@ static long btrfs_fallocate(struct file *file, int mode,
 		return -EOPNOTSUPP;
 
 	if (mode & FALLOC_FL_PUNCH_HOLE)
-		return btrfs_punch_hole(inode, offset, len);
+		return btrfs_punch_hole(file, offset, len);
 
 	/*
 	 * Only trigger disk allocation, don't trigger qgroup reserve
@@ -3413,6 +3418,10 @@ static long btrfs_fallocate(struct file *file, int mode,
 			goto out;
 	}
 
+	ret = file_modified(file);
+	if (ret)
+		goto out;
+
 	/*
 	 * TODO: Move these two operations after we have checked
 	 * accurate reserved space, or fallocate can still fail but
Signature · 1 line
2.35.1
author maintainer
#132 lore raw

PATCH 132/219 btrfs: do not warn for free space inode in cow_file_range

In reply to Greg Kroah-Hartman

From: Josef Bacik <[email protected]>

[ Upstream commit a7d16d9a07bbcb7dcd5214a1bea75c808830bc0d ]

This is a long time leftover from when I originally added the free space inode, the point was to catch cases where we weren't honoring the NOCOW flag. However there exists a race with relocation, if we allocate our free space inode in a block group that is about to be relocated, we could trigger the COW path before the relocation has the opportunity to find the extents and delete the free space cache. In production where we have auto-relocation enabled we're seeing this WARN_ON_ONCE() around 5k times in a 2 week period, so not super common but enough that it's at the top of our metrics.

We're properly handling the error here, and with us phasing out v1 space cache anyway just drop the WARN_ON_ONCE.

---
 fs/btrfs/inode.c | 1 -
 1 file changed, 1 deletion(-)
fs/btrfs/inode.c +0 -1
index 85daae70afda..9547088a9306 100644
@@ -1130,7 +1130,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
 	int ret = 0;
 
 	if (btrfs_is_free_space_inode(inode)) {
-		WARN_ON_ONCE(1);
 		ret = -EINVAL;
 		goto out_unlock;
 	}
Signature · 1 line
2.35.1
author maintainer
#133 lore raw

PATCH 133/219 drm/amdgpu: conduct a proper cleanup of PDB bo

In reply to Greg Kroah-Hartman

From: Guchun Chen <[email protected]>

[ Upstream commit 2d505453f38e18d42ba7d5428aaa17aaa7752c65 ]

Use amdgpu_bo_free_kernel instead of amdgpu_bo_unref to perform a proper cleanup of PDB bo.

v2: update subject to be more accurate

---
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +1 -1
index 88c1eb9ad068..34ee75cf7954 100644
@@ -1684,7 +1684,7 @@ static int gmc_v9_0_sw_fini(void *handle)
 	amdgpu_gem_force_release(adev);
 	amdgpu_vm_manager_fini(adev);
 	amdgpu_gart_table_vram_free(adev);
-	amdgpu_bo_unref(&adev->gmc.pdb0_bo);
+	amdgpu_bo_free_kernel(&adev->gmc.pdb0_bo, NULL, &adev->gmc.ptr_pdb0);
 	amdgpu_bo_fini(adev);
 
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#134 lore raw

PATCH 134/219 drm/amdgpu/gmc: use PCI BARs for APUs in passthrough

In reply to Greg Kroah-Hartman

From: Alex Deucher <[email protected]>

[ Upstream commit b818a5d374542ccec73dcfe578a081574029820e ]

If the GPU is passed through to a guest VM, use the PCI BAR for CPU FB access rather than the physical address of carve out. The physical address is not valid in a guest.

v2: Fix HDP handing as suggested by Michel

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++--
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c     | 2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c      | 5 +++--
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c      | 2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c      | 2 +-
 5 files changed, 8 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -2
index b87dca6d09fa..052816f0efed 100644
@@ -5678,7 +5678,7 @@ void amdgpu_device_flush_hdp(struct amdgpu_device *adev,
 		struct amdgpu_ring *ring)
 {
 #ifdef CONFIG_X86_64
-	if (adev->flags & AMD_IS_APU)
+	if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev))
 		return;
 #endif
 	if (adev->gmc.xgmi.connected_to_cpu)
@@ -5694,7 +5694,7 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev,
 		struct amdgpu_ring *ring)
 {
 #ifdef CONFIG_X86_64
-	if (adev->flags & AMD_IS_APU)
+	if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev))
 		return;
 #endif
 	if (adev->gmc.xgmi.connected_to_cpu)
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +1 -1
index a2f8ed0e6a64..f1b794d5d87d 100644
@@ -788,7 +788,7 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev)
 	adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
 
 #ifdef CONFIG_X86_64
-	if (adev->flags & AMD_IS_APU) {
+	if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) {
 		adev->gmc.aper_base = adev->gfxhub.funcs->get_mc_fb_offset(adev);
 		adev->gmc.aper_size = adev->gmc.real_vram_size;
 	}
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +3 -2
index ab8adbff9e2d..5206e2da334a 100644
@@ -381,8 +381,9 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
 	adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
 
 #ifdef CONFIG_X86_64
-	if (adev->flags & AMD_IS_APU &&
-	    adev->gmc.real_vram_size > adev->gmc.aper_size) {
+	if ((adev->flags & AMD_IS_APU) &&
+	    adev->gmc.real_vram_size > adev->gmc.aper_size &&
+	    !amdgpu_passthrough(adev)) {
 		adev->gmc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
 		adev->gmc.aper_size = adev->gmc.real_vram_size;
 	}
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +1 -1
index 054733838292..d07d36786836 100644
@@ -581,7 +581,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
 	adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
 
 #ifdef CONFIG_X86_64
-	if (adev->flags & AMD_IS_APU) {
+	if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) {
 		adev->gmc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
 		adev->gmc.aper_size = adev->gmc.real_vram_size;
 	}
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +1 -1
index 34ee75cf7954..2fb24178eaef 100644
@@ -1420,7 +1420,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
 	 */
 
 	/* check whether both host-gpu and gpu-gpu xgmi links exist */
-	if ((adev->flags & AMD_IS_APU) ||
+	if (((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) ||
 	    (adev->gmc.xgmi.supported &&
 	     adev->gmc.xgmi.connected_to_cpu)) {
 		adev->gmc.aper_base =
Signature · 1 line
2.35.1
author maintainer
#135 lore raw

PATCH 135/219 drm/amd/display: fix audio format not updated after edid updated

In reply to Greg Kroah-Hartman

From: Charlene Liu <[email protected]>

[ Upstream commit 5e8a71cf13bc9184fee915b2220be71b4c6cac74 ]

[why]
for the case edid change only changed audio format. driver still need to update stream.

---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +2 -2
index ac3071e38e4a..f0a97b82c33a 100644
@@ -1667,8 +1667,8 @@ bool dc_is_stream_unchanged(
 	if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param)
 		return false;
 
-	// Only Have Audio left to check whether it is same or not. This is a corner case for Tiled sinks
-	if (old_stream->audio_info.mode_count != stream->audio_info.mode_count)
+	/*compare audio info*/
+	if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0)
 		return false;
 
 	return true;
Signature · 1 line
2.35.1
author maintainer
#136 lore raw

PATCH 136/219 drm/amd/display: FEC check in timing validation

In reply to Greg Kroah-Hartman

From: Chiawen Huang <[email protected]>

[ Upstream commit 7d56a154e22ffb3613fdebf83ec34d5225a22993 ]

[Why]
disable/enable leads FEC mismatch between hw/sw FEC state.

[How]
check FEC status to fastboot on/off.

---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc.c +4 -0
index 62bc6ce88753..78e17a4af4ab 100644
@@ -1495,6 +1495,10 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc,
 	if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
 		return false;
 
+	/* Check for FEC status*/
+	if (link->link_enc->funcs->fec_is_active(link->link_enc))
+		return false;
+
 	enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
 
 	if (enc_inst == ENGINE_ID_UNKNOWN)
Signature · 1 line
2.35.1
author maintainer
#137 lore raw

PATCH 137/219 drm/amd/display: Update VTEM Infopacket definition

In reply to Greg Kroah-Hartman

From: Leo (Hanghong) Ma <[email protected]>

[ Upstream commit c9fbf6435162ed5fb7201d1d4adf6585c6a8c327 ]

[Why & How]
The latest HDMI SPEC has updated the VTEM packet structure, so change the VTEM Infopacket defined in the driver side to align with the SPEC.

---
 .../gpu/drm/amd/display/modules/info_packet/info_packet.c    | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +3 -2
index 57f198de5e2c..4e075b01d48b 100644
@@ -100,7 +100,8 @@ enum vsc_packet_revision {
 //PB7 = MD0
 #define MASK_VTEM_MD0__VRR_EN         0x01
 #define MASK_VTEM_MD0__M_CONST        0x02
-#define MASK_VTEM_MD0__RESERVED2      0x0C
+#define MASK_VTEM_MD0__QMS_EN         0x04
+#define MASK_VTEM_MD0__RESERVED2      0x08
 #define MASK_VTEM_MD0__FVA_FACTOR_M1  0xF0
 
 //MD1
@@ -109,7 +110,7 @@ enum vsc_packet_revision {
 //MD2
 #define MASK_VTEM_MD2__BASE_REFRESH_RATE_98  0x03
 #define MASK_VTEM_MD2__RB                    0x04
-#define MASK_VTEM_MD2__RESERVED3             0xF8
+#define MASK_VTEM_MD2__NEXT_TFR              0xF8
 
 //MD3
 #define MASK_VTEM_MD3__BASE_REFRESH_RATE_07  0xFF
Signature · 1 line
2.35.1
author maintainer
#138 lore raw

PATCH 138/219 drm/amdkfd: Fix Incorrect VMIDs passed to HWS

In reply to Greg Kroah-Hartman

From: Tushar Patel <[email protected]>

[ Upstream commit b7dfbd2e601f3fee545bc158feceba4f340fe7cf ]

Compute-only GPUs have more than 8 VMIDs allocated to KFD. Fix this by passing correct number of VMIDs to HWS

v2: squash in warning fix (Alex)

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 11 +++--------
 2 files changed, 4 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +1 -1
index 284892b2d3b4..c853266957ce 100644
@@ -686,7 +686,7 @@ MODULE_PARM_DESC(sched_policy,
  * Maximum number of processes that HWS can schedule concurrently. The maximum is the
  * number of VMIDs assigned to the HWS, which is also the default.
  */
-int hws_max_conc_proc = 8;
+int hws_max_conc_proc = -1;
 module_param(hws_max_conc_proc, int, 0444);
 MODULE_PARM_DESC(hws_max_conc_proc,
 	"Max # processes HWS can execute concurrently when sched_policy=0 (0 = no concurrency, #VMIDs for KFD = Maximum(default))");
drivers/gpu/drm/amd/amdkfd/kfd_device.c +3 -8
index 2b65d0acae2c..2fdbe2f475e4 100644
@@ -480,15 +480,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 	}
 
 	/* Verify module parameters regarding mapped process number*/
-	if ((hws_max_conc_proc < 0)
-			|| (hws_max_conc_proc > kfd->vm_info.vmid_num_kfd)) {
-		dev_err(kfd_device,
-			"hws_max_conc_proc %d must be between 0 and %d, use %d instead\n",
-			hws_max_conc_proc, kfd->vm_info.vmid_num_kfd,
-			kfd->vm_info.vmid_num_kfd);
+	if (hws_max_conc_proc >= 0)
+		kfd->max_proc_per_quantum = min((u32)hws_max_conc_proc, kfd->vm_info.vmid_num_kfd);
+	else
 		kfd->max_proc_per_quantum = kfd->vm_info.vmid_num_kfd;
-	} else
-		kfd->max_proc_per_quantum = hws_max_conc_proc;
 
 	/* calculate max size of mqds needed for queues */
 	size = max_num_of_queues_per_device *
Signature · 1 line
2.35.1
author maintainer
#139 lore raw

PATCH 139/219 drm/amdgpu/vcn: improve vcn dpg stop procedure

In reply to Greg Kroah-Hartman

From: Tianci Yin <[email protected]>

[ Upstream commit 6ea239adc2a712eb318f04f5c29b018ba65ea38a ]

Prior to disabling dpg, VCN need unpausing dpg mode, or VCN will hang in S3 resuming.

---
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +3 -0
index 0ce2a7aa400b..ad9bfc772bdf 100644
@@ -1474,8 +1474,11 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
 
 static int vcn_v3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
 {
+	struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
 	uint32_t tmp;
 
+	vcn_v3_0_pause_dpg_mode(adev, 0, &state);
+
 	/* Wait for power status to be 1 */
 	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
 		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
Signature · 1 line
2.35.1
author maintainer
#140 lore raw

PATCH 140/219 drm/amdkfd: Check for potential null return of kmalloc_array()

In reply to Greg Kroah-Hartman

From: QintaoShen <[email protected]>

[ Upstream commit ebbb7bb9e80305820dc2328a371c1b35679f2667 ]

As the kmalloc_array() may return null, the 'event_waiters[i].wait' would lead to null-pointer dereference. Therefore, it is better to check the return value of kmalloc_array() to avoid this confusion.

---
 drivers/gpu/drm/amd/amdkfd/kfd_events.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdkfd/kfd_events.c +2 -0
index afe72dd11325..6ca7e12bdab8 100644
@@ -531,6 +531,8 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
 	event_waiters = kmalloc_array(num_events,
 					sizeof(struct kfd_event_waiter),
 					GFP_KERNEL);
+	if (!event_waiters)
+		return NULL;
 
 	for (i = 0; (event_waiters) && (i < num_events) ; i++) {
 		init_wait(&event_waiters[i].wait);
Signature · 1 line
2.35.1
author maintainer
#141 lore raw

PATCH 141/219 Drivers: hv: vmbus: Deactivate sysctl_record_panic_msg by default in isolated guests

In reply to Greg Kroah-Hartman

From: Andrea Parri (Microsoft) <[email protected]>

[ Upstream commit 9f8b577f7b43b2170628d6c537252785dcc2dcea ]

hv_panic_page might contain guest-sensitive information, do not dump it over to Hyper-V by default in isolated guests.

While at it, update some comments in hyperv_{panic,die}_event().

---
 drivers/hv/vmbus_drv.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/hv/vmbus_drv.c +12 -6
index 4bea1dfa41cd..6c057c76c2ca 100644
@@ -77,8 +77,8 @@ static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
 
 	/*
 	 * Hyper-V should be notified only once about a panic.  If we will be
-	 * doing hyperv_report_panic_msg() later with kmsg data, don't do
-	 * the notification here.
+	 * doing hv_kmsg_dump() with kmsg data later, don't do the notification
+	 * here.
 	 */
 	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
 	    && hyperv_report_reg()) {
@@ -100,8 +100,8 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
 
 	/*
 	 * Hyper-V should be notified only once about a panic.  If we will be
-	 * doing hyperv_report_panic_msg() later with kmsg data, don't do
-	 * the notification here.
+	 * doing hv_kmsg_dump() with kmsg data later, don't do the notification
+	 * here.
 	 */
 	if (hyperv_report_reg())
 		hyperv_report_panic(regs, val, true);
@@ -1546,14 +1546,20 @@ static int vmbus_bus_init(void)
 	if (ret)
 		goto err_connect;
 
+	if (hv_is_isolation_supported())
+		sysctl_record_panic_msg = 0;
+
 	/*
 	 * Only register if the crash MSRs are available
 	 */
 	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
 		u64 hyperv_crash_ctl;
 		/*
-		 * Sysctl registration is not fatal, since by default
-		 * reporting is enabled.
+		 * Panic message recording (sysctl_record_panic_msg)
+		 * is enabled by default in non-isolated guests and
+		 * disabled by default in isolated guests; the panic
+		 * message recording won't be available in isolated
+		 * guests should the following registration fail.
 		 */
 		hv_ctl_table_hdr = register_sysctl_table(hv_root_table);
 		if (!hv_ctl_table_hdr)
Signature · 1 line
2.35.1
author maintainer
#142 lore raw

PATCH 142/219 Drivers: hv: vmbus: Propagate VMbus coherence to each VMbus device

In reply to Greg Kroah-Hartman

From: Michael Kelley <[email protected]>

[ Upstream commit 37200078ed6aa2ac3c88a01a64996133dccfdd34 ]

VMbus synthetic devices are not represented in the ACPI DSDT -- only the top level VMbus device is represented. As a result, on ARM64 coherence information in the _CCA method is not specified for synthetic devices, so they default to not hardware coherent. Drivers for some of these synthetic devices have been recently updated to use the standard DMA APIs, and they are incurring extra overhead of unneeded software coherence management.

Fix this by propagating coherence information from the VMbus node in ACPI to the individual synthetic devices. There's no effect on x86/x64 where devices are always hardware coherent.

---
 drivers/hv/hv_common.c         | 11 +++++++++++
 drivers/hv/vmbus_drv.c         | 31 +++++++++++++++++++++++++++++++
 include/asm-generic/mshyperv.h |  1 +
 3 files changed, 43 insertions(+)
drivers/hv/hv_common.c +11 -0
index 181d16bbf49d..820e81406251 100644
@@ -20,6 +20,7 @@
 #include <linux/panic_notifier.h>
 #include <linux/ptrace.h>
 #include <linux/slab.h>
+#include <linux/dma-map-ops.h>
 #include <asm/hyperv-tlfs.h>
 #include <asm/mshyperv.h>
 
@@ -216,6 +217,16 @@ bool hv_query_ext_cap(u64 cap_query)
 }
 EXPORT_SYMBOL_GPL(hv_query_ext_cap);
 
+void hv_setup_dma_ops(struct device *dev, bool coherent)
+{
+	/*
+	 * Hyper-V does not offer a vIOMMU in the guest
+	 * VM, so pass 0/NULL for the IOMMU settings
+	 */
+	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+}
+EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
+
 bool hv_is_hibernation_supported(void)
 {
 	return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);
drivers/hv/vmbus_drv.c +31 -0
index 6c057c76c2ca..3cd0d3a44fa2 100644
@@ -920,6 +920,21 @@ static int vmbus_probe(struct device *child_device)
 	return ret;
 }
 
+/*
+ * vmbus_dma_configure -- Configure DMA coherence for VMbus device
+ */
+static int vmbus_dma_configure(struct device *child_device)
+{
+	/*
+	 * On ARM64, propagate the DMA coherence setting from the top level
+	 * VMbus ACPI device to the child VMbus device being added here.
+	 * On x86/x64 coherence is assumed and these calls have no effect.
+	 */
+	hv_setup_dma_ops(child_device,
+		device_get_dma_attr(&hv_acpi_dev->dev) == DEV_DMA_COHERENT);
+	return 0;
+}
+
 /*
  * vmbus_remove - Remove a vmbus device
  */
@@ -1040,6 +1055,7 @@ static struct bus_type  hv_bus = {
 	.remove =		vmbus_remove,
 	.probe =		vmbus_probe,
 	.uevent =		vmbus_uevent,
+	.dma_configure =	vmbus_dma_configure,
 	.dev_groups =		vmbus_dev_groups,
 	.drv_groups =		vmbus_drv_groups,
 	.bus_groups =		vmbus_bus_groups,
@@ -2435,6 +2451,21 @@ static int vmbus_acpi_add(struct acpi_device *device)
 
 	hv_acpi_dev = device;
 
+	/*
+	 * Older versions of Hyper-V for ARM64 fail to include the _CCA
+	 * method on the top level VMbus device in the DSDT. But devices
+	 * are hardware coherent in all current Hyper-V use cases, so fix
+	 * up the ACPI device to behave as if _CCA is present and indicates
+	 * hardware coherence.
+	 */
+	ACPI_COMPANION_SET(&device->dev, device);
+	if (IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED) &&
+	    device_get_dma_attr(&device->dev) == DEV_DMA_NOT_SUPPORTED) {
+		pr_info("No ACPI _CCA found; assuming coherent device I/O\n");
+		device->flags.cca_seen = true;
+		device->flags.coherent_dma = true;
+	}
+
 	result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
 					vmbus_walk_resources, NULL);
 
include/asm-generic/mshyperv.h +1 -0
index c08758b6b364..c05d2ce9b6cd 100644
@@ -269,6 +269,7 @@ bool hv_isolation_type_snp(void);
 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
 void hyperv_cleanup(void);
 bool hv_query_ext_cap(u64 cap_query);
+void hv_setup_dma_ops(struct device *dev, bool coherent);
 void *hv_map_memory(void *addr, unsigned long size);
 void hv_unmap_memory(void *addr);
 #else /* CONFIG_HYPERV */
Signature · 1 line
2.35.1
author maintainer
#143 lore raw

PATCH 143/219 PCI: hv: Propagate coherence from VMbus device to PCI device

In reply to Greg Kroah-Hartman

From: Michael Kelley <[email protected]>

[ Upstream commit 8d21732475c637c7efcdb91dc927a4c594e97898 ]

PCI pass-thru devices in a Hyper-V VM are represented as a VMBus device and as a PCI device. The coherence of the VMbus device is set based on the VMbus node in ACPI, but the PCI device has no ACPI node and defaults to not hardware coherent. This results in extra software coherence management overhead on ARM64 when devices are hardware coherent.

Fix this by setting up the PCI host bus so that normal PCI mechanisms will propagate the coherence of the VMbus device to the PCI device. There's no effect on x86/x64 where devices are always hardware coherent.

---
 drivers/pci/controller/pci-hyperv.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/pci/controller/pci-hyperv.c +9 -0
index ae0bc2fee4ca..88b3b56d0522 100644
@@ -3404,6 +3404,15 @@ static int hv_pci_probe(struct hv_device *hdev,
 	hbus->bridge->domain_nr = dom;
 #ifdef CONFIG_X86
 	hbus->sysdata.domain = dom;
+#elif defined(CONFIG_ARM64)
+	/*
+	 * Set the PCI bus parent to be the corresponding VMbus
+	 * device. Then the VMbus device will be assigned as the
+	 * ACPI companion in pcibios_root_bridge_prepare() and
+	 * pci_dma_configure() will propagate device coherence
+	 * information to devices created on the bus.
+	 */
+	hbus->sysdata.parent = hdev->device.parent;
 #endif
 
 	hbus->hdev = hdev;
Signature · 1 line
2.35.1
author maintainer
#144 lore raw

PATCH 144/219 Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer

In reply to Greg Kroah-Hartman

From: Michael Kelley <[email protected]>

[ Upstream commit b6cae15b5710c8097aad26a2e5e752c323ee5348 ]

When reading a packet from a host-to-guest ring buffer, there is no memory barrier between reading the write index (to see if there is a packet to read) and reading the contents of the packet. The Hyper-V host uses store-release when updating the write index to ensure that writes of the packet data are completed first. On the guest side, the processor can reorder and read the packet data before the write index, and sometimes get stale packet data. Getting such stale packet data has been observed in a reproducible case in a VM on ARM64.

Fix this by using virt_load_acquire() to read the write index, ensuring that reads of the packet data cannot be reordered before it. Preventing such reordering is logically correct, and with this change, getting stale data can no longer be reproduced.

---
 drivers/hv/ring_buffer.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/hv/ring_buffer.c +10 -1
index 71efacb90965..3d215d9dec43 100644
@@ -439,7 +439,16 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
 static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
 {
 	u32 priv_read_loc = rbi->priv_read_index;
-	u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+	u32 write_loc;
+
+	/*
+	 * The Hyper-V host writes the packet data, then uses
+	 * store_release() to update the write_index.  Use load_acquire()
+	 * here to prevent loads of the packet data from being re-ordered
+	 * before the read of the write_index and potentially getting
+	 * stale data.
+	 */
+	write_loc = virt_load_acquire(&rbi->ring_buffer->write_index);
 
 	if (write_loc >= priv_read_loc)
 		return write_loc - priv_read_loc;
Signature · 1 line
2.35.1
author maintainer
#145 lore raw

PATCH 145/219 scsi: target: tcmu: Fix possible page UAF

In reply to Greg Kroah-Hartman

From: Xiaoguang Wang <[email protected]>

[ Upstream commit a6968f7a367f128d120447360734344d5a3d5336 ]

tcmu_try_get_data_page() looks up pages under cmdr_lock, but it does not take refcount properly and just returns page pointer. When tcmu_try_get_data_page() returns, the returned page may have been freed by tcmu_blocks_release().

We need to get_page() under cmdr_lock to avoid concurrent tcmu_blocks_release().

---
 drivers/target/target_core_user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/target/target_core_user.c +2 -1
index 7b2a89a67cdb..06a5c4086551 100644
@@ -1820,6 +1820,7 @@ static struct page *tcmu_try_get_data_page(struct tcmu_dev *udev, uint32_t dpi)
 	mutex_lock(&udev->cmdr_lock);
 	page = xa_load(&udev->data_pages, dpi);
 	if (likely(page)) {
+		get_page(page);
 		mutex_unlock(&udev->cmdr_lock);
 		return page;
 	}
@@ -1876,6 +1877,7 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
 		/* For the vmalloc()ed cmd area pages */
 		addr = (void *)(unsigned long)info->mem[mi].addr + offset;
 		page = vmalloc_to_page(addr);
+		get_page(page);
 	} else {
 		uint32_t dpi;
 
@@ -1886,7 +1888,6 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
 			return VM_FAULT_SIGBUS;
 	}
 
-	get_page(page);
 	vmf->page = page;
 	return 0;
 }
Signature · 1 line
2.35.1
author maintainer
#146 lore raw

PATCH 146/219 scsi: lpfc: Improve PCI EEH Error and Recovery Handling

In reply to Greg Kroah-Hartman

From: James Smart <[email protected]>

[ Upstream commit 35ed9613d83f3c1f011877d591fd7d36f2666106 ]

Following EEH errors, the driver can crash or hang when deleting the localport or when attempting to unload.

The EEH handlers in the driver did not notify the NVMe-FC transport before tearing the driver down. This was delayed until the resume steps. This worked for SCSI because lpfc_block_scsi() would notify the scsi_fc_transport that the target was not available but it would not clean up all the references to the ndlp.

The SLI3 prep for dev reset handler did the lpfc_offline_prep() and lpfc_offline() calls to get the port stopped before restarting. The SLI4 version of the prep for dev reset just destroyed the queues and did not stop NVMe from continuing. Also because the port was not really stopped the localport destroy would hang because the transport was still waiting for I/O. Additionally, a devloss tmo can fire and post events to a stopped worker thread creating another hang condition.

lpfc_sli4_prep_dev_for_reset() is modified to call lpfc_offline_prep() and lpfc_offline() rather than just lpfc_scsi_dev_block() to ensure both SCSI and NVMe transports are notified to block I/O to the driver.

Logic is added to devloss handler and worker thread to clean up ndlp references and quiesce appropriately.

---
 drivers/scsi/lpfc/lpfc.h         |   7 +-
 drivers/scsi/lpfc/lpfc_crtn.h    |   3 +
 drivers/scsi/lpfc/lpfc_hbadisc.c | 119 +++++++++++++++++++++++++------
 drivers/scsi/lpfc/lpfc_init.c    |  60 ++++++++++------
 drivers/scsi/lpfc/lpfc_nvme.c    |  11 ++-
 drivers/scsi/lpfc/lpfc_sli.c     |  15 ++--
 6 files changed, 157 insertions(+), 58 deletions(-)
drivers/scsi/lpfc/lpfc.h +5 -2
index 98cabe09c040..8748c5996478 100644
@@ -897,6 +897,11 @@ enum lpfc_irq_chann_mode {
 	NHT_MODE,
 };
 
+enum lpfc_hba_bit_flags {
+	FABRIC_COMANDS_BLOCKED,
+	HBA_PCI_ERR,
+};
+
 struct lpfc_hba {
 	/* SCSI interface function jump table entries */
 	struct lpfc_io_buf * (*lpfc_get_scsi_buf)
@@ -1025,7 +1030,6 @@ struct lpfc_hba {
 					 * Firmware supports Forced Link Speed
 					 * capability
 					 */
-#define HBA_PCI_ERR		0x80000 /* The PCI slot is offline */
 #define HBA_FLOGI_ISSUED	0x100000 /* FLOGI was issued */
 #define HBA_SHORT_CMF		0x200000 /* shorter CMF timer routine */
 #define HBA_CGN_DAY_WRAP	0x400000 /* HBA Congestion info day wraps */
@@ -1335,7 +1339,6 @@ struct lpfc_hba {
 	atomic_t fabric_iocb_count;
 	struct timer_list fabric_block_timer;
 	unsigned long bit_flags;
-#define	FABRIC_COMANDS_BLOCKED	0
 	atomic_t num_rsrc_err;
 	atomic_t num_cmd_success;
 	unsigned long last_rsrc_error_time;
drivers/scsi/lpfc/lpfc_crtn.h +3 -0
index 89e36bf14d8f..d4340e5a3aac 100644
@@ -652,3 +652,6 @@ struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport,
 					      uint32_t hash, uint8_t *buf);
 void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport);
 int lpfc_issue_els_qfpa(struct lpfc_vport *vport);
+
+void lpfc_sli_rpi_release(struct lpfc_vport *vport,
+			  struct lpfc_nodelist *ndlp);
drivers/scsi/lpfc/lpfc_hbadisc.c +96 -23

244 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_init.c +38 -22

156 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_nvme.c +5 -6
index 9601edd838e1..8983f6440858 100644
@@ -2169,8 +2169,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
 			abts_nvme = 0;
 			for (i = 0; i < phba->cfg_hdw_queue; i++) {
 				qp = &phba->sli4_hba.hdwq[i];
-				if (!vport || !vport->localport ||
-				    !qp || !qp->io_wq)
+				if (!vport->localport || !qp || !qp->io_wq)
 					return;
 
 				pring = qp->io_wq->pring;
@@ -2180,8 +2179,9 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
 				abts_scsi += qp->abts_scsi_io_bufs;
 				abts_nvme += qp->abts_nvme_io_bufs;
 			}
-			if (!vport || !vport->localport ||
-			    vport->phba->hba_flag & HBA_PCI_ERR)
+			if (!vport->localport ||
+			    test_bit(HBA_PCI_ERR, &vport->phba->bit_flags) ||
+			    vport->load_flag & FC_UNLOADING)
 				return;
 
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
@@ -2541,8 +2541,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 		 * return values is ignored.  The upcall is a courtesy to the
 		 * transport.
 		 */
-		if (vport->load_flag & FC_UNLOADING ||
-		    unlikely(vport->phba->hba_flag & HBA_PCI_ERR))
+		if (vport->load_flag & FC_UNLOADING)
 			(void)nvme_fc_set_remoteport_devloss(remoteport, 0);
 
 		ret = nvme_fc_unregister_remoteport(remoteport);
drivers/scsi/lpfc/lpfc_sli.c +10 -5
index 430abebf99f1..661ed0999f1c 100644
@@ -2833,6 +2833,12 @@ __lpfc_sli_rpi_release(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 	ndlp->nlp_flag &= ~NLP_UNREG_INP;
 }
 
+void
+lpfc_sli_rpi_release(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
+{
+	__lpfc_sli_rpi_release(vport, ndlp);
+}
+
 /**
  * lpfc_sli_def_mbox_cmpl - Default mailbox completion handler
  * @phba: Pointer to HBA context object.
@@ -4554,11 +4560,6 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
 	struct lpfc_iocbq *piocb, *next_iocb;
 
 	spin_lock_irq(&phba->hbalock);
-	if (phba->hba_flag & HBA_IOQ_FLUSH ||
-	    !phba->sli4_hba.hdwq) {
-		spin_unlock_irq(&phba->hbalock);
-		return;
-	}
 	/* Indicate the I/O queues are flushed */
 	phba->hba_flag |= HBA_IOQ_FLUSH;
 	spin_unlock_irq(&phba->hbalock);
@@ -11235,6 +11236,10 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
 	unsigned long iflags;
 	int rc;
 
+	/* If the PCI channel is in offline state, do not post iocbs. */
+	if (unlikely(pci_channel_offline(phba->pcidev)))
+		return IOCB_ERROR;
+
 	if (phba->sli_rev == LPFC_SLI_REV4) {
 		eq = phba->sli4_hba.hdwq[piocb->hba_wqidx].hba_eq;
 
Signature · 1 line
2.35.1
author maintainer
#147 lore raw

PATCH 147/219 scsi: lpfc: Fix unload hang after back to back PCI EEH faults

In reply to Greg Kroah-Hartman

From: James Smart <[email protected]>

[ Upstream commit a4691038b4071ff0d9ae486d8822a2c0d41d5796 ]

When injecting EEH errors the port is getting hung up waiting on the node list to empty, message number 0233. The driver is stuck at this point and also can't unload. The driver makes transport remoteport delete calls which try to abort I/O's, but the EEH daemon has already called the driver to detach and the detachment has set the global FC_UNLOADING flag. There are several code paths that will avoid I/O cleanup if the FC_UNLOADING flag is set, resulting in transports waiting for I/O while the driver is waiting on transports to clean up.

Additionally, during study of the list, a locking issue was found in lpfc_sli_abort_iocb_ring that could corrupt the list.

A special case was added to the lpfc_cleanup() routine to call lpfc_sli_flush_rings() if the driver is FC_UNLOADING and if the pci-slot is offline (e.g. EEH).

The SLI4 part of lpfc_sli_abort_iocb_ring() is changed to use the ring_lock. Also added code to cancel the I/Os if the pci-slot is offline and added checks and returns for the FC_UNLOADING and HBA_IOQ_FLUSH flags to prevent trying to send an I/O that we cannot handle.

---
 drivers/scsi/lpfc/lpfc_hbadisc.c |  1 +
 drivers/scsi/lpfc/lpfc_init.c    | 26 +++++++++++++++--
 drivers/scsi/lpfc/lpfc_nvme.c    | 16 ++++++++--
 drivers/scsi/lpfc/lpfc_sli.c     | 50 ++++++++++++++++++++++----------
 4 files changed, 72 insertions(+), 21 deletions(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +1 -0
index e10371611ef8..0cba306de0db 100644
@@ -5416,6 +5416,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 				ndlp->nlp_flag &= ~NLP_UNREG_INP;
 				mempool_free(mbox, phba->mbox_mem_pool);
 				acc_plogi = 1;
+				lpfc_nlp_put(ndlp);
 			}
 		} else {
 			lpfc_printf_vlog(vport, KERN_INFO,
drivers/scsi/lpfc/lpfc_init.c +23 -3
index fe9a04b2df3e..c8c049cf8d96 100644
@@ -95,6 +95,7 @@ static void lpfc_sli4_oas_verify(struct lpfc_hba *phba);
 static uint16_t lpfc_find_cpu_handle(struct lpfc_hba *, uint16_t, int);
 static void lpfc_setup_bg(struct lpfc_hba *, struct Scsi_Host *);
 static int lpfc_sli4_cgn_parm_chg_evt(struct lpfc_hba *);
+static void lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba);
 
 static struct scsi_transport_template *lpfc_transport_template = NULL;
 static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
@@ -1995,6 +1996,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
 	if (pci_channel_offline(phba->pcidev)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
 				"3166 pci channel is offline\n");
+		lpfc_sli_flush_io_rings(phba);
 		return;
 	}
 
@@ -2983,6 +2985,22 @@ lpfc_cleanup(struct lpfc_vport *vport)
 					NLP_EVT_DEVICE_RM);
 	}
 
+	/* This is a special case flush to return all
+	 * IOs before entering this loop. There are
+	 * two points in the code where a flush is
+	 * avoided if the FC_UNLOADING flag is set.
+	 * one is in the multipool destroy,
+	 * (this prevents a crash) and the other is
+	 * in the nvme abort handler, ( also prevents
+	 * a crash). Both of these exceptions are
+	 * cases where the slot is still accessible.
+	 * The flush here is only when the pci slot
+	 * is offline.
+	 */
+	if (vport->load_flag & FC_UNLOADING &&
+	    pci_channel_offline(phba->pcidev))
+		lpfc_sli_flush_io_rings(vport->phba);
+
 	/* At this point, ALL ndlp's should be gone
 	 * because of the previous NLP_EVT_DEVICE_RM.
 	 * Lets wait for this to happen, if needed.
@@ -2995,7 +3013,7 @@ lpfc_cleanup(struct lpfc_vport *vport)
 			list_for_each_entry_safe(ndlp, next_ndlp,
 						&vport->fc_nodes, nlp_listp) {
 				lpfc_printf_vlog(ndlp->vport, KERN_ERR,
-						 LOG_TRACE_EVENT,
+						 LOG_DISCOVERY,
 						 "0282 did:x%x ndlp:x%px "
 						 "refcnt:%d xflags x%x nflag x%x\n",
 						 ndlp->nlp_DID, (void *)ndlp,
@@ -13371,8 +13389,9 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
 	/* Abort all iocbs associated with the hba */
 	lpfc_sli_hba_iocb_abort(phba);
 
-	/* Wait for completion of device XRI exchange busy */
-	lpfc_sli4_xri_exchange_busy_wait(phba);
+	if (!pci_channel_offline(phba->pcidev))
+		/* Wait for completion of device XRI exchange busy */
+		lpfc_sli4_xri_exchange_busy_wait(phba);
 
 	/* per-phba callback de-registration for hotplug event */
 	if (phba->pport)
@@ -14276,6 +14295,7 @@ lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba)
 			"2711 PCI channel permanent disable for failure\n");
 	/* Block all SCSI devices' I/Os on the host */
 	lpfc_scsi_dev_block(phba);
+	lpfc_sli4_prep_dev_for_reset(phba);
 
 	/* stop all timers */
 	lpfc_stop_hba_timers(phba);
drivers/scsi/lpfc/lpfc_nvme.c +13 -3
index 8983f6440858..df73abb59407 100644
@@ -93,6 +93,11 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport,
 
 	lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
 	vport = lport->vport;
+
+	if (!vport || vport->load_flag & FC_UNLOADING ||
+	    vport->phba->hba_flag & HBA_IOQ_FLUSH)
+		return -ENODEV;
+
 	qhandle = kzalloc(sizeof(struct lpfc_nvme_qhandle), GFP_KERNEL);
 	if (qhandle == NULL)
 		return -ENOMEM;
@@ -267,7 +272,8 @@ lpfc_nvme_handle_lsreq(struct lpfc_hba *phba,
 		return -EINVAL;
 
 	remoteport = lpfc_rport->remoteport;
-	if (!vport->localport)
+	if (!vport->localport ||
+	    vport->phba->hba_flag & HBA_IOQ_FLUSH)
 		return -EINVAL;
 
 	lport = vport->localport->private;
@@ -559,6 +565,8 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 				 ndlp->nlp_DID, ntype, nstate);
 		return -ENODEV;
 	}
+	if (vport->phba->hba_flag & HBA_IOQ_FLUSH)
+		return -ENODEV;
 
 	if (!vport->phba->sli4_hba.nvmels_wq)
 		return -ENOMEM;
@@ -662,7 +670,8 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 		return -EINVAL;
 
 	vport = lport->vport;
-	if (vport->load_flag & FC_UNLOADING)
+	if (vport->load_flag & FC_UNLOADING ||
+	    vport->phba->hba_flag & HBA_IOQ_FLUSH)
 		return -ENODEV;
 
 	atomic_inc(&lport->fc4NvmeLsRequests);
@@ -1515,7 +1524,8 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
 
 	phba = vport->phba;
 
-	if (unlikely(vport->load_flag & FC_UNLOADING)) {
+	if ((unlikely(vport->load_flag & FC_UNLOADING)) ||
+	    phba->hba_flag & HBA_IOQ_FLUSH) {
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
 				 "6124 Fail IO, Driver unload\n");
 		atomic_inc(&lport->xmt_fcp_err);
drivers/scsi/lpfc/lpfc_sli.c +35 -15

77 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#148 lore raw

PATCH 148/219 scsi: lpfc: Fix queue failures when recovering from PCI parity error

In reply to Greg Kroah-Hartman

From: James Smart <[email protected]>

[ Upstream commit df0101197c4d9596682901631f3ee193ed354873 ]

When recovering from a pci-parity error the driver is failing to re-create queues, causing recovery to fail. Looking deeper, it was found that the interrupt vector count allocated on the recovery was fewer than the vectors originally allocated. This disparity resulted in CPU map entries with stale information. When the driver tries to re-create the queues, it attempts to use the stale information which indicates an eq/interrupt vector that was no longer created.

Fix by clearng the cpup map array before enabling and requesting the IRQs in the lpfc_sli_reset_slot_s4 routine().

---
 drivers/scsi/lpfc/lpfc_init.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/scsi/lpfc/lpfc_init.c +2 -0
index c8c049cf8d96..9569a7390f9d 100644
@@ -15248,6 +15248,8 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev)
 	psli->sli_flag &= ~LPFC_SLI_ACTIVE;
 	spin_unlock_irq(&phba->hbalock);
 
+	/* Init cpu_map array */
+	lpfc_cpu_map_array_init(phba);
 	/* Configure and enable interrupt */
 	intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
 	if (intr_mode == LPFC_INTR_ERROR) {
Signature · 1 line
2.35.1
author maintainer
#149 lore raw

PATCH 149/219 scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024

In reply to Greg Kroah-Hartman

From: Tyrel Datwyler <[email protected]>

[ Upstream commit 0bade8e53279157c7cc9dd95d573b7e82223d78a ]

The adapter request_limit is hardcoded to be INITIAL_SRP_LIMIT which is currently an arbitrary value of 800. Increase this value to 1024 which better matches the characteristics of the typical IBMi Initiator that supports 32 LUNs and a queue depth of 32.

This change also has the secondary benefit of being a power of two as required by the kfifo API. Since, Commit ab9bb6318b09 ("Partially revert "kfifo: fix kfifo_alloc() and kfifo_init()"") the size of IU pool for each target has been rounded down to 512 when attempting to kfifo_init() those pools with the current request_limit size of 800.

---
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +1 -1
index 61f06f6885a5..89b9fbce7488 100644
@@ -36,7 +36,7 @@
 
 #define IBMVSCSIS_VERSION	"v0.2"
 
-#define	INITIAL_SRP_LIMIT	800
+#define	INITIAL_SRP_LIMIT	1024
 #define	DEFAULT_MAX_SECTORS	256
 #define MAX_TXU			1024 * 1024
 
Signature · 1 line
2.35.1
author maintainer
#150 lore raw

PATCH 150/219 net: micrel: fix KS8851_MLL Kconfig

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

[ Upstream commit c3efcedd272aa6dd5929e20cf902a52ddaa1197a ]

KS8851_MLL selects MICREL_PHY, which depends on PTP_1588_CLOCK_OPTIONAL, so make KS8851_MLL also depend on PTP_1588_CLOCK_OPTIONAL since 'select' does not follow any dependency chains.

Fixes kconfig warning and build errors:

WARNING: unmet direct dependencies detected for MICREL_PHY
Depends on [m]: NETDEVICES [=y] && PHYLIB [=y] && PTP_1588_CLOCK_OPTIONAL [=m] Selected by [y]:
- KS8851_MLL [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_MICREL [=y] && HAS_IOMEM [=y]

ld: drivers/net/phy/micrel.o: in function `lan8814_ts_info':
micrel.c:(.text+0xb35): undefined reference to `ptp_clock_index'
ld: drivers/net/phy/micrel.o: in function `lan8814_probe':
micrel.c:(.text+0x2586): undefined reference to `ptp_clock_register'

---
 drivers/net/ethernet/micrel/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/micrel/Kconfig +1 -0
index 93df3049cdc0..1b632cdd7630 100644
@@ -39,6 +39,7 @@ config KS8851
 config KS8851_MLL
 	tristate "Micrel KS8851 MLL"
 	depends on HAS_IOMEM
+	depends on PTP_1588_CLOCK_OPTIONAL
 	select MII
 	select CRC32
 	select EEPROM_93CX6
Signature · 1 line
2.35.1
author maintainer
#151 lore raw

PATCH 151/219 ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs

In reply to Greg Kroah-Hartman

From: Christian Lamparter <[email protected]>

[ Upstream commit 5399752299396a3c9df6617f4b3c907d7aa4ded8 ]

Samsung' 840 EVO with the latest firmware (EXT0DB6Q) locks up with the a message: "READ LOG DMA EXT failed, trying PIO" during boot.

Initially this was discovered because it caused a crash with the sata_dwc_460ex controller on a WD MyBook Live DUO.

The reporter "Tice Rex" which has the unique opportunity that he has two Samsung 840 EVO SSD! One with the older firmware "EXT0BB0Q" which booted fine and didn't expose "READ LOG DMA EXT". But the newer/latest firmware "EXT0DB6Q" caused the headaches.

---
 drivers/ata/libata-core.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/ata/libata-core.c +3 -0
index 0c854aebfe0b..760c0d81d148 100644
@@ -4014,6 +4014,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "Crucial_CT*MX100*",		"MU01",	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
+	{ "Samsung SSD 840 EVO*",	NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
+						ATA_HORKAGE_NO_DMA_LOG |
+						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "Samsung SSD 840*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "Samsung SSD 850*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
Signature · 1 line
2.35.1
author maintainer
#152 lore raw

PATCH 152/219 gpu: ipu-v3: Fix dev_dbg frequency output

In reply to Greg Kroah-Hartman

From: Leo Ruan <[email protected]>

[ Upstream commit 070a88fd4a03f921b73a2059e97d55faaa447dab ]

This commit corrects the printing of the IPU clock error percentage if it is between -0.1% to -0.9%. For example, if the pixel clock requested is 27.2 MHz but only 27.0 MHz can be achieved the deviation is -0.8%. But the fixed point math had a flaw and calculated error of 0.2%.

Before:
Clocks: IPU 270000000Hz DI 24716667Hz Needed 27200000Hz IPU clock can give 27000000 with divider 10, error 0.2% Want 27200000Hz IPU 270000000Hz DI 24716667Hz using IPU, 27000000Hz

After:
Clocks: IPU 270000000Hz DI 24716667Hz Needed 27200000Hz IPU clock can give 27000000 with divider 10, error -0.8% Want 27200000Hz IPU 270000000Hz DI 24716667Hz using IPU, 27000000Hz

---
 drivers/gpu/ipu-v3/ipu-di.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/ipu-v3/ipu-di.c +3 -2
index 666223c6bec4..0a34e0ab4fe6 100644
@@ -447,8 +447,9 @@ static void ipu_di_config_clock(struct ipu_di *di,
 
 		error = rate / (sig->mode.pixelclock / 1000);
 
-		dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider %u, error %d.%u%%\n",
-			rate, div, (signed)(error - 1000) / 10, error % 10);
+		dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider %u, error %c%d.%d%%\n",
+			rate, div, error < 1000 ? '-' : '+',
+			abs(error - 1000) / 10, abs(error - 1000) % 10);
 
 		/* Allow a 1% error */
 		if (error < 1010 && error >= 990) {
Signature · 1 line
2.35.1
author maintainer
#153 lore raw

PATCH 153/219 regulator: wm8994: Add an off-on delay for WM8994 variant

In reply to Greg Kroah-Hartman

From: Jonathan Bakker <[email protected]>

[ Upstream commit 92d96b603738ec4f35cde7198c303ae264dd47cb ]

As per Table 130 of the wm8994 datasheet at [1], there is an off-on delay for LDO1 and LDO2. In the wm8958 datasheet [2], I could not find any reference to it. I could not find a wm1811 datasheet to double-check there, but as no one has complained presumably it works without it.

This solves the issue on Samsung Aries boards with a wm8994 where register writes fail when the device is powered off and back-on quickly.

[1] https://statics.cirrus.com/pubs/proDatasheet/WM8994_Rev4.6.pdf
[2] https://statics.cirrus.com/pubs/proDatasheet/WM8958_v3.5.pdf

---
 drivers/regulator/wm8994-regulator.c | 42 ++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 3 deletions(-)
drivers/regulator/wm8994-regulator.c +39 -3
index cadea0344486..40befdd9dfa9 100644
@@ -71,6 +71,35 @@ static const struct regulator_ops wm8994_ldo2_ops = {
 };
 
 static const struct regulator_desc wm8994_ldo_desc[] = {
+	{
+		.name = "LDO1",
+		.id = 1,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
+		.vsel_reg = WM8994_LDO_1,
+		.vsel_mask = WM8994_LDO1_VSEL_MASK,
+		.ops = &wm8994_ldo1_ops,
+		.min_uV = 2400000,
+		.uV_step = 100000,
+		.enable_time = 3000,
+		.off_on_delay = 36000,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "LDO2",
+		.id = 2,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
+		.vsel_reg = WM8994_LDO_2,
+		.vsel_mask = WM8994_LDO2_VSEL_MASK,
+		.ops = &wm8994_ldo2_ops,
+		.enable_time = 3000,
+		.off_on_delay = 36000,
+		.owner = THIS_MODULE,
+	},
+};
+
+static const struct regulator_desc wm8958_ldo_desc[] = {
 	{
 		.name = "LDO1",
 		.id = 1,
@@ -172,9 +201,16 @@ static int wm8994_ldo_probe(struct platform_device *pdev)
 	 * regulator core and we need not worry about it on the
 	 * error path.
 	 */
-	ldo->regulator = devm_regulator_register(&pdev->dev,
-						 &wm8994_ldo_desc[id],
-						 &config);
+	if (ldo->wm8994->type == WM8994) {
+		ldo->regulator = devm_regulator_register(&pdev->dev,
+							 &wm8994_ldo_desc[id],
+							 &config);
+	} else {
+		ldo->regulator = devm_regulator_register(&pdev->dev,
+							 &wm8958_ldo_desc[id],
+							 &config);
+	}
+
 	if (IS_ERR(ldo->regulator)) {
 		ret = PTR_ERR(ldo->regulator);
 		dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
Signature · 1 line
2.35.1
author maintainer
#154 lore raw

PATCH 154/219 static_call: Properly initialise DEFINE_STATIC_CALL_RET0()

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

[ Upstream commit 5517d500829c683a358a8de04ecb2e28af629ae5 ]

When a static call is updated with __static_call_return0() as target, arch_static_call_transform() set it to use an optimised set of instructions which are meant to lay in the same cacheline.

But when initialising a static call with DEFINE_STATIC_CALL_RET0(), we get a branch to the real __static_call_return0() function instead of getting the optimised setup:

	c00d8120 <__SCT__perf_snapshot_branch_stack>:
	c00d8120:	4b ff ff f4 	b       c00d8114 <__static_call_return0>
	c00d8124:	3d 80 c0 0e 	lis     r12,-16370
	c00d8128:	81 8c 81 3c 	lwz     r12,-32452(r12)
	c00d812c:	7d 89 03 a6 	mtctr   r12
	c00d8130:	4e 80 04 20 	bctr
	c00d8134:	38 60 00 00 	li      r3,0
	c00d8138:	4e 80 00 20 	blr
	c00d813c:	00 00 00 00 	.long 0x0

Add ARCH_DEFINE_STATIC_CALL_RET0_TRAMP() defined by each architecture to setup the optimised configuration, and rework DEFINE_STATIC_CALL_RET0() to call it:

	c00d8120 <__SCT__perf_snapshot_branch_stack>:
	c00d8120:	48 00 00 14 	b       c00d8134 <__SCT__perf_snapshot_branch_stack+0x14>
	c00d8124:	3d 80 c0 0e 	lis     r12,-16370
	c00d8128:	81 8c 81 3c 	lwz     r12,-32452(r12)
	c00d812c:	7d 89 03 a6 	mtctr   r12
	c00d8130:	4e 80 04 20 	bctr
	c00d8134:	38 60 00 00 	li      r3,0
	c00d8138:	4e 80 00 20 	blr
	c00d813c:	00 00 00 00 	.long 0x0
---
 arch/powerpc/include/asm/static_call.h |  1 +
 arch/x86/include/asm/static_call.h     |  2 ++
 include/linux/static_call.h            | 20 +++++++++++++++++---
 3 files changed, 20 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/static_call.h +1 -0
index 0a0bc79bd1fa..de1018cc522b 100644
@@ -24,5 +24,6 @@
 
 #define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func)	__PPC_SCT(name, "b " #func)
 #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)	__PPC_SCT(name, "blr")
+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)	__PPC_SCT(name, "b .+20")
 
 #endif /* _ASM_POWERPC_STATIC_CALL_H */
arch/x86/include/asm/static_call.h +2 -0
index ed4f8bb6c2d9..2455d721503e 100644
@@ -38,6 +38,8 @@
 #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)			\
 	__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; int3; nop; nop; nop")
 
+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)			\
+	ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
 
 #define ARCH_ADD_TRAMP_KEY(name)					\
 	asm(".pushsection .static_call_tramp_key, \"a\"		\n"	\
include/linux/static_call.h +17 -3
index fcc5b48989b3..3c50b0fdda16 100644
@@ -196,6 +196,14 @@ extern long __static_call_return0(void);
 	};								\
 	ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	DECLARE_STATIC_CALL(name, _func);				\
+	struct static_call_key STATIC_CALL_KEY(name) = {		\
+		.func = __static_call_return0,				\
+		.type = 1,						\
+	};								\
+	ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)
+
 #define static_call_cond(name)	(void)__static_call(name)
 
 #define EXPORT_STATIC_CALL(name)					\
@@ -231,6 +239,12 @@ static inline int static_call_init(void) { return 0; }
 	};								\
 	ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name)
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	DECLARE_STATIC_CALL(name, _func);				\
+	struct static_call_key STATIC_CALL_KEY(name) = {		\
+		.func = __static_call_return0,				\
+	};								\
+	ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name)
 
 #define static_call_cond(name)	(void)__static_call(name)
 
@@ -284,6 +298,9 @@ static inline long __static_call_return0(void)
 		.func = NULL,						\
 	}
 
+#define DEFINE_STATIC_CALL_RET0(name, _func)				\
+	__DEFINE_STATIC_CALL(name, _func, __static_call_return0)
+
 static inline void __static_call_nop(void) { }
 
 /*
@@ -327,7 +344,4 @@ static inline int static_call_text_reserved(void *start, void *end)
 #define DEFINE_STATIC_CALL(name, _func)					\
 	__DEFINE_STATIC_CALL(name, _func, _func)
 
-#define DEFINE_STATIC_CALL_RET0(name, _func)				\
-	__DEFINE_STATIC_CALL(name, _func, __static_call_return0)
-
 #endif /* _LINUX_STATIC_CALL_H */
Signature · 1 line
2.35.1
author maintainer
#155 lore raw

PATCH 155/219 arm64: alternatives: mark patch_alternative() as `noinstr`

In reply to Greg Kroah-Hartman

From: Joey Gouly <[email protected]>

[ Upstream commit a2c0b0fbe01419f8f5d1c0b9c581631f34ffce8b ]

The alternatives code must be noinstr such that it does not patch itself, as the cache invalidation is only performed after all the alternatives have been applied.

Mark patch_alternative() as noinstr. Mark branch_insn_requires_update() and get_alt_insn() with __always_inline since they are both only called through patch_alternative().

Booting a kernel in QEMU TCG with KCSAN=y and ARM64_USE_LSE_ATOMICS=y caused a boot hang:

[    0.241121] CPU: All CPU(s) started at EL2

The alternatives code was patching the atomics in __tsan_read4() from LL/SC atomics to LSE atomics.

The following fragment is using LL/SC atomics in the .text section:

  | <__tsan_unaligned_read4+304>:     ldxr    x6, [x2]
  | <__tsan_unaligned_read4+308>:     add     x6, x6, x5
  | <__tsan_unaligned_read4+312>:     stxr    w7, x6, [x2]
  | <__tsan_unaligned_read4+316>:     cbnz    w7, <__tsan_unaligned_read4+304>

This LL/SC atomic sequence was to be replaced with LSE atomics. However since the alternatives code was instrumentable, __tsan_read4() was being called after only the first instruction was replaced, which led to the following code in memory:

  | <__tsan_unaligned_read4+304>:     ldadd   x5, x6, [x2]
  | <__tsan_unaligned_read4+308>:     add     x6, x6, x5
  | <__tsan_unaligned_read4+312>:     stxr    w7, x6, [x2]
  | <__tsan_unaligned_read4+316>:     cbnz    w7, <__tsan_unaligned_read4+304>

This caused an infinite loop as the stxr instruction never completed successfully, so w7 was always 0.

---
 arch/arm64/kernel/alternative.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/kernel/alternative.c +3 -3
index 3fb79b76e9d9..7bbf5104b7b7 100644
@@ -42,7 +42,7 @@ bool alternative_is_applied(u16 cpufeature)
 /*
  * Check if the target PC is within an alternative block.
  */
-static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
+static __always_inline bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
 {
 	unsigned long replptr = (unsigned long)ALT_REPL_PTR(alt);
 	return !(pc >= replptr && pc <= (replptr + alt->alt_len));
@@ -50,7 +50,7 @@ static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
 
 #define align_down(x, a)	((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
 
-static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr)
+static __always_inline u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr)
 {
 	u32 insn;
 
@@ -95,7 +95,7 @@ static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnp
 	return insn;
 }
 
-static void patch_alternative(struct alt_instr *alt,
+static noinstr void patch_alternative(struct alt_instr *alt,
 			      __le32 *origptr, __le32 *updptr, int nr_inst)
 {
 	__le32 *replptr;
Signature · 1 line
2.35.1
author maintainer
#156 lore raw

PATCH 156/219 tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry

In reply to Greg Kroah-Hartman

From: Steve Capper <[email protected]>

[ Upstream commit 697a1d44af8ba0477ee729e632f4ade37999249a ]

tlb_remove_huge_tlb_entry only considers PMD_SIZE and PUD_SIZE when updating the mmu_gather structure.

Unfortunately on arm64 there are two additional huge page sizes that need to be covered: CONT_PTE_SIZE and CONT_PMD_SIZE. Where an end-user attempts to employ contiguous huge pages, a VM_BUG_ON can be experienced due to the fact that the tlb structure hasn't been correctly updated by the relevant tlb_flush_p.._range() call from tlb_remove_huge_tlb_entry.

This patch adds inequality logic to the generic implementation of tlb_remove_huge_tlb_entry s.t. CONT_PTE_SIZE and CONT_PMD_SIZE are effectively covered on arm64. Also, as well as ptes, pmds and puds; p4ds are now considered too.

---
 include/asm-generic/tlb.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
include/asm-generic/tlb.h +7 -3
index 2c68a545ffa7..71942a1c642d 100644
@@ -565,10 +565,14 @@ static inline void tlb_flush_p4d_range(struct mmu_gather *tlb,
 #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)	\
 	do {							\
 		unsigned long _sz = huge_page_size(h);		\
-		if (_sz == PMD_SIZE)				\
-			tlb_flush_pmd_range(tlb, address, _sz);	\
-		else if (_sz == PUD_SIZE)			\
+		if (_sz >= P4D_SIZE)				\
+			tlb_flush_p4d_range(tlb, address, _sz);	\
+		else if (_sz >= PUD_SIZE)			\
 			tlb_flush_pud_range(tlb, address, _sz);	\
+		else if (_sz >= PMD_SIZE)			\
+			tlb_flush_pmd_range(tlb, address, _sz);	\
+		else						\
+			tlb_flush_pte_range(tlb, address, _sz);	\
 		__tlb_remove_tlb_entry(tlb, ptep, address);	\
 	} while (0)
 
Signature · 1 line
2.35.1
author maintainer
#157 lore raw

PATCH 157/219 net: axienet: setup mdio unconditionally

In reply to Greg Kroah-Hartman

From: Andy Chiu <[email protected]>

[ Upstream commit d1c4f93e3f0a023024a6f022a61528c06cf1daa9 ]

The call to axienet_mdio_setup should not depend on whether "phy-node" pressents on the DT. Besides, since lp->phy_node is used if PHY is in SGMII or 100Base-X modes, move it into the if statement. And the next patch will remove lp->phy_node from driver's private structure and do an of_node_put on it right away after use since it is not used elsewhere.

---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +6 -7
index 90d96eb79984..a960227f61da 100644
@@ -2072,15 +2072,14 @@ static int axienet_probe(struct platform_device *pdev)
 	if (ret)
 		goto cleanup_clk;
 
-	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
-	if (lp->phy_node) {
-		ret = axienet_mdio_setup(lp);
-		if (ret)
-			dev_warn(&pdev->dev,
-				 "error registering MDIO bus: %d\n", ret);
-	}
+	ret = axienet_mdio_setup(lp);
+	if (ret)
+		dev_warn(&pdev->dev,
+			 "error registering MDIO bus: %d\n", ret);
+
 	if (lp->phy_mode == PHY_INTERFACE_MODE_SGMII ||
 	    lp->phy_mode == PHY_INTERFACE_MODE_1000BASEX) {
+		lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
 		if (!lp->phy_node) {
 			dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n");
 			ret = -EINVAL;
Signature · 1 line
2.35.1
author maintainer
#158 lore raw

PATCH 158/219 Drivers: hv: balloon: Disable balloon and hot-add accordingly

In reply to Greg Kroah-Hartman

From: Boqun Feng <[email protected]>

[ Upstream commit be5802795cf8d0b881745fa9ba7790293b382280 ]

Currently there are known potential issues for balloon and hot-add on ARM64:

* Unballoon requests from Hyper-V should only unballoon ranges
that are guest page size aligned, otherwise guests cannot handle because it's impossible to partially free a page. This is a problem when guest page size > 4096 bytes.

* Memory hot-add requests from Hyper-V should provide the NUMA
node id of the added ranges or ARM64 should have a functional memory_add_physaddr_to_nid(), otherwise the node id is missing for add_memory().

These issues require discussions on design and implementation. In the meanwhile, post_status() is working and essential to guest monitoring. Therefore instead of disabling the entire hv_balloon driver, the ballooning (when page size > 4096 bytes) and hot-add are disabled accordingly for now. Once the issues are fixed, they can be re-enable in these cases.

---
 drivers/hv/hv_balloon.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
drivers/hv/hv_balloon.c +34 -2
index 439f99b8b5de..3cf334c46c31 100644
@@ -1653,6 +1653,38 @@ static void disable_page_reporting(void)
 	}
 }
 
+static int ballooning_enabled(void)
+{
+	/*
+	 * Disable ballooning if the page size is not 4k (HV_HYP_PAGE_SIZE),
+	 * since currently it's unclear to us whether an unballoon request can
+	 * make sure all page ranges are guest page size aligned.
+	 */
+	if (PAGE_SIZE != HV_HYP_PAGE_SIZE) {
+		pr_info("Ballooning disabled because page size is not 4096 bytes\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static int hot_add_enabled(void)
+{
+	/*
+	 * Disable hot add on ARM64, because we currently rely on
+	 * memory_add_physaddr_to_nid() to get a node id of a hot add range,
+	 * however ARM64's memory_add_physaddr_to_nid() always return 0 and
+	 * DM_MEM_HOT_ADD_REQUEST doesn't have the NUMA node information for
+	 * add_memory().
+	 */
+	if (IS_ENABLED(CONFIG_ARM64)) {
+		pr_info("Memory hot add disabled on ARM64\n");
+		return 0;
+	}
+
+	return 1;
+}
+
 static int balloon_connect_vsp(struct hv_device *dev)
 {
 	struct dm_version_request version_req;
@@ -1724,8 +1756,8 @@ static int balloon_connect_vsp(struct hv_device *dev)
 	 * currently still requires the bits to be set, so we have to add code
 	 * to fail the host's hot-add and balloon up/down requests, if any.
 	 */
-	cap_msg.caps.cap_bits.balloon = 1;
-	cap_msg.caps.cap_bits.hot_add = 1;
+	cap_msg.caps.cap_bits.balloon = ballooning_enabled();
+	cap_msg.caps.cap_bits.hot_add = hot_add_enabled();
 
 	/*
 	 * Specify our alignment requirements as it relates
Signature · 1 line
2.35.1