Skip to contentSkip to conversation

5.19.12-rc1 review

PATCH In review Greg Kroah-Hartman 14 participants 228 messages Sep 26, 2022 – Sep 29, 2022 Page 1 of 2

Subsystems (3)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.19.12-rc1 review

This is the start of the stable review cycle for the 5.19.12 release. There are 207 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, 28 Sep 2022 10:07:26 +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.19.12-rc1.gz

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

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 5.19.12-rc1

Christoph Hellwig <[email protected]>
Revert "block: freeze the queue earlier in del_gendisk"

Jan Kara <[email protected]>
ext4: use buckets for cr 1 block scan instead of rbtree

Jan Kara <[email protected]>
ext4: use locality group preallocation for small closed files

Jan Kara <[email protected]>
ext4: make directory inode spreading reflect flexbg size

Jan Kara <[email protected]>
ext4: avoid unnecessary spreading of allocations among groups

Jan Kara <[email protected]>
ext4: make mballoc try target group first even with mb_optimize_scan

Theodore Ts'o <[email protected]>
ext4: limit the number of retries after discarding preallocations blocks

Luís Henriques <[email protected]>

    ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0

Dan Williams <[email protected]>
devdax: Fix soft-reservation memory description

Nick Desaulniers <[email protected]>
Makefile.debug: re-enable debug info for .S files

Nick Desaulniers <[email protected]>
Makefile.debug: set -g unconditional on CONFIG_DEBUG_INFO_SPLIT

Masahiro Yamada <[email protected]>
certs: make system keyring depend on built-in x509 parser

Alex Deucher <[email protected]>
drm/amdgpu: don't register a dirty callback for non-atomic

Dan Carpenter <[email protected]>
i2c: mux: harden i2c_mux_alloc() against integer overflows

Asmaa Mnebhi <[email protected]>
i2c: mlxbf: Fix frequency calculation

Asmaa Mnebhi <[email protected]>
i2c: mlxbf: prevent stack overflow in mlxbf_i2c_smbus_start_transaction()

Asmaa Mnebhi <[email protected]>
i2c: mlxbf: incorrect base address passed during io write

Uwe Kleine-König <[email protected]>
i2c: imx: If pm_runtime_get_sync() returned 1 device access is possible

Tetsuo Handa <[email protected]>
workqueue: don't skip lockdep work dependency in cancel_work_sync()

Li Jinlin <[email protected]>
fsdax: Fix infinite loop in dax_iomap_rw()

Jane Chu <[email protected]>
pmem: fix a name collision

Sergio Paracuellos <[email protected]>
gpio: mt7621: Make the irqchip immutable

Nathan Huckleberry <[email protected]>
drm/rockchip: Fix return type of cdn_dp_connector_mode_valid

Nathan Chancellor <[email protected]>
drm/amd/display: Mark dml30's UseMinimumDCFCLK() as noinline for stack usage

Nathan Chancellor <[email protected]>
drm/amd/display: Reduce number of arguments of dml31's CalculateFlipSchedule()

Nathan Chancellor <[email protected]>
drm/amd/display: Reduce number of arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport()

Yao Wang1 <[email protected]>
drm/amd/display: Limit user regamma to a valid value

Candice Li <[email protected]>
drm/amdgpu: Skip reset error status for psp v13_0_0

Alex Deucher <[email protected]>
drm/amdgpu: add HDP remap functionality to nbio 7.7

Yang Wang <[email protected]>
drm/amdgpu: change the alignment size of TMR BO to 1M

Hamza Mahfooz <[email protected]>
drm/amdgpu: use dirty framebuffer helper

Guchun Chen <[email protected]>
drm/amd/pm: disable BACO entry/exit completely on several sienna cichlid cards

Linus Walleij <[email protected]>
gpio: ixp4xx: Make irqchip immutable

Hans de Goede <[email protected]>
drm/gma500: Fix (vblank) IRQs not working after suspend/resume

Hans de Goede <[email protected]>

    drm/gma500: Fix WARN_ON(lock->magic != lock) error

Hans de Goede <[email protected]>
drm/gma500: Fix BUG: sleeping function called from invalid context errors

Vitaly Kuznetsov <[email protected]>
Drivers: hv: Never allocate anything besides framebuffer from framebuffer memory region

Rafael Mendonca <[email protected]>
block: Do not call blk_put_queue() if gendisk allocation fails

Christoph Hellwig <[email protected]>
block: call blk_mq_exit_queue from disk_release for never added disks

Christoph Hellwig <[email protected]>
blk-mq: fix error handling in __blk_mq_alloc_disk

José Roberto de Souza <[email protected]>
drm/i915/display: Fix handling of enable_psr parameter

Stefan Haberland <[email protected]>
s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup

Pali Rohár <[email protected]>
phy: marvell: phy-mvebu-a3700-comphy: Remove broken reset support

Ming Lei <[email protected]>
cgroup: cgroup_get_from_id() must check the looked-up kn is a directory

Ilpo Järvinen <[email protected]>
serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting

Ilpo Järvinen <[email protected]>
serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting

Ilpo Järvinen <[email protected]>
serial: Create uart_xmit_advance()

Lukas Wunner <[email protected]>
serial: fsl_lpuart: Reset prior to registration

Jens Axboe <[email protected]>
io_uring: ensure that cached task references are always put on exit

Hangbin Liu <[email protected]>
selftests: forwarding: add shebang for sch_red.sh

Jakub Kicinski <[email protected]>
bnxt: prevent skb UAF after handing over to PTP worker

Hangyu Hua <[email protected]>
net: sched: fix possible refcount leak in tc_new_tfilter()

Sean Anderson <[email protected]>
net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD

Jonathan Toppins <[email protected]>
bonding: fix NULL deref in bond_rr_gen_slave_id

Michael Walle <[email protected]>
net: phy: micrel: fix shared interrupt on LAN8814

Wen Gu <[email protected]>
net/smc: Stop the CLC flow if no link to map buffers on

Larysa Zaremba <[email protected]>
ice: Fix ice_xdp_xmit() when XDP TX queue number is not sufficient

Nícolas F. R. A. Prado <[email protected]>
drm/mediatek: dsi: Move mtk_dsi_stop() call back to mtk_dsi_poweroff()

Namhyung Kim <[email protected]>
perf tools: Honor namespace when synthesizing build-ids

Adrian Hunter <[email protected]>
perf kcore_copy: Do not check /proc/modules is unchanged

Lieven Hey <[email protected]>
perf jit: Include program header in ELF files

Namhyung Kim <[email protected]>
perf stat: Fix cpu map index in bperf cgroup code

Namhyung Kim <[email protected]>
perf stat: Fix BPF program section name

Marc Kleine-Budde <[email protected]>

    can: gs_usb: gs_can_open(): fix race dev->can.state condition

Dongliang Mu <[email protected]>
gpio: tqmx86: fix uninitialized variable girq

Geert Uytterhoeven <[email protected]>
net: sh_eth: Fix PHY state warning splat during system resume

Geert Uytterhoeven <[email protected]>
net: ravb: Fix PHY state warning splat during system resume

Florian Westphal <[email protected]>
netfilter: nf_ct_ftp: fix deadlock when nat rewrite is needed

Florian Westphal <[email protected]>
netfilter: ebtables: fix memory leak when blob is malformed

Tetsuo Handa <[email protected]>
netfilter: nf_tables: fix percpu memory leak at nf_tables_addchain()

Tetsuo Handa <[email protected]>
netfilter: nf_tables: fix nft_counters_enabled underflow at nf_tables_addchain()

Mateusz Palczewski <[email protected]>
ice: Fix interface being down after reset with link-down-on-close flag on

Michal Swiatkowski <[email protected]>
ice: config netdev tc before setting queues number

Vladimir Oltean <[email protected]>
net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs

Vladimir Oltean <[email protected]>
net/sched: taprio: avoid disabling offload when it was never enabled

Ido Schimmel <[email protected]>
ipv6: Fix crash when IPv6 is administratively disabled

Vladimir Oltean <[email protected]>
net: enetc: deny offload of tc-based TSN features on VF interfaces

Vladimir Oltean <[email protected]>
net: enetc: move enetc_set_psfp() out of the common enetc_set_features()

Jason A. Donenfeld <[email protected]>
wireguard: netlink: avoid variable-sized memcpy on sockaddr

Jason A. Donenfeld <[email protected]>
wireguard: ratelimiter: disable timings test by default

Íñigo Huguet <[email protected]>
sfc/siena: fix null pointer dereference in efx_hard_start_xmit

Íñigo Huguet <[email protected]>
sfc/siena: fix TX channel offset when using legacy interrupts

Alex Elder <[email protected]>
net: ipa: properly limit modem routing table use

Liang He <[email protected]>
of: mdio: Add of_node_put() when breaking out of for_each_xx

Randy Dunlap <[email protected]>
drm/hisilicon: Add depends on MMU

Shailend Chand <[email protected]>
gve: Fix GFP flags when allocing pages

Vadim Fedorenko <[email protected]>
bnxt_en: fix flags to check for supported fw version

Íñigo Huguet <[email protected]>
sfc: fix null pointer dereference in efx_hard_start_xmit

Íñigo Huguet <[email protected]>
sfc: fix TX channel offset when using legacy interrupts

Ido Schimmel <[email protected]>
netdevsim: Fix hwstats debugfs file permissions

Michal Jaron <[email protected]>
i40e: Fix set max_tx_rate when it is lower than 1 Mbps

Michal Jaron <[email protected]>
i40e: Fix VF set max MTU size

Michal Jaron <[email protected]>
iavf: Fix set max MTU size with port VLAN and jumbo frames

David Thompson <[email protected]>
mlxbf_gige: clear MDIO gateway lock after read

Norbert Zulinski <[email protected]>
iavf: Fix bad page state

Christian Lamparter <[email protected]>
um: fix default console kernel parameter

Serge Semin <[email protected]>
MIPS: Loongson32: Fix PHY-mode being left unspecified

Randy Dunlap <[email protected]>
MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko

Feng Tang <[email protected]>
mm/slab_common: fix possible double free of kmem_cache

Heiko Schocher <[email protected]>
drm/panel: simple: Fix innolux_g121i1_l01 bus_format

Benjamin Poirier <[email protected]>
net: team: Unsync device addresses on ndo_stop

Benjamin Poirier <[email protected]>
net: bonding: Unsync device addresses on ndo_stop

Benjamin Poirier <[email protected]>
net: bonding: Share lacpdu_mcast_addr definition

Sreekanth Reddy <[email protected]>
scsi: mpt3sas: Fix return value check of dma_get_required_mask()

Rafael Mendonca <[email protected]>
scsi: qla2xxx: Fix memory leak in __qlt_24xx_handle_abts()

Tim Harvey <[email protected]>
arm64: dts: imx8mp-venice-gw74xx: fix port/phy validation

Ioana Ciornei <[email protected]>
net: phy: aquantia: wait for the suspend/resume operations to finish

Horatiu Vultur <[email protected]>
ARM: dts: lan966x: Fix the interrupt number for internal PHYs

Tim Harvey <[email protected]>

    arm64: dts: imx8mp-venice-gw74xx: fix ksz9477 cpu port

Tim Harvey <[email protected]>
arm64: dts: imx8mp-venice-gw74xx: fix CAN STBY polarity

Allen-KH Cheng <[email protected]>
drm/mediatek: Fix wrong dither settings

Fabio Estevam <[email protected]>
arm64: dts: tqma8mqml: Include phy-imx8-pcie.h header

Toke Høiland-Jørgensen <[email protected]>
wifi: iwlwifi: Mark IWLMEI as broken

Ludovic Cintrat <[email protected]>
net: core: fix flow symmetric hash

Lu Wei <[email protected]>

    ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header

Brett Creeley <[email protected]>
iavf: Fix cached head and tail value for iavf_get_tx_pending

Ding Hui <[email protected]>
ice: Fix crash by keep old cfg when update TCs more than queues

Dave Ertman <[email protected]>
ice: Don't double unplug aux on peer initiated reset

Pablo Neira Ayuso <[email protected]>
netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find()

David Leadbeater <[email protected]>
netfilter: nf_conntrack_irc: Tighten matching on DCC message

Igor Ryzhov <[email protected]>
netfilter: nf_conntrack_sip: fix ct_sip_walk_headers

Philippe Schenker <[email protected]>
arm64: dts: imx8mm-verdin: extend pmic voltages

Fabio Estevam <[email protected]>
arm64: dts: rockchip: Remove 'enable-active-low' from rk3566-quartz64-a

Fabio Estevam <[email protected]>
arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma

Michael Riesch <[email protected]>
arm64: dts: rockchip: fix property for usb2 phy supply on rk3568-evb1-v10

Michael Riesch <[email protected]>
arm64: dts: rockchip: fix property for usb2 phy supply on rock-3a

Liang He <[email protected]>
dmaengine: ti: k3-udma-private: Fix refcount leak bug in of_xudma_dev_get()

Peng Fan <[email protected]>
arm64: dts: imx8ulp: add #reset-cells for pcc

Marco Felsch <[email protected]>
arm64: dts: imx8mn: remove GPU power domain reset

zain wang <[email protected]>
arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz

Marek Vasut <[email protected]>
arm64: dts: imx8mm: Reverse CPLD_Dn GPIO label mapping on MX8Menlo

AngeloGioacchino Del Regno <[email protected]>
drm/mediatek: dsi: Add atomic {destroy,duplicate}_state, reset callbacks

Jagan Teki <[email protected]>
arm64: dts: rockchip: Fix typo in lisense text for PX30.Core

Brian Norris <[email protected]>
arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob

Nicolas Frattaroli <[email protected]>
arm64: dts: rockchip: Lower sd speed on quartz64-b

Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix the asynchronous reset requests

Cristian Marussi <[email protected]>
firmware: arm_scmi: Harden accesses to the reset domains

Shigeru Yoshida <[email protected]>
batman-adv: Fix hang up with small MTU hard-interface

Will Deacon <[email protected]>
vmlinux.lds.h: CFI: Reduce alignment of jump-table to function alignment

Sergey Shtylyov <[email protected]>
arm64: topology: fix possible overflow in amu_fie_setup()

Ilkka Koskinen <[email protected]>
perf/arm-cmn: Add more bits to child node address offset field

Sean Christopherson <[email protected]>
KVM: x86: Inject #UD on emulated XSETBV if XSAVES isn't enabled

Dr. David Alan Gilbert <[email protected]>
KVM: x86: Always enable legacy FP/SSE in allowed user XFEATURES

Sean Christopherson <[email protected]>
KVM: x86: Reinstate kvm_vcpu_arch.guest_supported_xcr0

Maurizio Lombardi <[email protected]>
mm: slub: fix flush_cpu_slab()/__free_slab() invocations in task context.

Chao Yu <[email protected]>
mm/slub: fix to return errno if kmalloc() fails

Haiyang Zhang <[email protected]>
net: mana: Add rmb after checking owner bits

Marc Kleine-Budde <[email protected]>
can: flexcan: flexcan_mailbox_read() fix return value for drop = true

Peter Collingbourne <[email protected]>
kasan: call kasan_malloc() from __kmalloc_*track_caller()

Juergen Gross <[email protected]>
xen/xenbus: fix xenbus_setup_ring()

Chris Wilson <[email protected]>
drm/i915/gem: Really move i915_gem_context.link under ref protection

Janusz Krzysztofik <[email protected]>
drm/i915/gem: Flush contexts on driver release

Randy Dunlap <[email protected]>
riscv: fix RISCV_ISA_SVPBMT kconfig dependency warning

Al Viro <[email protected]>
riscv: fix a nasty sigreturn bug...

Meng Li <[email protected]>
gpiolib: cdev: Set lineevent_state::irq after IRQ register successfully

Andy Shevchenko <[email protected]>
gpio: mockup: Fix potential resource leakage when register a chip

Bartosz Golaszewski <[email protected]>
gpio: mockup: fix NULL pointer dereference when removing debugfs

Felix Fietkau <[email protected]>
wifi: mt76: fix reading current per-tid starting sequence number for aggregation

Ard Biesheuvel <[email protected]>
efi: libstub: check Shim mode using MokSBStateRT

Ard Biesheuvel <[email protected]>
efi: x86: Wipe setup_data on pure EFI boot

Gil Fine <[email protected]>
thunderbolt: Add support for Intel Maple Ridge single port controller

William Wu <[email protected]>
usb: dwc3: core: leave default DMA if the controller does not support 64-bit DMA

Johan Hovold <[email protected]>
media: flexcop-usb: fix endpoint type check

Adrian Hunter <[email protected]>
libperf evlist: Fix polling of system-wide events

Naohiro Aota <[email protected]>
btrfs: zoned: wait for extent buffer IOs before finishing a zone

Filipe Manana <[email protected]>
btrfs: fix hang during unmount when stopping a space reclaim worker

Filipe Manana <[email protected]>
btrfs: fix hang during unmount when stopping block group reclaim worker

Yuezhang Mo <[email protected]>
exfat: fix overflow for large capacity partition

Yi Liu <[email protected]>
iommu/vt-d: Check correct capability for sagaw determination

Daniel Houldsworth <[email protected]>
ALSA: hda/realtek: Add a quirk for HP OMEN 16 (8902) mute LED

Callum Osmotherly <[email protected]>
ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop

Luke D. Jones <[email protected]>
ALSA: hda/realtek: Add quirk for ASUS GA503R laptop

Luke D. Jones <[email protected]>
ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack

Luke D. Jones <[email protected]>
ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack

Takashi Iwai <[email protected]>
ALSA: hda/realtek: Re-arrange quirk table entries

Callum Osmotherly <[email protected]>
ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5570 laptop

huangwenhui <[email protected]>
ALSA: hda/realtek: Add quirk for Huawei WRT-WX9

Kai Vehmanen <[email protected]>
ALSA: hda: add Intel 5 Series / 3400 PCI DID

Mohan Kumar <[email protected]>
ALSA: hda: Fix Nvidia dp infoframe

Takashi Iwai <[email protected]>
ALSA: hda: Fix hang at HD-audio codec unbinding due to refcount saturation

Mohan Kumar <[email protected]>
ALSA: hda/tegra: set depop delay for tegra

Takashi Iwai <[email protected]>
ALSA: core: Fix double-free at snd_card_new()

Takashi Iwai <[email protected]>
Revert "ALSA: usb-audio: Split endpoint setups for hw_params and prepare"

jerry meng <[email protected]>
USB: serial: option: add Quectel RM520N

Carl Yin(殷张成) <[email protected]>

    USB: serial: option: add Quectel BG95 0x0203 composition

Alan Stern <[email protected]>
USB: core: Fix RST error in hub.c

Phil Auld <[email protected]>
drivers/base: Fix unsigned comparison to -1 in CPUMAP_FILE_MAX_BYTES

Bart Van Assche <[email protected]>
scsi: core: Fix a use-after-free

Christoph Hellwig <[email protected]>
block: simplify disk shutdown

Christoph Hellwig <[email protected]>
block: stop setting the nomerges flags in blk_cleanup_queue

Christoph Hellwig <[email protected]>
block: remove QUEUE_FLAG_DEAD

Antony Antony <[email protected]>
xfrm: fix XFRMA_LASTUSED comment

Greg Kroah-Hartman <[email protected]>
Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio"

Greg Kroah-Hartman <[email protected]>
Revert "usb: add quirks for Lenovo OneLink+ Dock"

Steve French <[email protected]>
smb3: use filemap_write_and_wait_range instead of filemap_write_and_wait

Piyush Mehta <[email protected]>
usb: gadget: udc-xilinx: replace memcpy with memcpy_toio

Jean-Francois Le Fillatre <[email protected]>
usb: add quirks for Lenovo OneLink+ Dock

David Howells <[email protected]>
smb3: fix temporary data corruption in insert range

Steve French <[email protected]>
smb3: fix temporary data corruption in collapse range

David Howells <[email protected]>
smb3: Move the flush out of smb2_copychunk_range() into its callers

Jani Nikula <[email protected]>
drm/i915/dsi: fix dual-link DSI backlight and CABC ports for display 11+

Jani Nikula <[email protected]>
drm/i915/dsi: filter invalid backlight and CABC ports

Ville Syrjälä <[email protected]>
drm/i915/bios: Split VBT data into per-panel vs. global parts

Ville Syrjälä <[email protected]>
drm/i915/bios: Split VBT parsing to global vs. panel specific parts

Ville Syrjälä <[email protected]>
drm/i915/bios: Split parse_driver_features() into two parts

Ville Syrjälä <[email protected]>
drm/i915/pps: Split pps_init_delays() into distinct parts

Ville Syrjälä <[email protected]>

    drm/i915: Extract intel_edp_fixup_vbt_bpp()

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

Diffstat:

 Makefile                                           |   4 +-
 arch/arm/boot/dts/lan966x.dtsi                     |   4 +-
 arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts  |  10 +-
 .../boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts |   1 -
 .../arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi |   1 +
 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi   |  10 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi          |   1 -
 .../boot/dts/freescale/imx8mp-venice-gw74xx.dts    |  12 +-
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi         |   3 +
 .../boot/dts/rockchip/px30-engicam-px30-core.dtsi  |   4 +-
 arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts    |   5 +
 .../boot/dts/rockchip/rk3399-gru-chromebook.dtsi   |   9 +
 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi      |   1 -
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts |   1 -
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts |   2 +-
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts   |   2 +-
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts    |   2 +-
 arch/arm64/kernel/topology.c                       |   2 +-
 arch/mips/lantiq/clk.c                             |   1 +
 arch/mips/loongson32/common/platform.c             |  16 +-
 arch/riscv/Kconfig                                 |   1 +
 arch/riscv/kernel/signal.c                         |   2 +
 arch/um/kernel/um_arch.c                           |   2 +-
 arch/x86/include/asm/kvm_host.h                    |   1 +
 arch/x86/kvm/cpuid.c                               |  11 +-
 arch/x86/kvm/emulate.c                             |   3 +
 arch/x86/kvm/x86.c                                 |  10 +-
 block/blk-core.c                                   |  43 ---
 block/blk-mq-debugfs.c                             |   8 +-
 block/blk-mq.c                                     |  43 ++-
 block/blk-sysfs.c                                  |   5 -
 block/blk.h                                        |   3 +
 block/bsg-lib.c                                    |   4 +-
 block/genhd.c                                      |  45 ++-
 certs/Kconfig                                      |   2 +-
 drivers/block/ataflop.c                            |   1 -
 drivers/block/loop.c                               |   1 -
 drivers/block/mtip32xx/mtip32xx.c                  |   2 -
 drivers/block/rnbd/rnbd-clt.c                      |   2 +-
 drivers/block/sx8.c                                |   4 +-
 drivers/block/virtio_blk.c                         |   1 -
 drivers/block/z2ram.c                              |   1 -
 drivers/cdrom/gdrom.c                              |   1 -
 drivers/dax/hmem/device.c                          |   1 +
 drivers/dma/ti/k3-udma-private.c                   |   6 +-
 drivers/firmware/arm_scmi/reset.c                  |  10 +-
 drivers/firmware/efi/libstub/secureboot.c          |   8 +-
 drivers/firmware/efi/libstub/x86-stub.c            |   7 +
 drivers/gpio/gpio-ixp4xx.c                         |  17 +-
 drivers/gpio/gpio-mockup.c                         |   6 +-
 drivers/gpio/gpio-mt7621.c                         |  21 +-
 drivers/gpio/gpio-tqmx86.c                         |   4 +-
 drivers/gpio/gpiolib-cdev.c                        |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c        |  13 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c            |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h            |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |   3 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c             |   9 +
 .../amd/display/dc/dml/dcn30/display_mode_vba_30.c |   3 +-
 .../amd/display/dc/dml/dcn31/display_mode_vba_31.c | 420 +++++----------------
 .../drm/amd/display/modules/color/color_gamma.c    |   4 +
 .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c    |  11 +
 drivers/gpu/drm/gma500/cdv_device.c                |   4 +-
 drivers/gpu/drm/gma500/gem.c                       |   4 +-
 drivers/gpu/drm/gma500/gma_display.c               |  11 +-
 drivers/gpu/drm/gma500/oaktrail_device.c           |   5 +-
 drivers/gpu/drm/gma500/power.c                     |   8 +-
 drivers/gpu/drm/gma500/psb_drv.c                   |   2 +-
 drivers/gpu/drm/gma500/psb_drv.h                   |   5 +-
 drivers/gpu/drm/gma500/psb_irq.c                   |  15 +-
 drivers/gpu/drm/gma500/psb_irq.h                   |   2 +-
 drivers/gpu/drm/hisilicon/hibmc/Kconfig            |   1 +
 drivers/gpu/drm/i915/display/g4x_dp.c              |  22 +-
 drivers/gpu/drm/i915/display/icl_dsi.c             |  18 +-
 drivers/gpu/drm/i915/display/intel_backlight.c     |  23 +-
 drivers/gpu/drm/i915/display/intel_bios.c          | 384 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_bios.h          |   4 +
 drivers/gpu/drm/i915/display/intel_ddi.c           |  22 +-
 drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c |   9 +-
 drivers/gpu/drm/i915/display/intel_display_types.h |  69 ++++
 drivers/gpu/drm/i915/display/intel_dp.c            |  40 +-
 drivers/gpu/drm/i915/display/intel_dp.h            |   2 +
 .../gpu/drm/i915/display/intel_dp_aux_backlight.c  |   6 +-
 drivers/gpu/drm/i915/display/intel_drrs.c          |   3 -
 drivers/gpu/drm/i915/display/intel_dsi.c           |   2 +-
 .../gpu/drm/i915/display/intel_dsi_dcs_backlight.c |   9 +-
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c       |  56 +--
 drivers/gpu/drm/i915/display/intel_lvds.c          |   6 +-
 drivers/gpu/drm/i915/display/intel_panel.c         |  13 +-
 drivers/gpu/drm/i915/display/intel_pps.c           |  70 +++-
 drivers/gpu/drm/i915/display/intel_psr.c           |  35 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c          |   3 +
 drivers/gpu/drm/i915/display/vlv_dsi.c             |  21 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c        |   8 +-
 drivers/gpu/drm/i915/i915_drv.h                    |  63 ----
 drivers/gpu/drm/i915/i915_gem.c                    |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c        |   2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c                 |  24 +-
 drivers/gpu/drm/panel/panel-simple.c               |   2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |   5 +-
 drivers/hv/vmbus_drv.c                             |  10 +-
 drivers/i2c/busses/i2c-imx.c                       |   2 +-
 drivers/i2c/busses/i2c-mlxbf.c                     |  68 ++--
 drivers/i2c/i2c-mux.c                              |   5 +-
 drivers/iommu/intel/iommu.c                        |   2 +-
 drivers/media/usb/b2c2/flexcop-usb.c               |   2 +-
 drivers/memstick/core/ms_block.c                   |   1 -
 drivers/memstick/core/mspro_block.c                |   1 -
 drivers/mmc/core/block.c                           |   1 -
 drivers/mmc/core/queue.c                           |   1 -
 drivers/net/bonding/bond_3ad.c                     |   5 +-
 drivers/net/bonding/bond_main.c                    |  72 ++--
 drivers/net/can/flexcan/flexcan-core.c             |  10 +-
 drivers/net/can/usb/gs_usb.c                       |   4 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |  10 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c      |   4 +-
 drivers/net/ethernet/freescale/enetc/Makefile      |   1 -
 drivers/net/ethernet/freescale/enetc/enetc.c       |  53 +--
 drivers/net/ethernet/freescale/enetc/enetc.h       |  12 +-
 drivers/net/ethernet/freescale/enetc/enetc_pf.c    |  32 +-
 drivers/net/ethernet/freescale/enetc/enetc_qos.c   |  23 ++
 drivers/net/ethernet/freescale/enetc/enetc_vf.c    |  17 +-
 drivers/net/ethernet/google/gve/gve_rx_dqo.c       |   2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c        |  32 +-
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |  20 +
 drivers/net/ethernet/intel/iavf/iavf_txrx.c        |   9 +-
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c    |   7 +-
 drivers/net/ethernet/intel/ice/ice_lib.c           |  42 ++-
 drivers/net/ethernet/intel/ice/ice_main.c          |  25 +-
 drivers/net/ethernet/intel/ice/ice_txrx.c          |   5 +-
 .../ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c |   6 +
 drivers/net/ethernet/microsoft/mana/gdma_main.c    |  10 +
 drivers/net/ethernet/renesas/ravb_main.c           |   2 +
 drivers/net/ethernet/renesas/sh_eth.c              |   2 +
 drivers/net/ethernet/sfc/efx_channels.c            |   2 +-
 drivers/net/ethernet/sfc/siena/efx_channels.c      |   2 +-
 drivers/net/ethernet/sfc/siena/tx.c                |   2 +-
 drivers/net/ethernet/sfc/tx.c                      |   2 +-
 drivers/net/ethernet/sun/sunhme.c                  |   4 +-
 drivers/net/ipa/ipa_qmi.c                          |   8 +-
 drivers/net/ipa/ipa_qmi_msg.c                      |   8 +-
 drivers/net/ipa/ipa_qmi_msg.h                      |  37 +-
 drivers/net/ipa/ipa_table.c                        |   2 -
 drivers/net/ipa/ipa_table.h                        |   3 +
 drivers/net/ipvlan/ipvlan_core.c                   |   6 +-
 drivers/net/mdio/of_mdio.c                         |   1 +
 drivers/net/netdevsim/hwstats.c                    |   6 +-
 drivers/net/phy/aquantia_main.c                    |  53 ++-
 drivers/net/phy/micrel.c                           |  18 +-
 drivers/net/team/team.c                            |  24 +-
 drivers/net/wireguard/netlink.c                    |  13 +-
 drivers/net/wireguard/selftest/ratelimiter.c       |  25 +-
 drivers/net/wireless/intel/iwlwifi/Kconfig         |   1 +
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c    |   2 +-
 drivers/nvdimm/pmem.c                              |   6 +-
 drivers/nvme/host/apple.c                          |   2 +-
 drivers/nvme/host/core.c                           |   1 -
 drivers/nvme/host/fc.c                             |  12 +-
 drivers/nvme/host/pci.c                            |   2 +-
 drivers/nvme/host/rdma.c                           |  12 +-
 drivers/nvme/host/tcp.c                            |  12 +-
 drivers/nvme/target/loop.c                         |  12 +-
 drivers/perf/arm-cmn.c                             |   2 +-
 drivers/phy/marvell/phy-mvebu-a3700-comphy.c       |  87 +----
 drivers/s390/block/dasd.c                          |   2 +-
 drivers/s390/block/dasd_alias.c                    |   9 +-
 drivers/s390/block/dasd_genhd.c                    |   4 +-
 drivers/scsi/hosts.c                               |  16 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c                |   2 +-
 drivers/scsi/qla2xxx/qla_target.c                  |   4 +-
 drivers/scsi/scsi_lib.c                            |  12 +-
 drivers/scsi/scsi_priv.h                           |   2 +-
 drivers/scsi/scsi_scan.c                           |   1 +
 drivers/scsi/scsi_sysfs.c                          |   3 +-
 drivers/scsi/sd.c                                  |   4 +-
 drivers/scsi/sr.c                                  |   4 +-
 drivers/thunderbolt/icm.c                          |   1 +
 drivers/thunderbolt/nhi.h                          |   1 +
 drivers/tty/serial/fsl_lpuart.c                    |   9 +-
 drivers/tty/serial/serial-tegra.c                  |   5 +-
 drivers/tty/serial/tegra-tcu.c                     |   2 +-
 drivers/ufs/core/ufshcd.c                          |   4 +-
 drivers/usb/core/hub.c                             |   2 +-
 drivers/usb/dwc3/core.c                            |  13 +-
 drivers/usb/serial/option.c                        |   6 +
 drivers/xen/xenbus/xenbus_client.c                 |   9 +-
 fs/btrfs/disk-io.c                                 |  42 ++-
 fs/btrfs/zoned.c                                   |  40 +-
 fs/cifs/cifsfs.c                                   |   6 +
 fs/cifs/smb2ops.c                                  |  69 ++--
 fs/dax.c                                           |   3 +
 fs/exfat/fatent.c                                  |   3 +-
 fs/ext4/ext4.h                                     |  10 +-
 fs/ext4/extents.c                                  |   4 +
 fs/ext4/ialloc.c                                   |   2 +-
 fs/ext4/mballoc.c                                  | 318 +++++++---------
 fs/ext4/mballoc.h                                  |   1 -
 include/asm-generic/vmlinux.lds.h                  |   3 +-
 include/linux/blk-mq.h                             |   3 +
 include/linux/blkdev.h                             |   6 +-
 include/linux/cpumask.h                            |   5 +-
 include/linux/serial_core.h                        |  17 +
 include/net/bond_3ad.h                             |   2 -
 include/net/bonding.h                              |   3 +
 include/scsi/scsi_host.h                           |   2 +
 include/uapi/linux/xfrm.h                          |   2 +-
 io_uring/io_uring.c                                |   3 +
 kernel/cgroup/cgroup.c                             |   5 +-
 kernel/workqueue.c                                 |   6 +-
 lib/Kconfig.debug                                  |   4 +-
 mm/slab_common.c                                   |   5 +-
 mm/slub.c                                          |  18 +-
 net/batman-adv/hard-interface.c                    |   4 +
 net/bridge/netfilter/ebtables.c                    |   4 +-
 net/core/flow_dissector.c                          |   5 +-
 net/ipv6/af_inet6.c                                |   4 +-
 net/netfilter/nf_conntrack_ftp.c                   |   6 +-
 net/netfilter/nf_conntrack_irc.c                   |  34 +-
 net/netfilter/nf_conntrack_sip.c                   |   4 +-
 net/netfilter/nf_tables_api.c                      |   8 +-
 net/netfilter/nfnetlink_osf.c                      |   4 +-
 net/sched/cls_api.c                                |   1 +
 net/sched/sch_taprio.c                             |  18 +-
 net/smc/smc_core.c                                 |   5 +-
 scripts/Makefile.debug                             |  21 +-
 sound/core/init.c                                  |  10 +-
 sound/pci/hda/hda_bind.c                           |   4 +-
 sound/pci/hda/hda_intel.c                          |   2 +
 sound/pci/hda/patch_hdmi.c                         |  24 +-
 sound/pci/hda/patch_realtek.c                      |  33 +-
 sound/usb/endpoint.c                               |  23 +-
 sound/usb/endpoint.h                               |   6 +-
 sound/usb/pcm.c                                    |  14 +-
 tools/lib/perf/evlist.c                            |   5 +-
 tools/perf/util/bpf_counter_cgroup.c               |   4 +-
 tools/perf/util/bpf_skel/bperf_cgroup.bpf.c        |   2 +-
 tools/perf/util/genelf.c                           |  14 +
 tools/perf/util/genelf.h                           |   4 +
 tools/perf/util/symbol-elf.c                       |   7 +-
 tools/perf/util/synthetic-events.c                 |  17 +-
 tools/testing/selftests/net/forwarding/sch_red.sh  |   1 +
 241 files changed, 2013 insertions(+), 1656 deletions(-)
author maintainer
#1 lore raw

PATCH 1/207 drm/i915: Extract intel_edp_fixup_vbt_bpp()

From: Ville Syrjälä <[email protected]>

[ Upstream commit 822e5ae701af2964c5808b6ade1d6f3b1eaec967 ]

We have the same "override eDP VBT bpp with the current bpp" code duplciated in two places. Extract it to a helper function.

TODO: Having this in .get_config() is pretty ugly. Should probably try to move it somewhere else (setup_hw_state()/etc.)...

Stable-dep-of: 607f41768a1e ("drm/i915/dsi: filter invalid backlight and CABC ports")

---
 drivers/gpu/drm/i915/display/g4x_dp.c    | 22 ++-------------------
 drivers/gpu/drm/i915/display/intel_ddi.c | 22 ++-------------------
 drivers/gpu/drm/i915/display/intel_dp.c  | 25 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h  |  1 +
 4 files changed, 30 insertions(+), 40 deletions(-)
drivers/gpu/drm/i915/display/g4x_dp.c +2 -20
index 5a957acebfd6..82ad8fe7440c 100644
@@ -395,26 +395,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 		intel_dotclock_calculate(pipe_config->port_clock,
 					 &pipe_config->dp_m_n);
 
-	if (intel_dp_is_edp(intel_dp) && dev_priv->vbt.edp.bpp &&
-	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
-		/*
-		 * This is a big fat ugly hack.
-		 *
-		 * Some machines in UEFI boot mode provide us a VBT that has 18
-		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
-		 * unknown we fail to light up. Yet the same BIOS boots up with
-		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
-		 * max, not what it tells us to use.
-		 *
-		 * Note: This will still be broken if the eDP panel is not lit
-		 * up by the BIOS, and thus we can't get the mode at module
-		 * load.
-		 */
-		drm_dbg_kms(&dev_priv->drm,
-			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
-		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
-	}
+	if (intel_dp_is_edp(intel_dp))
+		intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp);
 }
 
 static void
drivers/gpu/drm/i915/display/intel_ddi.c +2 -20
index 9e6fa59eabba..333871cf3a2c 100644
@@ -3433,26 +3433,8 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
 
-	if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
-	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
-		/*
-		 * This is a big fat ugly hack.
-		 *
-		 * Some machines in UEFI boot mode provide us a VBT that has 18
-		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
-		 * unknown we fail to light up. Yet the same BIOS boots up with
-		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
-		 * max, not what it tells us to use.
-		 *
-		 * Note: This will still be broken if the eDP panel is not lit
-		 * up by the BIOS, and thus we can't get the mode at module
-		 * load.
-		 */
-		drm_dbg_kms(&dev_priv->drm,
-			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
-		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
-	}
+	if (encoder->type == INTEL_OUTPUT_EDP)
+		intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp);
 
 	ddi_dotclock_get(pipe_config);
 
drivers/gpu/drm/i915/display/intel_dp.c +25 -0
index fe8b6b72970a..affc820bf8d0 100644
@@ -2737,6 +2737,31 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
 		    DRM_MODE_ARG(mode));
 }
 
+void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	if (dev_priv->vbt.edp.bpp && pipe_bpp > dev_priv->vbt.edp.bpp) {
+		/*
+		 * This is a big fat ugly hack.
+		 *
+		 * Some machines in UEFI boot mode provide us a VBT that has 18
+		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
+		 * unknown we fail to light up. Yet the same BIOS boots up with
+		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
+		 * max, not what it tells us to use.
+		 *
+		 * Note: This will still be broken if the eDP panel is not lit
+		 * up by the BIOS, and thus we can't get the mode at module
+		 * load.
+		 */
+		drm_dbg_kms(&dev_priv->drm,
+			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
+			    pipe_bpp, dev_priv->vbt.edp.bpp);
+		dev_priv->vbt.edp.bpp = pipe_bpp;
+	}
+}
+
 static void intel_edp_mso_init(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
drivers/gpu/drm/i915/display/intel_dp.h +1 -0
index d457e17bdc57..e794d910df56 100644
@@ -63,6 +63,7 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port,
 void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state);
 void intel_edp_backlight_off(const struct drm_connector_state *conn_state);
+void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
 void intel_dp_mst_suspend(struct drm_i915_private *dev_priv);
 void intel_dp_mst_resume(struct drm_i915_private *dev_priv);
 int intel_dp_max_link_rate(struct intel_dp *intel_dp);
Signature · 1 line
2.35.1
author maintainer
#2 lore raw

PATCH 2/207 drm/i915/pps: Split pps_init_delays() into distinct parts

In reply to Greg Kroah-Hartman

From: Ville Syrjälä <[email protected]>

[ Upstream commit 75bd0d5e4eadb9ce3e9b6fb71971b6e87c38799e ]

Split each of the hw/vbt/spec PPS delay initialization into separate functions to make the whole thing less cluttered.

Stable-dep-of: 607f41768a1e ("drm/i915/dsi: filter invalid backlight and CABC ports")

---
 drivers/gpu/drm/i915/display/intel_pps.c | 66 +++++++++++++++++-------
 1 file changed, 48 insertions(+), 18 deletions(-)
drivers/gpu/drm/i915/display/intel_pps.c +48 -18
index 5a598dd06039..5b72c892a6f2 100644
@@ -1159,53 +1159,83 @@ intel_pps_verify_state(struct intel_dp *intel_dp)
 	}
 }
 
-static void pps_init_delays(struct intel_dp *intel_dp)
+static void pps_init_delays_cur(struct intel_dp *intel_dp,
+				struct edp_power_seq *cur)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct edp_power_seq cur, vbt, spec,
-		*final = &intel_dp->pps.pps_delays;
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
-	/* already initialized? */
-	if (final->t11_t12 != 0)
-		return;
+	intel_pps_readout_hw_state(intel_dp, cur);
+
+	intel_pps_dump_state(intel_dp, "cur", cur);
+}
 
-	intel_pps_readout_hw_state(intel_dp, &cur);
+static void pps_init_delays_vbt(struct intel_dp *intel_dp,
+				struct edp_power_seq *vbt)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	intel_pps_dump_state(intel_dp, "cur", &cur);
+	*vbt = dev_priv->vbt.edp.pps;
 
-	vbt = dev_priv->vbt.edp.pps;
 	/* On Toshiba Satellite P50-C-18C system the VBT T12 delay
 	 * of 500ms appears to be too short. Ocassionally the panel
 	 * just fails to power back on. Increasing the delay to 800ms
 	 * seems sufficient to avoid this problem.
 	 */
 	if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) {
-		vbt.t11_t12 = max_t(u16, vbt.t11_t12, 1300 * 10);
+		vbt->t11_t12 = max_t(u16, vbt->t11_t12, 1300 * 10);
 		drm_dbg_kms(&dev_priv->drm,
 			    "Increasing T12 panel delay as per the quirk to %d\n",
-			    vbt.t11_t12);
+			    vbt->t11_t12);
 	}
+
 	/* T11_T12 delay is special and actually in units of 100ms, but zero
 	 * based in the hw (so we need to add 100 ms). But the sw vbt
 	 * table multiplies it with 1000 to make it in units of 100usec,
 	 * too. */
-	vbt.t11_t12 += 100 * 10;
+	vbt->t11_t12 += 100 * 10;
+
+	intel_pps_dump_state(intel_dp, "vbt", vbt);
+}
+
+static void pps_init_delays_spec(struct intel_dp *intel_dp,
+				 struct edp_power_seq *spec)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
 
 	/* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
 	 * our hw here, which are all in 100usec. */
-	spec.t1_t3 = 210 * 10;
-	spec.t8 = 50 * 10; /* no limit for t8, use t7 instead */
-	spec.t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */
-	spec.t10 = 500 * 10;
+	spec->t1_t3 = 210 * 10;
+	spec->t8 = 50 * 10; /* no limit for t8, use t7 instead */
+	spec->t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */
+	spec->t10 = 500 * 10;
 	/* This one is special and actually in units of 100ms, but zero
 	 * based in the hw (so we need to add 100 ms). But the sw vbt
 	 * table multiplies it with 1000 to make it in units of 100usec,
 	 * too. */
-	spec.t11_t12 = (510 + 100) * 10;
+	spec->t11_t12 = (510 + 100) * 10;
+
+	intel_pps_dump_state(intel_dp, "spec", spec);
+}
+
+static void pps_init_delays(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct edp_power_seq cur, vbt, spec,
+		*final = &intel_dp->pps.pps_delays;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	/* already initialized? */
+	if (final->t11_t12 != 0)
+		return;
 
-	intel_pps_dump_state(intel_dp, "vbt", &vbt);
+	pps_init_delays_cur(intel_dp, &cur);
+	pps_init_delays_vbt(intel_dp, &vbt);
+	pps_init_delays_spec(intel_dp, &spec);
 
 	/* Use the max of the register settings and vbt. If both are
 	 * unset, fall back to the spec limits. */
Signature · 1 line
2.35.1
author maintainer
#3 lore raw

PATCH 3/207 drm/i915/bios: Split parse_driver_features() into two parts

In reply to Greg Kroah-Hartman

From: Ville Syrjälä <[email protected]>

[ Upstream commit c3fbcf60bc74b630967f291f47f0d9d0de6fcea7 ]

We use the "driver features" block for two different kinds of data: global data, and per panel data. Split the function into two parts along that line so that we can start doing the parsing in two different locations.

Stable-dep-of: 607f41768a1e ("drm/i915/dsi: filter invalid backlight and CABC ports")

---
 drivers/gpu/drm/i915/display/intel_bios.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/i915/display/intel_bios.c +11 -0
index 91caf4523b34..5ceabc380808 100644
@@ -1188,6 +1188,16 @@ parse_driver_features(struct drm_i915_private *i915)
 		    driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS)
 			i915->vbt.int_lvds_support = 0;
 	}
+}
+
+static void
+parse_panel_driver_features(struct drm_i915_private *i915)
+{
+	const struct bdb_driver_features *driver;
+
+	driver = find_section(i915, BDB_DRIVER_FEATURES);
+	if (!driver)
+		return;
 
 	if (i915->vbt.version < 228) {
 		drm_dbg_kms(&i915->drm, "DRRS State Enabled:%d\n",
@@ -2965,6 +2975,7 @@ void intel_bios_init(struct drm_i915_private *i915)
 	parse_lfp_backlight(i915);
 	parse_sdvo_panel_data(i915);
 	parse_driver_features(i915);
+	parse_panel_driver_features(i915);
 	parse_power_conservation_features(i915);
 	parse_edp(i915);
 	parse_psr(i915);
Signature · 1 line
2.35.1
author maintainer
#4 lore raw

PATCH 4/207 drm/i915/bios: Split VBT parsing to global vs. panel specific parts

In reply to Greg Kroah-Hartman

From: Ville Syrjälä <[email protected]>

[ Upstream commit c2fdb424d32204faf5be29d55f0086b611c94e38 ]

Parsing the panel specific data (anything that depends on panel_type) from VBT is currently happening too early. Split the whole thing into global vs. panel specific parts so that we can start doing the panel specific parsing at a later time.

v2: Clarify that this is about panel_type (Jani)
Split out the leak checks (Jani)

Stable-dep-of: 607f41768a1e ("drm/i915/dsi: filter invalid backlight and CABC ports")

---
 drivers/gpu/drm/i915/display/intel_bios.c    | 26 +++++++++++---------
 drivers/gpu/drm/i915/display/intel_bios.h    |  1 +
 drivers/gpu/drm/i915/display/intel_display.c |  1 +
 3 files changed, 17 insertions(+), 11 deletions(-)
drivers/gpu/drm/i915/display/intel_bios.c +15 -11
index 5ceabc380808..d5cae64b916b 100644
@@ -2969,18 +2969,7 @@ void intel_bios_init(struct drm_i915_private *i915)
 	/* Grab useful general definitions */
 	parse_general_features(i915);
 	parse_general_definitions(i915);
-	parse_panel_options(i915);
-	parse_generic_dtd(i915);
-	parse_lfp_data(i915);
-	parse_lfp_backlight(i915);
-	parse_sdvo_panel_data(i915);
 	parse_driver_features(i915);
-	parse_panel_driver_features(i915);
-	parse_power_conservation_features(i915);
-	parse_edp(i915);
-	parse_psr(i915);
-	parse_mipi_config(i915);
-	parse_mipi_sequence(i915);
 
 	/* Depends on child device list */
 	parse_compression_parameters(i915);
@@ -2999,6 +2988,21 @@ void intel_bios_init(struct drm_i915_private *i915)
 	kfree(oprom_vbt);
 }
 
+void intel_bios_init_panel(struct drm_i915_private *i915)
+{
+	parse_panel_options(i915);
+	parse_generic_dtd(i915);
+	parse_lfp_data(i915);
+	parse_lfp_backlight(i915);
+	parse_sdvo_panel_data(i915);
+	parse_panel_driver_features(i915);
+	parse_power_conservation_features(i915);
+	parse_edp(i915);
+	parse_psr(i915);
+	parse_mipi_config(i915);
+	parse_mipi_sequence(i915);
+}
+
 /**
  * intel_bios_driver_remove - Free any resources allocated by intel_bios_init()
  * @i915: i915 device instance
drivers/gpu/drm/i915/display/intel_bios.h +1 -0
index 4709c4d29805..c744d75fa435 100644
@@ -230,6 +230,7 @@ struct mipi_pps_data {
 } __packed;
 
 void intel_bios_init(struct drm_i915_private *dev_priv);
+void intel_bios_init_panel(struct drm_i915_private *dev_priv);
 void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
drivers/gpu/drm/i915/display/intel_display.c +1 -0
index 806d50b302ab..e384db157f34 100644
@@ -9580,6 +9580,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
 	}
 
 	intel_bios_init(i915);
+	intel_bios_init_panel(i915);
 
 	ret = intel_vga_register(i915);
 	if (ret)
Signature · 1 line
2.35.1
author maintainer
#5 lore raw

PATCH 5/207 drm/i915/bios: Split VBT data into per-panel vs. global parts

In reply to Greg Kroah-Hartman

From: Ville Syrjälä <[email protected]>

[ Upstream commit 3cf050762534cc268a02793ec00240f81c6e2229 ]

Move the panel specific VBT parsing to happen during the output probing stage. Needs to be done because the VBT parsing will need to look at the EDID to determine the correct panel_type on some machines.

We split the parsed VBT data (i915->vbt) along the same boundary. For the moment we just hoist all the panel specific stuff into connector->panel.vbt since that seems like the most convenient place for eg. the backlight code.

Note that we simply drop the drrs type check from intel_drrs_frontbuffer_update() since that operates on the whole device rather than a specific connector/encoder. But the check was just a micro optimization so removing it doesn't actually mattter for correctness.

TODO: Lot's of cleanup to be done in the future. Eg. most of the DSI stuff could probably be eliminated entirely and just parsed on demand during DSI init.

v2: Note the intel_drrs_frontbuffer_update() change

Stable-dep-of: 607f41768a1e ("drm/i915/dsi: filter invalid backlight and CABC ports")

---
 drivers/gpu/drm/i915/display/icl_dsi.c        |  11 +-
 .../gpu/drm/i915/display/intel_backlight.c    |  23 +-
 drivers/gpu/drm/i915/display/intel_bios.c     | 371 ++++++++++--------
 drivers/gpu/drm/i915/display/intel_bios.h     |   5 +-
 .../drm/i915/display/intel_ddi_buf_trans.c    |   9 +-
 drivers/gpu/drm/i915/display/intel_display.c  |   1 -
 .../drm/i915/display/intel_display_types.h    |  69 ++++
 drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
 drivers/gpu/drm/i915/display/intel_dp.h       |   1 +
 .../drm/i915/display/intel_dp_aux_backlight.c |   6 +-
 drivers/gpu/drm/i915/display/intel_drrs.c     |   3 -
 drivers/gpu/drm/i915/display/intel_dsi.c      |   2 +-
 .../i915/display/intel_dsi_dcs_backlight.c    |   9 +-
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c  |  56 +--
 drivers/gpu/drm/i915/display/intel_lvds.c     |   6 +-
 drivers/gpu/drm/i915/display/intel_panel.c    |  13 +-
 drivers/gpu/drm/i915/display/intel_pps.c      |   6 +-
 drivers/gpu/drm/i915/display/intel_psr.c      |  30 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c     |   3 +
 drivers/gpu/drm/i915/display/vlv_dsi.c        |  14 +-
 drivers/gpu/drm/i915/i915_drv.h               |  63 ---
 21 files changed, 391 insertions(+), 331 deletions(-)
drivers/gpu/drm/i915/display/icl_dsi.c +7 -4
index 5508ebb9eb43..5c46acb46516 100644
@@ -1864,7 +1864,8 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
 {
 	struct drm_device *dev = intel_dsi->base.base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
+	struct intel_connector *connector = intel_dsi->attached_connector;
+	struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
 	u32 tlpx_ns;
 	u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
 	u32 ths_prepare_ns, tclk_trail_ns;
@@ -2051,6 +2052,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	/* attach connector to encoder */
 	intel_connector_attach_encoder(intel_connector, encoder);
 
+	intel_bios_init_panel(dev_priv, &intel_connector->panel);
+
 	mutex_lock(&dev->mode_config.mutex);
 	intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
 	mutex_unlock(&dev->mode_config.mutex);
@@ -2064,13 +2067,13 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 
 	intel_backlight_setup(intel_connector, INVALID_PIPE);
 
-	if (dev_priv->vbt.dsi.config->dual_link)
+	if (intel_connector->panel.vbt.dsi.config->dual_link)
 		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
 	else
 		intel_dsi->ports = BIT(port);
 
-	intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
-	intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
+	intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
+	intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
 
 	for_each_dsi_port(port, intel_dsi->ports) {
 		struct intel_dsi_host *host;
drivers/gpu/drm/i915/display/intel_backlight.c +12 -11
index 3e200a2e4ba2..5182bb66bd28 100644
@@ -1158,9 +1158,10 @@ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
 }
 
-static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
+static u16 get_vbt_pwm_freq(struct intel_connector *connector)
 {
-	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u16 pwm_freq_hz = connector->panel.vbt.backlight.pwm_freq_hz;
 
 	if (pwm_freq_hz) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -1180,7 +1181,7 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
+	u16 pwm_freq_hz = get_vbt_pwm_freq(connector);
 	u32 pwm;
 
 	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
@@ -1217,11 +1218,11 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector)
 	 * against this by letting the minimum be at most (arbitrarily chosen)
 	 * 25% of the max.
 	 */
-	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
-	if (min != dev_priv->vbt.backlight.min_brightness) {
+	min = clamp_t(int, connector->panel.vbt.backlight.min_brightness, 0, 64);
+	if (min != connector->panel.vbt.backlight.min_brightness) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "clamping VBT min backlight %d/255 to %d/255\n",
-			    dev_priv->vbt.backlight.min_brightness, min);
+			    connector->panel.vbt.backlight.min_brightness, min);
 	}
 
 	/* vbt value is a coefficient in range [0..255] */
@@ -1410,7 +1411,7 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
 	struct intel_panel *panel = &connector->panel;
 	u32 pwm_ctl, val;
 
-	panel->backlight.controller = dev_priv->vbt.backlight.controller;
+	panel->backlight.controller = connector->panel.vbt.backlight.controller;
 
 	pwm_ctl = intel_de_read(dev_priv,
 				BXT_BLC_PWM_CTL(panel->backlight.controller));
@@ -1483,7 +1484,7 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
 	u32 level;
 
 	/* Get the right PWM chip for DSI backlight according to VBT */
-	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
+	if (connector->panel.vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
 		panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
 		desc = "PMIC";
 	} else {
@@ -1512,11 +1513,11 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
 
 		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
 			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
-			    get_vbt_pwm_freq(dev_priv), level);
+			    get_vbt_pwm_freq(connector), level);
 	} else {
 		/* Set period from VBT frequency, leave other settings at 0. */
 		panel->backlight.pwm_state.period =
-			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
+			NSEC_PER_SEC / get_vbt_pwm_freq(connector);
 	}
 
 	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
@@ -1601,7 +1602,7 @@ int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe)
 	struct intel_panel *panel = &connector->panel;
 	int ret;
 
-	if (!dev_priv->vbt.backlight.present) {
+	if (!connector->panel.vbt.backlight.present) {
 		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
 			drm_dbg_kms(&dev_priv->drm,
 				    "no backlight present per VBT, but present per quirk\n");
drivers/gpu/drm/i915/display/intel_bios.c +197 -174

853 lines not on this page · raw message

drivers/gpu/drm/i915/display/intel_bios.h +4 -1
index c744d75fa435..86129f015718 100644
@@ -36,6 +36,7 @@ struct drm_i915_private;
 struct intel_bios_encoder_data;
 struct intel_crtc_state;
 struct intel_encoder;
+struct intel_panel;
 enum port;
 
 enum intel_backlight_type {
@@ -230,7 +231,9 @@ struct mipi_pps_data {
 } __packed;
 
 void intel_bios_init(struct drm_i915_private *dev_priv);
-void intel_bios_init_panel(struct drm_i915_private *dev_priv);
+void intel_bios_init_panel(struct drm_i915_private *dev_priv,
+			   struct intel_panel *panel);
+void intel_bios_fini_panel(struct intel_panel *panel);
 void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +5 -4
index 85f58dd3df72..b490acd0ab69 100644
@@ -1062,17 +1062,18 @@ bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table)
 
 static bool use_edp_hobl(struct intel_encoder *encoder)
 {
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_connector *connector = intel_dp->attached_connector;
 
-	return i915->vbt.edp.hobl && !intel_dp->hobl_failed;
+	return connector->panel.vbt.edp.hobl && !intel_dp->hobl_failed;
 }
 
 static bool use_edp_low_vswing(struct intel_encoder *encoder)
 {
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_connector *connector = intel_dp->attached_connector;
 
-	return i915->vbt.edp.low_vswing;
+	return connector->panel.vbt.edp.low_vswing;
 }
 
 static const struct intel_ddi_buf_trans *
drivers/gpu/drm/i915/display/intel_display.c +0 -1
index e384db157f34..806d50b302ab 100644
@@ -9580,7 +9580,6 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
 	}
 
 	intel_bios_init(i915);
-	intel_bios_init_panel(i915);
 
 	ret = intel_vga_register(i915);
 	if (ret)
drivers/gpu/drm/i915/display/intel_display_types.h +69 -0

81 lines not on this page · raw message

drivers/gpu/drm/i915/display/intel_dp.c +13 -8
index affc820bf8d0..0efec6023fbe 100644
@@ -1246,11 +1246,12 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,
 	if (intel_dp_is_edp(intel_dp)) {
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
 		if (intel_connector->base.display_info.bpc == 0 &&
-		    dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) {
+		    intel_connector->panel.vbt.edp.bpp &&
+		    intel_connector->panel.vbt.edp.bpp < bpp) {
 			drm_dbg_kms(&dev_priv->drm,
 				    "clamping bpp for eDP panel to BIOS-provided %i\n",
-				    dev_priv->vbt.edp.bpp);
-			bpp = dev_priv->vbt.edp.bpp;
+				    intel_connector->panel.vbt.edp.bpp);
+			bpp = intel_connector->panel.vbt.edp.bpp;
 		}
 	}
 
@@ -1907,7 +1908,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
 	}
 
 	if (IS_IRONLAKE(i915) || IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915))
-		pipe_config->msa_timing_delay = i915->vbt.edp.drrs_msa_timing_delay;
+		pipe_config->msa_timing_delay = connector->panel.vbt.edp.drrs_msa_timing_delay;
 
 	pipe_config->has_drrs = true;
 
@@ -2740,8 +2741,10 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
 void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_connector *connector = intel_dp->attached_connector;
 
-	if (dev_priv->vbt.edp.bpp && pipe_bpp > dev_priv->vbt.edp.bpp) {
+	if (connector->panel.vbt.edp.bpp && pipe_bpp > connector->panel.vbt.edp.bpp) {
 		/*
 		 * This is a big fat ugly hack.
 		 *
@@ -2757,8 +2760,8 @@ void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp)
 		 */
 		drm_dbg_kms(&dev_priv->drm,
 			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			    pipe_bpp, dev_priv->vbt.edp.bpp);
-		dev_priv->vbt.edp.bpp = pipe_bpp;
+			    pipe_bpp, connector->panel.vbt.edp.bpp);
+		connector->panel.vbt.edp.bpp = pipe_bpp;
 	}
 }
 
@@ -5237,8 +5240,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	}
 	intel_connector->edid = edid;
 
+	intel_bios_init_panel(dev_priv, &intel_connector->panel);
+
 	intel_panel_add_edid_fixed_modes(intel_connector,
-					 dev_priv->vbt.drrs_type != DRRS_TYPE_NONE);
+					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
 
 	/* MSO requires information from the EDID */
 	intel_edp_mso_init(intel_dp);
drivers/gpu/drm/i915/display/intel_dp.h +1 -0
index e794d910df56..a54902c713a3 100644
@@ -29,6 +29,7 @@ struct link_config_limits {
 	int min_bpp, max_bpp;
 };
 
+void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
 void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
 				       struct intel_crtc_state *pipe_config,
 				       struct link_config_limits *limits);
drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +3 -3
index fb6cf30ee628..c92d5bb2326a 100644
@@ -370,7 +370,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
 	int ret;
 
 	ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
-				     i915->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
+				     panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
 				     &current_level, &current_mode);
 	if (ret < 0)
 		return ret;
@@ -454,7 +454,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
 	case INTEL_DP_AUX_BACKLIGHT_OFF:
 		return -ENODEV;
 	case INTEL_DP_AUX_BACKLIGHT_AUTO:
-		switch (i915->vbt.backlight.type) {
+		switch (panel->vbt.backlight.type) {
 		case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
 			try_vesa_interface = true;
 			break;
@@ -466,7 +466,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
 		}
 		break;
 	case INTEL_DP_AUX_BACKLIGHT_ON:
-		if (i915->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
+		if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
 			try_intel_interface = true;
 
 		try_vesa_interface = true;
drivers/gpu/drm/i915/display/intel_drrs.c +0 -3
index 166caf293f7b..7da4a9cbe4ba 100644
@@ -217,9 +217,6 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
 {
 	struct intel_crtc *crtc;
 
-	if (dev_priv->vbt.drrs_type != DRRS_TYPE_SEAMLESS)
-		return;
-
 	for_each_intel_crtc(&dev_priv->drm, crtc) {
 		unsigned int frontbuffer_bits;
 
drivers/gpu/drm/i915/display/intel_dsi.c +1 -1
index 389a8c24cdc1..35e121cd226c 100644
@@ -102,7 +102,7 @@ intel_dsi_get_panel_orientation(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	enum drm_panel_orientation orientation;
 
-	orientation = dev_priv->vbt.dsi.orientation;
+	orientation = connector->panel.vbt.dsi.orientation;
 	if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
 		return orientation;
 
drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +3 -6
index 7d234429e71e..1bc7118c56a2 100644
@@ -160,12 +160,10 @@ static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state,
 static int dcs_setup_backlight(struct intel_connector *connector,
 			       enum pipe unused)
 {
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_panel *panel = &connector->panel;
 
-	if (dev_priv->vbt.backlight.brightness_precision_bits > 8)
-		panel->backlight.max = (1 << dev_priv->vbt.backlight.brightness_precision_bits) - 1;
+	if (panel->vbt.backlight.brightness_precision_bits > 8)
+		panel->backlight.max = (1 << panel->vbt.backlight.brightness_precision_bits) - 1;
 	else
 		panel->backlight.max = PANEL_PWM_MAX_VALUE;
 
@@ -185,11 +183,10 @@ static const struct intel_panel_bl_funcs dcs_bl_funcs = {
 int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
 {
 	struct drm_device *dev = intel_connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_encoder *encoder = intel_attached_encoder(intel_connector);
 	struct intel_panel *panel = &intel_connector->panel;
 
-	if (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
+	if (panel->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
 		return -ENODEV;
 
 	if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI))
drivers/gpu/drm/i915/display/intel_dsi_vbt.c +33 -23

173 lines not on this page · raw message

drivers/gpu/drm/i915/display/intel_lvds.c +4 -2
index e8478161f8b9..9f250a70519a 100644
@@ -809,7 +809,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
 	else
 		val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK);
 	if (val == 0)
-		val = dev_priv->vbt.bios_lvds_val;
+		val = connector->panel.vbt.bios_lvds_val;
 
 	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
 }
@@ -967,9 +967,11 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	}
 	intel_connector->edid = edid;
 
+	intel_bios_init_panel(dev_priv, &intel_connector->panel);
+
 	/* Try EDID first */
 	intel_panel_add_edid_fixed_modes(intel_connector,
-					 dev_priv->vbt.drrs_type != DRRS_TYPE_NONE);
+					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
 
 	/* Failed to get EDID, what about VBT? */
 	if (!intel_panel_preferred_fixed_mode(intel_connector))
drivers/gpu/drm/i915/display/intel_panel.c +6 -7
index d1d1b59102d6..d055e4118558 100644
@@ -75,9 +75,8 @@ const struct drm_display_mode *
 intel_panel_downclock_mode(struct intel_connector *connector,
 			   const struct drm_display_mode *adjusted_mode)
 {
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	const struct drm_display_mode *fixed_mode, *best_mode = NULL;
-	int min_vrefresh = i915->vbt.seamless_drrs_min_refresh_rate;
+	int min_vrefresh = connector->panel.vbt.seamless_drrs_min_refresh_rate;
 	int max_vrefresh = drm_mode_vrefresh(adjusted_mode);
 
 	/* pick the fixed_mode with the lowest refresh rate */
@@ -113,13 +112,11 @@ int intel_panel_get_modes(struct intel_connector *connector)
 
 enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
 {
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
-
 	if (list_empty(&connector->panel.fixed_modes) ||
 	    list_is_singular(&connector->panel.fixed_modes))
 		return DRRS_TYPE_NONE;
 
-	return i915->vbt.drrs_type;
+	return connector->panel.vbt.drrs_type;
 }
 
 int intel_panel_compute_config(struct intel_connector *connector,
@@ -260,7 +257,7 @@ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	const struct drm_display_mode *mode;
 
-	mode = i915->vbt.lfp_lvds_vbt_mode;
+	mode = connector->panel.vbt.lfp_lvds_vbt_mode;
 	if (!mode)
 		return;
 
@@ -274,7 +271,7 @@ void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector)
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	const struct drm_display_mode *mode;
 
-	mode = i915->vbt.sdvo_lvds_vbt_mode;
+	mode = connector->panel.vbt.sdvo_lvds_vbt_mode;
 	if (!mode)
 		return;
 
@@ -639,6 +636,8 @@ void intel_panel_fini(struct intel_connector *connector)
 
 	intel_backlight_destroy(panel);
 
+	intel_bios_fini_panel(panel);
+
 	list_for_each_entry_safe(fixed_mode, next, &panel->fixed_modes, head) {
 		list_del(&fixed_mode->head);
 		drm_mode_destroy(connector->base.dev, fixed_mode);
drivers/gpu/drm/i915/display/intel_pps.c +4 -2
index 5b72c892a6f2..a226e4e5c569 100644
@@ -209,7 +209,8 @@ static int
 bxt_power_sequencer_idx(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	int backlight_controller = dev_priv->vbt.backlight.controller;
+	struct intel_connector *connector = intel_dp->attached_connector;
+	int backlight_controller = connector->panel.vbt.backlight.controller;
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -1175,8 +1176,9 @@ static void pps_init_delays_vbt(struct intel_dp *intel_dp,
 				struct edp_power_seq *vbt)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
 
-	*vbt = dev_priv->vbt.edp.pps;
+	*vbt = connector->panel.vbt.edp.pps;
 
 	/* On Toshiba Satellite P50-C-18C system the VBT T12 delay
 	 * of 500ms appears to be too short. Ocassionally the panel
drivers/gpu/drm/i915/display/intel_psr.c +17 -13
index 06db407e2749..195ed9631128 100644
@@ -399,6 +399,7 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
 
 static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 {
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val = 0;
 
@@ -411,20 +412,20 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 		goto check_tp3_sel;
 	}
 
-	if (dev_priv->vbt.psr.tp1_wakeup_time_us == 0)
+	if (connector->panel.vbt.psr.tp1_wakeup_time_us == 0)
 		val |= EDP_PSR_TP1_TIME_0us;
-	else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 100)
+	else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 100)
 		val |= EDP_PSR_TP1_TIME_100us;
-	else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 500)
+	else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 500)
 		val |= EDP_PSR_TP1_TIME_500us;
 	else
 		val |= EDP_PSR_TP1_TIME_2500us;
 
-	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us == 0)
+	if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us == 0)
 		val |= EDP_PSR_TP2_TP3_TIME_0us;
-	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 100)
+	else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 100)
 		val |= EDP_PSR_TP2_TP3_TIME_100us;
-	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 500)
+	else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 500)
 		val |= EDP_PSR_TP2_TP3_TIME_500us;
 	else
 		val |= EDP_PSR_TP2_TP3_TIME_2500us;
@@ -441,13 +442,14 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 
 static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
 {
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	int idle_frames;
 
 	/* Let's use 6 as the minimum to cover all known cases including the
 	 * off-by-one issue that HW has in some cases.
 	 */
-	idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
+	idle_frames = max(6, connector->panel.vbt.psr.idle_frames);
 	idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1);
 
 	if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf))
@@ -483,18 +485,19 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
 
 static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
 {
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val = 0;
 
 	if (dev_priv->params.psr_safest_params)
 		return EDP_PSR2_TP2_TIME_2500us;
 
-	if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 &&
-	    dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50)
+	if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 &&
+	    connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50)
 		val |= EDP_PSR2_TP2_TIME_50us;
-	else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100)
+	else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100)
 		val |= EDP_PSR2_TP2_TIME_100us;
-	else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500)
+	else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500)
 		val |= EDP_PSR2_TP2_TIME_500us;
 	else
 		val |= EDP_PSR2_TP2_TIME_2500us;
@@ -2344,6 +2347,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
  */
 void intel_psr_init(struct intel_dp *intel_dp)
 {
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -2368,13 +2372,13 @@ void intel_psr_init(struct intel_dp *intel_dp)
 	intel_dp->psr.source_support = true;
 
 	if (dev_priv->params.enable_psr == -1)
-		if (!dev_priv->vbt.psr.enable)
+		if (!connector->panel.vbt.psr.enable)
 			dev_priv->params.enable_psr = 0;
 
 	/* Set link_standby x link_off defaults */
 	if (DISPLAY_VER(dev_priv) < 12)
 		/* For new platforms up to TGL let's respect VBT back again */
-		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
+		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
 
 	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
 	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work);
drivers/gpu/drm/i915/display/intel_sdvo.c +3 -0
index d81855d57cdc..14a64bd61176 100644
@@ -2869,6 +2869,7 @@ static bool
 intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
 {
 	struct drm_encoder *encoder = &intel_sdvo->base.base;
+	struct drm_i915_private *i915 = to_i915(encoder->dev);
 	struct drm_connector *connector;
 	struct intel_connector *intel_connector;
 	struct intel_sdvo_connector *intel_sdvo_connector;
@@ -2900,6 +2901,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
 	if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
 		goto err;
 
+	intel_bios_init_panel(i915, &intel_connector->panel);
+
 	/*
 	 * Fetch modes from VBT. For SDVO prefer the VBT mode since some
 	 * SDVO->LVDS transcoders can't cope with the EDID mode.
drivers/gpu/drm/i915/display/vlv_dsi.c +9 -5
index 1954f07f0d3e..be8fd3c362df 100644
@@ -782,6 +782,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	enum port port;
@@ -838,7 +839,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
 	 * the delay in that case. If there is no deassert-seq, then an
 	 * unconditional msleep is used to give the panel time to power-on.
 	 */
-	if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) {
+	if (connector->panel.vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) {
 		intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay);
 		intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
 	} else {
@@ -1690,7 +1691,8 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
 {
 	struct drm_device *dev = intel_dsi->base.base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
+	struct intel_connector *connector = intel_dsi->attached_connector;
+	struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
 	u32 tlpx_ns, extra_byte_count, tlpx_ui;
 	u32 ui_num, ui_den;
 	u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
@@ -1924,13 +1926,15 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 
 	intel_dsi->panel_power_off_time = ktime_get_boottime();
 
-	if (dev_priv->vbt.dsi.config->dual_link)
+	intel_bios_init_panel(dev_priv, &intel_connector->panel);
+
+	if (intel_connector->panel.vbt.dsi.config->dual_link)
 		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);
 	else
 		intel_dsi->ports = BIT(port);
 
-	intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
-	intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
+	intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
+	intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
 
 	/* Create a DSI host (and a device) for each port. */
 	for_each_dsi_port(port, intel_dsi->ports) {
drivers/gpu/drm/i915/i915_drv.h +0 -63

88 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#6 lore raw

PATCH 6/207 drm/i915/dsi: filter invalid backlight and CABC ports

In reply to Greg Kroah-Hartman

From: Jani Nikula <[email protected]>

[ Upstream commit 607f41768a1ef9c7721866b00fbdeeea5359bc07 ]

Avoid using ports that aren't initialized in case the VBT backlight or CABC ports have invalid values. This fixes a NULL pointer dereference of intel_dsi->dsi_hosts[port] in such cases.

---
 drivers/gpu/drm/i915/display/icl_dsi.c | 7 +++++++
 drivers/gpu/drm/i915/display/vlv_dsi.c | 7 +++++++
 2 files changed, 14 insertions(+)
drivers/gpu/drm/i915/display/icl_dsi.c +7 -0
index 5c46acb46516..f416499dad6f 100644
@@ -2072,7 +2072,14 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	else
 		intel_dsi->ports = BIT(port);
 
+	if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports))
+		intel_connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports;
+
 	intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
+
+	if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports))
+		intel_connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports;
+
 	intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
 
 	for_each_dsi_port(port, intel_dsi->ports) {
drivers/gpu/drm/i915/display/vlv_dsi.c +7 -0
index be8fd3c362df..02f75e95b2ec 100644
@@ -1933,7 +1933,14 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 	else
 		intel_dsi->ports = BIT(port);
 
+	if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports))
+		intel_connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports;
+
 	intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
+
+	if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports))
+		intel_connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports;
+
 	intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
 
 	/* Create a DSI host (and a device) for each port. */
Signature · 1 line
2.35.1
author maintainer
#7 lore raw

PATCH 7/207 drm/i915/dsi: fix dual-link DSI backlight and CABC ports for display 11+

In reply to Greg Kroah-Hartman

From: Jani Nikula <[email protected]>

[ Upstream commit 13393f65b77445d8b0f99c7b605cc9ccc936586f ]

The VBT dual-link DSI backlight and CABC still use ports A and C, both in Bspec and code, while display 11+ DSI only supports ports A and B. Assume port C actually means port B for display 11+ when parsing VBT.

Bspec: 20154

---
 drivers/gpu/drm/i915/display/intel_bios.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/display/intel_bios.c +6 -4
index d5d20a44f373..b5de61fe9cc6 100644
@@ -1473,6 +1473,8 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *i915,
 				      struct intel_panel *panel,
 				      enum port port)
 {
+	enum port port_bc = DISPLAY_VER(i915) >= 11 ? PORT_B : PORT_C;
+
 	if (!panel->vbt.dsi.config->dual_link || i915->vbt.version < 197) {
 		panel->vbt.dsi.bl_ports = BIT(port);
 		if (panel->vbt.dsi.config->cabc_supported)
@@ -1486,11 +1488,11 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *i915,
 		panel->vbt.dsi.bl_ports = BIT(PORT_A);
 		break;
 	case DL_DCS_PORT_C:
-		panel->vbt.dsi.bl_ports = BIT(PORT_C);
+		panel->vbt.dsi.bl_ports = BIT(port_bc);
 		break;
 	default:
 	case DL_DCS_PORT_A_AND_C:
-		panel->vbt.dsi.bl_ports = BIT(PORT_A) | BIT(PORT_C);
+		panel->vbt.dsi.bl_ports = BIT(PORT_A) | BIT(port_bc);
 		break;
 	}
 
@@ -1502,12 +1504,12 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *i915,
 		panel->vbt.dsi.cabc_ports = BIT(PORT_A);
 		break;
 	case DL_DCS_PORT_C:
-		panel->vbt.dsi.cabc_ports = BIT(PORT_C);
+		panel->vbt.dsi.cabc_ports = BIT(port_bc);
 		break;
 	default:
 	case DL_DCS_PORT_A_AND_C:
 		panel->vbt.dsi.cabc_ports =
-					BIT(PORT_A) | BIT(PORT_C);
+					BIT(PORT_A) | BIT(port_bc);
 		break;
 	}
 }
Signature · 1 line
2.35.1
author maintainer
#8 lore raw

PATCH 8/207 smb3: Move the flush out of smb2_copychunk_range() into its callers

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit c3a72bb213209adfe981a4a92ea5746a778323e4 ]

Move the flush out of smb2_copychunk_range() into its callers. This will allow the pagecache to be invalidated between the flush and the operation in smb3_collapse_range() and smb3_insert_range().

Stable-dep-of: fa30a81f255a ("smb3: fix temporary data corruption in collapse range")

---
 fs/cifs/cifsfs.c  |  2 ++
 fs/cifs/smb2ops.c | 20 ++++++++------------
 2 files changed, 10 insertions(+), 12 deletions(-)
fs/cifs/cifsfs.c +2 -0
index 8f2e003e0590..2b51f0cbf4d2 100644
@@ -1203,6 +1203,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
 
 	cifs_dbg(FYI, "copychunk range\n");
 
+	filemap_write_and_wait(src_inode->i_mapping);
+
 	if (!src_file->private_data || !dst_file->private_data) {
 		rc = -EBADF;
 		cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
fs/cifs/smb2ops.c +8 -12
index e8a8daa82ed7..ef8cb7fbabeb 100644
@@ -1886,17 +1886,8 @@ smb2_copychunk_range(const unsigned int xid,
 	int chunks_copied = 0;
 	bool chunk_sizes_updated = false;
 	ssize_t bytes_written, total_bytes_written = 0;
-	struct inode *inode;
 
 	pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
-
-	/*
-	 * We need to flush all unwritten data before we can send the
-	 * copychunk ioctl to the server.
-	 */
-	inode = d_inode(trgtfile->dentry);
-	filemap_write_and_wait(inode->i_mapping);
-
 	if (pcchunk == NULL)
 		return -ENOMEM;
 
@@ -3977,6 +3968,8 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 		goto out;
 	}
 
+	filemap_write_and_wait(inode->i_mapping);
+
 	rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
 				  i_size_read(inode) - off - len, off);
 	if (rc < 0)
@@ -4004,18 +3997,21 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 	int rc;
 	unsigned int xid;
 	struct cifsFileInfo *cfile = file->private_data;
+	struct inode *inode = file_inode(file);
 	__le64 eof;
 	__u64  count;
 
 	xid = get_xid();
 
-	if (off >= i_size_read(file->f_inode)) {
+	if (off >= i_size_read(inode)) {
 		rc = -EINVAL;
 		goto out;
 	}
 
-	count = i_size_read(file->f_inode) - off;
-	eof = cpu_to_le64(i_size_read(file->f_inode) + len);
+	count = i_size_read(inode) - off;
+	eof = cpu_to_le64(i_size_read(inode) + len);
+
+	filemap_write_and_wait(inode->i_mapping);
 
 	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 			  cfile->fid.volatile_fid, cfile->pid, &eof);
Signature · 1 line
2.35.1
author maintainer
#9 lore raw

PATCH 9/207 smb3: fix temporary data corruption in collapse range

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

[ Upstream commit fa30a81f255a56cccd89552cd6ce7ea6e8d8acc4 ]

collapse range doesn't discard the affected cached region so can risk temporarily corrupting the file data. This fixes xfstest generic/031

I also decided to merge a minor cleanup to this into the same patch (avoiding rereading inode size repeatedly unnecessarily) to make it clearer.

Fixes 5476b5dd82c8b ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE")
cc Ronnie Sahlberg <[email protected]>
---
 fs/cifs/smb2ops.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)
fs/cifs/smb2ops.c +16 -10
index ef8cb7fbabeb..8e55495c4f7e 100644
@@ -3952,41 +3952,47 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 {
 	int rc;
 	unsigned int xid;
-	struct inode *inode;
+	struct inode *inode = file_inode(file);
 	struct cifsFileInfo *cfile = file->private_data;
-	struct cifsInodeInfo *cifsi;
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
 	__le64 eof;
+	loff_t old_eof;
 
 	xid = get_xid();
 
-	inode = d_inode(cfile->dentry);
-	cifsi = CIFS_I(inode);
+	inode_lock(inode);
 
-	if (off >= i_size_read(inode) ||
-	    off + len >= i_size_read(inode)) {
+	old_eof = i_size_read(inode);
+	if ((off >= old_eof) ||
+	    off + len >= old_eof) {
 		rc = -EINVAL;
 		goto out;
 	}
 
+	filemap_invalidate_lock(inode->i_mapping);
 	filemap_write_and_wait(inode->i_mapping);
+	truncate_pagecache_range(inode, off, old_eof);
 
 	rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
-				  i_size_read(inode) - off - len, off);
+				  old_eof - off - len, off);
 	if (rc < 0)
-		goto out;
+		goto out_2;
 
-	eof = cpu_to_le64(i_size_read(inode) - len);
+	eof = cpu_to_le64(old_eof - len);
 	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 			  cfile->fid.volatile_fid, cfile->pid, &eof);
 	if (rc < 0)
-		goto out;
+		goto out_2;
 
 	rc = 0;
 
 	cifsi->server_eof = i_size_read(inode) - len;
 	truncate_setsize(inode, cifsi->server_eof);
 	fscache_resize_cookie(cifs_inode_cookie(inode), cifsi->server_eof);
+out_2:
+	filemap_invalidate_unlock(inode->i_mapping);
  out:
+	inode_unlock(inode);
 	free_xid(xid);
 	return rc;
 }
Signature · 1 line
2.35.1
author maintainer
#10 lore raw

PATCH 10/207 smb3: fix temporary data corruption in insert range

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit 9c8b7a293f50253e694f19161c045817a938e551 ]

insert range doesn't discard the affected cached region so can risk temporarily corrupting file data.

Also includes some minor cleanup (avoiding rereading inode size repeatedly unnecessarily) to make it clearer.

Fixes 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support")
cc Ronnie Sahlberg <[email protected]>
---
 fs/cifs/smb2ops.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
fs/cifs/smb2ops.c +16 -8
index 8e55495c4f7e..774c6e5f6584 100644
@@ -4005,35 +4005,43 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 	struct cifsFileInfo *cfile = file->private_data;
 	struct inode *inode = file_inode(file);
 	__le64 eof;
-	__u64  count;
+	__u64  count, old_eof;
 
 	xid = get_xid();
 
-	if (off >= i_size_read(inode)) {
+	inode_lock(inode);
+
+	old_eof = i_size_read(inode);
+	if (off >= old_eof) {
 		rc = -EINVAL;
 		goto out;
 	}
 
-	count = i_size_read(inode) - off;
-	eof = cpu_to_le64(i_size_read(inode) + len);
+	count = old_eof - off;
+	eof = cpu_to_le64(old_eof + len);
 
+	filemap_invalidate_lock(inode->i_mapping);
 	filemap_write_and_wait(inode->i_mapping);
+	truncate_pagecache_range(inode, off, old_eof);
 
 	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 			  cfile->fid.volatile_fid, cfile->pid, &eof);
 	if (rc < 0)
-		goto out;
+		goto out_2;
 
 	rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len);
 	if (rc < 0)
-		goto out;
+		goto out_2;
 
-	rc = smb3_zero_range(file, tcon, off, len, 1);
+	rc = smb3_zero_data(file, tcon, off, len, xid);
 	if (rc < 0)
-		goto out;
+		goto out_2;
 
 	rc = 0;
+out_2:
+	filemap_invalidate_unlock(inode->i_mapping);
  out:
+	inode_unlock(inode);
 	free_xid(xid);
 	return rc;
 }
Signature · 1 line
2.35.1
author maintainer
#11 lore raw

PATCH 11/207 usb: add quirks for Lenovo OneLink+ Dock

In reply to Greg Kroah-Hartman

From: Jean-Francois Le Fillatre <[email protected]>

[ Upstream commit 3d5f70949f1b1168fbb17d06eb5c57e984c56c58 ]

The Lenovo OneLink+ Dock contains two VL812 USB3.0 controllers:
17ef:1018 upstream
17ef:1019 downstream

Those two controllers both have problems with some USB3.0 devices, particularly self-powered ones. Typical error messages include:

Timeout while waiting for setup device command
device not accepting address X, error -62
unable to enumerate USB device

By process of elimination the controllers themselves were identified as the cause of the problem. Through trial and error the issue was solved by using USB_QUIRK_RESET_RESUME for both chips.

---
 drivers/usb/core/quirks.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/usb/core/quirks.c +4 -0
index f99a65a64588..999b7c9697fc 100644
@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+	/* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
+	{ USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
+	{ USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
 	{ USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
 
Signature · 1 line
2.35.1
author maintainer
#12 lore raw

PATCH 12/207 usb: gadget: udc-xilinx: replace memcpy with memcpy_toio

In reply to Greg Kroah-Hartman

From: Piyush Mehta <[email protected]>

[ Upstream commit 8cb339f1c1f04baede9d54c1e40ac96247a6393b ]

For ARM processor, unaligned access to device memory is not allowed. Method memcpy does not take care of alignment.

USB detection failure with the unaligned address of memory access, with below kernel crash. To fix the unaligned address the kernel panic issue, replace memcpy with memcpy_toio method.

Kernel crash:

Unable to handle kernel paging request at virtual address ffff80000c05008a

Mem abort info:
ESR = 0x96000061
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x21: alignment fault
Data abort info:
ISV = 0, ISS = 0x00000061
CM = 0, WnR = 1
swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000000143b000 [ffff80000c05008a] pgd=100000087ffff003, p4d=100000087ffff003, pud=100000087fffe003, pmd=1000000800bcc003, pte=00680000a0010713

Internal error: Oops: 96000061 [#1] SMP
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.15.19-xilinx-v2022.1 #1
Hardware name: ZynqMP ZCU102 Rev1.0 (DT)
pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __memcpy+0x30/0x260
lr : __xudc_ep0_queue+0xf0/0x110

sp : ffff800008003d00
x29: ffff800008003d00 x28: ffff800009474e80 x27: 00000000000000a0
x26: 0000000000000100 x25: 0000000000000012 x24: ffff000800bc8080
x23: 0000000000000001 x22: 0000000000000012 x21: ffff000800bc8080
x20: 0000000000000012 x19: ffff000800bc8080 x18: 0000000000000000
x17: ffff800876482000 x16: ffff800008004000 x15: 0000000000004000
x14: 00001f09785d0400 x13: 0103020101005567 x12: 0781400000000200
x11: 00000000c5672a10 x10: 00000000000008d0 x9 : ffff800009463cf0 x8 : ffff8000094757b0 x7 : 0201010055670781 x6 : 4000000002000112 x5 : ffff80000c05009a x4 : ffff000800a15012 x3 : ffff00080362ad80 x2 : 0000000000000012 x1 : ffff000800a15000 x0 : ffff80000c050088

Call trace:
 __memcpy+0x30/0x260
 xudc_ep0_queue+0x3c/0x60
 usb_ep_queue+0x38/0x44
 composite_ep0_queue.constprop.0+0x2c/0xc0
 composite_setup+0x8d0/0x185c
 configfs_composite_setup+0x74/0xb0
 xudc_irq+0x570/0xa40
 __handle_irq_event_percpu+0x58/0x170
 handle_irq_event+0x60/0x120
 handle_fasteoi_irq+0xc0/0x220
 handle_domain_irq+0x60/0x90
 gic_handle_irq+0x74/0xa0
 call_on_irq_stack+0x2c/0x60
 do_interrupt_handler+0x54/0x60
 el1_interrupt+0x30/0x50
 el1h_64_irq_handler+0x18/0x24
 el1h_64_irq+0x78/0x7c
 arch_cpu_idle+0x18/0x2c
 do_idle+0xdc/0x15c
 cpu_startup_entry+0x28/0x60
 rest_init+0xc8/0xe0
 arch_call_rest_init+0x10/0x1c
 start_kernel+0x694/0x6d4
 __primary_switched+0xa4/0xac
---
 drivers/usb/gadget/udc/udc-xilinx.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/usb/gadget/udc/udc-xilinx.c +8 -8
index 4827e3cd3834..054b69dc2f0c 100644
@@ -499,11 +499,11 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req,
 		/* Get the Buffer address and copy the transmit data.*/
 		eprambase = (u32 __force *)(udc->addr + ep->rambase);
 		if (ep->is_in) {
-			memcpy(eprambase, bufferptr, bytestosend);
+			memcpy_toio(eprambase, bufferptr, bytestosend);
 			udc->write_fn(udc->addr, ep->offset +
 				      XUSB_EP_BUF0COUNT_OFFSET, bufferlen);
 		} else {
-			memcpy(bufferptr, eprambase, bytestosend);
+			memcpy_toio(bufferptr, eprambase, bytestosend);
 		}
 		/*
 		 * Enable the buffer for transmission.
@@ -517,11 +517,11 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req,
 		eprambase = (u32 __force *)(udc->addr + ep->rambase +
 			     ep->ep_usb.maxpacket);
 		if (ep->is_in) {
-			memcpy(eprambase, bufferptr, bytestosend);
+			memcpy_toio(eprambase, bufferptr, bytestosend);
 			udc->write_fn(udc->addr, ep->offset +
 				      XUSB_EP_BUF1COUNT_OFFSET, bufferlen);
 		} else {
-			memcpy(bufferptr, eprambase, bytestosend);
+			memcpy_toio(bufferptr, eprambase, bytestosend);
 		}
 		/*
 		 * Enable the buffer for transmission.
@@ -1023,7 +1023,7 @@ static int __xudc_ep0_queue(struct xusb_ep *ep0, struct xusb_req *req)
 			   udc->addr);
 		length = req->usb_req.actual = min_t(u32, length,
 						     EP0_MAX_PACKET);
-		memcpy(corebuf, req->usb_req.buf, length);
+		memcpy_toio(corebuf, req->usb_req.buf, length);
 		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, length);
 		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
 	} else {
@@ -1752,7 +1752,7 @@ static void xudc_handle_setup(struct xusb_udc *udc)
 
 	/* Load up the chapter 9 command buffer.*/
 	ep0rambase = (u32 __force *) (udc->addr + XUSB_SETUP_PKT_ADDR_OFFSET);
-	memcpy(&setup, ep0rambase, 8);
+	memcpy_toio(&setup, ep0rambase, 8);
 
 	udc->setup = setup;
 	udc->setup.wValue = cpu_to_le16(setup.wValue);
@@ -1839,7 +1839,7 @@ static void xudc_ep0_out(struct xusb_udc *udc)
 			     (ep0->rambase << 2));
 		buffer = req->usb_req.buf + req->usb_req.actual;
 		req->usb_req.actual = req->usb_req.actual + bytes_to_rx;
-		memcpy(buffer, ep0rambase, bytes_to_rx);
+		memcpy_toio(buffer, ep0rambase, bytes_to_rx);
 
 		if (req->usb_req.length == req->usb_req.actual) {
 			/* Data transfer completed get ready for Status stage */
@@ -1915,7 +1915,7 @@ static void xudc_ep0_in(struct xusb_udc *udc)
 				     (ep0->rambase << 2));
 			buffer = req->usb_req.buf + req->usb_req.actual;
 			req->usb_req.actual = req->usb_req.actual + length;
-			memcpy(ep0rambase, buffer, length);
+			memcpy_toio(ep0rambase, buffer, length);
 		}
 		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, count);
 		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
Signature · 1 line
2.35.1
author maintainer
#13 lore raw

PATCH 13/207 smb3: use filemap_write_and_wait_range instead of filemap_write_and_wait

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

[ Upstream commit 3e3761f1ec7df67d88cfca5e2ea98538f529e645 ]

When doing insert range and collapse range we should be writing out the cached pages for the ranges affected but not the whole file.

Fixes c3a72bb21320 ("smb3: Move the flush out of smb2_copychunk_range() into its callers")
---
 fs/cifs/cifsfs.c  | 8 ++++++--
 fs/cifs/smb2ops.c | 9 +++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)
fs/cifs/cifsfs.c +6 -2
index 2b51f0cbf4d2..97278c43f8dc 100644
@@ -1203,8 +1203,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
 
 	cifs_dbg(FYI, "copychunk range\n");
 
-	filemap_write_and_wait(src_inode->i_mapping);
-
 	if (!src_file->private_data || !dst_file->private_data) {
 		rc = -EBADF;
 		cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
@@ -1234,6 +1232,12 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
 	lock_two_nondirectories(target_inode, src_inode);
 
 	cifs_dbg(FYI, "about to flush pages\n");
+
+	rc = filemap_write_and_wait_range(src_inode->i_mapping, off,
+					  off + len - 1);
+	if (rc)
+		goto out;
+
 	/* should we flush first and last page first */
 	truncate_inode_pages(&target_inode->i_data, 0);
 
fs/cifs/smb2ops.c +7 -2
index 774c6e5f6584..cc180d37b8ce 100644
@@ -3970,7 +3970,10 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 	}
 
 	filemap_invalidate_lock(inode->i_mapping);
-	filemap_write_and_wait(inode->i_mapping);
+	rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof - 1);
+	if (rc < 0)
+		goto out_2;
+
 	truncate_pagecache_range(inode, off, old_eof);
 
 	rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
@@ -4021,7 +4024,9 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 	eof = cpu_to_le64(old_eof + len);
 
 	filemap_invalidate_lock(inode->i_mapping);
-	filemap_write_and_wait(inode->i_mapping);
+	rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof + len - 1);
+	if (rc < 0)
+		goto out_2;
 	truncate_pagecache_range(inode, off, old_eof);
 
 	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
Signature · 1 line
2.35.1
author maintainer
#14 lore raw

PATCH 14/207 Revert "usb: add quirks for Lenovo OneLink+ Dock"

In reply to Greg Kroah-Hartman

From: Greg Kroah-Hartman <[email protected]>

[ Upstream commit 58bfe7d8e31014d7ce246788df99c56e3cfe6c68 ]

This reverts commit 3d5f70949f1b1168fbb17d06eb5c57e984c56c58.

The quirk does not work properly, more work is needed to determine what should be done here.

Cc Jean-Francois Le Fillatre <[email protected]>
Cc stable <[email protected]>
Fixes 3d5f70949f1b ("usb: add quirks for Lenovo OneLink+ Dock")
---
 drivers/usb/core/quirks.c | 4 ----
 1 file changed, 4 deletions(-)
drivers/usb/core/quirks.c +0 -4
index 999b7c9697fc..f99a65a64588 100644
@@ -437,10 +437,6 @@ static const struct usb_device_id usb_quirk_list[] = {
 	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
-	/* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
-	{ USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
-	{ USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME },
-
 	/* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
 	{ USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
 
Signature · 1 line
2.35.1
#15 lore raw

Re: [PATCH 5.19 014/207] Revert "usb: add quirks for Lenovo OneLink+ Dock"

I wonder, does it make sense to queue the commit (as 011/207) and immediately its revert (the patch below) in a single release? I doubt that...

The same holds for 012 (patch) + 015 (revert).

Quoted 35 lines · Greg Kroah-Hartman

From: Greg Kroah-Hartman <[email protected]>

[ Upstream commit 58bfe7d8e31014d7ce246788df99c56e3cfe6c68 ]

This reverts commit 3d5f70949f1b1168fbb17d06eb5c57e984c56c58.

The quirk does not work properly, more work is needed to determine what should be done here.

Cc Jean-Francois Le Fillatre <[email protected]>
Cc stable <[email protected]>
Fixes 3d5f70949f1b ("usb: add quirks for Lenovo OneLink+ Dock")
---
  drivers/usb/core/quirks.c | 4 ----
  1 file changed, 4 deletions(-)
drivers/usb/core/quirks.c +0 -4
index 999b7c9697fc..f99a65a64588 100644
@@ -437,10 +437,6 @@ static const struct usb_device_id usb_quirk_list[] = {
  	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
  			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
-	/* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
-	{ USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
-	{ USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME },
-
  	/* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
  	{ USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
 
Signature · 2 lines
js
suse labs
author maintainer
#16 lore raw

Re: [PATCH 5.19 014/207] Revert "usb: add quirks for Lenovo OneLink+ Dock"

Quoted 5 lines · Jiri Slaby

I wonder, does it make sense to queue the commit (as 011/207) and immediately its revert (the patch below) in a single release? I doubt that...

The same holds for 012 (patch) + 015 (revert).

Yes it does, otherwise tools will pick up "hey, you forgot this patch that should have been applied here!" all the time. Having the patch, and the revert, in the tree prevents that from happening.

thanks,

greg k-h

#17 lore raw

Re: [PATCH 5.19 014/207] Revert "usb: add quirks for Lenovo OneLink+ Dock"

Quoted 10 lines · Greg Kroah-Hartman
Quoted 5 lines · Jiri Slaby

I wonder, does it make sense to queue the commit (as 011/207) and immediately its revert (the patch below) in a single release? I doubt that...

The same holds for 012 (patch) + 015 (revert).

Yes it does, otherwise tools will pick up "hey, you forgot this patch that should have been applied here!" all the time. Having the patch, and the revert, in the tree prevents that from happening.

It'd be fairly easy to fix the tools not to pick up reverted commits, right?

thanks,

Signature · 2 lines
js
suse labs
author maintainer
#18 lore raw

Re: [PATCH 5.19 014/207] Revert "usb: add quirks for Lenovo OneLink+ Dock"

Quoted 6 lines · Jiri Slaby
Quoted 5 lines · Greg Kroah-Hartman
Quoted 4 lines · Jiri Slaby

I wonder, does it make sense to queue the commit (as 011/207) and immediately its revert (the patch below) in a single release? I doubt that...

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

The same holds for 012 (patch) + 015 (revert).

Yes it does, otherwise tools will pick up "hey, you forgot this patch that should have been applied here!" all the time. Having the patch, and the revert, in the tree prevents that from happening.

It'd be fairly easy to fix the tools not to pick up reverted commits, right?

Not really as they are usually quite "far" away from the original commits.

But hey, if you have some scripts that can find all of that, I'm all for it, the ones I have right now don't account for this.

thanks,

greg k-h

#19 lore raw

Re: [PATCH 5.19 014/207] Revert "usb: add quirks for Lenovo OneLink+ Dock"

Quoted 9 lines · Greg Kroah-Hartman
Quoted 8 lines · Jiri Slaby
Quoted 7 lines · Greg Kroah-Hartman
Quoted 5 lines · Jiri Slaby

I wonder, does it make sense to queue the commit (as 011/207) and immediately its revert (the patch below) in a single release? I doubt that...

The same holds for 012 (patch) + 015 (revert).

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Yes it does, otherwise tools will pick up "hey, you forgot this patch that should have been applied here!" all the time. Having the patch, and the revert, in the tree prevents that from happening.

It'd be fairly easy to fix the tools not to pick up reverted commits, right?

Not really as they are usually quite "far" away from the original commits.

Yes, but you need to deal with this only in a particular release (a revert has to be applied if the commit is already in some previous release, of course).

Quoted 2 lines

But hey, if you have some scripts that can find all of that, I'm all for it, the ones I have right now don't account for this.

I don't know your/Sasha's scripts. But they are apparently able to find the revert as can we see above. So instead of direct:
cherry-pick revert-patch-for-commit-X
it would be:
if (PATCH=git grep -l "[Cc]ommit X" queue-RELEASE/)
git rm PATCH
else
cherry-pick revert-patch-for-commit-X
fi

Or am I missing something?

thanks,

Signature · 1 line
js
author maintainer
#20 lore raw

PATCH 15/207 Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio"

In reply to Greg Kroah-Hartman

From: Greg Kroah-Hartman <[email protected]>

[ Upstream commit fe0a2ac7c627b064c479ad0c3b25e531d342e048 ]

This reverts commit 8cb339f1c1f04baede9d54c1e40ac96247a6393b as it throws up a bunch of sparse warnings as reported by the kernel test robot.

Fixes 8cb339f1c1f0 ("usb: gadget: udc-xilinx: replace memcpy with memcpy_toio")
Cc Linus Walleij <[email protected]>
Cc Piyush Mehta <[email protected]>
---
 drivers/usb/gadget/udc/udc-xilinx.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/usb/gadget/udc/udc-xilinx.c +8 -8
index 054b69dc2f0c..4827e3cd3834 100644
@@ -499,11 +499,11 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req,
 		/* Get the Buffer address and copy the transmit data.*/
 		eprambase = (u32 __force *)(udc->addr + ep->rambase);
 		if (ep->is_in) {
-			memcpy_toio(eprambase, bufferptr, bytestosend);
+			memcpy(eprambase, bufferptr, bytestosend);
 			udc->write_fn(udc->addr, ep->offset +
 				      XUSB_EP_BUF0COUNT_OFFSET, bufferlen);
 		} else {
-			memcpy_toio(bufferptr, eprambase, bytestosend);
+			memcpy(bufferptr, eprambase, bytestosend);
 		}
 		/*
 		 * Enable the buffer for transmission.
@@ -517,11 +517,11 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req,
 		eprambase = (u32 __force *)(udc->addr + ep->rambase +
 			     ep->ep_usb.maxpacket);
 		if (ep->is_in) {
-			memcpy_toio(eprambase, bufferptr, bytestosend);
+			memcpy(eprambase, bufferptr, bytestosend);
 			udc->write_fn(udc->addr, ep->offset +
 				      XUSB_EP_BUF1COUNT_OFFSET, bufferlen);
 		} else {
-			memcpy_toio(bufferptr, eprambase, bytestosend);
+			memcpy(bufferptr, eprambase, bytestosend);
 		}
 		/*
 		 * Enable the buffer for transmission.
@@ -1023,7 +1023,7 @@ static int __xudc_ep0_queue(struct xusb_ep *ep0, struct xusb_req *req)
 			   udc->addr);
 		length = req->usb_req.actual = min_t(u32, length,
 						     EP0_MAX_PACKET);
-		memcpy_toio(corebuf, req->usb_req.buf, length);
+		memcpy(corebuf, req->usb_req.buf, length);
 		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, length);
 		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
 	} else {
@@ -1752,7 +1752,7 @@ static void xudc_handle_setup(struct xusb_udc *udc)
 
 	/* Load up the chapter 9 command buffer.*/
 	ep0rambase = (u32 __force *) (udc->addr + XUSB_SETUP_PKT_ADDR_OFFSET);
-	memcpy_toio(&setup, ep0rambase, 8);
+	memcpy(&setup, ep0rambase, 8);
 
 	udc->setup = setup;
 	udc->setup.wValue = cpu_to_le16(setup.wValue);
@@ -1839,7 +1839,7 @@ static void xudc_ep0_out(struct xusb_udc *udc)
 			     (ep0->rambase << 2));
 		buffer = req->usb_req.buf + req->usb_req.actual;
 		req->usb_req.actual = req->usb_req.actual + bytes_to_rx;
-		memcpy_toio(buffer, ep0rambase, bytes_to_rx);
+		memcpy(buffer, ep0rambase, bytes_to_rx);
 
 		if (req->usb_req.length == req->usb_req.actual) {
 			/* Data transfer completed get ready for Status stage */
@@ -1915,7 +1915,7 @@ static void xudc_ep0_in(struct xusb_udc *udc)
 				     (ep0->rambase << 2));
 			buffer = req->usb_req.buf + req->usb_req.actual;
 			req->usb_req.actual = req->usb_req.actual + length;
-			memcpy_toio(ep0rambase, buffer, length);
+			memcpy(ep0rambase, buffer, length);
 		}
 		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, count);
 		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
Signature · 1 line
2.35.1
author maintainer
#21 lore raw

PATCH 16/207 xfrm: fix XFRMA_LASTUSED comment

In reply to Greg Kroah-Hartman

From: Antony Antony <[email protected]>

[ Upstream commit 36d763509be326bb383b1b1852a129ff58d74e3b ]

It is a __u64, internally time64_t.

Fixes bf825f81b454 ("xfrm: introduce basic mark infrastructure")
---
 include/uapi/linux/xfrm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/linux/xfrm.h +1 -1
index 65e13a099b1a..a9f5d884560a 100644
@@ -296,7 +296,7 @@ enum xfrm_attr_type_t {
 	XFRMA_ETIMER_THRESH,
 	XFRMA_SRCADDR,		/* xfrm_address_t */
 	XFRMA_COADDR,		/* xfrm_address_t */
-	XFRMA_LASTUSED,		/* unsigned long  */
+	XFRMA_LASTUSED,		/* __u64 */
 	XFRMA_POLICY_TYPE,	/* struct xfrm_userpolicy_type */
 	XFRMA_MIGRATE,
 	XFRMA_ALG_AEAD,		/* struct xfrm_algo_aead */
Signature · 1 line
2.35.1
author maintainer
#22 lore raw

PATCH 17/207 block: remove QUEUE_FLAG_DEAD

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

[ Upstream commit 1f90307e5f0d7bc9a336ead528f616a5df8e5944 ]

Disallow setting the blk-mq state on any queue that is already dying as setting the state even then is a bad idea, and remove the now unused QUEUE_FLAG_DEAD flag.

Stable-dep-of: 8fe4ce5836e9 ("scsi: core: Fix a use-after-free")

---
 block/blk-core.c       | 3 ---
 block/blk-mq-debugfs.c | 8 +++-----
 include/linux/blkdev.h | 2 --
 3 files changed, 3 insertions(+), 10 deletions(-)
block/blk-core.c +0 -3
index cc6fbcb6d252..76f070c3a3b0 100644
@@ -313,9 +313,6 @@ void blk_cleanup_queue(struct request_queue *q)
 	 * after draining finished.
 	 */
 	blk_freeze_queue(q);
-
-	blk_queue_flag_set(QUEUE_FLAG_DEAD, q);
-
 	blk_sync_queue(q);
 	if (queue_is_mq(q)) {
 		blk_mq_cancel_work_sync(q);
block/blk-mq-debugfs.c +3 -5
index 61f179e5f151..28adb01f6441 100644
@@ -116,7 +116,6 @@ static const char *const blk_queue_flag_name[] = {
 	QUEUE_FLAG_NAME(NOXMERGES),
 	QUEUE_FLAG_NAME(ADD_RANDOM),
 	QUEUE_FLAG_NAME(SAME_FORCE),
-	QUEUE_FLAG_NAME(DEAD),
 	QUEUE_FLAG_NAME(INIT_DONE),
 	QUEUE_FLAG_NAME(STABLE_WRITES),
 	QUEUE_FLAG_NAME(POLL),
@@ -151,11 +150,10 @@ static ssize_t queue_state_write(void *data, const char __user *buf,
 	char opbuf[16] = { }, *op;
 
 	/*
-	 * The "state" attribute is removed after blk_cleanup_queue() has called
-	 * blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set to avoid
-	 * triggering a use-after-free.
+	 * The "state" attribute is removed when the queue is removed.  Don't
+	 * allow setting the state on a dying queue to avoid a use-after-free.
 	 */
-	if (blk_queue_dead(q))
+	if (blk_queue_dying(q))
 		return -ENOENT;
 
 	if (count >= sizeof(opbuf)) {
include/linux/blkdev.h +0 -2
index 62e3ff52ab03..76f77eed58c3 100644
@@ -559,7 +559,6 @@ struct request_queue {
 #define QUEUE_FLAG_NOXMERGES	9	/* No extended merges */
 #define QUEUE_FLAG_ADD_RANDOM	10	/* Contributes to random pool */
 #define QUEUE_FLAG_SAME_FORCE	12	/* force complete on same CPU */
-#define QUEUE_FLAG_DEAD		13	/* queue tear-down finished */
 #define QUEUE_FLAG_INIT_DONE	14	/* queue is initialized */
 #define QUEUE_FLAG_STABLE_WRITES 15	/* don't modify blks until WB is done */
 #define QUEUE_FLAG_POLL		16	/* IO polling enabled if set */
@@ -587,7 +586,6 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
 #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_dying(q)	test_bit(QUEUE_FLAG_DYING, &(q)->queue_flags)
 #define blk_queue_has_srcu(q)	test_bit(QUEUE_FLAG_HAS_SRCU, &(q)->queue_flags)
-#define blk_queue_dead(q)	test_bit(QUEUE_FLAG_DEAD, &(q)->queue_flags)
 #define blk_queue_init_done(q)	test_bit(QUEUE_FLAG_INIT_DONE, &(q)->queue_flags)
 #define blk_queue_nomerges(q)	test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
 #define blk_queue_noxmerges(q)	\
Signature · 1 line
2.35.1
author maintainer
#23 lore raw

PATCH 18/207 block: stop setting the nomerges flags in blk_cleanup_queue

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

[ Upstream commit 0e3534022f26ae51f7cf28347a253230604b6f4e ]

These flags only apply to file system I/O, and all file system I/O is already drained by del_gendisk and thus can't be in progress when blk_cleanup_queue is called.

Stable-dep-of: 8fe4ce5836e9 ("scsi: core: Fix a use-after-free")

---
 block/blk-core.c | 3 ---
 1 file changed, 3 deletions(-)
block/blk-core.c +0 -3
index 76f070c3a3b0..b8083decc07f 100644
@@ -304,9 +304,6 @@ void blk_cleanup_queue(struct request_queue *q)
 	blk_queue_flag_set(QUEUE_FLAG_DYING, q);
 	blk_queue_start_drain(q);
 
-	blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q);
-	blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
-
 	/*
 	 * Drain all requests queued before DYING marking. Set DEAD flag to
 	 * prevent that blk_mq_run_hw_queues() accesses the hardware queues
Signature · 1 line
2.35.1
author maintainer
#24 lore raw

PATCH 19/207 block: simplify disk shutdown

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

[ Upstream commit 6f8191fdf41d3a53cc1d63fe2234e812c55a0092 ]

Set the queue dying flag and call blk_mq_exit_queue from del_gendisk for all disks that do not have separately allocated queues, and thus remove the need to call blk_cleanup_queue for them.

Rename blk_cleanup_disk to blk_mq_destroy_queue to make it clear that this function is intended only for separately allocated blk-mq queues.

This saves an extra queue freeze for devices without a separately allocated queue.

Stable-dep-of: 8fe4ce5836e9 ("scsi: core: Fix a use-after-free")

---
 block/blk-core.c                    | 37 -------------------------
 block/blk-mq.c                      | 43 +++++++++++++++++++++++++++--
 block/blk-sysfs.c                   |  5 ----
 block/blk.h                         |  3 ++
 block/bsg-lib.c                     |  4 +--
 block/genhd.c                       | 23 ++++++++-------
 drivers/block/ataflop.c             |  1 -
 drivers/block/loop.c                |  1 -
 drivers/block/mtip32xx/mtip32xx.c   |  2 --
 drivers/block/rnbd/rnbd-clt.c       |  2 +-
 drivers/block/sx8.c                 |  4 +--
 drivers/block/virtio_blk.c          |  1 -
 drivers/block/z2ram.c               |  1 -
 drivers/cdrom/gdrom.c               |  1 -
 drivers/memstick/core/ms_block.c    |  1 -
 drivers/memstick/core/mspro_block.c |  1 -
 drivers/mmc/core/block.c            |  1 -
 drivers/mmc/core/queue.c            |  1 -
 drivers/nvme/host/apple.c           |  2 +-
 drivers/nvme/host/core.c            |  1 -
 drivers/nvme/host/fc.c              | 12 ++++----
 drivers/nvme/host/pci.c             |  2 +-
 drivers/nvme/host/rdma.c            | 12 ++++----
 drivers/nvme/host/tcp.c             | 12 ++++----
 drivers/nvme/target/loop.c          | 12 ++++----
 drivers/s390/block/dasd.c           |  2 +-
 drivers/s390/block/dasd_genhd.c     |  4 +--
 drivers/scsi/scsi_lib.c             |  6 ++--
 drivers/scsi/scsi_sysfs.c           |  2 +-
 drivers/scsi/sd.c                   |  4 +--
 drivers/scsi/sr.c                   |  4 +--
 drivers/ufs/core/ufshcd.c           |  4 +--
 include/linux/blk-mq.h              |  3 ++
 include/linux/blkdev.h              |  4 +--
 34 files changed, 105 insertions(+), 113 deletions(-)
block/blk-core.c +0 -37
index b8083decc07f..7743c68177e8 100644
@@ -284,43 +284,6 @@ void blk_queue_start_drain(struct request_queue *q)
 	wake_up_all(&q->mq_freeze_wq);
 }
 
-/**
- * blk_cleanup_queue - shutdown a request queue
- * @q: request queue to shutdown
- *
- * Mark @q DYING, drain all pending requests, mark @q DEAD, destroy and
- * put it.  All future requests will be failed immediately with -ENODEV.
- *
- * Context: can sleep
- */
-void blk_cleanup_queue(struct request_queue *q)
-{
-	/* cannot be called from atomic context */
-	might_sleep();
-
-	WARN_ON_ONCE(blk_queue_registered(q));
-
-	/* mark @q DYING, no new request or merges will be allowed afterwards */
-	blk_queue_flag_set(QUEUE_FLAG_DYING, q);
-	blk_queue_start_drain(q);
-
-	/*
-	 * Drain all requests queued before DYING marking. Set DEAD flag to
-	 * prevent that blk_mq_run_hw_queues() accesses the hardware queues
-	 * after draining finished.
-	 */
-	blk_freeze_queue(q);
-	blk_sync_queue(q);
-	if (queue_is_mq(q)) {
-		blk_mq_cancel_work_sync(q);
-		blk_mq_exit_queue(q);
-	}
-
-	/* @q is and will stay empty, shutdown and put */
-	blk_put_queue(q);
-}
-EXPORT_SYMBOL(blk_cleanup_queue);
-
 /**
  * blk_queue_enter() - try to increase q->q_usage_counter
  * @q: request queue pointer
block/blk-mq.c +41 -2

67 lines not on this page · raw message

block/blk-sysfs.c +0 -5
index 9b905e9443e4..84d7f8701567 100644
@@ -748,11 +748,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
  * decremented with blk_put_queue(). Once the refcount reaches 0 this function
  * is called.
  *
- * For drivers that have a request_queue on a gendisk and added with
- * __device_add_disk() the refcount to request_queue will reach 0 with
- * the last put_disk() called by the driver. For drivers which don't use
- * __device_add_disk() this happens with blk_cleanup_queue().
- *
  * Drivers exist which depend on the release of the request_queue to be
  * synchronous, it should not be deferred.
  *
block/blk.h +3 -0
index 434017701403..0d6668663ab5 100644
@@ -411,6 +411,9 @@ int bdev_resize_partition(struct gendisk *disk, int partno, sector_t start,
 		sector_t length);
 void blk_drop_partitions(struct gendisk *disk);
 
+struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
+		struct lock_class_key *lkclass);
+
 int bio_add_hw_page(struct request_queue *q, struct bio *bio,
 		struct page *page, unsigned int len, unsigned int offset,
 		unsigned int max_sectors, bool *same_page);
block/bsg-lib.c +2 -2
index acfe1357bf6c..fd4cd5e68282 100644
@@ -324,7 +324,7 @@ void bsg_remove_queue(struct request_queue *q)
 			container_of(q->tag_set, struct bsg_set, tag_set);
 
 		bsg_unregister_queue(bset->bd);
-		blk_cleanup_queue(q);
+		blk_mq_destroy_queue(q);
 		blk_mq_free_tag_set(&bset->tag_set);
 		kfree(bset);
 	}
@@ -399,7 +399,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
 
 	return q;
 out_cleanup_queue:
-	blk_cleanup_queue(q);
+	blk_mq_destroy_queue(q);
 out_queue:
 	blk_mq_free_tag_set(set);
 out_tag_set:
block/genhd.c +13 -10
index 278227ba1d53..4d15f828c449 100644
@@ -617,6 +617,8 @@ void del_gendisk(struct gendisk *disk)
 	 * Fail any new I/O.
 	 */
 	set_bit(GD_DEAD, &disk->state);
+	if (test_bit(GD_OWNS_QUEUE, &disk->state))
+		blk_queue_flag_set(QUEUE_FLAG_DYING, q);
 	set_capacity(disk, 0);
 
 	/*
@@ -663,11 +665,16 @@ void del_gendisk(struct gendisk *disk)
 	blk_mq_unquiesce_queue(q);
 
 	/*
-	 * Allow using passthrough request again after the queue is torn down.
+	 * If the disk does not own the queue, allow using passthrough requests
+	 * again.  Else leave the queue frozen to fail all I/O.
 	 */
-	blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
-	__blk_mq_unfreeze_queue(q, true);
-
+	if (!test_bit(GD_OWNS_QUEUE, &disk->state)) {
+		blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
+		__blk_mq_unfreeze_queue(q, true);
+	} else {
+		if (queue_is_mq(q))
+			blk_mq_exit_queue(q);
+	}
 }
 EXPORT_SYMBOL(del_gendisk);
 
@@ -1338,9 +1345,6 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
 {
 	struct gendisk *disk;
 
-	if (!blk_get_queue(q))
-		return NULL;
-
 	disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
 	if (!disk)
 		goto out_put_queue;
@@ -1391,7 +1395,6 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
 	blk_put_queue(q);
 	return NULL;
 }
-EXPORT_SYMBOL(__alloc_disk_node);
 
 struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass)
 {
@@ -1404,9 +1407,10 @@ struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass)
 
 	disk = __alloc_disk_node(q, node, lkclass);
 	if (!disk) {
-		blk_cleanup_queue(q);
+		blk_put_queue(q);
 		return NULL;
 	}
+	set_bit(GD_OWNS_QUEUE, &disk->state);
 	return disk;
 }
 EXPORT_SYMBOL(__blk_alloc_disk);
@@ -1439,7 +1443,6 @@ EXPORT_SYMBOL(put_disk);
  */
 void blk_cleanup_disk(struct gendisk *disk)
 {
-	blk_cleanup_queue(disk->queue);
 	put_disk(disk);
 }
 EXPORT_SYMBOL(blk_cleanup_disk);
drivers/block/ataflop.c +0 -1
index e232cc4fd444..c6e41ee18aaa 100644
@@ -2045,7 +2045,6 @@ static void atari_floppy_cleanup(void)
 			if (!unit[i].disk[type])
 				continue;
 			del_gendisk(unit[i].disk[type]);
-			blk_cleanup_queue(unit[i].disk[type]->queue);
 			put_disk(unit[i].disk[type]);
 		}
 		blk_mq_free_tag_set(&unit[i].tag_set);
drivers/block/loop.c +0 -1
index a59910ef948e..1c036ef686fb 100644
@@ -2062,7 +2062,6 @@ static void loop_remove(struct loop_device *lo)
 {
 	/* Make this loop device unreachable from pathname. */
 	del_gendisk(lo->lo_disk);
-	blk_cleanup_queue(lo->lo_disk->queue);
 	blk_mq_free_tag_set(&lo->tag_set);
 
 	mutex_lock(&loop_ctl_mutex);
drivers/block/mtip32xx/mtip32xx.c +0 -2
index 6699e4b2f7f4..06994a35acc7 100644
@@ -3677,7 +3677,6 @@ static int mtip_block_shutdown(struct driver_data *dd)
 	if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
 		del_gendisk(dd->disk);
 
-	blk_cleanup_queue(dd->queue);
 	blk_mq_free_tag_set(&dd->tags);
 	put_disk(dd->disk);
 	return 0;
@@ -4040,7 +4039,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
 		dev_info(&dd->pdev->dev, "device %s surprise removal\n",
 						dd->disk->disk_name);
 
-	blk_cleanup_queue(dd->queue);
 	blk_mq_free_tag_set(&dd->tags);
 
 	/* De-initialize the protocol layer. */
drivers/block/rnbd/rnbd-clt.c +1 -1
index 409c76b81aed..a4470374f54f 100644
@@ -1755,7 +1755,7 @@ static void rnbd_destroy_sessions(void)
 		list_for_each_entry_safe(dev, tn, &sess->devs_list, list) {
 			/*
 			 * Here unmap happens in parallel for only one reason:
-			 * blk_cleanup_queue() takes around half a second, so
+			 * del_gendisk() takes around half a second, so
 			 * on huge amount of devices the whole module unload
 			 * procedure takes minutes.
 			 */
drivers/block/sx8.c +2 -2
index 63b4f6431d2e..75057dbbcfbe 100644
@@ -1536,7 +1536,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 		clear_bit(0, &carm_major_alloc);
 	else if (host->major == 161)
 		clear_bit(1, &carm_major_alloc);
-	blk_cleanup_queue(host->oob_q);
+	blk_mq_destroy_queue(host->oob_q);
 	blk_mq_free_tag_set(&host->tag_set);
 err_out_dma_free:
 	dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma);
@@ -1570,7 +1570,7 @@ static void carm_remove_one (struct pci_dev *pdev)
 		clear_bit(0, &carm_major_alloc);
 	else if (host->major == 161)
 		clear_bit(1, &carm_major_alloc);
-	blk_cleanup_queue(host->oob_q);
+	blk_mq_destroy_queue(host->oob_q);
 	blk_mq_free_tag_set(&host->tag_set);
 	dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma);
 	iounmap(host->mmio);
drivers/block/virtio_blk.c +0 -1
index d756423e0059..59d6d5faf739 100644
@@ -1107,7 +1107,6 @@ static void virtblk_remove(struct virtio_device *vdev)
 	flush_work(&vblk->config_work);
 
 	del_gendisk(vblk->disk);
-	blk_cleanup_queue(vblk->disk->queue);
 	blk_mq_free_tag_set(&vblk->tag_set);
 
 	mutex_lock(&vblk->vdev_mutex);
drivers/block/z2ram.c +0 -1
index 7a6ed83481b8..18ad43d9933e 100644
@@ -384,7 +384,6 @@ static void __exit z2_exit(void)
 
 	for (i = 0; i < Z2MINOR_COUNT; i++) {
 		del_gendisk(z2ram_gendisk[i]);
-		blk_cleanup_queue(z2ram_gendisk[i]->queue);
 		put_disk(z2ram_gendisk[i]);
 	}
 	blk_mq_free_tag_set(&tag_set);
drivers/cdrom/gdrom.c +0 -1
index 8e78b37d0f6a..f4cc90ea6198 100644
@@ -831,7 +831,6 @@ static int probe_gdrom(struct platform_device *devptr)
 
 static int remove_gdrom(struct platform_device *devptr)
 {
-	blk_cleanup_queue(gd.gdrom_rq);
 	blk_mq_free_tag_set(&gd.tag_set);
 	free_irq(HW_EVENT_GDROM_CMD, &gd);
 	free_irq(HW_EVENT_GDROM_DMA, &gd);
drivers/memstick/core/ms_block.c +0 -1
index f8fdf88fb240..ecbc46714e68 100644
@@ -2188,7 +2188,6 @@ static void msb_remove(struct memstick_dev *card)
 
 	/* Remove the disk */
 	del_gendisk(msb->disk);
-	blk_cleanup_queue(msb->queue);
 	blk_mq_free_tag_set(&msb->tag_set);
 	msb->queue = NULL;
 
drivers/memstick/core/mspro_block.c +0 -1
index 725ba74ded30..72e91c06c618 100644
@@ -1294,7 +1294,6 @@ static void mspro_block_remove(struct memstick_dev *card)
 	del_gendisk(msb->disk);
 	dev_dbg(&card->dev, "mspro block remove\n");
 
-	blk_cleanup_queue(msb->queue);
 	blk_mq_free_tag_set(&msb->tag_set);
 	msb->queue = NULL;
 
drivers/mmc/core/block.c +0 -1
index 912a398a9a76..2f89ae55c177 100644
@@ -2509,7 +2509,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
 	return md;
 
  err_cleanup_queue:
-	blk_cleanup_queue(md->disk->queue);
 	blk_mq_free_tag_set(&md->queue.tag_set);
  err_kfree:
 	kfree(md);
drivers/mmc/core/queue.c +0 -1
index fa5324ceeebe..f824cfdab75a 100644
@@ -494,7 +494,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
 	if (blk_queue_quiesced(q))
 		blk_mq_unquiesce_queue(q);
 
-	blk_cleanup_queue(q);
 	blk_mq_free_tag_set(&mq->tag_set);
 
 	/*
drivers/nvme/host/apple.c +1 -1
index d702d7d60235..2d23b7d41f7e 100644
@@ -1502,7 +1502,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
 
 	if (!blk_get_queue(anv->ctrl.admin_q)) {
 		nvme_start_admin_queue(&anv->ctrl);
-		blk_cleanup_queue(anv->ctrl.admin_q);
+		blk_mq_destroy_queue(anv->ctrl.admin_q);
 		anv->ctrl.admin_q = NULL;
 		ret = -ENODEV;
 		goto put_dev;
drivers/nvme/host/core.c +0 -1
index 2f965356f345..6d76fc608b74 100644
@@ -4105,7 +4105,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	if (!nvme_ns_head_multipath(ns->head))
 		nvme_cdev_del(&ns->cdev, &ns->cdev_device);
 	del_gendisk(ns->disk);
-	blk_cleanup_queue(ns->queue);
 
 	down_write(&ns->ctrl->namespaces_rwsem);
 	list_del_init(&ns->list);
drivers/nvme/host/fc.c +6 -6
index 4aff83b1b0c0..9a5ce70d7f21 100644
@@ -2392,7 +2392,7 @@ nvme_fc_ctrl_free(struct kref *ref)
 	unsigned long flags;
 
 	if (ctrl->ctrl.tagset) {
-		blk_cleanup_queue(ctrl->ctrl.connect_q);
+		blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 		blk_mq_free_tag_set(&ctrl->tag_set);
 	}
 
@@ -2402,8 +2402,8 @@ nvme_fc_ctrl_free(struct kref *ref)
 	spin_unlock_irqrestore(&ctrl->rport->lock, flags);
 
 	nvme_start_admin_queue(&ctrl->ctrl);
-	blk_cleanup_queue(ctrl->ctrl.admin_q);
-	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+	blk_mq_destroy_queue(ctrl->ctrl.admin_q);
+	blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 	blk_mq_free_tag_set(&ctrl->admin_tag_set);
 
 	kfree(ctrl->queues);
@@ -2953,7 +2953,7 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
 out_delete_hw_queues:
 	nvme_fc_delete_hw_io_queues(ctrl);
 out_cleanup_blk_queue:
-	blk_cleanup_queue(ctrl->ctrl.connect_q);
+	blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 out_free_tag_set:
 	blk_mq_free_tag_set(&ctrl->tag_set);
 	nvme_fc_free_io_queues(ctrl);
@@ -3642,9 +3642,9 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 	return ERR_PTR(-EIO);
 
 out_cleanup_admin_q:
-	blk_cleanup_queue(ctrl->ctrl.admin_q);
+	blk_mq_destroy_queue(ctrl->ctrl.admin_q);
 out_cleanup_fabrics_q:
-	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+	blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 out_free_admin_tag_set:
 	blk_mq_free_tag_set(&ctrl->admin_tag_set);
 out_free_queues:
drivers/nvme/host/pci.c +1 -1
index 9f6614f7dbeb..3516678d3754 100644
@@ -1760,7 +1760,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
 		 * queue to flush these to completion.
 		 */
 		nvme_start_admin_queue(&dev->ctrl);
-		blk_cleanup_queue(dev->ctrl.admin_q);
+		blk_mq_destroy_queue(dev->ctrl.admin_q);
 		blk_mq_free_tag_set(&dev->admin_tagset);
 	}
 }
drivers/nvme/host/rdma.c +6 -6
index 46c2dcf72f7e..240024dd5d85 100644
@@ -840,8 +840,8 @@ static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl,
 		bool remove)
 {
 	if (remove) {
-		blk_cleanup_queue(ctrl->ctrl.admin_q);
-		blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+		blk_mq_destroy_queue(ctrl->ctrl.admin_q);
+		blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 		blk_mq_free_tag_set(ctrl->ctrl.admin_tagset);
 	}
 	if (ctrl->async_event_sqe.data) {
@@ -935,10 +935,10 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
 	nvme_cancel_admin_tagset(&ctrl->ctrl);
 out_cleanup_queue:
 	if (new)
-		blk_cleanup_queue(ctrl->ctrl.admin_q);
+		blk_mq_destroy_queue(ctrl->ctrl.admin_q);
 out_cleanup_fabrics_q:
 	if (new)
-		blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+		blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 out_free_tagset:
 	if (new)
 		blk_mq_free_tag_set(ctrl->ctrl.admin_tagset);
@@ -957,7 +957,7 @@ static void nvme_rdma_destroy_io_queues(struct nvme_rdma_ctrl *ctrl,
 		bool remove)
 {
 	if (remove) {
-		blk_cleanup_queue(ctrl->ctrl.connect_q);
+		blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 		blk_mq_free_tag_set(ctrl->ctrl.tagset);
 	}
 	nvme_rdma_free_io_queues(ctrl);
@@ -1012,7 +1012,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
 out_cleanup_connect_q:
 	nvme_cancel_tagset(&ctrl->ctrl);
 	if (new)
-		blk_cleanup_queue(ctrl->ctrl.connect_q);
+		blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 out_free_tag_set:
 	if (new)
 		blk_mq_free_tag_set(ctrl->ctrl.tagset);
drivers/nvme/host/tcp.c +6 -6
index daa0e160e121..d7e5bbdb9b75 100644
@@ -1881,7 +1881,7 @@ static void nvme_tcp_destroy_io_queues(struct nvme_ctrl *ctrl, bool remove)
 {
 	nvme_tcp_stop_io_queues(ctrl);
 	if (remove) {
-		blk_cleanup_queue(ctrl->connect_q);
+		blk_mq_destroy_queue(ctrl->connect_q);
 		blk_mq_free_tag_set(ctrl->tagset);
 	}
 	nvme_tcp_free_io_queues(ctrl);
@@ -1936,7 +1936,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new)
 out_cleanup_connect_q:
 	nvme_cancel_tagset(ctrl);
 	if (new)
-		blk_cleanup_queue(ctrl->connect_q);
+		blk_mq_destroy_queue(ctrl->connect_q);
 out_free_tag_set:
 	if (new)
 		blk_mq_free_tag_set(ctrl->tagset);
@@ -1949,8 +1949,8 @@ static void nvme_tcp_destroy_admin_queue(struct nvme_ctrl *ctrl, bool remove)
 {
 	nvme_tcp_stop_queue(ctrl, 0);
 	if (remove) {
-		blk_cleanup_queue(ctrl->admin_q);
-		blk_cleanup_queue(ctrl->fabrics_q);
+		blk_mq_destroy_queue(ctrl->admin_q);
+		blk_mq_destroy_queue(ctrl->fabrics_q);
 		blk_mq_free_tag_set(ctrl->admin_tagset);
 	}
 	nvme_tcp_free_admin_queue(ctrl);
@@ -2008,10 +2008,10 @@ static int nvme_tcp_configure_admin_queue(struct nvme_ctrl *ctrl, bool new)
 	nvme_cancel_admin_tagset(ctrl);
 out_cleanup_queue:
 	if (new)
-		blk_cleanup_queue(ctrl->admin_q);
+		blk_mq_destroy_queue(ctrl->admin_q);
 out_cleanup_fabrics_q:
 	if (new)
-		blk_cleanup_queue(ctrl->fabrics_q);
+		blk_mq_destroy_queue(ctrl->fabrics_q);
 out_free_tagset:
 	if (new)
 		blk_mq_free_tag_set(ctrl->admin_tagset);
drivers/nvme/target/loop.c +6 -6
index 59024af2da2e..0f5c77e22a0a 100644
@@ -266,8 +266,8 @@ static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl)
 	if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags))
 		return;
 	nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
-	blk_cleanup_queue(ctrl->ctrl.admin_q);
-	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+	blk_mq_destroy_queue(ctrl->ctrl.admin_q);
+	blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 	blk_mq_free_tag_set(&ctrl->admin_tag_set);
 }
 
@@ -283,7 +283,7 @@ static void nvme_loop_free_ctrl(struct nvme_ctrl *nctrl)
 	mutex_unlock(&nvme_loop_ctrl_mutex);
 
 	if (nctrl->tagset) {
-		blk_cleanup_queue(ctrl->ctrl.connect_q);
+		blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 		blk_mq_free_tag_set(&ctrl->tag_set);
 	}
 	kfree(ctrl->queues);
@@ -410,9 +410,9 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
 
 out_cleanup_queue:
 	clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags);
-	blk_cleanup_queue(ctrl->ctrl.admin_q);
+	blk_mq_destroy_queue(ctrl->ctrl.admin_q);
 out_cleanup_fabrics_q:
-	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
+	blk_mq_destroy_queue(ctrl->ctrl.fabrics_q);
 out_free_tagset:
 	blk_mq_free_tag_set(&ctrl->admin_tag_set);
 out_free_sq:
@@ -554,7 +554,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
 	return 0;
 
 out_cleanup_connect_q:
-	blk_cleanup_queue(ctrl->ctrl.connect_q);
+	blk_mq_destroy_queue(ctrl->ctrl.connect_q);
 out_free_tagset:
 	blk_mq_free_tag_set(&ctrl->tag_set);
 out_destroy_queues:
drivers/s390/block/dasd.c +1 -1
index ba6d78789660..e8489331f12b 100644
@@ -3280,7 +3280,7 @@ static int dasd_alloc_queue(struct dasd_block *block)
 static void dasd_free_queue(struct dasd_block *block)
 {
 	if (block->request_queue) {
-		blk_cleanup_queue(block->request_queue);
+		blk_mq_destroy_queue(block->request_queue);
 		blk_mq_free_tag_set(&block->tag_set);
 		block->request_queue = NULL;
 	}
drivers/s390/block/dasd_genhd.c +2 -2
index a7a33ebf4bbe..5a83f0a39901 100644
@@ -41,8 +41,8 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 	if (base->devindex >= DASD_PER_MAJOR)
 		return -EBUSY;
 
-	gdp = __alloc_disk_node(block->request_queue, NUMA_NO_NODE,
-				&dasd_bio_compl_lkclass);
+	gdp = blk_mq_alloc_disk_for_queue(block->request_queue,
+					  &dasd_bio_compl_lkclass);
 	if (!gdp)
 		return -ENOMEM;
 
drivers/scsi/scsi_lib.c +3 -3
index f5c876d03c1a..0a267d6e2f7c 100644
@@ -168,7 +168,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
 	 * Requeue this command.  It will go before all other commands
 	 * that are already in the queue. Schedule requeue work under
 	 * lock such that the kblockd_schedule_work() call happens
-	 * before blk_cleanup_queue() finishes.
+	 * before blk_mq_destroy_queue() finishes.
 	 */
 	cmd->result = 0;
 
@@ -429,9 +429,9 @@ static void scsi_starved_list_run(struct Scsi_Host *shost)
 		 * it and the queue.  Mitigate by taking a reference to the
 		 * queue and never touching the sdev again after we drop the
 		 * host lock.  Note: if __scsi_remove_device() invokes
-		 * blk_cleanup_queue() before the queue is run from this
+		 * blk_mq_destroy_queue() before the queue is run from this
 		 * function then blk_run_queue() will return immediately since
-		 * blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING.
+		 * blk_mq_destroy_queue() marks the queue with QUEUE_FLAG_DYING.
 		 */
 		slq = sdev->request_queue;
 		if (!blk_get_queue(slq))
drivers/scsi/scsi_sysfs.c +1 -1
index 43949798a2e4..aa70d9282161 100644
@@ -1475,7 +1475,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
 	scsi_device_set_state(sdev, SDEV_DEL);
 	mutex_unlock(&sdev->state_mutex);
 
-	blk_cleanup_queue(sdev->request_queue);
+	blk_mq_destroy_queue(sdev->request_queue);
 	cancel_work_sync(&sdev->requeue_work);
 
 	if (sdev->host->hostt->slave_destroy)
drivers/scsi/sd.c +2 -2
index a1a2ac09066f..cb587e488601 100644
@@ -3440,8 +3440,8 @@ static int sd_probe(struct device *dev)
 	if (!sdkp)
 		goto out;
 
-	gd = __alloc_disk_node(sdp->request_queue, NUMA_NO_NODE,
-			       &sd_bio_compl_lkclass);
+	gd = blk_mq_alloc_disk_for_queue(sdp->request_queue,
+					 &sd_bio_compl_lkclass);
 	if (!gd)
 		goto out_free;
 
drivers/scsi/sr.c +2 -2
index 32d3b8274f14..a278b739d0c5 100644
@@ -624,8 +624,8 @@ static int sr_probe(struct device *dev)
 	if (!cd)
 		goto fail;
 
-	disk = __alloc_disk_node(sdev->request_queue, NUMA_NO_NODE,
-				 &sr_bio_compl_lkclass);
+	disk = blk_mq_alloc_disk_for_queue(sdev->request_queue,
+					   &sr_bio_compl_lkclass);
 	if (!disk)
 		goto fail_free;
 	mutex_init(&cd->lock);
drivers/ufs/core/ufshcd.c +2 -2
index 829da9cb14a8..55bb0d0422d5 100644
@@ -9519,7 +9519,7 @@ void ufshcd_remove(struct ufs_hba *hba)
 	ufs_bsg_remove(hba);
 	ufshpb_remove(hba);
 	ufs_sysfs_remove_nodes(hba->dev);
-	blk_cleanup_queue(hba->tmf_queue);
+	blk_mq_destroy_queue(hba->tmf_queue);
 	blk_mq_free_tag_set(&hba->tmf_tag_set);
 	scsi_remove_host(hba->host);
 	/* disable interrupts */
@@ -9815,7 +9815,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	return 0;
 
 free_tmf_queue:
-	blk_cleanup_queue(hba->tmf_queue);
+	blk_mq_destroy_queue(hba->tmf_queue);
 free_tmf_tag_set:
 	blk_mq_free_tag_set(&hba->tmf_tag_set);
 out_remove_scsi_host:
include/linux/blk-mq.h +3 -0
index e2d9daf7e8dd..0fd96e92c6c6 100644
@@ -686,10 +686,13 @@ struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata,
 									\
 	__blk_mq_alloc_disk(set, queuedata, &__key);			\
 })
+struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
+		struct lock_class_key *lkclass);
 struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *);
 int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
 		struct request_queue *q);
 void blk_mq_unregister_dev(struct device *, struct request_queue *);
+void blk_mq_destroy_queue(struct request_queue *);
 
 int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set);
 int blk_mq_alloc_sq_tag_set(struct blk_mq_tag_set *set,
include/linux/blkdev.h +1 -3
index 76f77eed58c3..83eb8869a8c9 100644
@@ -148,6 +148,7 @@ struct gendisk {
 #define GD_NATIVE_CAPACITY		3
 #define GD_ADDED			4
 #define GD_SUPPRESS_PART_SCAN		5
+#define GD_OWNS_QUEUE			6
 
 	struct mutex open_mutex;	/* open/close mutex */
 	unsigned open_partitions;	/* number of open partitions */
@@ -810,8 +811,6 @@ static inline u64 sb_bdev_nr_blocks(struct super_block *sb)
 
 int bdev_disk_changed(struct gendisk *disk, bool invalidate);
 
-struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
-		struct lock_class_key *lkclass);
 void put_disk(struct gendisk *disk);
 struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass);
 
@@ -953,7 +952,6 @@ static inline unsigned int blk_max_size_offset(struct request_queue *q,
 /*
  * Access functions for manipulating queue properties
  */
-extern void blk_cleanup_queue(struct request_queue *);
 void blk_queue_bounce_limit(struct request_queue *q, enum blk_bounce limit);
 extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
 extern void blk_queue_chunk_sectors(struct request_queue *, unsigned int);
Signature · 1 line
2.35.1
author maintainer
#25 lore raw

PATCH 20/207 scsi: core: Fix a use-after-free

In reply to Greg Kroah-Hartman

From: Bart Van Assche <[email protected]>

[ Upstream commit 8fe4ce5836e932f5766317cb651c1ff2a4cd0506 ]

There are two .exit_cmd_priv implementations. Both implementations use resources associated with the SCSI host. Make sure that these resources are still available when .exit_cmd_priv is called by waiting inside scsi_remove_host() until the tag set has been freed.

This commit fixes the following use-after-free:

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

BUG: KASAN: use-after-free in srp_exit_cmd_priv+0x27/0xd0 [ib_srp]
Read of size 8 at addr ffff888100337000 by task multipathd/16727
Call Trace:
 <TASK>
 dump_stack_lvl+0x34/0x44
 print_report.cold+0x5e/0x5db
 kasan_report+0xab/0x120
 srp_exit_cmd_priv+0x27/0xd0 [ib_srp]
 scsi_mq_exit_request+0x4d/0x70
 blk_mq_free_rqs+0x143/0x410
 __blk_mq_free_map_and_rqs+0x6e/0x100
 blk_mq_free_tag_set+0x2b/0x160
 scsi_host_dev_release+0xf3/0x1a0
 device_release+0x54/0xe0
 kobject_put+0xa5/0x120
 device_release+0x54/0xe0
 kobject_put+0xa5/0x120
 scsi_device_dev_release_usercontext+0x4c1/0x4e0
 execute_in_process_context+0x23/0x90
 device_release+0x54/0xe0
 kobject_put+0xa5/0x120
 scsi_disk_release+0x3f/0x50
 device_release+0x54/0xe0
 kobject_put+0xa5/0x120
 disk_release+0x17f/0x1b0
 device_release+0x54/0xe0
 kobject_put+0xa5/0x120
 dm_put_table_device+0xa3/0x160 [dm_mod]
 dm_put_device+0xd0/0x140 [dm_mod]
 free_priority_group+0xd8/0x110 [dm_multipath]
 free_multipath+0x94/0xe0 [dm_multipath]
 dm_table_destroy+0xa2/0x1e0 [dm_mod]
 __dm_destroy+0x196/0x350 [dm_mod]
 dev_remove+0x10c/0x160 [dm_mod]
 ctl_ioctl+0x2c2/0x590 [dm_mod]
 dm_ctl_ioctl+0x5/0x10 [dm_mod]
 __x64_sys_ioctl+0xb4/0xf0
 dm_ctl_ioctl+0x5/0x10 [dm_mod]
 __x64_sys_ioctl+0xb4/0xf0
 do_syscall_64+0x3b/0x90
 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Fixes 65ca846a5314 ("scsi: core: Introduce {init,exit}_cmd_priv()")
Cc Ming Lei <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Mike Christie <[email protected]>
Cc Hannes Reinecke <[email protected]>
Cc John Garry <[email protected]>
Cc Li Zhijian <[email protected]>
---
 drivers/scsi/hosts.c      | 16 +++++++++++++---
 drivers/scsi/scsi_lib.c   |  6 +++++-
 drivers/scsi/scsi_priv.h  |  2 +-
 drivers/scsi/scsi_scan.c  |  1 +
 drivers/scsi/scsi_sysfs.c |  1 +
 include/scsi/scsi_host.h  |  2 ++
 6 files changed, 23 insertions(+), 5 deletions(-)
drivers/scsi/hosts.c +13 -3
index 8352f90d997d..ae9a107c520d 100644
@@ -182,6 +182,15 @@ void scsi_remove_host(struct Scsi_Host *shost)
 	mutex_unlock(&shost->scan_mutex);
 	scsi_proc_host_rm(shost);
 
+	/*
+	 * New SCSI devices cannot be attached anymore because of the SCSI host
+	 * state so drop the tag set refcnt. Wait until the tag set refcnt drops
+	 * to zero because .exit_cmd_priv implementations may need the host
+	 * pointer.
+	 */
+	kref_put(&shost->tagset_refcnt, scsi_mq_free_tags);
+	wait_for_completion(&shost->tagset_freed);
+
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (scsi_host_set_state(shost, SHOST_DEL))
 		BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
@@ -240,6 +249,9 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
 	if (error)
 		goto fail;
 
+	kref_init(&shost->tagset_refcnt);
+	init_completion(&shost->tagset_freed);
+
 	/*
 	 * Increase usage count temporarily here so that calling
 	 * scsi_autopm_put_host() will trigger runtime idle if there is
@@ -312,6 +324,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
 	pm_runtime_disable(&shost->shost_gendev);
 	pm_runtime_set_suspended(&shost->shost_gendev);
 	pm_runtime_put_noidle(&shost->shost_gendev);
+	kref_put(&shost->tagset_refcnt, scsi_mq_free_tags);
  fail:
 	return error;
 }
@@ -345,9 +358,6 @@ static void scsi_host_dev_release(struct device *dev)
 		kfree(dev_name(&shost->shost_dev));
 	}
 
-	if (shost->tag_set.tags)
-		scsi_mq_destroy_tags(shost);
-
 	kfree(shost->shost_data);
 
 	ida_simple_remove(&host_index_ida, shost->host_no);
drivers/scsi/scsi_lib.c +5 -1
index 0a267d6e2f7c..7e990f7a9f16 100644
@@ -1995,9 +1995,13 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
 	return blk_mq_alloc_tag_set(tag_set);
 }
 
-void scsi_mq_destroy_tags(struct Scsi_Host *shost)
+void scsi_mq_free_tags(struct kref *kref)
 {
+	struct Scsi_Host *shost = container_of(kref, typeof(*shost),
+					       tagset_refcnt);
+
 	blk_mq_free_tag_set(&shost->tag_set);
+	complete(&shost->tagset_freed);
 }
 
 /**
drivers/scsi/scsi_priv.h +1 -1
index 5c4786310a31..a0ee31d55f5f 100644
@@ -94,7 +94,7 @@ extern void scsi_run_host_queues(struct Scsi_Host *shost);
 extern void scsi_requeue_run_queue(struct work_struct *work);
 extern void scsi_start_queue(struct scsi_device *sdev);
 extern int scsi_mq_setup_tags(struct Scsi_Host *shost);
-extern void scsi_mq_destroy_tags(struct Scsi_Host *shost);
+extern void scsi_mq_free_tags(struct kref *kref);
 extern void scsi_exit_queue(void);
 extern void scsi_evt_thread(struct work_struct *work);
 
drivers/scsi/scsi_scan.c +1 -0
index 91ac901a6682..5d27f5196de6 100644
@@ -340,6 +340,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
 		kfree(sdev);
 		goto out;
 	}
+	kref_get(&sdev->host->tagset_refcnt);
 	sdev->request_queue = q;
 	q->queuedata = sdev;
 	__scsi_init_queue(sdev->host, q);
drivers/scsi/scsi_sysfs.c +1 -0
index aa70d9282161..5d61f58399dc 100644
@@ -1476,6 +1476,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
 	mutex_unlock(&sdev->state_mutex);
 
 	blk_mq_destroy_queue(sdev->request_queue);
+	kref_put(&sdev->host->tagset_refcnt, scsi_mq_free_tags);
 	cancel_work_sync(&sdev->requeue_work);
 
 	if (sdev->host->hostt->slave_destroy)
include/scsi/scsi_host.h +2 -0
index 667d889b92b5..3e1cea155049 100644
@@ -557,6 +557,8 @@ struct Scsi_Host {
 	struct scsi_host_template *hostt;
 	struct scsi_transport_template *transportt;
 
+	struct kref		tagset_refcnt;
+	struct completion	tagset_freed;
 	/* Area to keep a shared tag map */
 	struct blk_mq_tag_set	tag_set;
 
Signature · 1 line
2.35.1
author maintainer
#26 lore raw

PATCH 21/207 drivers/base: Fix unsigned comparison to -1 in CPUMAP_FILE_MAX_BYTES

In reply to Greg Kroah-Hartman

From: Phil Auld <[email protected]>

commit d7f06bdd6ee87fbefa05af5f57361d85e7715b11 upstream.

As PAGE_SIZE is unsigned long, -1 > PAGE_SIZE when NR_CPUS <= 3. This leads to very large file sizes:

topology$ ls -l
total 0

-r--r--r-- 1 root root 18446744073709551615 Sep  5 11:59 core_cpus
-r--r--r-- 1 root root                 4096 Sep  5 11:59 core_cpus_list
-r--r--r-- 1 root root                 4096 Sep  5 10:58 core_id
-r--r--r-- 1 root root 18446744073709551615 Sep  5 10:10 core_siblings
-r--r--r-- 1 root root                 4096 Sep  5 11:59 core_siblings_list
-r--r--r-- 1 root root 18446744073709551615 Sep  5 11:59 die_cpus
-r--r--r-- 1 root root                 4096 Sep  5 11:59 die_cpus_list
-r--r--r-- 1 root root                 4096 Sep  5 11:59 die_id
-r--r--r-- 1 root root 18446744073709551615 Sep  5 11:59 package_cpus
-r--r--r-- 1 root root                 4096 Sep  5 11:59 package_cpus_list
-r--r--r-- 1 root root                 4096 Sep  5 10:58 physical_package_id
-r--r--r-- 1 root root 18446744073709551615 Sep  5 10:10 thread_siblings
-r--r--r-- 1 root root                 4096 Sep  5 11:59 thread_siblings_list

Adjust the inequality to catch the case when NR_CPUS is configured to a small value.

Fixes 7ee951acd31a ("drivers/base: fix userspace break from using bin_attributes for cpumap and cpulist")
Cc Greg Kroah-Hartman <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
Cc Yury Norov <[email protected]>
Cc feng xiangjun <[email protected]>
---
 include/linux/cpumask.h |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
include/linux/cpumask.h +3 -2
@@ -1083,9 +1083,10 @@ cpumap_print_list_to_buf(char *buf, cons
  * cover a worst-case of every other cpu being on one of two nodes for a
  * very large NR_CPUS.
  *
- *  Use PAGE_SIZE as a minimum for smaller configurations.
+ *  Use PAGE_SIZE as a minimum for smaller configurations while avoiding
+ *  unsigned comparison to -1.
  */
-#define CPUMAP_FILE_MAX_BYTES  ((((NR_CPUS * 9)/32 - 1) > PAGE_SIZE) \
+#define CPUMAP_FILE_MAX_BYTES  (((NR_CPUS * 9)/32 > PAGE_SIZE) \
 					? (NR_CPUS * 9)/32 - 1 : PAGE_SIZE)
 #define CPULIST_FILE_MAX_BYTES  (((NR_CPUS * 7)/2 > PAGE_SIZE) ? (NR_CPUS * 7)/2 : PAGE_SIZE)
 
author maintainer
#27 lore raw

PATCH 22/207 USB: core: Fix RST error in hub.c

In reply to Greg Kroah-Hartman

From: Alan Stern <[email protected]>

commit 766a96dc558385be735a370db867e302c8f22153 upstream.

A recent commit added an invalid RST expression to a kerneldoc comment in hub.c. The fix is trivial.

---
 drivers/usb/core/hub.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/core/hub.c +1 -1
@@ -6049,7 +6049,7 @@ re_enumerate:
  *
  * Return: The same as for usb_reset_and_verify_device().
  * However, if a reset is already in progress (for instance, if a
- * driver doesn't have pre_ or post_reset() callbacks, and while
+ * driver doesn't have pre_reset() or post_reset() callbacks, and while
  * being unbound or re-bound during the ongoing reset its disconnect()
  * or probe() routine tries to perform a second, nested reset), the
  * routine returns -EINPROGRESS.
author maintainer
#28 lore raw

PATCH 23/207 USB: serial: option: add Quectel BG95 0x0203 composition

In reply to Greg Kroah-Hartman

From: Carl Yin(殷张成) <[email protected]>

commit f8f67eff6847f9b8d753fa029723bcc54296055a upstream.

Add support for the following Quectel BG95 composition:

0x0203: Diag + GNSS + Modem + ECM

usb-devices output:

T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  2 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=0203 Rev= 0.00
S:  Manufacturer=Quectel, Incorporated
S:  Product=Quectel LPWA Module
S:  SerialNumber=71d3a21b
C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
A:  FirstIf#= 3 IfCount= 2 Cls=02(comm.) Sub=00 Prot=00
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
E:  Ad=83(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=85(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
I:  If#= 4 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
I:* If#= 4 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
---
 drivers/usb/serial/option.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -1138,6 +1138,8 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff),
 	  .driver_info = NUMEP2 },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */
+	  .driver_info = ZLP },
 	{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
 	  .driver_info = RSVD(4) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
author maintainer
#29 lore raw

PATCH 24/207 USB: serial: option: add Quectel RM520N

In reply to Greg Kroah-Hartman

From: jerry meng <[email protected]>

commit d640c4cb8f2f933c0ca896541f9de7fb1ae245f4 upstream.

add support for Quectel RM520N which is based on Qualcomm SDX62 chip.

0x0801: DIAG + NMEA + AT + MODEM + RMNET

T:  Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 10 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=0801 Rev= 5.04
S:  Manufacturer=Quectel
S:  Product=RM520N-GL
S:  SerialNumber=384af524
C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option
E:  Ad=83(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=85(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=87(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
E:  Ad=88(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
---
 drivers/usb/serial/option.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/usb/serial/option.c +4 -0
@@ -256,6 +256,7 @@ static void option_instat_callback(struc
 #define QUECTEL_PRODUCT_EM060K			0x030b
 #define QUECTEL_PRODUCT_EM12			0x0512
 #define QUECTEL_PRODUCT_RM500Q			0x0800
+#define QUECTEL_PRODUCT_RM520N			0x0801
 #define QUECTEL_PRODUCT_EC200S_CN		0x6002
 #define QUECTEL_PRODUCT_EC200T			0x6026
 #define QUECTEL_PRODUCT_RM500K			0x7001
@@ -1161,6 +1162,9 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
 	  .driver_info = ZLP },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
author maintainer
#30 lore raw

PATCH 25/207 Revert "ALSA: usb-audio: Split endpoint setups for hw_params and prepare"

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 79764ec772bc1346441ae1c4b1f3bd1991d634e8 upstream.

This reverts commit ff878b408a03bef5d610b7e2302702e16a53636e.

Unfortunately the recent fix seems bringing another regressions with PulseAudio / pipewire, at least for Steinberg and MOTU devices.

As a temporary solution, do a straight revert. The issue for Android will be revisited again later by another different fix (if any).

Fixes ff878b408a03 ("ALSA: usb-audio: Split endpoint setups for hw_params and prepare")
---
 sound/usb/endpoint.c |   23 ++++++++++++++---------
 sound/usb/endpoint.h |    6 ++----
 sound/usb/pcm.c      |   14 ++++----------
 3 files changed, 20 insertions(+), 23 deletions(-)
sound/usb/endpoint.c +14 -9
@@ -758,8 +758,7 @@ bool snd_usb_endpoint_compatible(struct
  * The endpoint needs to be closed via snd_usb_endpoint_close() later.
  *
  * Note that this function doesn't configure the endpoint.  The substream
- * needs to set it up later via snd_usb_endpoint_set_params() and
- * snd_usb_endpoint_prepare().
+ * needs to set it up later via snd_usb_endpoint_configure().
  */
 struct snd_usb_endpoint *
 snd_usb_endpoint_open(struct snd_usb_audio *chip,
@@ -1293,13 +1292,12 @@ out_of_memory:
 /*
  * snd_usb_endpoint_set_params: configure an snd_usb_endpoint
  *
- * It's called either from hw_params callback.
  * Determine the number of URBs to be used on this endpoint.
  * An endpoint must be configured before it can be started.
  * An endpoint that is already running can not be reconfigured.
  */
-int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
-				struct snd_usb_endpoint *ep)
+static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
+				       struct snd_usb_endpoint *ep)
 {
 	const struct audioformat *fmt = ep->cur_audiofmt;
 	int err;
@@ -1382,18 +1380,18 @@ static int init_sample_rate(struct snd_u
 }
 
 /*
- * snd_usb_endpoint_prepare: Prepare the endpoint
+ * snd_usb_endpoint_configure: Configure the endpoint
  *
  * This function sets up the EP to be fully usable state.
- * It's called either from prepare callback.
+ * It's called either from hw_params or prepare callback.
  * The function checks need_setup flag, and performs nothing unless needed,
  * so it's safe to call this multiple times.
  *
  * This returns zero if unchanged, 1 if the configuration has changed,
  * or a negative error code.
  */
-int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
-			     struct snd_usb_endpoint *ep)
+int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
+			       struct snd_usb_endpoint *ep)
 {
 	bool iface_first;
 	int err = 0;
@@ -1414,6 +1412,9 @@ int snd_usb_endpoint_prepare(struct snd_
 			if (err < 0)
 				goto unlock;
 		}
+		err = snd_usb_endpoint_set_params(chip, ep);
+		if (err < 0)
+			goto unlock;
 		goto done;
 	}
 
@@ -1441,6 +1442,10 @@ int snd_usb_endpoint_prepare(struct snd_
 	if (err < 0)
 		goto unlock;
 
+	err = snd_usb_endpoint_set_params(chip, ep);
+	if (err < 0)
+		goto unlock;
+
 	err = snd_usb_select_mode_quirk(chip, ep->cur_audiofmt);
 	if (err < 0)
 		goto unlock;
sound/usb/endpoint.h +2 -4
@@ -17,10 +17,8 @@ snd_usb_endpoint_open(struct snd_usb_aud
 		      bool is_sync_ep);
 void snd_usb_endpoint_close(struct snd_usb_audio *chip,
 			    struct snd_usb_endpoint *ep);
-int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
-				struct snd_usb_endpoint *ep);
-int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
-			     struct snd_usb_endpoint *ep);
+int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
+			       struct snd_usb_endpoint *ep);
 int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock);
 
 bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
sound/usb/pcm.c +4 -10
@@ -443,17 +443,17 @@ static int configure_endpoints(struct sn
 		if (stop_endpoints(subs, false))
 			sync_pending_stops(subs);
 		if (subs->sync_endpoint) {
-			err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint);
+			err = snd_usb_endpoint_configure(chip, subs->sync_endpoint);
 			if (err < 0)
 				return err;
 		}
-		err = snd_usb_endpoint_prepare(chip, subs->data_endpoint);
+		err = snd_usb_endpoint_configure(chip, subs->data_endpoint);
 		if (err < 0)
 			return err;
 		snd_usb_set_format_quirk(subs, subs->cur_audiofmt);
 	} else {
 		if (subs->sync_endpoint) {
-			err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint);
+			err = snd_usb_endpoint_configure(chip, subs->sync_endpoint);
 			if (err < 0)
 				return err;
 		}
@@ -551,13 +551,7 @@ static int snd_usb_hw_params(struct snd_
 	subs->cur_audiofmt = fmt;
 	mutex_unlock(&chip->mutex);
 
-	if (subs->sync_endpoint) {
-		ret = snd_usb_endpoint_set_params(chip, subs->sync_endpoint);
-		if (ret < 0)
-			goto unlock;
-	}
-
-	ret = snd_usb_endpoint_set_params(chip, subs->data_endpoint);
+	ret = configure_endpoints(chip, subs);
 
  unlock:
 	if (ret < 0)
author maintainer
#31 lore raw

PATCH 26/207 ALSA: core: Fix double-free at snd_card_new()

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit c3afa2a402d1ecefa59f88d55d9e765f52f75bd9 upstream.

During the code change to add the support for devres-managed card instance, we put an explicit kfree(card) call at the error path in snd_card_new(). This is needed for the early error path before the card is initialized with the device, but is rather superfluous and causes a double-free at the error path after the card instance is initialized, as the destructor of the card object already contains a kfree() call.

This patch fixes the double-free situation by removing the superfluous kfree(). Meanwhile we need to call kfree() explicitly for the early error path, so it's added there instead.

---
 sound/core/init.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
sound/core/init.c +5 -5
@@ -178,10 +178,8 @@ int snd_card_new(struct device *parent,
 		return -ENOMEM;
 
 	err = snd_card_init(card, parent, idx, xid, module, extra_size);
-	if (err < 0) {
-		kfree(card);
-		return err;
-	}
+	if (err < 0)
+		return err; /* card is freed by error handler */
 
 	*card_ret = card;
 	return 0;
@@ -231,7 +229,7 @@ int snd_devm_card_new(struct device *par
 	card->managed = true;
 	err = snd_card_init(card, parent, idx, xid, module, extra_size);
 	if (err < 0) {
-		devres_free(card);
+		devres_free(card); /* in managed mode, we need to free manually */
 		return err;
 	}
 
@@ -293,6 +291,8 @@ static int snd_card_init(struct snd_card
 		mutex_unlock(&snd_card_mutex);
 		dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
 			 idx, snd_ecards_limit - 1, err);
+		if (!card->managed)
+			kfree(card); /* manually free here, as no destructor called */
 		return err;
 	}
 	set_bit(idx, snd_cards_lock);		/* lock it */
author maintainer
#32 lore raw

PATCH 27/207 ALSA: hda/tegra: set depop delay for tegra

In reply to Greg Kroah-Hartman

From: Mohan Kumar <[email protected]>

commit 3c4d8c24fb6c44f426e447b04800b0ed61a7b5ae upstream.

Reduce the suspend time by setting depop delay to 10ms for tegra.

---
 sound/pci/hda/patch_hdmi.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -3984,6 +3984,7 @@ static int tegra_hdmi_init(struct hda_co
 
 	generic_hdmi_init_per_pins(codec);
 
+	codec->depop_delay = 10;
 	codec->patch_ops.build_pcms = tegra_hdmi_build_pcms;
 	spec->chmap.ops.chmap_cea_alloc_validate_get_type =
 		nvhdmi_chmap_cea_alloc_validate_get_type;
author maintainer
#33 lore raw

PATCH 28/207 ALSA: hda: Fix hang at HD-audio codec unbinding due to refcount saturation

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit ead3d3c5b54f76da79c079e61bacb4279ec56965 upstream.

We fixed the potential deadlock at dynamic unbinding the HD-audio codec at the commit 7206998f578d ("ALSA: hda: Fix potential deadlock at codec unbinding"), but ironically, this caused another potential deadlock. The current code uses refcount_dec() and waits for the pending task with wait_event for dropping the refcount to 0. This works fine when PCMs are assigned and actually waiting for the refcount drop.

Meanwhile, when there was no PCM assigned, the refcount_dec() call itself was supposed to drop to zero -- alas, it doesn't in reality; refcount_dec() complains, spews kernel warning and it saturates instead of dropping to 0, due to the nature of refcount_dec() implementation. This eventually blocks the wait_event() wakeup and the code get stuck there.

For avoiding the problem, we call refcount_dec_and_test() and skips the sync-wait if it already reaches to zero.

The patch does a slight code reshuffling to make sure to invoke other disconnect calls before the sync-wait, too.

---
 sound/pci/hda/hda_bind.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/hda_bind.c +2 -2
@@ -157,10 +157,10 @@ static int hda_codec_driver_remove(struc
 		return codec->bus->core.ext_ops->hdev_detach(&codec->core);
 	}
 
-	refcount_dec(&codec->pcm_ref);
 	snd_hda_codec_disconnect_pcms(codec);
 	snd_hda_jack_tbl_disconnect(codec);
-	wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref));
+	if (!refcount_dec_and_test(&codec->pcm_ref))
+		wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref));
 	snd_power_sync_ref(codec->bus->card);
 
 	if (codec->patch_ops.free)
author maintainer
#34 lore raw

PATCH 29/207 ALSA: hda: Fix Nvidia dp infoframe

In reply to Greg Kroah-Hartman

From: Mohan Kumar <[email protected]>

commit f89e409402e2aeb3bc3aa44d2b7a597959e4e6af upstream.

Nvidia HDA HW expects infoframe data bytes order same for both HDMI and DP i.e infoframe data starts from 5th bytes offset. As dp infoframe structure has 4th byte as valid infoframe data, use hdmi infoframe structure for nvidia dp infoframe to match HW behvaior.

---
 sound/pci/hda/patch_hdmi.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
sound/pci/hda/patch_hdmi.c +19 -4
@@ -170,6 +170,8 @@ struct hdmi_spec {
 	bool dyn_pcm_no_legacy;
 	/* hdmi interrupt trigger control flag for Nvidia codec */
 	bool hdmi_intr_trig_ctrl;
+	bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+
 	bool intel_hsw_fixup;	/* apply Intel platform-specific fixups */
 	/*
 	 * Non-generic VIA/NVIDIA specific
@@ -679,15 +681,24 @@ static void hdmi_pin_setup_infoframe(str
 				     int ca, int active_channels,
 				     int conn_type)
 {
+	struct hdmi_spec *spec = codec->spec;
 	union audio_infoframe ai;
 
 	memset(&ai, 0, sizeof(ai));
-	if (conn_type == 0) { /* HDMI */
+	if ((conn_type == 0) || /* HDMI */
+		/* Nvidia DisplayPort: Nvidia HW expects same layout as HDMI */
+		(conn_type == 1 && spec->nv_dp_workaround)) {
 		struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
 
-		hdmi_ai->type		= 0x84;
-		hdmi_ai->ver		= 0x01;
-		hdmi_ai->len		= 0x0a;
+		if (conn_type == 0) { /* HDMI */
+			hdmi_ai->type		= 0x84;
+			hdmi_ai->ver		= 0x01;
+			hdmi_ai->len		= 0x0a;
+		} else {/* Nvidia DP */
+			hdmi_ai->type		= 0x84;
+			hdmi_ai->ver		= 0x1b;
+			hdmi_ai->len		= 0x11 << 2;
+		}
 		hdmi_ai->CC02_CT47	= active_channels - 1;
 		hdmi_ai->CA		= ca;
 		hdmi_checksum_audio_infoframe(hdmi_ai);
@@ -3617,6 +3628,7 @@ static int patch_nvhdmi_2ch(struct hda_c
 	spec->pcm_playback.rates = SUPPORTED_RATES;
 	spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
 	spec->pcm_playback.formats = SUPPORTED_FORMATS;
+	spec->nv_dp_workaround = true;
 	return 0;
 }
 
@@ -3756,6 +3768,7 @@ static int patch_nvhdmi(struct hda_codec
 	spec->chmap.ops.chmap_cea_alloc_validate_get_type =
 		nvhdmi_chmap_cea_alloc_validate_get_type;
 	spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+	spec->nv_dp_workaround = true;
 
 	codec->link_down_at_suspend = 1;
 
@@ -3779,6 +3792,7 @@ static int patch_nvhdmi_legacy(struct hd
 	spec->chmap.ops.chmap_cea_alloc_validate_get_type =
 		nvhdmi_chmap_cea_alloc_validate_get_type;
 	spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+	spec->nv_dp_workaround = true;
 
 	codec->link_down_at_suspend = 1;
 
@@ -3993,6 +4007,7 @@ static int tegra_hdmi_init(struct hda_co
 	spec->chmap.ops.chmap_cea_alloc_validate_get_type =
 		nvhdmi_chmap_cea_alloc_validate_get_type;
 	spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+	spec->nv_dp_workaround = true;
 
 	return 0;
 }
author maintainer
#35 lore raw

PATCH 30/207 ALSA: hda: add Intel 5 Series / 3400 PCI DID

In reply to Greg Kroah-Hartman

From: Kai Vehmanen <[email protected]>

commit 4d40ceef4745536289012670103c59264e0fb3ec upstream.

Handle 0x3b57 variant with same AZX_DCAPS_INTEL_PCH_NOPM capabilities as 0x3b56. In practise this allow use of HDMI/DP display audio via i915.

---
 sound/pci/hda/hda_intel.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/hda/hda_intel.c +2 -0
@@ -2550,6 +2550,8 @@ static const struct pci_device_id azx_id
 	/* 5 Series/3400 */
 	{ PCI_DEVICE(0x8086, 0x3b56),
 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
+	{ PCI_DEVICE(0x8086, 0x3b57),
+	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
 	/* Poulsbo */
 	{ PCI_DEVICE(0x8086, 0x811b),
 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
author maintainer
#36 lore raw

PATCH 31/207 ALSA: hda/realtek: Add quirk for Huawei WRT-WX9

In reply to Greg Kroah-Hartman

From: huangwenhui <[email protected]>

commit cbcdf8c4d35cd74aee8581eb2f0453e0ecab7b05 upstream.

Fixes headphone and headset microphone detection on Huawei WRT-WX9.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9532,6 +9532,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 	SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
 	SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
+	SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
 	SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
 	SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
author maintainer
#37 lore raw

PATCH 32/207 ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5570 laptop

In reply to Greg Kroah-Hartman

From: Callum Osmotherly <[email protected]>

commit bdc9b7396f7d4d6533e70fd8d5472f505b5ef58f upstream.

The Dell Precision 5570 uses the same 4-speakers-on-ALC289 just like the previous Precision 5560. I replicated that patch onto this one, and can confirm that the audio is much better (the woofers are now working); I've tested it on my Dell Precision 5570.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9130,6 +9130,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
+	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
author maintainer
#38 lore raw

PATCH 33/207 ALSA: hda/realtek: Re-arrange quirk table entries

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit b16c8f229a58eaddfc58aab447253464abd3c85e upstream.

A few entries have been mistakenly inserted in wrong positions without considering the SSID ordering. Place them at right positions.

Fixes b7557267c233 ("ALSA: hda/realtek: Add quirk for ASUS GA402")
Fixes 94db9cc8f8fa ("ALSA: hda/realtek: Add quirk for ASUS GU603")
Fixes 739d0959fbed ("ALSA: hda: Add quirk for ASUS Flow x13")
---
 sound/pci/hda/patch_realtek.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
sound/pci/hda/patch_realtek.c +3 -3
@@ -9305,10 +9305,11 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
 	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
 	SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
+	SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
+	SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
 	SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
-	SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
 	SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
 	SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
@@ -9325,13 +9326,12 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+	SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
 	SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
 	SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
-	SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
-	SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
 	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
author maintainer
#39 lore raw

PATCH 34/207 ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack

In reply to Greg Kroah-Hartman

From: Luke D. Jones <[email protected]>

commit c611e659044168e7abcbae8ba1ea833521498fbb upstream.

Fixes up the pincfg for ASUS ROG Strix G513 headphone and mic combo jack

[ Fixed the position in the quirk table by tiwai ]

---
 sound/pci/hda/patch_realtek.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
sound/pci/hda/patch_realtek.c +11 -0
@@ -7037,6 +7037,7 @@ enum {
 	ALC294_FIXUP_ASUS_GU502_HP,
 	ALC294_FIXUP_ASUS_GU502_PINS,
 	ALC294_FIXUP_ASUS_GU502_VERBS,
+	ALC294_FIXUP_ASUS_G513_PINS,
 	ALC285_FIXUP_HP_GPIO_LED,
 	ALC285_FIXUP_HP_MUTE_LED,
 	ALC236_FIXUP_HP_GPIO_LED,
@@ -8375,6 +8376,15 @@ static const struct hda_fixup alc269_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc294_fixup_gu502_hp,
 	},
+	 [ALC294_FIXUP_ASUS_G513_PINS] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+				{ 0x19, 0x03a11050 }, /* front HP mic */
+				{ 0x1a, 0x03a11c30 }, /* rear external mic */
+				{ 0x21, 0x03211420 }, /* front HP out */
+				{ }
+		},
+	},
 	[ALC294_FIXUP_ASUS_COEF_1B] = {
 		.type = HDA_FIXUP_VERBS,
 		.v.verbs = (const struct hda_verb[]) {
@@ -9330,6 +9340,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
 	SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
 	SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
+	SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
author maintainer
#40 lore raw

PATCH 35/207 ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack

In reply to Greg Kroah-Hartman

From: Luke D. Jones <[email protected]>

commit bc2c23549ccd7105eb6ff0d4f0ac519285628673 upstream.

Fixes up the pincfg for ASUS ROG Strix G15 (G533Z) headphone combo jack

[ Fixed the position in the quirk table by tiwai ]

---
 sound/pci/hda/patch_realtek.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
sound/pci/hda/patch_realtek.c +11 -0
@@ -7038,6 +7038,7 @@ enum {
 	ALC294_FIXUP_ASUS_GU502_PINS,
 	ALC294_FIXUP_ASUS_GU502_VERBS,
 	ALC294_FIXUP_ASUS_G513_PINS,
+	ALC285_FIXUP_ASUS_G533Z_PINS,
 	ALC285_FIXUP_HP_GPIO_LED,
 	ALC285_FIXUP_HP_MUTE_LED,
 	ALC236_FIXUP_HP_GPIO_LED,
@@ -8385,6 +8386,15 @@ static const struct hda_fixup alc269_fix
 				{ }
 		},
 	},
+	[ALC285_FIXUP_ASUS_G533Z_PINS] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x14, 0x90170120 },
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC294_FIXUP_ASUS_G513_PINS,
+	},
 	[ALC294_FIXUP_ASUS_COEF_1B] = {
 		.type = HDA_FIXUP_VERBS,
 		.v.verbs = (const struct hda_verb[]) {
@@ -9335,6 +9345,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+	SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
 	SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
author maintainer
#41 lore raw

PATCH 36/207 ALSA: hda/realtek: Add quirk for ASUS GA503R laptop

In reply to Greg Kroah-Hartman

From: Luke D. Jones <[email protected]>

commit ba1f818053b0668a1ce2fe86b840e81b592cc560 upstream.

The ASUS G15 2022 (GA503R) series laptop has the same node-to-DAC pairs as early models and the G14, this includes bass speakers which are by default mapped incorrectly to the 0x06 node.

Add a quirk to use the same DAC pairs as the G14.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9353,6 +9353,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+	SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
 	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
author maintainer
#42 lore raw

PATCH 37/207 ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop

In reply to Greg Kroah-Hartman

From: Callum Osmotherly <[email protected]>

commit 1885ff13d4c42910b37a0e3f7c2f182520f4eed1 upstream.

Just as with the 5570 (and the other Dell laptops), this enables the two subwoofer speakers on the Dell Precision 5530 together with the main ones, significantly increasing the audio quality. I've tested this myself on a 5530 and can confirm it's working as expected.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9134,6 +9134,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
+	SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK),
 	SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
author maintainer
#43 lore raw

PATCH 38/207 ALSA: hda/realtek: Add a quirk for HP OMEN 16 (8902) mute LED

In reply to Greg Kroah-Hartman

From: Daniel Houldsworth <[email protected]>

commit 496322302bf1e58dc2ff134173527493105f51ab upstream.

Similair to the HP OMEN 15, the HP OMEN 16 also needs ALC285_FIXUP_HP_MUTE_LED for the mute LED to work.

[ Rearranged the entry in PCI SSID order by tiwai ]

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9279,6 +9279,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
 	SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
+	SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
 	SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
author maintainer
#44 lore raw

PATCH 39/207 iommu/vt-d: Check correct capability for sagaw determination

In reply to Greg Kroah-Hartman

From: Yi Liu <[email protected]>

commit 154897807050c1161cb2660e502fc0470d46b986 upstream.

Check 5-level paging capability for 57 bits address width instead of checking 1GB large page capability.

---
 drivers/iommu/intel/iommu.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/iommu.c +1 -1
@@ -419,7 +419,7 @@ static unsigned long __iommu_calculate_s
 {
 	unsigned long fl_sagaw, sl_sagaw;
 
-	fl_sagaw = BIT(2) | (cap_fl1gp_support(iommu->cap) ? BIT(3) : 0);
+	fl_sagaw = BIT(2) | (cap_5lp_support(iommu->cap) ? BIT(3) : 0);
 	sl_sagaw = cap_sagaw(iommu->cap);
 
 	/* Second level only. */
author maintainer
#45 lore raw

PATCH 40/207 exfat: fix overflow for large capacity partition

In reply to Greg Kroah-Hartman

From: Yuezhang Mo <[email protected]>

commit 2e9ceb6728f1dc2fa4b5d08f37d88cbc49a20a62 upstream.

Using int type for sector index, there will be overflow in a large capacity partition.

For example, if storage with sector size of 512 bytes and partition capacity is larger than 2TB, there will be overflow.

Fixes 1b6138385499 ("exfat: reduce block requests when zeroing a cluster")
Cc [email protected] # v5.19+
---
 fs/exfat/fatent.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/exfat/fatent.c +1 -2
index ee0b7cf51157..41ae4cce1f42 100644
@@ -270,8 +270,7 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
 	struct super_block *sb = dir->i_sb;
 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
 	struct buffer_head *bh;
-	sector_t blknr, last_blknr;
-	int i;
+	sector_t blknr, last_blknr, i;
 
 	blknr = exfat_cluster_to_sector(sbi, clu);
 	last_blknr = blknr + sbi->sect_per_clus;
Signature · 1 line
2.37.3
author maintainer
#46 lore raw

PATCH 41/207 btrfs: fix hang during unmount when stopping block group reclaim worker

In reply to Greg Kroah-Hartman

From: Filipe Manana <[email protected]>

commit 8a1f1e3d1eecf9d2359a2709e276743a67e145db upstream.

During early unmount, at close_ctree(), we try to stop the block group reclaim task with cancel_work_sync(), but that may hang if the block group reclaim task is currently at btrfs_relocate_block_group() waiting for the flag BTRFS_FS_UNFINISHED_DROPS to be cleared from fs_info->flags. During unmount we only clear that flag later, after trying to stop the block group reclaim task.

Fix that by clearing BTRFS_FS_UNFINISHED_DROPS before trying to stop the block group reclaim task and after setting BTRFS_FS_CLOSING_START, so that if the reclaim task is waiting on that bit, it will stop immediately after being woken, because it sees the filesystem is closing (with a call to btrfs_fs_closing()), and then returns immediately with -EINTR.

Fixes 31e70e527806c5 ("btrfs: fix hang during unmount when block group reclaim task is running")
---
 fs/btrfs/disk-io.c |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
fs/btrfs/disk-io.c +11 -6
@@ -4587,6 +4587,17 @@ void __cold close_ctree(struct btrfs_fs_
 	set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags);
 
 	/*
+	 * If we had UNFINISHED_DROPS we could still be processing them, so
+	 * clear that bit and wake up relocation so it can stop.
+	 * We must do this before stopping the block group reclaim task, because
+	 * at btrfs_relocate_block_group() we wait for this bit, and after the
+	 * wait we stop with -EINTR if btrfs_fs_closing() returns non-zero - we
+	 * have just set BTRFS_FS_CLOSING_START, so btrfs_fs_closing() will
+	 * return 1.
+	 */
+	btrfs_wake_unfinished_drop(fs_info);
+
+	/*
 	 * We may have the reclaim task running and relocating a data block group,
 	 * in which case it may create delayed iputs. So stop it before we park
 	 * the cleaner kthread otherwise we can get new delayed iputs after
@@ -4604,12 +4615,6 @@ void __cold close_ctree(struct btrfs_fs_
 	 */
 	kthread_park(fs_info->cleaner_kthread);
 
-	/*
-	 * If we had UNFINISHED_DROPS we could still be processing them, so
-	 * clear that bit and wake up relocation so it can stop.
-	 */
-	btrfs_wake_unfinished_drop(fs_info);
-
 	/* wait for the qgroup rescan worker to stop */
 	btrfs_qgroup_wait_for_completion(fs_info, false);
 
author maintainer
#47 lore raw

PATCH 42/207 btrfs: fix hang during unmount when stopping a space reclaim worker

In reply to Greg Kroah-Hartman

From: Filipe Manana <[email protected]>

commit a362bb864b8db4861977d00bd2c3222503ccc34b upstream.

Often when running generic/562 from fstests we can hang during unmount, resulting in a trace like this:

  Sep 07 11:52:00 debian9 unknown: run fstests generic/562 at 2022-09-07 11:52:00
  Sep 07 11:55:32 debian9 kernel: INFO: task umount:49438 blocked for more than 120 seconds.
  Sep 07 11:55:32 debian9 kernel:       Not tainted 6.0.0-rc2-btrfs-next-122 #1
  Sep 07 11:55:32 debian9 kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  Sep 07 11:55:32 debian9 kernel: task:umount          state:D stack:    0 pid:49438 ppid: 25683 flags:0x00004000
  Sep 07 11:55:32 debian9 kernel: Call Trace:
  Sep 07 11:55:32 debian9 kernel:  <TASK>
  Sep 07 11:55:32 debian9 kernel:  __schedule+0x3c8/0xec0
  Sep 07 11:55:32 debian9 kernel:  ? rcu_read_lock_sched_held+0x12/0x70
  Sep 07 11:55:32 debian9 kernel:  schedule+0x5d/0xf0
  Sep 07 11:55:32 debian9 kernel:  schedule_timeout+0xf1/0x130
  Sep 07 11:55:32 debian9 kernel:  ? lock_release+0x224/0x4a0
  Sep 07 11:55:32 debian9 kernel:  ? lock_acquired+0x1a0/0x420
  Sep 07 11:55:32 debian9 kernel:  ? trace_hardirqs_on+0x2c/0xd0
  Sep 07 11:55:32 debian9 kernel:  __wait_for_common+0xac/0x200
  Sep 07 11:55:32 debian9 kernel:  ? usleep_range_state+0xb0/0xb0
  Sep 07 11:55:32 debian9 kernel:  __flush_work+0x26d/0x530
  Sep 07 11:55:32 debian9 kernel:  ? flush_workqueue_prep_pwqs+0x140/0x140
  Sep 07 11:55:32 debian9 kernel:  ? trace_clock_local+0xc/0x30
  Sep 07 11:55:32 debian9 kernel:  __cancel_work_timer+0x11f/0x1b0
  Sep 07 11:55:32 debian9 kernel:  ? close_ctree+0x12b/0x5b3 [btrfs]
  Sep 07 11:55:32 debian9 kernel:  ? __trace_bputs+0x10b/0x170
  Sep 07 11:55:32 debian9 kernel:  close_ctree+0x152/0x5b3 [btrfs]
  Sep 07 11:55:32 debian9 kernel:  ? evict_inodes+0x166/0x1c0
  Sep 07 11:55:32 debian9 kernel:  generic_shutdown_super+0x71/0x120
  Sep 07 11:55:32 debian9 kernel:  kill_anon_super+0x14/0x30
  Sep 07 11:55:32 debian9 kernel:  btrfs_kill_super+0x12/0x20 [btrfs]
  Sep 07 11:55:32 debian9 kernel:  deactivate_locked_super+0x2e/0xa0
  Sep 07 11:55:32 debian9 kernel:  cleanup_mnt+0x100/0x160
  Sep 07 11:55:32 debian9 kernel:  task_work_run+0x59/0xa0
  Sep 07 11:55:32 debian9 kernel:  exit_to_user_mode_prepare+0x1a6/0x1b0
  Sep 07 11:55:32 debian9 kernel:  syscall_exit_to_user_mode+0x16/0x40
  Sep 07 11:55:32 debian9 kernel:  do_syscall_64+0x48/0x90
  Sep 07 11:55:32 debian9 kernel:  entry_SYSCALL_64_after_hwframe+0x63/0xcd
  Sep 07 11:55:32 debian9 kernel: RIP: 0033:0x7fcde59a57a7
  Sep 07 11:55:32 debian9 kernel: RSP: 002b:00007ffe914217c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
  Sep 07 11:55:32 debian9 kernel: RAX: 0000000000000000 RBX: 00007fcde5ae8264 RCX: 00007fcde59a57a7
  Sep 07 11:55:32 debian9 kernel: RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000055b57556cdd0
  Sep 07 11:55:32 debian9 kernel: RBP: 000055b57556cba0 R08: 0000000000000000 R09: 00007ffe91420570
  Sep 07 11:55:32 debian9 kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
  Sep 07 11:55:32 debian9 kernel: R13: 000055b57556cdd0 R14: 000055b57556ccb8 R15: 0000000000000000
  Sep 07 11:55:32 debian9 kernel:  </TASK>

What happens is the following:

1) The cleaner kthread tries to start a transaction to delete an unused block group, but the metadata reservation can not be satisfied right away, so a reservation ticket is created and it starts the async metadata reclaim task (fs_info->async_reclaim_work);

2) Writeback for all the filler inodes with an i_size of 2K starts (generic/562 creates a lot of 2K files with the goal of filling metadata space). We try to create an inline extent for them, but we fail when trying to insert the inline extent with -ENOSPC (at cow_file_range_inline()) - since this is not critical, we fallback to non-inline mode (back to cow_file_range()), reserve extents, create extent maps and create the ordered extents;

3) An unmount starts, enters close_ctree();

4) The async reclaim task is flushing stuff, entering the flush states one by one, until it reaches RUN_DELAYED_IPUTS. There it runs all current delayed iputs.

After running the delayed iputs and before calling btrfs_wait_on_delayed_iputs(), one or more ordered extents complete, and btrfs_add_delayed_iput() is called for each one through btrfs_finish_ordered_io() -> btrfs_put_ordered_extent(). This results in bumping fs_info->nr_delayed_iputs from 0 to some positive value.

So the async reclaim task blocks at btrfs_wait_on_delayed_iputs() waiting for fs_info->nr_delayed_iputs to become 0;

5) The current transaction is committed by the transaction kthread, we then start unpinning extents and end up calling btrfs_try_granting_tickets() through unpin_extent_range(), since we released some space. This results in satisfying the ticket created by the cleaner kthread at step 1, waking up the cleaner kthread;

6) At close_ctree() we ask the cleaner kthread to park;

7) The cleaner kthread starts the transaction, deletes the unused block group, and then calls kthread_should_park(), which returns true, so it parks. And at this point we have the delayed iputs added by the completion of the ordered extents still pending;

8) Then later at close_ctree(), when we call:

       cancel_work_sync(&fs_info->async_reclaim_work);

We hang forever, since the cleaner was parked and no one else can run delayed iputs after that, while the reclaim task is waiting for the remaining delayed iputs to be completed.

Fix this by waiting for all ordered extents to complete and running the delayed iputs before attempting to stop the async reclaim tasks. Note that we can not wait for ordered extents with btrfs_wait_ordered_roots() (or other similar functions) because that waits for the BTRFS_ORDERED_COMPLETE flag to be set on an ordered extent, but the delayed iput is added after that, when doing the final btrfs_put_ordered_extent(). So instead wait for the work queues used for executing ordered extent completion to be empty, which works because we do the final put on an ordered extent at btrfs_finish_ordered_io() (while we are in the unmount context).

Fixes d6fd0ae25c6495 ("Btrfs: fix missing delayed iputs on unmount")
---
 fs/btrfs/disk-io.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
fs/btrfs/disk-io.c +25 -0
@@ -4637,6 +4637,31 @@ void __cold close_ctree(struct btrfs_fs_
 	/* clear out the rbtree of defraggable inodes */
 	btrfs_cleanup_defrag_inodes(fs_info);
 
+	/*
+	 * After we parked the cleaner kthread, ordered extents may have
+	 * completed and created new delayed iputs. If one of the async reclaim
+	 * tasks is running and in the RUN_DELAYED_IPUTS flush state, then we
+	 * can hang forever trying to stop it, because if a delayed iput is
+	 * added after it ran btrfs_run_delayed_iputs() and before it called
+	 * btrfs_wait_on_delayed_iputs(), it will hang forever since there is
+	 * no one else to run iputs.
+	 *
+	 * So wait for all ongoing ordered extents to complete and then run
+	 * delayed iputs. This works because once we reach this point no one
+	 * can either create new ordered extents nor create delayed iputs
+	 * through some other means.
+	 *
+	 * Also note that btrfs_wait_ordered_roots() is not safe here, because
+	 * it waits for BTRFS_ORDERED_COMPLETE to be set on an ordered extent,
+	 * but the delayed iput for the respective inode is made only when doing
+	 * the final btrfs_put_ordered_extent() (which must happen at
+	 * btrfs_finish_ordered_io() when we are unmounting).
+	 */
+	btrfs_flush_workqueue(fs_info->endio_write_workers);
+	/* Ordered extents for free space inodes. */
+	btrfs_flush_workqueue(fs_info->endio_freespace_worker);
+	btrfs_run_delayed_iputs(fs_info);
+
 	cancel_work_sync(&fs_info->async_reclaim_work);
 	cancel_work_sync(&fs_info->async_data_reclaim_work);
 	cancel_work_sync(&fs_info->preempt_reclaim_work);
author maintainer
#48 lore raw

PATCH 43/207 btrfs: zoned: wait for extent buffer IOs before finishing a zone

In reply to Greg Kroah-Hartman

From: Naohiro Aota <[email protected]>

commit 2dd7e7bc02829eded71be2342a93dc035f5223f9 upstream.

Before sending REQ_OP_ZONE_FINISH to a zone, we need to ensure that ongoing IOs already finished. Or, we will see a "Zone Is Full" error for the IOs, as the ZONE_FINISH command makes the zone full.

We ensure that with btrfs_wait_block_group_reservations() and btrfs_wait_ordered_roots() for a data block group. And, for a metadata block group, the comparison of alloc_offset vs meta_write_pointer mostly ensures IOs for the allocated region already sent. However, there still can be a little time frame where the IOs are sent but not yet completed.

Introduce wait_eb_writebacks() to ensure such IOs are completed for a metadata block group. It walks the buffer_radix to find extent buffers in the block group and calls wait_on_extent_buffer_writeback() on them.

Fixes afba2bc036b0 ("btrfs: zoned: implement active zone tracking")
---
 fs/btrfs/zoned.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)
fs/btrfs/zoned.c +38 -2
index 62e7007a7e46..73c6929f7be6 100644
@@ -1918,10 +1918,44 @@ out_unlock:
 	return ret;
 }
 
+static void wait_eb_writebacks(struct btrfs_block_group *block_group)
+{
+	struct btrfs_fs_info *fs_info = block_group->fs_info;
+	const u64 end = block_group->start + block_group->length;
+	struct radix_tree_iter iter;
+	struct extent_buffer *eb;
+	void __rcu **slot;
+
+	rcu_read_lock();
+	radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter,
+				 block_group->start >> fs_info->sectorsize_bits) {
+		eb = radix_tree_deref_slot(slot);
+		if (!eb)
+			continue;
+		if (radix_tree_deref_retry(eb)) {
+			slot = radix_tree_iter_retry(&iter);
+			continue;
+		}
+
+		if (eb->start < block_group->start)
+			continue;
+		if (eb->start >= end)
+			break;
+
+		slot = radix_tree_iter_resume(slot, &iter);
+		rcu_read_unlock();
+		wait_on_extent_buffer_writeback(eb);
+		rcu_read_lock();
+	}
+	rcu_read_unlock();
+}
+
 static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_written)
 {
 	struct btrfs_fs_info *fs_info = block_group->fs_info;
 	struct map_lookup *map;
+	const bool is_metadata = (block_group->flags &
+			(BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM));
 	int ret = 0;
 	int i;
 
@@ -1932,8 +1966,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
 	}
 
 	/* Check if we have unwritten allocated space */
-	if ((block_group->flags &
-	     (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM)) &&
+	if (is_metadata &&
 	    block_group->start + block_group->alloc_offset > block_group->meta_write_pointer) {
 		spin_unlock(&block_group->lock);
 		return -EAGAIN;
@@ -1958,6 +1991,9 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
 		/* No need to wait for NOCOW writers. Zoned mode does not allow that */
 		btrfs_wait_ordered_roots(fs_info, U64_MAX, block_group->start,
 					 block_group->length);
+		/* Wait for extent buffers to be written. */
+		if (is_metadata)
+			wait_eb_writebacks(block_group);
 
 		spin_lock(&block_group->lock);
 
Signature · 1 line
2.37.3
author maintainer
#49 lore raw

PATCH 44/207 libperf evlist: Fix polling of system-wide events

In reply to Greg Kroah-Hartman

From: Adrian Hunter <[email protected]>

commit 6cc447964555df209c590756bd804d3bb9ce1fe0 upstream.

Originally, (refer commit f90d194a867a5a1d ("perf evlist: Do not poll events that use the system_wide flag") there wasn't much reason to poll system-wide events because:

1. The mmaps get "merged" via set-output anyway (the per-cpu case)
2. perf reads all mmaps when any event is woken
3. system-wide mmaps do not fill up as fast as the mmaps for user selected events

But there was 1 reason not to poll which was that it prevented correct termination due to POLLHUP on all user selected events. That issue is now easily resolved by using fdarray_flag__nonfilterable.

With the advent of commit ae4f8ae16a078964 ("libperf evlist: Allow mixing per-thread and per-cpu mmaps"), system-wide mmaps can be used also in the per-thread case where reason 1 does not apply.

Fix the omission of system-wide events from polling by using the fdarray_flag__nonfilterable flag.

Example:

Before:

    $ perf record --no-bpf-event -vvv -e intel_pt// --per-thread uname 2>err.txt
    Linux
    $ grep 'sys_perf_event_open.*=\|pollfd' err.txt
    sys_perf_event_open: pid 155076  cpu -1  group_fd -1  flags 0x8 = 5
    sys_perf_event_open: pid 155076  cpu -1  group_fd -1  flags 0x8 = 6
    sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 7
    sys_perf_event_open: pid -1  cpu 1  group_fd -1  flags 0x8 = 9
    sys_perf_event_open: pid -1  cpu 2  group_fd -1  flags 0x8 = 10
    sys_perf_event_open: pid -1  cpu 3  group_fd -1  flags 0x8 = 11
    sys_perf_event_open: pid -1  cpu 4  group_fd -1  flags 0x8 = 12
    sys_perf_event_open: pid -1  cpu 5  group_fd -1  flags 0x8 = 13
    sys_perf_event_open: pid -1  cpu 6  group_fd -1  flags 0x8 = 14
    sys_perf_event_open: pid -1  cpu 7  group_fd -1  flags 0x8 = 15
    thread_data[0x55fb43c29e80]: pollfd[0] <- event_fd=5
    thread_data[0x55fb43c29e80]: pollfd[1] <- event_fd=6
    thread_data[0x55fb43c29e80]: pollfd[2] <- non_perf_event fd=4

After:

    $ perf record --no-bpf-event -vvv -e intel_pt// --per-thread uname 2>err.txt
    Linux
    $ grep 'sys_perf_event_open.*=\|pollfd' err.txt
    sys_perf_event_open: pid 156316  cpu -1  group_fd -1  flags 0x8 = 5
    sys_perf_event_open: pid 156316  cpu -1  group_fd -1  flags 0x8 = 6
    sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 7
    sys_perf_event_open: pid -1  cpu 1  group_fd -1  flags 0x8 = 9
    sys_perf_event_open: pid -1  cpu 2  group_fd -1  flags 0x8 = 10
    sys_perf_event_open: pid -1  cpu 3  group_fd -1  flags 0x8 = 11
    sys_perf_event_open: pid -1  cpu 4  group_fd -1  flags 0x8 = 12
    sys_perf_event_open: pid -1  cpu 5  group_fd -1  flags 0x8 = 13
    sys_perf_event_open: pid -1  cpu 6  group_fd -1  flags 0x8 = 14
    sys_perf_event_open: pid -1  cpu 7  group_fd -1  flags 0x8 = 15
    thread_data[0x55cc19e58e80]: pollfd[0] <- event_fd=5
    thread_data[0x55cc19e58e80]: pollfd[1] <- event_fd=6
    thread_data[0x55cc19e58e80]: pollfd[2] <- event_fd=7
    thread_data[0x55cc19e58e80]: pollfd[3] <- event_fd=9
    thread_data[0x55cc19e58e80]: pollfd[4] <- event_fd=10
    thread_data[0x55cc19e58e80]: pollfd[5] <- event_fd=11
    thread_data[0x55cc19e58e80]: pollfd[6] <- event_fd=12
    thread_data[0x55cc19e58e80]: pollfd[7] <- event_fd=13
    thread_data[0x55cc19e58e80]: pollfd[8] <- event_fd=14
    thread_data[0x55cc19e58e80]: pollfd[9] <- event_fd=15
    thread_data[0x55cc19e58e80]: pollfd[10] <- non_perf_event fd=4
Fixes ae4f8ae16a078964 ("libperf evlist: Allow mixing per-thread and per-cpu mmaps")
Cc Ian Rogers <[email protected]>
Cc Jiri Olsa <[email protected]>
---
 tools/lib/perf/evlist.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
tools/lib/perf/evlist.c +3 -2
index 6b1bafe267a4..8ec5b9f344e0 100644
@@ -441,6 +441,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
 
 	perf_evlist__for_each_entry(evlist, evsel) {
 		bool overwrite = evsel->attr.write_backward;
+		enum fdarray_flags flgs;
 		struct perf_mmap *map;
 		int *output, fd, cpu;
 
@@ -504,8 +505,8 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
 
 		revent = !overwrite ? POLLIN : 0;
 
-		if (!evsel->system_wide &&
-		    perf_evlist__add_pollfd(evlist, fd, map, revent, fdarray_flag__default) < 0) {
+		flgs = evsel->system_wide ? fdarray_flag__nonfilterable : fdarray_flag__default;
+		if (perf_evlist__add_pollfd(evlist, fd, map, revent, flgs) < 0) {
 			perf_mmap__put(map);
 			return -1;
 		}
Signature · 1 line
2.37.3
author maintainer
#50 lore raw

PATCH 45/207 media: flexcop-usb: fix endpoint type check

In reply to Greg Kroah-Hartman

From: Johan Hovold <[email protected]>

commit 763679f0eeff0185fc431498849bbc1c24460875 upstream.

Commit d725d20e81c2 ("media: flexcop-usb: sanity checking of endpoint type") tried to add an endpoint type sanity check for the single isochronous endpoint but instead broke the driver by checking the wrong descriptor or random data beyond the last endpoint descriptor.

Make sure to check the right endpoint descriptor.

Fixes d725d20e81c2 ("media: flexcop-usb: sanity checking of endpoint type")
Cc Oliver Neukum <[email protected]>
---
 drivers/media/usb/b2c2/flexcop-usb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/b2c2/flexcop-usb.c +1 -1
@@ -511,7 +511,7 @@ static int flexcop_usb_init(struct flexc
 
 	if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1)
 		return -ENODEV;
-	if (!usb_endpoint_is_isoc_in(&fc_usb->uintf->cur_altsetting->endpoint[1].desc))
+	if (!usb_endpoint_is_isoc_in(&fc_usb->uintf->cur_altsetting->endpoint[0].desc))
 		return -ENODEV;
 
 	switch (fc_usb->udev->speed) {
author maintainer
#51 lore raw

PATCH 46/207 usb: dwc3: core: leave default DMA if the controller does not support 64-bit DMA

In reply to Greg Kroah-Hartman

From: William Wu <[email protected]>

commit 91062e663b261815573ce00967b1895a99e668df upstream.

On some DWC3 controllers (e.g. Rockchip SoCs), the DWC3 core doesn't support 64-bit DMA address width. In this case, this driver should use the default 32-bit mask. Otherwise, the DWC3 controller will break if it runs on above 4GB physical memory environment.

This patch reads the DWC_USB3_AWIDTH bits of GHWPARAMS0 which used for the DMA address width, and only configure 64-bit DMA mask if the DWC_USB3_AWIDTH is 64.

Fixes 45d39448b4d0 ("usb: dwc3: support 64 bit DMA in platform driver")
Cc stable <[email protected]>
---
 drivers/usb/dwc3/core.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/usb/dwc3/core.c +7 -6
@@ -1718,12 +1718,6 @@ static int dwc3_probe(struct platform_de
 
 	dwc3_get_properties(dwc);
 
-	if (!dwc->sysdev_is_parent) {
-		ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
-		if (ret)
-			return ret;
-	}
-
 	dwc->reset = devm_reset_control_array_get_optional_shared(dev);
 	if (IS_ERR(dwc->reset))
 		return PTR_ERR(dwc->reset);
@@ -1789,6 +1783,13 @@ static int dwc3_probe(struct platform_de
 	platform_set_drvdata(pdev, dwc);
 	dwc3_cache_hwparams(dwc);
 
+	if (!dwc->sysdev_is_parent &&
+	    DWC3_GHWPARAMS0_AWIDTH(dwc->hwparams.hwparams0) == 64) {
+		ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
+		if (ret)
+			goto disable_clks;
+	}
+
 	spin_lock_init(&dwc->lock);
 	mutex_init(&dwc->mutex);
 
author maintainer
#52 lore raw

PATCH 47/207 thunderbolt: Add support for Intel Maple Ridge single port controller

In reply to Greg Kroah-Hartman

From: Gil Fine <[email protected]>

commit 14c7d905283744809e6b82efae2f490660a11cda upstream.

Add support for Maple Ridge discrete USB4 host controller from Intel which has a single USB4 port (versus the already supported dual port Maple Ridge USB4 host controller).

---
 drivers/thunderbolt/icm.c |    1 +
 drivers/thunderbolt/nhi.h |    1 +
 2 files changed, 2 insertions(+)
drivers/thunderbolt/icm.c +1 -0
@@ -2527,6 +2527,7 @@ struct tb *icm_probe(struct tb_nhi *nhi)
 		tb->cm_ops = &icm_icl_ops;
 		break;
 
+	case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI:
 	case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI:
 		icm->is_supported = icm_tgl_is_supported;
 		icm->get_mode = icm_ar_get_mode;
drivers/thunderbolt/nhi.h +1 -0
@@ -55,6 +55,7 @@ extern const struct tb_nhi_ops icl_nhi_o
  * need for the PCI quirk anymore as we will use ICM also on Apple
  * hardware.
  */
+#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI		0x1134
 #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI		0x1137
 #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI            0x157d
 #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE         0x157e
author maintainer
#53 lore raw

PATCH 48/207 efi: x86: Wipe setup_data on pure EFI boot

In reply to Greg Kroah-Hartman

From: Ard Biesheuvel <[email protected]>

commit 63bf28ceb3ebbe76048c3fb2987996ca1ae64f83 upstream.

When booting the x86 kernel via EFI using the LoadImage/StartImage boot services [as opposed to the deprecated EFI handover protocol], the setup header is taken from the image directly, and given that EFI's LoadImage has no Linux/x86 specific knowledge regarding struct bootparams or struct setup_header, any absolute addresses in the setup header must originate from the file and not from a prior loading stage.

Since we cannot generally predict where LoadImage() decides to load an image (*), such absolute addresses must be treated as suspect: even if a prior boot stage intended to make them point somewhere inside the [signed] image, there is no way to validate that, and if they point at an arbitrary location in memory, the setup_data nodes will not be covered by any signatures or TPM measurements either, and could be made to contain an arbitrary sequence of SETUP_xxx nodes, which could interfere quite badly with the early x86 boot sequence.

(*) Note that, while LoadImage() does take a buffer/size tuple in addition to a device path, which can be used to provide the image contents directly, it will re-allocate such images, as the memory footprint of an image is generally larger than the PE/COFF file representation.

---
 drivers/firmware/efi/libstub/x86-stub.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/firmware/efi/libstub/x86-stub.c +7 -0
@@ -517,6 +517,13 @@ efi_status_t __efiapi efi_pe_entry(efi_h
 	hdr->ramdisk_image = 0;
 	hdr->ramdisk_size = 0;
 
+	/*
+	 * Disregard any setup data that was provided by the bootloader:
+	 * setup_data could be pointing anywhere, and we have no way of
+	 * authenticating or validating the payload.
+	 */
+	hdr->setup_data = 0;
+
 	efi_stub_entry(handle, sys_table_arg, boot_params);
 	/* not reached */
 
author maintainer
#54 lore raw

PATCH 49/207 efi: libstub: check Shim mode using MokSBStateRT

In reply to Greg Kroah-Hartman

From: Ard Biesheuvel <[email protected]>

commit 5f56a74cc0a6d9b9f8ba89cea29cd7c4774cb2b1 upstream.

We currently check the MokSBState variable to decide whether we should treat UEFI secure boot as being disabled, even if the firmware thinks otherwise. This is used by shim to indicate that it is not checking signatures on boot images. In the kernel, we use this to relax lockdown policies.

However, in cases where shim is not even being used, we don't want this variable to interfere with lockdown, given that the variable may be non-volatile and therefore persist across a reboot. This means setting it once will persistently disable lockdown checks on a given system.

So switch to the mirrored version of this variable, called MokSBStateRT, which is supposed to be volatile, and this is something we can check.

---
 drivers/firmware/efi/libstub/secureboot.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/firmware/efi/libstub/secureboot.c +4 -4
@@ -14,7 +14,7 @@
 
 /* SHIM variables */
 static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
-static const efi_char16_t shim_MokSBState_name[] = L"MokSBState";
+static const efi_char16_t shim_MokSBState_name[] = L"MokSBStateRT";
 
 static efi_status_t get_var(efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
 			    unsigned long *data_size, void *data)
@@ -43,8 +43,8 @@ enum efi_secureboot_mode efi_get_secureb
 
 	/*
 	 * See if a user has put the shim into insecure mode. If so, and if the
-	 * variable doesn't have the runtime attribute set, we might as well
-	 * honor that.
+	 * variable doesn't have the non-volatile attribute set, we might as
+	 * well honor that.
 	 */
 	size = sizeof(moksbstate);
 	status = get_efi_var(shim_MokSBState_name, &shim_guid,
@@ -53,7 +53,7 @@ enum efi_secureboot_mode efi_get_secureb
 	/* If it fails, we don't care why. Default to secure */
 	if (status != EFI_SUCCESS)
 		goto secure_boot_enabled;
-	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) && moksbstate == 1)
+	if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1)
 		return efi_secureboot_mode_disabled;
 
 secure_boot_enabled:
author maintainer
#55 lore raw

PATCH 50/207 wifi: mt76: fix reading current per-tid starting sequence number for aggregation

In reply to Greg Kroah-Hartman

From: Felix Fietkau <[email protected]>

commit c3a510e2b53785df31d882a773c4c0780b4c825f upstream.

The code was accidentally shifting register values down by tid % 32 instead of (tid * field_size) % 32.

Fixes a28bef561a5c ("mt76: mt7615: re-enable offloading of sequence number assignment")
---
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +1 -1
@@ -1138,7 +1138,7 @@ u32 mt7615_mac_get_sta_tid_sn(struct mt7
 	offset %= 32;
 
 	val = mt76_rr(dev, addr);
-	val >>= (tid % 32);
+	val >>= offset;
 
 	if (offset > 20) {
 		addr += 4;
author maintainer
#56 lore raw

PATCH 51/207 gpio: mockup: fix NULL pointer dereference when removing debugfs

In reply to Greg Kroah-Hartman

From: Bartosz Golaszewski <[email protected]>

commit b7df41a6f79dfb18ba2203f8c5f0e9c0b9b57f68 upstream.

We now remove the device's debugfs entries when unbinding the driver. This now causes a NULL-pointer dereference on module exit because the platform devices are unregistered *after* the global debugfs directory has been recursively removed. Fix it by unregistering the devices first.

Fixes 303e6da99429 ("gpio: mockup: remove gpio debugfs when remove device")
Cc Wei Yongjun <[email protected]>
---
 drivers/gpio/gpio-mockup.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-mockup.c +1 -1
@@ -597,9 +597,9 @@ static int __init gpio_mockup_init(void)
 
 static void __exit gpio_mockup_exit(void)
 {
+	gpio_mockup_unregister_pdevs();
 	debugfs_remove_recursive(gpio_mockup_dbg_dir);
 	platform_driver_unregister(&gpio_mockup_driver);
-	gpio_mockup_unregister_pdevs();
 }
 
 module_init(gpio_mockup_init);
author maintainer
#57 lore raw

PATCH 52/207 gpio: mockup: Fix potential resource leakage when register a chip

In reply to Greg Kroah-Hartman

From: Andy Shevchenko <[email protected]>

commit 02743c4091ccfb246f5cdbbe3f44b152d5d12933 upstream.

If creation of software node fails, the locally allocated string array is left unfreed. Free it on error path.

Fixes 6fda593f3082 ("gpio: mockup: Convert to use software nodes")
---
 drivers/gpio/gpio-mockup.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpio/gpio-mockup.c +3 -1
@@ -533,8 +533,10 @@ static int __init gpio_mockup_register_c
 	}
 
 	fwnode = fwnode_create_software_node(properties, NULL);
-	if (IS_ERR(fwnode))
+	if (IS_ERR(fwnode)) {
+		kfree_strarray(line_names, ngpio);
 		return PTR_ERR(fwnode);
+	}
 
 	pdevinfo.name = "gpio-mockup";
 	pdevinfo.id = idx;
author maintainer
#58 lore raw

PATCH 53/207 gpiolib: cdev: Set lineevent_state::irq after IRQ register successfully

In reply to Greg Kroah-Hartman

From: Meng Li <[email protected]>

commit 69bef19d6b9700e96285f4b4e28691cda3dcd0d1 upstream.

When running gpio test on nxp-ls1028 platform with below command gpiomon --num-events=3 --rising-edge gpiochip1 25 There will be a warning trace as below:

Call trace:
free_irq+0x204/0x360
lineevent_free+0x64/0x70
gpio_ioctl+0x598/0x6a0
__arm64_sys_ioctl+0xb4/0x100
invoke_syscall+0x5c/0x130

......
el0t_64_sync+0x1a0/0x1a4
The reason of this issue is that calling request_threaded_irq() function failed, and then lineevent_free() is invoked to release the resource. Since the lineevent_state::irq was already set, so the subsequent invocation of free_irq() would trigger the above warning call trace. To fix this issue, set the lineevent_state::irq after the IRQ register successfully.

Fixes 468242724143 ("gpiolib: cdev: refactor lineevent cleanup into lineevent_free")
---
 drivers/gpio/gpiolib-cdev.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpio/gpiolib-cdev.c +3 -2
@@ -1975,7 +1975,6 @@ static int lineevent_create(struct gpio_
 		ret = -ENODEV;
 		goto out_free_le;
 	}
-	le->irq = irq;
 
 	if (eflags & GPIOEVENT_REQUEST_RISING_EDGE)
 		irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
@@ -1989,7 +1988,7 @@ static int lineevent_create(struct gpio_
 	init_waitqueue_head(&le->wait);
 
 	/* Request a thread to read the events */
-	ret = request_threaded_irq(le->irq,
+	ret = request_threaded_irq(irq,
 				   lineevent_irq_handler,
 				   lineevent_irq_thread,
 				   irqflags,
@@ -1998,6 +1997,8 @@ static int lineevent_create(struct gpio_
 	if (ret)
 		goto out_free_le;
 
+	le->irq = irq;
+
 	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
 	if (fd < 0) {
 		ret = fd;
author maintainer
#59 lore raw

PATCH 54/207 riscv: fix a nasty sigreturn bug...

In reply to Greg Kroah-Hartman

From: Al Viro <[email protected]>

commit 762df359aa5849e010ef04c3ed79d57588ce17d9 upstream.

riscv has an equivalent of arm bug fixed by 653d48b22166 ("arm: fix really nasty sigreturn bug"); if signal gets caught by an interrupt that hits when we have the right value in a0 (-513), *and* another signal gets delivered upon sigreturn() (e.g. included into the blocked mask for the first signal and posted while the handler had been running), the syscall restart logics will see regs->cause equal to EXC_SYSCALL (we are in a syscall, after all) and a0 already restored to its original value (-513, which happens to be -ERESTARTNOINTR) and assume that we need to apply the usual syscall restart logics.

---
 arch/riscv/kernel/signal.c |    2 ++
 1 file changed, 2 insertions(+)
arch/riscv/kernel/signal.c +2 -0
@@ -124,6 +124,8 @@ SYSCALL_DEFINE0(rt_sigreturn)
 	if (restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
 
+	regs->cause = -1UL;
+
 	return regs->a0;
 
 badframe:
author maintainer
#60 lore raw

PATCH 55/207 riscv: fix RISCV_ISA_SVPBMT kconfig dependency warning

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

commit 225e47ea20ea4f37031131f4fa7a6c281fac6657 upstream.

RISCV_ISA_SVPBMT selects RISCV_ALTERNATIVE which depends on !XIP_KERNEL. Therefore RISCV_ISA_SVPBMT should also depend on !XIP_KERNEL so quieten this kconfig warning:

WARNING: unmet direct dependencies detected for RISCV_ALTERNATIVE
Depends on [n]: !XIP_KERNEL [=y]
Selected by [y]:
- RISCV_ISA_SVPBMT [=y] && 64BIT [=y] && MMU [=y]

---
 arch/riscv/Kconfig |    1 +
 1 file changed, 1 insertion(+)
arch/riscv/Kconfig +1 -0
@@ -361,6 +361,7 @@ config RISCV_ISA_C
 config RISCV_ISA_SVPBMT
 	bool "SVPBMT extension support"
 	depends on 64BIT && MMU
+	depends on !XIP_KERNEL
 	select RISCV_ALTERNATIVE
 	default y
 	help
author maintainer
#61 lore raw

PATCH 56/207 drm/i915/gem: Flush contexts on driver release

In reply to Greg Kroah-Hartman

From: Janusz Krzysztofik <[email protected]>

commit 5ce8f7444f8fbb5adee644590c0e4e1890ab004c upstream.

Due to i915_perf assuming that it can use the i915_gem_context reference to protect its i915->gem.contexts.list iteration, we need to defer removal of the context from the list until last reference to the context is put. However, there is a risk of triggering kernel warning on contexts list not empty at driver release time if we deleagate that task to a worker for i915_gem_context_release_work(), unless that work is flushed first. Unfortunately, it is not flushed on driver release. Fix it.

Instead of additionally calling flush_workqueue(), either directly or via a new dedicated wrapper around it, replace last call to i915_gem_drain_freed_objects() with existing i915_gem_drain_workqueue() that performs both tasks.

Fixes 75eefd82581f ("drm/i915: Release i915_gem_context from a worker")
Cc [email protected] # v5.16+
(cherry picked from commit 1cec34442408a77ba5396b19725fed2c398005c3)
---
 drivers/gpu/drm/i915/i915_gem.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_gem.c +2 -1
@@ -1191,7 +1191,8 @@ void i915_gem_driver_release(struct drm_
 
 	intel_uc_cleanup_firmwares(&to_gt(dev_priv)->uc);
 
-	i915_gem_drain_freed_objects(dev_priv);
+	/* Flush any outstanding work, including i915_gem_context.release_work. */
+	i915_gem_drain_workqueue(dev_priv);
 
 	drm_WARN_ON(&dev_priv->drm, !list_empty(&dev_priv->gem.contexts.list));
 }
author maintainer
#62 lore raw

PATCH 57/207 drm/i915/gem: Really move i915_gem_context.link under ref protection

In reply to Greg Kroah-Hartman

From: Chris Wilson <[email protected]>

commit d119888b09bd567e07c6b93a07f175df88857e02 upstream.

i915_perf assumes that it can use the i915_gem_context reference to protect its i915->gem.contexts.list iteration. However, this requires that we do not remove the context from the list until after we drop the final reference and release the struct. If, as currently, we remove the context from the list during context_close(), the link.next pointer may be poisoned while we are holding the context reference and cause a GPF:

[ 4070.573157] i915 0000:00:02.0: [drm:i915_perf_open_ioctl [i915]] filtering on ctx_id=0x1fffff ctx_id_mask=0x1fffff
[ 4070.574881] general protection fault, probably for non-canonical address 0xdead000000000100: 0000 [#1] PREEMPT SMP
[ 4070.574897] CPU: 1 PID: 284392 Comm: amd_performance Tainted: G            E     5.17.9 #180
[ 4070.574903] Hardware name: Intel Corporation NUC7i5BNK/NUC7i5BNB, BIOS BNKBL357.86A.0052.2017.0918.1346 09/18/2017
[ 4070.574907] RIP: 0010:oa_configure_all_contexts.isra.0+0x222/0x350 [i915]
[ 4070.574982] Code: 08 e8 32 6e 10 e1 4d 8b 6d 50 b8 ff ff ff ff 49 83 ed 50 f0 41 0f c1 04 24 83 f8 01 0f 84 e3 00 00 00 85 c0 0f 8e fa 00 00 00 <49> 8b 45 50 48 8d 70 b0 49 8d 45 50 48 39 44 24 10 0f 85 34 fe ff
[ 4070.574990] RSP: 0018:ffffc90002077b78 EFLAGS: 00010202
[ 4070.574995] RAX: 0000000000000002 RBX: 0000000000000002 RCX: 0000000000000000
[ 4070.575000] RDX: 0000000000000001 RSI: ffffc90002077b20 RDI: ffff88810ddc7c68
[ 4070.575004] RBP: 0000000000000001 R08: ffff888103242648 R09: fffffffffffffffc
[ 4070.575008] R10: ffffffff82c50bc0 R11: 0000000000025c80 R12: ffff888101bf1860
[ 4070.575012] R13: dead0000000000b0 R14: ffffc90002077c04 R15: ffff88810be5cabc
[ 4070.575016] FS:  00007f1ed50c0780(0000) GS:ffff88885ec80000(0000) knlGS:0000000000000000
[ 4070.575021] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 4070.575025] CR2: 00007f1ed5590280 CR3: 000000010ef6f005 CR4: 00000000003706e0
[ 4070.575029] Call Trace:
[ 4070.575033]  <TASK>
[ 4070.575037]  lrc_configure_all_contexts+0x13e/0x150 [i915]
[ 4070.575103]  gen8_enable_metric_set+0x4d/0x90 [i915]
[ 4070.575164]  i915_perf_open_ioctl+0xbc0/0x1500 [i915]
[ 4070.575224]  ? asm_common_interrupt+0x1e/0x40
[ 4070.575232]  ? i915_oa_init_reg_state+0x110/0x110 [i915]
[ 4070.575290]  drm_ioctl_kernel+0x85/0x110
[ 4070.575296]  ? update_load_avg+0x5f/0x5e0
[ 4070.575302]  drm_ioctl+0x1d3/0x370
[ 4070.575307]  ? i915_oa_init_reg_state+0x110/0x110 [i915]
[ 4070.575382]  ? gen8_gt_irq_handler+0x46/0x130 [i915]
[ 4070.575445]  __x64_sys_ioctl+0x3c4/0x8d0
[ 4070.575451]  ? __do_softirq+0xaa/0x1d2
[ 4070.575456]  do_syscall_64+0x35/0x80
[ 4070.575461]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 4070.575467] RIP: 0033:0x7f1ed5c10397
[ 4070.575471] Code: 3c 1c e8 1c ff ff ff 85 c0 79 87 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a9 da 0d 00 f7 d8 64 89 01 48
[ 4070.575478] RSP: 002b:00007ffd65c8d7a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 4070.575484] RAX: ffffffffffffffda RBX: 0000000000000006 RCX: 00007f1ed5c10397
[ 4070.575488] RDX: 00007ffd65c8d7c0 RSI: 0000000040106476 RDI: 0000000000000006
[ 4070.575492] RBP: 00005620972f9c60 R08: 000000000000000a R09: 0000000000000005
[ 4070.575496] R10: 000000000000000d R11: 0000000000000246 R12: 000000000000000a
[ 4070.575500] R13: 000000000000000d R14: 0000000000000000 R15: 00007ffd65c8d7c0
[ 4070.575505]  </TASK>
[ 4070.575507] Modules linked in: nls_ascii(E) nls_cp437(E) vfat(E) fat(E) i915(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) crct10dif_pclmul(E) crc32_pclmul(E) crc32c_intel(E) aesni_intel(E) crypto_simd(E) intel_gtt(E) cryptd(E) ttm(E) rapl(E) intel_cstate(E) drm_kms_helper(E) cfbfillrect(E) syscopyarea(E) cfbimgblt(E) intel_uncore(E) sysfillrect(E) mei_me(E) sysimgblt(E) i2c_i801(E) fb_sys_fops(E) mei(E) intel_pch_thermal(E) i2c_smbus(E) cfbcopyarea(E) video(E) button(E) efivarfs(E) autofs4(E)
[ 4070.575549] ---[ end trace 0000000000000000 ]---

v3: fix incorrect syntax of spin_lock() replacing spin_lock_irqsave()

v2: irqsave not required in a worker, neither conversion to irq safe
elsewhere (Tvrtko),
- perf: it's safe to call gen8_configure_context() even if context has been closed, no need to check,
- drop unrelated cleanup (Andi, Tvrtko)

Fixes f8246cf4d9a9 ("drm/i915/gem: Drop free_work for GEM contexts")
Cc Tvrtko Ursulin <[email protected]>
Cc <[email protected]> # v5.12+
(cherry picked from commit ad3aa7c31efa5a09b0dba42e66cfdf77e0db7dc2)
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/gem/i915_gem_context.c +4 -4
@@ -1269,6 +1269,10 @@ static void i915_gem_context_release_wor
 	trace_i915_context_free(ctx);
 	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
 
+	spin_lock(&ctx->i915->gem.contexts.lock);
+	list_del(&ctx->link);
+	spin_unlock(&ctx->i915->gem.contexts.lock);
+
 	if (ctx->syncobj)
 		drm_syncobj_put(ctx->syncobj);
 
@@ -1514,10 +1518,6 @@ static void context_close(struct i915_ge
 
 	ctx->file_priv = ERR_PTR(-EBADF);
 
-	spin_lock(&ctx->i915->gem.contexts.lock);
-	list_del(&ctx->link);
-	spin_unlock(&ctx->i915->gem.contexts.lock);
-
 	client = ctx->client;
 	if (client) {
 		spin_lock(&client->ctx_lock);
author maintainer
#63 lore raw

PATCH 58/207 xen/xenbus: fix xenbus_setup_ring()

In reply to Greg Kroah-Hartman

From: Juergen Gross <[email protected]>

commit ce6b8ccdef959ba86b2711e090e84a987a000bf7 upstream.

Commit 4573240f0764 ("xen/xenbus: eliminate xenbus_grant_ring()") introduced an error for initialization of multi-page rings.

---
 drivers/xen/xenbus/xenbus_client.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/xen/xenbus/xenbus_client.c +6 -3
index d5f3f763717e..d4b251925796 100644
@@ -382,9 +382,10 @@ int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr,
 	unsigned long ring_size = nr_pages * XEN_PAGE_SIZE;
 	grant_ref_t gref_head;
 	unsigned int i;
+	void *addr;
 	int ret;
 
-	*vaddr = alloc_pages_exact(ring_size, gfp | __GFP_ZERO);
+	addr = *vaddr = alloc_pages_exact(ring_size, gfp | __GFP_ZERO);
 	if (!*vaddr) {
 		ret = -ENOMEM;
 		goto err;
@@ -401,13 +402,15 @@ int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr,
 		unsigned long gfn;
 
 		if (is_vmalloc_addr(*vaddr))
-			gfn = pfn_to_gfn(vmalloc_to_pfn(vaddr[i]));
+			gfn = pfn_to_gfn(vmalloc_to_pfn(addr));
 		else
-			gfn = virt_to_gfn(vaddr[i]);
+			gfn = virt_to_gfn(addr);
 
 		grefs[i] = gnttab_claim_grant_reference(&gref_head);
 		gnttab_grant_foreign_access_ref(grefs[i], dev->otherend_id,
 						gfn, 0);
+
+		addr += XEN_PAGE_SIZE;
 	}
 
 	return 0;
Signature · 1 line
2.37.3
author maintainer
#64 lore raw

PATCH 59/207 kasan: call kasan_malloc() from __kmalloc_*track_caller()

In reply to Greg Kroah-Hartman

From: Peter Collingbourne <[email protected]>

commit 5373b8a09d6e037ee0587cb5d9fe4cc09077deeb upstream.

We were failing to call kasan_malloc() from __kmalloc_*track_caller() which was causing us to sometimes fail to produce KASAN error reports for allocations made using e.g. devm_kcalloc(), as the KASAN poison was not being initialized. Fix it.

---
 mm/slub.c |    4 ++++
 1 file changed, 4 insertions(+)
mm/slub.c +4 -0
@@ -4950,6 +4950,8 @@ void *__kmalloc_track_caller(size_t size
 	/* Honor the call site pointer we received. */
 	trace_kmalloc(caller, ret, size, s->size, gfpflags);
 
+	ret = kasan_kmalloc(s, ret, size, gfpflags);
+
 	return ret;
 }
 EXPORT_SYMBOL(__kmalloc_track_caller);
@@ -4981,6 +4983,8 @@ void *__kmalloc_node_track_caller(size_t
 	/* Honor the call site pointer we received. */
 	trace_kmalloc_node(caller, ret, size, s->size, gfpflags, node);
 
+	ret = kasan_kmalloc(s, ret, size, gfpflags);
+
 	return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node_track_caller);
author maintainer
#65 lore raw

PATCH 60/207 can: flexcan: flexcan_mailbox_read() fix return value for drop = true

In reply to Greg Kroah-Hartman

From: Marc Kleine-Budde <[email protected]>

commit a09721dd47c8468b3f2fdd73f40422699ffe26dd upstream.

The following happened on an i.MX25 using flexcan with many packets on the bus:

The rx-offload queue reached a length more than skb_queue_len_max. In can_rx_offload_offload_one() the drop variable was set to true which made the call to .mailbox_read() (here: flexcan_mailbox_read()) to _always_ return ERR_PTR(-ENOBUFS) and drop the rx'ed CAN frame. So can_rx_offload_offload_one() returned ERR_PTR(-ENOBUFS), too.

can_rx_offload_irq_offload_fifo() looks as follows:

| 	while (1) {
| 		skb = can_rx_offload_offload_one(offload, 0);
| 		if (IS_ERR(skb))
| 			continue;
| 		if (!skb)
| 			break;
| 		...
| 	}

The flexcan driver wrongly always returns ERR_PTR(-ENOBUFS) if drop is requested, even if there is no CAN frame pending. As the i.MX25 is a single core CPU, while the rx-offload processing is active, there is no thread to process packets from the offload queue. So the queue doesn't get any shorter and this results is a tight loop.

Instead of always returning ERR_PTR(-ENOBUFS) if drop is requested, return NULL if no CAN frame is pending.

Changes since v1: https://lore.kernel.org/all/[email protected]
- don't break in can_rx_offload_irq_offload_fifo() in case of an error,
return NULL in flexcan_mailbox_read() in case of no pending CAN frame
instead

---
 drivers/net/can/flexcan/flexcan-core.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/can/flexcan/flexcan-core.c +5 -5
@@ -941,11 +941,6 @@ static struct sk_buff *flexcan_mailbox_r
 	u32 reg_ctrl, reg_id, reg_iflag1;
 	int i;
 
-	if (unlikely(drop)) {
-		skb = ERR_PTR(-ENOBUFS);
-		goto mark_as_read;
-	}
-
 	mb = flexcan_get_mb(priv, n);
 
 	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
@@ -974,6 +969,11 @@ static struct sk_buff *flexcan_mailbox_r
 		reg_ctrl = priv->read(&mb->can_ctrl);
 	}
 
+	if (unlikely(drop)) {
+		skb = ERR_PTR(-ENOBUFS);
+		goto mark_as_read;
+	}
+
 	if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
 		skb = alloc_canfd_skb(offload->dev, &cfd);
 	else
author maintainer
#66 lore raw

PATCH 61/207 net: mana: Add rmb after checking owner bits

In reply to Greg Kroah-Hartman

From: Haiyang Zhang <[email protected]>

commit 6fd2c68da55c552f86e401ebe40c4a619025ef69 upstream.

Per GDMA spec, rmb is necessary after checking owner_bits, before reading EQ or CQ entries.

Add rmb in these two places to comply with the specs.

Fixes ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
---
 drivers/net/ethernet/microsoft/mana/gdma_main.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/net/ethernet/microsoft/mana/gdma_main.c +10 -0
@@ -370,6 +370,11 @@ static void mana_gd_process_eq_events(vo
 			break;
 		}
 
+		/* Per GDMA spec, rmb is necessary after checking owner_bits, before
+		 * reading eqe.
+		 */
+		rmb();
+
 		mana_gd_process_eqe(eq);
 
 		eq->head++;
@@ -1107,6 +1112,11 @@ static int mana_gd_read_cqe(struct gdma_
 	if (WARN_ON_ONCE(owner_bits != new_bits))
 		return -1;
 
+	/* Per GDMA spec, rmb is necessary after checking owner_bits, before
+	 * reading completion info
+	 */
+	rmb();
+
 	comp->wq_num = cqe->cqe_info.wq_num;
 	comp->is_sq = cqe->cqe_info.is_sq;
 	memcpy(comp->cqe_data, cqe->cqe_data, GDMA_COMP_DATA_SIZE);
author maintainer
#67 lore raw

PATCH 62/207 mm/slub: fix to return errno if kmalloc() fails

In reply to Greg Kroah-Hartman

From: Chao Yu <[email protected]>

commit 7e9c323c52b379d261a72dc7bd38120a761a93cd upstream.

In create_unique_id(), kmalloc(, GFP_KERNEL) can fail due to out-of-memory, if it fails, return errno correctly rather than triggering panic via BUG_ON();

kernel BUG at mm/slub.c:5893!

Internal error: Oops - BUG: 0 [#1] PREEMPT SMP

Call trace:
 sysfs_slab_add+0x258/0x260 mm/slub.c:5973
 __kmem_cache_create+0x60/0x118 mm/slub.c:4899
 create_cache mm/slab_common.c:229 [inline]
 kmem_cache_create_usercopy+0x19c/0x31c mm/slab_common.c:335
 kmem_cache_create+0x1c/0x28 mm/slab_common.c:390
 f2fs_kmem_cache_create fs/f2fs/f2fs.h:2766 [inline]
 f2fs_init_xattr_caches+0x78/0xb4 fs/f2fs/xattr.c:808
 f2fs_fill_super+0x1050/0x1e0c fs/f2fs/super.c:4149
 mount_bdev+0x1b8/0x210 fs/super.c:1400
 f2fs_mount+0x44/0x58 fs/f2fs/super.c:4512
 legacy_get_tree+0x30/0x74 fs/fs_context.c:610
 vfs_get_tree+0x40/0x140 fs/super.c:1530
 do_new_mount+0x1dc/0x4e4 fs/namespace.c:3040
 path_mount+0x358/0x914 fs/namespace.c:3370
 do_mount fs/namespace.c:3383 [inline]
 __do_sys_mount fs/namespace.c:3591 [inline]
 __se_sys_mount fs/namespace.c:3568 [inline]
 __arm64_sys_mount+0x2f8/0x408 fs/namespace.c:3568
---
 mm/slub.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
mm/slub.c +4 -1
@@ -5918,7 +5918,8 @@ static char *create_unique_id(struct kme
 	char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL);
 	char *p = name;
 
-	BUG_ON(!name);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
 
 	*p++ = ':';
 	/*
@@ -5976,6 +5977,8 @@ static int sysfs_slab_add(struct kmem_ca
 		 * for the symlinks.
 		 */
 		name = create_unique_id(s);
+		if (IS_ERR(name))
+			return PTR_ERR(name);
 	}
 
 	s->kobj.kset = kset;
author maintainer
#68 lore raw

PATCH 63/207 mm: slub: fix flush_cpu_slab()/__free_slab() invocations in task context.

In reply to Greg Kroah-Hartman

From: Maurizio Lombardi <[email protected]>

commit e45cc288724f0cfd497bb5920bcfa60caa335729 upstream.

Commit 5a836bf6b09f ("mm: slub: move flush_cpu_slab() invocations __free_slab() invocations out of IRQ context") moved all flush_cpu_slab() invocations to the global workqueue to avoid a problem related with deactivate_slab()/__free_slab() being called from an IRQ context on PREEMPT_RT kernels.

When the flush_all_cpu_locked() function is called from a task context it may happen that a workqueue with WQ_MEM_RECLAIM bit set ends up flushing the global workqueue, this will cause a dependency issue.

workqueue: WQ_MEM_RECLAIM nvme-delete-wq:nvme_delete_ctrl_work [nvme_core]
is flushing !WQ_MEM_RECLAIM events:flush_cpu_slab

 WARNING: CPU: 37 PID: 410 at kernel/workqueue.c:2637
   check_flush_dependency+0x10a/0x120
 Workqueue: nvme-delete-wq nvme_delete_ctrl_work [nvme_core]
 RIP: 0010:check_flush_dependency+0x10a/0x120[  453.262125] Call Trace:
 __flush_work.isra.0+0xbf/0x220
 ? __queue_work+0x1dc/0x420
 flush_all_cpus_locked+0xfb/0x120
 __kmem_cache_shutdown+0x2b/0x320
 kmem_cache_destroy+0x49/0x100
 bioset_exit+0x143/0x190
 blk_release_queue+0xb9/0x100
 kobject_cleanup+0x37/0x130
 nvme_fc_ctrl_free+0xc6/0x150 [nvme_fc]
 nvme_free_ctrl+0x1ac/0x2b0 [nvme_core]

Fix this bug by creating a workqueue for the flush operation with the WQ_MEM_RECLAIM bit set.

Fixes 5a836bf6b09f ("mm: slub: move flush_cpu_slab() invocations __free_slab() invocations out of IRQ context")
---
 mm/slub.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
mm/slub.c +8 -1
@@ -310,6 +310,11 @@ static inline void stat(const struct kme
  */
 static nodemask_t slab_nodes;
 
+/*
+ * Workqueue used for flush_cpu_slab().
+ */
+static struct workqueue_struct *flushwq;
+
 /********************************************************************
  * 			Core slab cache functions
  *******************************************************************/
@@ -2730,7 +2735,7 @@ static void flush_all_cpus_locked(struct
 		INIT_WORK(&sfw->work, flush_cpu_slab);
 		sfw->skip = false;
 		sfw->s = s;
-		schedule_work_on(cpu, &sfw->work);
+		queue_work_on(cpu, flushwq, &sfw->work);
 	}
 
 	for_each_online_cpu(cpu) {
@@ -4880,6 +4885,8 @@ void __init kmem_cache_init(void)
 
 void __init kmem_cache_init_late(void)
 {
+	flushwq = alloc_workqueue("slub_flushwq", WQ_MEM_RECLAIM, 0);
+	WARN_ON(!flushwq);
 }
 
 struct kmem_cache *
author maintainer
#69 lore raw

PATCH 64/207 KVM: x86: Reinstate kvm_vcpu_arch.guest_supported_xcr0

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

commit ee519b3a2ae3027c341bce829ee8c51f4f494f5b upstream.

Reinstate the per-vCPU guest_supported_xcr0 by partially reverting commit 988896bb6182; the implicit assessment that guest_supported_xcr0 is always the same as guest_fpu.fpstate->user_xfeatures was incorrect.

kvm_vcpu_after_set_cpuid() isn't the only place that sets user_xfeatures, as user_xfeatures is set to fpu_user_cfg.default_features when guest_fpu is allocated via fpu_alloc_guest_fpstate() => __fpstate_reset(). guest_supported_xcr0 on the other hand is zero-allocated. If userspace never invokes KVM_SET_CPUID2, supported XCR0 will be '0', whereas the allowed user XFEATURES will be non-zero.

Practically speaking, the edge case likely doesn't matter as no sane userspace will live migrate a VM without ever doing KVM_SET_CPUID2. The primary motivation is to prepare for KVM intentionally and explicitly setting bits in user_xfeatures that are not set in guest_supported_xcr0.

Because KVM_{G,S}ET_XSAVE can be used to svae/restore FP+SSE state even if the host doesn't support XSAVE, KVM needs to set the FP+SSE bits in user_xfeatures even if they're not allowed in XCR0, e.g. because XCR0 isn't exposed to the guest. At that point, the simplest fix is to track the two things separately (allowed save/restore vs. allowed XCR0).

Fixes 988896bb6182 ("x86/kvm/fpu: Remove kvm_vcpu_arch.guest_supported_xcr0")
Cc Leonardo Bras <[email protected]>

Message-Id: <[email protected]>

---
 arch/x86/include/asm/kvm_host.h |    1 +
 arch/x86/kvm/cpuid.c            |    5 ++---
 arch/x86/kvm/x86.c              |    9 ++-------
 3 files changed, 5 insertions(+), 10 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -713,6 +713,7 @@ struct kvm_vcpu_arch {
 	struct fpu_guest guest_fpu;
 
 	u64 xcr0;
+	u64 guest_supported_xcr0;
 
 	struct kvm_pio_request pio;
 	void *pio_data;
arch/x86/kvm/cpuid.c +2 -3
@@ -283,7 +283,6 @@ static void kvm_vcpu_after_set_cpuid(str
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;
 	struct kvm_cpuid_entry2 *best;
-	u64 guest_supported_xcr0;
 
 	best = kvm_find_cpuid_entry(vcpu, 1, 0);
 	if (best && apic) {
@@ -295,10 +294,10 @@ static void kvm_vcpu_after_set_cpuid(str
 		kvm_apic_set_version(vcpu);
 	}
 
-	guest_supported_xcr0 =
+	vcpu->arch.guest_supported_xcr0 =
 		cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
 
-	vcpu->arch.guest_fpu.fpstate->user_xfeatures = guest_supported_xcr0;
+	vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0;
 
 	kvm_update_pv_runtime(vcpu);
 
arch/x86/kvm/x86.c +2 -7
@@ -1025,15 +1025,10 @@ void kvm_load_host_xsave_state(struct kv
 }
 EXPORT_SYMBOL_GPL(kvm_load_host_xsave_state);
 
-static inline u64 kvm_guest_supported_xcr0(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.guest_fpu.fpstate->user_xfeatures;
-}
-
 #ifdef CONFIG_X86_64
 static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu)
 {
-	return kvm_guest_supported_xcr0(vcpu) & XFEATURE_MASK_USER_DYNAMIC;
+	return vcpu->arch.guest_supported_xcr0 & XFEATURE_MASK_USER_DYNAMIC;
 }
 #endif
 
@@ -1056,7 +1051,7 @@ static int __kvm_set_xcr(struct kvm_vcpu
 	 * saving.  However, xcr0 bit 0 is always set, even if the
 	 * emulated CPU does not support XSAVE (see kvm_vcpu_reset()).
 	 */
-	valid_bits = kvm_guest_supported_xcr0(vcpu) | XFEATURE_MASK_FP;
+	valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
 	if (xcr0 & ~valid_bits)
 		return 1;
 
author maintainer
#70 lore raw

PATCH 65/207 KVM: x86: Always enable legacy FP/SSE in allowed user XFEATURES

In reply to Greg Kroah-Hartman

From: Dr. David Alan Gilbert <[email protected]>

commit a1020a25e69755a8a1a37735d674b91d6f02939f upstream.

Allow FP and SSE state to be saved and restored via KVM_{G,SET}_XSAVE on XSAVE-capable hosts even if their bits are not exposed to the guest via XCR0.

Failing to allow FP+SSE first showed up as a QEMU live migration failure, where migrating a VM from a pre-XSAVE host, e.g. Nehalem, to an XSAVE host failed due to KVM rejecting KVM_SET_XSAVE. However, the bug also causes problems even when migrating between XSAVE-capable hosts as KVM_GET_SAVE won't set any bits in user_xfeatures if XSAVE isn't exposed to the guest, i.e. KVM will fail to actually migrate FP+SSE.

Because KVM_{G,S}ET_XSAVE are designed to allowing migrating between hosts with and without XSAVE, KVM_GET_XSAVE on a non-XSAVE (by way of fpu_copy_guest_fpstate_to_uabi()) always sets the FP+SSE bits in the header so that KVM_SET_XSAVE will work even if the new host supports XSAVE.

Fixes ad856280ddea ("x86/kvm/fpu: Limit guest user_xfeatures to supported bits of XCR0")

bz: https://bugzilla.redhat.com/show_bug.cgi?id=2079311

Cc Leonardo Bras <[email protected]>
[sean: add comment, massage changelog]

Message-Id: <[email protected]>

---
 arch/x86/kvm/cpuid.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/kvm/cpuid.c +7 -1
@@ -297,7 +297,13 @@ static void kvm_vcpu_after_set_cpuid(str
 	vcpu->arch.guest_supported_xcr0 =
 		cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
 
-	vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0;
+	/*
+	 * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if
+	 * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't
+	 * supported by the host.
+	 */
+	vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0 |
+						       XFEATURE_MASK_FPSSE;
 
 	kvm_update_pv_runtime(vcpu);
 
author maintainer
#71 lore raw

PATCH 66/207 KVM: x86: Inject #UD on emulated XSETBV if XSAVES isnt enabled

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

commit 50b2d49bafa16e6311ab2da82f5aafc5f9ada99b upstream.

Inject #UD when emulating XSETBV if CR4.OSXSAVE is not set. This also covers the "XSAVE not supported" check, as setting CR4.OSXSAVE=1 #GPs if XSAVE is not supported (and userspace gets to keep the pieces if it forces incoherent vCPU state).

Add a comment to kvm_emulate_xsetbv() to call out that the CPU checks CR4.OSXSAVE before checking for intercepts. AMD'S APM implies that #UD has priority (says that intercepts are checked before #GP exceptions), while Intel's SDM says nothing about interception priority. However, testing on hardware shows that both AMD and Intel CPUs prioritize the #UD over interception.

Fixes 02d4160fbd76 ("x86: KVM: add xsetbv to the emulator")
Cc Vitaly Kuznetsov <[email protected]>

Message-Id: <[email protected]>

---
 arch/x86/kvm/emulate.c |    3 +++
 arch/x86/kvm/x86.c     |    1 +
 2 files changed, 4 insertions(+)
arch/x86/kvm/emulate.c +3 -0
@@ -4134,6 +4134,9 @@ static int em_xsetbv(struct x86_emulate_
 {
 	u32 eax, ecx, edx;
 
+	if (!(ctxt->ops->get_cr(ctxt, 4) & X86_CR4_OSXSAVE))
+		return emulate_ud(ctxt);
+
 	eax = reg_read(ctxt, VCPU_REGS_RAX);
 	edx = reg_read(ctxt, VCPU_REGS_RDX);
 	ecx = reg_read(ctxt, VCPU_REGS_RCX);
arch/x86/kvm/x86.c +1 -0
@@ -1079,6 +1079,7 @@ static int __kvm_set_xcr(struct kvm_vcpu
 
 int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu)
 {
+	/* Note, #UD due to CR4.OSXSAVE=0 has priority over the intercept. */
 	if (static_call(kvm_x86_get_cpl)(vcpu) != 0 ||
 	    __kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) {
 		kvm_inject_gp(vcpu, 0);
author maintainer
#72 lore raw

PATCH 67/207 perf/arm-cmn: Add more bits to child node address offset field

In reply to Greg Kroah-Hartman

From: Ilkka Koskinen <[email protected]>

commit 05d6f6d346fea2fa4580a0c2b6be207456bebb08 upstream.

CMN-600 uses bits [27:0] for child node address offset while bits [30:28] are required to be zero.

For CMN-650, the child node address offset field has been increased to include bits [29:0] while leaving only bit 30 set to zero.

Let's include the missing two bits and assume older implementations comply with the spec and set bits [29:28] to 0.

---
 drivers/perf/arm-cmn.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/perf/arm-cmn.c +1 -1
index 80d8309652a4..b80a9b74662b 100644
@@ -36,7 +36,7 @@
 #define CMN_CI_CHILD_COUNT		GENMASK_ULL(15, 0)
 #define CMN_CI_CHILD_PTR_OFFSET		GENMASK_ULL(31, 16)
 
-#define CMN_CHILD_NODE_ADDR		GENMASK(27, 0)
+#define CMN_CHILD_NODE_ADDR		GENMASK(29, 0)
 #define CMN_CHILD_NODE_EXTERNAL		BIT(31)
 
 #define CMN_MAX_DIMENSION		12
Signature · 1 line
2.37.3
author maintainer
#73 lore raw

PATCH 68/207 arm64: topology: fix possible overflow in amu_fie_setup()

In reply to Greg Kroah-Hartman

From: Sergey Shtylyov <[email protected]>

commit d4955c0ad77dbc684fc716387070ac24801b8bca upstream.

cpufreq_get_hw_max_freq() returns max frequency in kHz as *unsigned int*, while freq_inv_set_max_ratio() gets passed this frequency in Hz as 'u64'. Multiplying max frequency by 1000 can potentially result in overflow -- multiplying by 1000ULL instead should avoid that...

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

Fixes cd0ed03a8903 ("arm64: use activity monitors for frequency invariance")
---
 arch/arm64/kernel/topology.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/topology.c +1 -1
@@ -251,7 +251,7 @@ static void amu_fie_setup(const struct c
 	for_each_cpu(cpu, cpus) {
 		if (!freq_counters_valid(cpu) ||
 		    freq_inv_set_max_ratio(cpu,
-					   cpufreq_get_hw_max_freq(cpu) * 1000,
+					   cpufreq_get_hw_max_freq(cpu) * 1000ULL,
 					   arch_timer_get_rate()))
 			return;
 	}
author maintainer
#74 lore raw

PATCH 69/207 vmlinux.lds.h: CFI: Reduce alignment of jump-table to function alignment

In reply to Greg Kroah-Hartman

From: Will Deacon <[email protected]>

commit 13b0566962914e167cb3238fbe29ced618f07a27 upstream.

Due to undocumented, hysterical raisins on x86, the CFI jump-table sections in .text are needlessly aligned to PMD_SIZE in the vmlinux linker script. When compiling a CFI-enabled arm64 kernel with a 64KiB page-size, a PMD maps 512MiB of virtual memory and so the .text section increases to a whopping 940MiB and blows the final Image up to 960MiB. Others report a link failure.

Since the CFI jump-table requires only instruction alignment, reduce the alignment directives to function alignment for parity with other parts of the .text section. This reduces the size of the .text section for the aforementioned 64KiB page size arm64 kernel to 19MiB for a much more reasonable total Image size of 39MiB.

---
 include/asm-generic/vmlinux.lds.h |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
include/asm-generic/vmlinux.lds.h +1 -2
@@ -543,10 +543,9 @@
  */
 #ifdef CONFIG_CFI_CLANG
 #define TEXT_CFI_JT							\
-		. = ALIGN(PMD_SIZE);					\
+		ALIGN_FUNCTION();					\
 		__cfi_jt_start = .;					\
 		*(.text..L.cfi.jumptable .text..L.cfi.jumptable.*)	\
-		. = ALIGN(PMD_SIZE);					\
 		__cfi_jt_end = .;
 #else
 #define TEXT_CFI_JT
author maintainer
#75 lore raw

PATCH 70/207 batman-adv: Fix hang up with small MTU hard-interface

In reply to Greg Kroah-Hartman

From: Shigeru Yoshida <[email protected]>

[ Upstream commit b1cb8a71f1eaec4eb77051590f7f561f25b15e32 ]

The system hangs up when batman-adv soft-interface is created on hard-interface with small MTU. For example, the following commands create batman-adv soft-interface on dummy interface with zero MTU:

  # ip link add name dummy0 type dummy
  # ip link set mtu 0 dev dummy0
  # ip link set up dev dummy0
  # ip link add name bat0 type batadv
  # ip link set dev dummy0 master bat0

These commands cause the system hang up with the following messages:

  [   90.578925][ T6689] batman_adv: bat0: Adding interface: dummy0
  [   90.580884][ T6689] batman_adv: bat0: The MTU of interface dummy0 is too small (0) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1560 would solve the problem.
  [   90.586264][ T6689] batman_adv: bat0: Interface activated: dummy0
  [   90.590061][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320)
  [   90.595517][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320)
  [   90.598499][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320)

This patch fixes this issue by returning error when enabling hard-interface with small MTU size.

Fixes c6c8fea29769 ("net: Add batman-adv meshing protocol")
---
 net/batman-adv/hard-interface.c | 4 ++++
 1 file changed, 4 insertions(+)
net/batman-adv/hard-interface.c +4 -0
index b8f8da7ee3de..41c1ad33d009 100644
@@ -10,6 +10,7 @@
 #include <linux/atomic.h>
 #include <linux/byteorder/generic.h>
 #include <linux/container_of.h>
+#include <linux/errno.h>
 #include <linux/gfp.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
@@ -700,6 +701,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
 	int max_header_len = batadv_max_header_len();
 	int ret;
 
+	if (hard_iface->net_dev->mtu < ETH_MIN_MTU + max_header_len)
+		return -EINVAL;
+
 	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
 		goto out;
 
Signature · 1 line
2.35.1
author maintainer
#76 lore raw

PATCH 71/207 firmware: arm_scmi: Harden accesses to the reset domains

In reply to Greg Kroah-Hartman

From: Cristian Marussi <[email protected]>

[ Upstream commit e9076ffbcaed5da6c182b144ef9f6e24554af268 ]

Accessing reset domains descriptors by the index upon the SCMI drivers requests through the SCMI reset operations interface can potentially lead to out-of-bound violations if the SCMI driver misbehave.

Add an internal consistency check before any such domains descriptors accesses.

Stable-dep-of: b75c83d9b961 ("firmware: arm_scmi: Fix the asynchronous reset requests")

---
 drivers/firmware/arm_scmi/reset.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/firmware/arm_scmi/reset.c +5 -1
index 673f3eb498f4..b0494165b1cb 100644
@@ -166,8 +166,12 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
 	struct scmi_xfer *t;
 	struct scmi_msg_reset_domain_reset *dom;
 	struct scmi_reset_info *pi = ph->get_priv(ph);
-	struct reset_dom_info *rdom = pi->dom_info + domain;
+	struct reset_dom_info *rdom;
 
+	if (domain >= pi->num_domains)
+		return -EINVAL;
+
+	rdom = pi->dom_info + domain;
 	if (rdom->async_reset)
 		flags |= ASYNCHRONOUS_RESET;
 
Signature · 1 line
2.35.1
author maintainer
#77 lore raw

PATCH 72/207 firmware: arm_scmi: Fix the asynchronous reset requests

In reply to Greg Kroah-Hartman

From: Cristian Marussi <[email protected]>

[ Upstream commit b75c83d9b961fd3abf7310f8d36d5e6e9f573efb ]

SCMI Reset protocol specification allows the asynchronous reset request only when an autonomous reset action is specified. Reset requests based on explicit assert/deassert of signals should not be served asynchronously.

Current implementation will instead issue an asynchronous request in any case, as long as the reset domain had advertised to support asynchronous resets.

Avoid requesting the asynchronous resets when the reset action is not of the autonomous type, even if the target reset domain does, in general, support the asynchronous requests.

Fixes 95a15d80aa0d ("firmware: arm_scmi: Add RESET protocol in SCMI v2.0")
---
 drivers/firmware/arm_scmi/reset.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/arm_scmi/reset.c +2 -2
index b0494165b1cb..e9afa8cab730 100644
@@ -172,7 +172,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
 		return -EINVAL;
 
 	rdom = pi->dom_info + domain;
-	if (rdom->async_reset)
+	if (rdom->async_reset && flags & AUTONOMOUS_RESET)
 		flags |= ASYNCHRONOUS_RESET;
 
 	ret = ph->xops->xfer_get_init(ph, RESET, sizeof(*dom), 0, &t);
@@ -184,7 +184,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
 	dom->flags = cpu_to_le32(flags);
 	dom->reset_state = cpu_to_le32(state);
 
-	if (rdom->async_reset)
+	if (flags & ASYNCHRONOUS_RESET)
 		ret = ph->xops->do_xfer_with_response(ph, t);
 	else
 		ret = ph->xops->do_xfer(ph, t);
Signature · 1 line
2.35.1
author maintainer
#78 lore raw

PATCH 73/207 arm64: dts: rockchip: Lower sd speed on quartz64-b

In reply to Greg Kroah-Hartman

From: Nicolas Frattaroli <[email protected]>

[ Upstream commit 1ea90b2d293fd8b1f3377c9ed08364ff6f2a8562 ]

The previously stated speed of sdr-104 is too high for the hardware to reliably communicate with some fast SD cards.

Lower this to sd-uhs-sdr50 to fix this.

Fixes dcc8c66bef79 ("arm64: dts: rockchip: add Pine64 Quartz64-B device tree")
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts +1 -1
index 02d5f5a8ca03..528bb4e8ac77 100644
@@ -506,7 +506,7 @@ &sdmmc0 {
 	disable-wp;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
-	sd-uhs-sdr104;
+	sd-uhs-sdr50;
 	vmmc-supply = <&vcc3v3_sd>;
 	vqmmc-supply = <&vccio_sd>;
 	status = "okay";
Signature · 1 line
2.35.1
author maintainer
#79 lore raw

PATCH 74/207 arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob

In reply to Greg Kroah-Hartman

From: Brian Norris <[email protected]>

[ Upstream commit e5467359a725de90b6b8d0dd865500f6373828ca ]

The Gru-Bob board does not have a pull-up resistor on its WLAN_HOST_WAKE# pin, but Kevin does. The production/vendor kernel specified the pin configuration correctly as a pull-up, but this didn't get ported correctly to upstream.

This means Bob's WLAN_HOST_WAKE# pin is floating, causing inconsistent wakeup behavior.

Note that bt_host_wake_l has a similar dynamic, but apparently the upstream choice was to redundantly configure both internal and external pull-up on Kevin (see the "Kevin has an external pull up" comment in rk3399-gru.dtsi). This doesn't cause any functional problem, although it's perhaps wasteful.

---
 arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts         | 5 +++++
 arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi | 1 +
 2 files changed, 6 insertions(+)
arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts +5 -0
index 31ebb4e5fd33..0f9cc042d9bf 100644
@@ -88,3 +88,8 @@ h1_int_od_l: h1-int-od-l {
 		};
 	};
 };
+
+&wlan_host_wake_l {
+	/* Kevin has an external pull up, but Bob does not. */
+	rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+};
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +1 -0
index 50d459ee4831..eed15fd61d62 100644
@@ -578,6 +578,7 @@ wifi_perst_l: wifi-perst-l {
 	};
 
 	wlan_host_wake_l: wlan-host-wake-l {
+		/* Kevin has an external pull up, but Bob does not */
 		rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
 	};
 };
Signature · 1 line
2.35.1
author maintainer
#80 lore raw

PATCH 75/207 arm64: dts: rockchip: Fix typo in lisense text for PX30.Core

In reply to Greg Kroah-Hartman

From: Jagan Teki <[email protected]>

[ Upstream commit 4a00c43818dcc19be97250d4c3c4a1e2f1ed4f9d ]

Fix the Amarula Solutions typo mistake in lisense text added in Engicam PX30.Core SoM dtsi.

Fixes d92a7c331f53c ("arm64: dts: rockchip: Add Engicam PX30.Core SOM")
---
 arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +2 -2
index 7249871530ab..5eecbefa8a33 100644
@@ -2,8 +2,8 @@
 /*
  * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
  * Copyright (c) 2020 Engicam srl
- * Copyright (c) 2020 Amarula Solutons
- * Copyright (c) 2020 Amarula Solutons(India)
+ * Copyright (c) 2020 Amarula Solutions
+ * Copyright (c) 2020 Amarula Solutions(India)
  */
 
 #include <dt-bindings/gpio/gpio.h>
Signature · 1 line
2.35.1
author maintainer
#81 lore raw

PATCH 76/207 drm/mediatek: dsi: Add atomic {destroy,duplicate}_state, reset callbacks

In reply to Greg Kroah-Hartman

From: AngeloGioacchino Del Regno <[email protected]>

[ Upstream commit eeda05b5e92f51d9a09646ecb493f0a1e872a6ef ]

Add callbacks for atomic_destroy_state, atomic_duplicate_state and atomic_reset to restore functionality of the DSI driver: this solves vblank timeouts when another bridge is present in the chain.

Tested bridge chain: DSI <=> ANX7625 => aux-bus panel

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/mediatek/mtk_dsi.c +3 -0
index af2f123e9a9a..e98b4aca2cb9 100644
@@ -808,10 +808,13 @@ static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
 
 static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
 	.attach = mtk_dsi_bridge_attach,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.atomic_disable = mtk_dsi_bridge_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_enable = mtk_dsi_bridge_atomic_enable,
 	.atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable,
 	.atomic_post_disable = mtk_dsi_bridge_atomic_post_disable,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
 	.mode_set = mtk_dsi_bridge_mode_set,
 };
 
Signature · 1 line
2.35.1
author maintainer
#82 lore raw

PATCH 77/207 arm64: dts: imx8mm: Reverse CPLD_Dn GPIO label mapping on MX8Menlo

In reply to Greg Kroah-Hartman

From: Marek Vasut <[email protected]>

[ Upstream commit 8194a356226ce6f53e1d98b44c0436c583db89d2 ]

The CPLD_Dn GPIO assignment between SoM and CPLD has now been clarified in schematic and the assignment is reversed. Update the DT to match the hardware.

Fixes 510c527b4ff57 ("arm64: dts: imx8mm: Add i.MX8M Mini Toradex Verdin based Menlo board")
---
 arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts +5 -5
index 92eaf4ef4563..57ecdfa0dfc0 100644
@@ -152,11 +152,11 @@ &gpio4 {
 	 * CPLD_reset is RESET_SOFT in schematic
 	 */
 	gpio-line-names =
-		"CPLD_D[1]", "CPLD_int", "CPLD_reset", "",
-		"", "CPLD_D[0]", "", "",
-		"", "", "", "CPLD_D[2]",
-		"CPLD_D[3]", "CPLD_D[4]", "CPLD_D[5]", "CPLD_D[6]",
-		"CPLD_D[7]", "", "", "",
+		"CPLD_D[6]", "CPLD_int", "CPLD_reset", "",
+		"", "CPLD_D[7]", "", "",
+		"", "", "", "CPLD_D[5]",
+		"CPLD_D[4]", "CPLD_D[3]", "CPLD_D[2]", "CPLD_D[1]",
+		"CPLD_D[0]", "", "", "",
 		"", "", "", "",
 		"", "", "", "KBD_intK",
 		"", "", "", "";
Signature · 1 line
2.35.1
author maintainer
#83 lore raw

PATCH 78/207 arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz

In reply to Greg Kroah-Hartman

From: zain wang <[email protected]>

[ Upstream commit 8123437cf46ea5a0f6ca5cb3c528d8b6db97b9c2 ]

We've found the AUX channel to be less reliable with PCLK_EDP at a higher rate (typically 25 MHz). This is especially important on systems with PSR-enabled panels (like Gru-Kevin), since we make heavy, constant use of AUX.

According to Rockchip, using any rate other than 24 MHz can cause "problems between syncing the PHY an PCLK", which leads to all sorts of unreliabilities around register operations.

---
 arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +8 -0
index eed15fd61d62..af5810e5f5b7 100644
@@ -244,6 +244,14 @@ &dmc {
 &edp {
 	status = "okay";
 
+	/*
+	 * eDP PHY/clk don't sync reliably at anything other than 24 MHz. Only
+	 * set this here, because rk3399-gru.dtsi ensures we can generate this
+	 * off GPLL=600MHz, whereas some other RK3399 boards may not.
+	 */
+	assigned-clocks = <&cru PCLK_EDP>;
+	assigned-clock-rates = <24000000>;
+
 	ports {
 		edp_out: port@1 {
 			reg = <1>;
Signature · 1 line
2.35.1
author maintainer
#84 lore raw

PATCH 79/207 arm64: dts: imx8mn: remove GPU power domain reset

In reply to Greg Kroah-Hartman

From: Marco Felsch <[email protected]>

[ Upstream commit 347155d1fa85972ac19d1bf58ae3f3ce95e51a5d ]

The PGC (power gating controller) already handles the reset for the GPUMIX power domain. By specifying it within the device tree the reset it issued a 2nd time. This confuses the hardware during power up and sporadically hangs the SoC. Fix this by removing the reset property and let the hardware handle the reset.

Fixes 9a0f3b157e22e ("arm64: dts: imx8mn: Enable GPU")
---
 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mn.dtsi +0 -1
index e41e1d56f980..7bd4eecd592e 100644
@@ -672,7 +672,6 @@ pgc_gpumix: power-domain@2 {
 							 <&clk IMX8MN_CLK_GPU_SHADER>,
 							 <&clk IMX8MN_CLK_GPU_BUS_ROOT>,
 							 <&clk IMX8MN_CLK_GPU_AHB>;
-						resets = <&src IMX8MQ_RESET_GPU_RESET>;
 					};
 
 					pgc_dispmix: power-domain@3 {
Signature · 1 line
2.35.1
author maintainer
#85 lore raw

PATCH 80/207 arm64: dts: imx8ulp: add #reset-cells for pcc

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 5fa383a25fd8a16a73485c90da4e3e33a78b45cf ]

The binding file clock/imx8ulp-pcc-clock.yaml indicates '#reset-cells' is a required property, add it.

Fixes fe6291e96313 ("arm64: dts: imx8ulp: Add the basic dtsi file for imx8ulp")
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 3 +++
 1 file changed, 3 insertions(+)
arch/arm64/boot/dts/freescale/imx8ulp.dtsi +3 -0
index 09f7364dd1d0..1cd389b1b95d 100644
@@ -172,6 +172,7 @@ pcc3: clock-controller@292d0000 {
 				compatible = "fsl,imx8ulp-pcc3";
 				reg = <0x292d0000 0x10000>;
 				#clock-cells = <1>;
+				#reset-cells = <1>;
 			};
 
 			tpm5: tpm@29340000 {
@@ -270,6 +271,7 @@ pcc4: clock-controller@29800000 {
 				compatible = "fsl,imx8ulp-pcc4";
 				reg = <0x29800000 0x10000>;
 				#clock-cells = <1>;
+				#reset-cells = <1>;
 			};
 
 			lpi2c6: i2c@29840000 {
@@ -414,6 +416,7 @@ pcc5: clock-controller@2da70000 {
 				compatible = "fsl,imx8ulp-pcc5";
 				reg = <0x2da70000 0x10000>;
 				#clock-cells = <1>;
+				#reset-cells = <1>;
 			};
 		};
 
Signature · 1 line
2.35.1
author maintainer
#86 lore raw

PATCH 81/207 dmaengine: ti: k3-udma-private: Fix refcount leak bug in of_xudma_dev_get()

In reply to Greg Kroah-Hartman

From: Liang He <[email protected]>

[ Upstream commit f9fdb0b86f087c2b7f6c6168dd0985a3c1eda87e ]

We should call of_node_put() for the reference returned by of_parse_phandle() in fail path or when it is not used anymore. Here we only need to move the of_node_put() before the check.

Fixes d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine users")
---
 drivers/dma/ti/k3-udma-private.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/dma/ti/k3-udma-private.c +3 -3
index d4f1e4e9603a..85e00701473c 100644
@@ -31,14 +31,14 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property)
 	}
 
 	pdev = of_find_device_by_node(udma_node);
+	if (np != udma_node)
+		of_node_put(udma_node);
+
 	if (!pdev) {
 		pr_debug("UDMA device not found\n");
 		return ERR_PTR(-EPROBE_DEFER);
 	}
 
-	if (np != udma_node)
-		of_node_put(udma_node);
-
 	ud = platform_get_drvdata(pdev);
 	if (!ud) {
 		pr_debug("UDMA has not been probed\n");
Signature · 1 line
2.35.1
author maintainer
#87 lore raw

PATCH 82/207 arm64: dts: rockchip: fix property for usb2 phy supply on rock-3a

In reply to Greg Kroah-Hartman

From: Michael Riesch <[email protected]>

[ Upstream commit 43e1d6d3b45c4e7e25171ec04a10d09969b0f889 ]

The property "vbus-supply" was copied from the vendor kernel but is not available in mainstream. Use correct property "phy-supply".

Fixes 254a1f6a29e7 ("arm64: dts: rockchip: add usb3 support to the radxa rock3 model a")
---
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts +1 -1
index 0813c0c5abde..26912f02684c 100644
@@ -543,7 +543,7 @@ &usb2phy0_host {
 };
 
 &usb2phy0_otg {
-	vbus-supply = <&vcc5v0_usb_otg>;
+	phy-supply = <&vcc5v0_usb_otg>;
 	status = "okay";
 };
 
Signature · 1 line
2.35.1
author maintainer
#88 lore raw

PATCH 83/207 arm64: dts: rockchip: fix property for usb2 phy supply on rk3568-evb1-v10

In reply to Greg Kroah-Hartman

From: Michael Riesch <[email protected]>

[ Upstream commit 1988e3ef0544bbe54cffa4ec30a5883e5a08c2b6 ]

The property "vbus-supply" was copied from the vendor kernel but is not available in mainstream. Use correct property "phy-supply".

Fixes d6cfb110b0fd ("arm64: dts: rockchip: add usb3 support to rk3568-evb1-v10")
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts +1 -1
index 622be8be9813..282f5c74d5cd 100644
@@ -618,7 +618,7 @@ &usb2phy0_host {
 };
 
 &usb2phy0_otg {
-	vbus-supply = <&vcc5v0_usb_otg>;
+	phy-supply = <&vcc5v0_usb_otg>;
 	status = "okay";
 };
 
Signature · 1 line
2.35.1
author maintainer
#89 lore raw

PATCH 84/207 arm64: dts: rockchip: Remove enable-active-low from rk3399-puma

In reply to Greg Kroah-Hartman

From: Fabio Estevam <[email protected]>

[ Upstream commit a994b34b9abb9c08ee09e835b4027ff2147f9d94 ]

The 'enable-active-low' property is not a valid one.

Only 'enable-active-high' is valid, and when this property is absent the gpio regulator will act as active low by default.

Remove the invalid 'enable-active-low' property.

Fixes 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
---
 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +0 -1
index b1ac3a89f259..aa3e21bd6c8f 100644
@@ -62,7 +62,6 @@ vcc3v3_sys: vcc3v3-sys {
 	vcc5v0_host: vcc5v0-host-regulator {
 		compatible = "regulator-fixed";
 		gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>;
-		enable-active-low;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc5v0_host_en>;
 		regulator-name = "vcc5v0_host";
Signature · 1 line
2.35.1
author maintainer
#90 lore raw

PATCH 85/207 arm64: dts: rockchip: Remove enable-active-low from rk3566-quartz64-a

In reply to Greg Kroah-Hartman

From: Fabio Estevam <[email protected]>

[ Upstream commit ea89926d9690f055fd8da929f6621a760e8e0f14 ]

The 'enable-active-low' property is not a valid one.

Only 'enable-active-high' is valid, and when this property is absent the gpio regulator will act as active low by default.

Remove the invalid 'enable-active-low' property.

Fixes b33a22a1e7c4 ("arm64: dts: rockchip: add basic dts for Pine64 Quartz64-A")
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +0 -1
index fa953b736642..fdbfdf3634e4 100644
@@ -163,7 +163,6 @@ vcc5v0_usb20_otg: vcc5v0_usb20_otg {
 
 	vcc3v3_sd: vcc3v3_sd {
 		compatible = "regulator-fixed";
-		enable-active-low;
 		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc_sd_h>;
Signature · 1 line
2.35.1
author maintainer
#91 lore raw

PATCH 86/207 arm64: dts: imx8mm-verdin: extend pmic voltages

In reply to Greg Kroah-Hartman

From: Philippe Schenker <[email protected]>

[ Upstream commit b5a76cb38df779076a3cff624ce6a368d9bcf330 ]

Currently, we limited the voltages from the PMIC very strictly. This causes an issue with one Toradex SKU that uses a consumer-grade chip that is capable of going up to 1.8GHz at 1.00V.

Extend the ranges to min/max values of the SoC operating ranges (table
10) in the datasheet. Detailed explanation as follows:

BUCK2:
- As already described above, the SKU with the consumer-grade chip needs a voltage of at least 1.00V. 1.05V is chosen now as this is listed as the maximum. Both industrial and consumer-grade chips have an absolute maximum rating of 1.15V which makes it still safe to put 1.05V
- Lower the regulator-min value to the smallest value allowed from the Quad-A53, 1.2GHz version of the SoC

BUCK3:
- This regulator is used for SoC input voltages VDD_GPU, VDD_VPU and VDD_DRAM.
- Use the smallest value of these three inputs as the regulator-min
- Use the largest value of these three inputs as the regulator-max

LDO2:
- This LDO is used for VDD_SNVS_0P8 SoC input voltage. As this has a single nominal input voltage just put this in the middle of 0.8V.

Fixes 6a57f224f734 ("arm64: dts: freescale: add initial support for verdin imx8m mini")
---
 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +5 -5
index c2d4da25482f..44b473494d0f 100644
@@ -359,8 +359,8 @@ reg_vdd_arm: BUCK2 {
 				nxp,dvs-standby-voltage = <850000>;
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-max-microvolt = <950000>;
-				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1050000>;
+				regulator-min-microvolt = <805000>;
 				regulator-name = "On-module +VDD_ARM (BUCK2)";
 				regulator-ramp-delay = <3125>;
 			};
@@ -368,8 +368,8 @@ reg_vdd_arm: BUCK2 {
 			reg_vdd_dram: BUCK3 {
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-max-microvolt = <950000>;
-				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-min-microvolt = <805000>;
 				regulator-name = "On-module +VDD_GPU_VPU_DDR (BUCK3)";
 			};
 
@@ -408,7 +408,7 @@ reg_nvcc_snvs: LDO1 {
 			reg_vdd_snvs: LDO2 {
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-max-microvolt = <900000>;
+				regulator-max-microvolt = <800000>;
 				regulator-min-microvolt = <800000>;
 				regulator-name = "On-module +V0.8_SNVS (LDO2)";
 			};
Signature · 1 line
2.35.1
author maintainer
#92 lore raw

PATCH 87/207 netfilter: nf_conntrack_sip: fix ct_sip_walk_headers

In reply to Greg Kroah-Hartman

From: Igor Ryzhov <[email protected]>

[ Upstream commit 39aebedeaaa95757f5c1f2ddb5f43fdddbf478ca ]

ct_sip_next_header and ct_sip_get_header return an absolute value of matchoff, not a shift from current dataoff. So dataoff should be assigned matchoff, not incremented by it.

This issue can be seen in the scenario when there are multiple Contact headers and the first one is using a hostname and other headers use IP addresses. In this case, ct_sip_walk_headers will work as follows:

The first ct_sip_get_header call to will find the first Contact header but will return -1 as the header uses a hostname. But matchoff will be changed to the offset of this header. After that, dataoff should be set to matchoff, so that the next ct_sip_get_header call find the next Contact header. But instead of assigning dataoff to matchoff, it is incremented by it, which is not correct, as matchoff is an absolute value of the offset. So on the next call to the ct_sip_get_header, dataoff will be incorrect, and the next Contact header may not be found at all.

Fixes 05e3ced297fe ("[NETFILTER]: nf_conntrack_sip: introduce SIP-URI parsing helper")
---
 net/netfilter/nf_conntrack_sip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nf_conntrack_sip.c +2 -2
index b83dc9bf0a5d..78fd9122b70c 100644
@@ -477,7 +477,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
 				return ret;
 			if (ret == 0)
 				break;
-			dataoff += *matchoff;
+			dataoff = *matchoff;
 		}
 		*in_header = 0;
 	}
@@ -489,7 +489,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
 			break;
 		if (ret == 0)
 			return ret;
-		dataoff += *matchoff;
+		dataoff = *matchoff;
 	}
 
 	if (in_header)
Signature · 1 line
2.35.1
author maintainer
#93 lore raw

PATCH 88/207 netfilter: nf_conntrack_irc: Tighten matching on DCC message

In reply to Greg Kroah-Hartman

From: David Leadbeater <[email protected]>

[ Upstream commit e8d5dfd1d8747b56077d02664a8838c71ced948e ]

CTCP messages should only be at the start of an IRC message, not anywhere within it.

While the helper only decodes packes in the ORIGINAL direction, its possible to make a client send a CTCP message back by empedding one into a PING request. As-is, thats enough to make the helper believe that it saw a CTCP message.

Fixes 869f37d8e48f ("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port")
---
 net/netfilter/nf_conntrack_irc.c | 34 ++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)
net/netfilter/nf_conntrack_irc.c +28 -6
index 992decbcaa5c..5703846bea3b 100644
@@ -157,15 +157,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
 	data = ib_ptr;
 	data_limit = ib_ptr + datalen;
 
-	/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
-	 * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
-	while (data < data_limit - (19 + MINMATCHLEN)) {
-		if (memcmp(data, "\1DCC ", 5)) {
+	/* Skip any whitespace */
+	while (data < data_limit - 10) {
+		if (*data == ' ' || *data == '\r' || *data == '\n')
+			data++;
+		else
+			break;
+	}
+
+	/* strlen("PRIVMSG x ")=10 */
+	if (data < data_limit - 10) {
+		if (strncasecmp("PRIVMSG ", data, 8))
+			goto out;
+		data += 8;
+	}
+
+	/* strlen(" :\1DCC SENT t AAAAAAAA P\1\n")=26
+	 * 7+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=26
+	 */
+	while (data < data_limit - (21 + MINMATCHLEN)) {
+		/* Find first " :", the start of message */
+		if (memcmp(data, " :", 2)) {
 			data++;
 			continue;
 		}
+		data += 2;
+
+		/* then check that place only for the DCC command */
+		if (memcmp(data, "\1DCC ", 5))
+			goto out;
 		data += 5;
-		/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
+		/* we have at least (21+MINMATCHLEN)-(2+5) bytes valid data left */
 
 		iph = ip_hdr(skb);
 		pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
@@ -181,7 +203,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
 			pr_debug("DCC %s detected\n", dccprotos[i]);
 
 			/* we have at least
-			 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
+			 * (21+MINMATCHLEN)-7-dccprotos[i].matchlen bytes valid
 			 * data left (== 14/13 bytes) */
 			if (parse_dcc(data, data_limit, &dcc_ip,
 				       &dcc_port, &addr_beg_p, &addr_end_p)) {
Signature · 1 line
2.35.1
author maintainer
#94 lore raw

PATCH 89/207 netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find()

In reply to Greg Kroah-Hartman

From: Pablo Neira Ayuso <[email protected]>

[ Upstream commit 559c36c5a8d730c49ef805a72b213d3bba155cc8 ]

nf_osf_find() incorrectly returns true on mismatch, this leads to copying uninitialized memory area in nft_osf which can be used to leak stale kernel stack data to userspace.

Fixes 22c7652cdaa8 ("netfilter: nft_osf: Add version option support")
---
 net/netfilter/nfnetlink_osf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/nfnetlink_osf.c +3 -1
index 0fa2e2030427..ee6840bd5933 100644
@@ -269,6 +269,7 @@ bool nf_osf_find(const struct sk_buff *skb,
 	struct nf_osf_hdr_ctx ctx;
 	const struct tcphdr *tcp;
 	struct tcphdr _tcph;
+	bool found = false;
 
 	memset(&ctx, 0, sizeof(ctx));
 
@@ -283,10 +284,11 @@ bool nf_osf_find(const struct sk_buff *skb,
 
 		data->genre = f->genre;
 		data->version = f->version;
+		found = true;
 		break;
 	}
 
-	return true;
+	return found;
 }
 EXPORT_SYMBOL_GPL(nf_osf_find);
 
Signature · 1 line
2.35.1
author maintainer
#95 lore raw

PATCH 90/207 ice: Dont double unplug aux on peer initiated reset

In reply to Greg Kroah-Hartman

From: Dave Ertman <[email protected]>

[ Upstream commit 23c619190318376769ad7b61504c2ea0703fb783 ]

In the IDC callback that is accessed when the aux drivers request a reset, the function to unplug the aux devices is called. This function is also called in the ice_prepare_for_reset function. This double call is causing a "scheduling while atomic" BUG.

[  662.676430] ice 0000:4c:00.0 rocep76s0: cqp opcode = 0x1 maj_err_code = 0xffff min_err_code = 0x8003
[  662.676609] ice 0000:4c:00.0 rocep76s0: [Modify QP Cmd Error][op_code=8] status=-29 waiting=1 completion_err=1 maj=0xffff min=0x8003
[  662.815006] ice 0000:4c:00.0 rocep76s0: ICE OICR event notification: oicr = 0x10000003
[  662.815014] ice 0000:4c:00.0 rocep76s0: critical PE Error, GLPE_CRITERR=0x00011424
[  662.815017] ice 0000:4c:00.0 rocep76s0: Requesting a reset
[  662.815475] BUG: scheduling while atomic: swapper/37/0/0x00010002
[  662.815475] BUG: scheduling while atomic: swapper/37/0/0x00010002
[  662.815477] Modules linked in: rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs rfkill 8021q garp mrp stp llc vfat fat rpcrdma intel_rapl_msr intel_rapl_common sunrpc i10nm_edac rdma_ucm nfit ib_srpt libnvdimm ib_isert iscsi_target_mod x86_pkg_temp_thermal intel_powerclamp coretemp target_core_mod snd_hda_intel ib_iser snd_intel_dspcfg libiscsi snd_intel_sdw_acpi scsi_transport_iscsi kvm_intel iTCO_wdt rdma_cm snd_hda_codec kvm iw_cm ipmi_ssif iTCO_vendor_support snd_hda_core irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hwdep snd_seq snd_seq_device rapl snd_pcm snd_timer isst_if_mbox_pci pcspkr isst_if_mmio irdma intel_uncore idxd acpi_ipmi joydev isst_if_common snd mei_me idxd_bus ipmi_si soundcore i2c_i801 mei ipmi_devintf i2c_smbus i2c_ismt ipmi_msghandler acpi_power_meter acpi_pad rv(OE) ib_uverbs ib_cm ib_core xfs libcrc32c ast i2c_algo_bit drm_vram_helper drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm_ttm_helpe
 r ttm
[  662.815546]  nvme nvme_core ice drm crc32c_intel i40e t10_pi wmi pinctrl_emmitsburg dm_mirror dm_region_hash dm_log dm_mod fuse
[  662.815557] Preemption disabled at:
[  662.815558] [<0000000000000000>] 0x0
[  662.815563] CPU: 37 PID: 0 Comm: swapper/37 Kdump: loaded Tainted: G S         OE     5.17.1 #2
[  662.815566] Hardware name: Intel Corporation D50DNP/D50DNP, BIOS SE5C6301.86B.6624.D18.2111021741 11/02/2021
[  662.815568] Call Trace:
[  662.815572]  <IRQ>
[  662.815574]  dump_stack_lvl+0x33/0x42
[  662.815581]  __schedule_bug.cold.147+0x7d/0x8a
[  662.815588]  __schedule+0x798/0x990
[  662.815595]  schedule+0x44/0xc0
[  662.815597]  schedule_preempt_disabled+0x14/0x20
[  662.815600]  __mutex_lock.isra.11+0x46c/0x490
[  662.815603]  ? __ibdev_printk+0x76/0xc0 [ib_core]
[  662.815633]  device_del+0x37/0x3d0
[  662.815639]  ice_unplug_aux_dev+0x1a/0x40 [ice]
[  662.815674]  ice_schedule_reset+0x3c/0xd0 [ice]
[  662.815693]  irdma_iidc_event_handler.cold.7+0xb6/0xd3 [irdma]
[  662.815712]  ? bitmap_find_next_zero_area_off+0x45/0xa0
[  662.815719]  ice_send_event_to_aux+0x54/0x70 [ice]
[  662.815741]  ice_misc_intr+0x21d/0x2d0 [ice]
[  662.815756]  __handle_irq_event_percpu+0x4c/0x180
[  662.815762]  handle_irq_event_percpu+0xf/0x40
[  662.815764]  handle_irq_event+0x34/0x60
[  662.815766]  handle_edge_irq+0x9a/0x1c0
[  662.815770]  __common_interrupt+0x62/0x100
[  662.815774]  common_interrupt+0xb4/0xd0
[  662.815779]  </IRQ>
[  662.815780]  <TASK>
[  662.815780]  asm_common_interrupt+0x1e/0x40
[  662.815785] RIP: 0010:cpuidle_enter_state+0xd6/0x380
[  662.815789] Code: 49 89 c4 0f 1f 44 00 00 31 ff e8 65 d7 95 ff 45 84 ff 74 12 9c 58 f6 c4 02 0f 85 64 02 00 00 31 ff e8 ae c5 9c ff fb 45 85 f6 <0f> 88 12 01 00 00 49 63 d6 4c 2b 24 24 48 8d 04 52 48 8d 04 82 49
[  662.815791] RSP: 0018:ff2c2c4f18edbe80 EFLAGS: 00000202
[  662.815793] RAX: ff280805df140000 RBX: 0000000000000002 RCX: 000000000000001f
[  662.815795] RDX: 0000009a52da2d08 RSI: ffffffff93f8240b RDI: ffffffff93f53ee7
[  662.815796] RBP: ff5e2bd11ff41928 R08: 0000000000000000 R09: 000000000002f8c0
[  662.815797] R10: 0000010c3f18e2cf R11: 000000000000000f R12: 0000009a52da2d08
[  662.815798] R13: ffffffff94ad7e20 R14: 0000000000000002 R15: 0000000000000000
[  662.815801]  cpuidle_enter+0x29/0x40
[  662.815803]  do_idle+0x261/0x2b0
[  662.815807]  cpu_startup_entry+0x19/0x20
[  662.815809]  start_secondary+0x114/0x150
[  662.815813]  secondary_startup_64_no_verify+0xd5/0xdb
[  662.815818]  </TASK>
[  662.815846] bad: scheduling from the idle thread!
[  662.815849] CPU: 37 PID: 0 Comm: swapper/37 Kdump: loaded Tainted: G S      W  OE     5.17.1 #2
[  662.815852] Hardware name: Intel Corporation D50DNP/D50DNP, BIOS SE5C6301.86B.6624.D18.2111021741 11/02/2021
[  662.815853] Call Trace:
[  662.815855]  <IRQ>
[  662.815856]  dump_stack_lvl+0x33/0x42
[  662.815860]  dequeue_task_idle+0x20/0x30
[  662.815863]  __schedule+0x1c3/0x990
[  662.815868]  schedule+0x44/0xc0
[  662.815871]  schedule_preempt_disabled+0x14/0x20
[  662.815873]  __mutex_lock.isra.11+0x3a8/0x490
[  662.815876]  ? __ibdev_printk+0x76/0xc0 [ib_core]
[  662.815904]  device_del+0x37/0x3d0
[  662.815909]  ice_unplug_aux_dev+0x1a/0x40 [ice]
[  662.815937]  ice_schedule_reset+0x3c/0xd0 [ice]
[  662.815961]  irdma_iidc_event_handler.cold.7+0xb6/0xd3 [irdma]
[  662.815979]  ? bitmap_find_next_zero_area_off+0x45/0xa0
[  662.815985]  ice_send_event_to_aux+0x54/0x70 [ice]
[  662.816011]  ice_misc_intr+0x21d/0x2d0 [ice]
[  662.816033]  __handle_irq_event_percpu+0x4c/0x180
[  662.816037]  handle_irq_event_percpu+0xf/0x40
[  662.816039]  handle_irq_event+0x34/0x60
[  662.816042]  handle_edge_irq+0x9a/0x1c0
[  662.816045]  __common_interrupt+0x62/0x100
[  662.816048]  common_interrupt+0xb4/0xd0
[  662.816052]  </IRQ>
[  662.816053]  <TASK>
[  662.816054]  asm_common_interrupt+0x1e/0x40
[  662.816057] RIP: 0010:cpuidle_enter_state+0xd6/0x380
[  662.816060] Code: 49 89 c4 0f 1f 44 00 00 31 ff e8 65 d7 95 ff 45 84 ff 74 12 9c 58 f6 c4 02 0f 85 64 02 00 00 31 ff e8 ae c5 9c ff fb 45 85 f6 <0f> 88 12 01 00 00 49 63 d6 4c 2b 24 24 48 8d 04 52 48 8d 04 82 49
[  662.816063] RSP: 0018:ff2c2c4f18edbe80 EFLAGS: 00000202
[  662.816065] RAX: ff280805df140000 RBX: 0000000000000002 RCX: 000000000000001f
[  662.816067] RDX: 0000009a52da2d08 RSI: ffffffff93f8240b RDI: ffffffff93f53ee7
[  662.816068] RBP: ff5e2bd11ff41928 R08: 0000000000000000 R09: 000000000002f8c0
[  662.816070] R10: 0000010c3f18e2cf R11: 000000000000000f R12: 0000009a52da2d08
[  662.816071] R13: ffffffff94ad7e20 R14: 0000000000000002 R15: 0000000000000000
[  662.816075]  cpuidle_enter+0x29/0x40
[  662.816077]  do_idle+0x261/0x2b0
[  662.816080]  cpu_startup_entry+0x19/0x20
[  662.816083]  start_secondary+0x114/0x150
[  662.816087]  secondary_startup_64_no_verify+0xd5/0xdb
[  662.816091]  </TASK>
[  662.816169] bad: scheduling from the idle thread!

The correct place to unplug the aux devices for a reset is in the prepare_for_reset function, as this is a common place for all reset flows. It also has built in protection from being called twice in a single reset instance before the aux devices are replugged.

Fixes f9f5301e7e2d4 ("ice: Register auxiliary device to provide RDMA")
---
 drivers/net/ethernet/intel/ice/ice_main.c | 2 --
 1 file changed, 2 deletions(-)
drivers/net/ethernet/intel/ice/ice_main.c +0 -2
index 4c6bb7482b36..0b567e8e3674 100644
@@ -2399,8 +2399,6 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset)
 		return -EBUSY;
 	}
 
-	ice_unplug_aux_dev(pf);
-
 	switch (reset) {
 	case ICE_RESET_PFR:
 		set_bit(ICE_PFR_REQ, pf->state);
Signature · 1 line
2.35.1
author maintainer
#96 lore raw

PATCH 91/207 ice: Fix crash by keep old cfg when update TCs more than queues

In reply to Greg Kroah-Hartman

From: Ding Hui <[email protected]>

[ Upstream commit a509702cac95a8b450228a037c8542f57e538e5b ]

There are problems if allocated queues less than Traffic Classes.

Commit a632b2a4c920 ("ice: ethtool: Prohibit improper channel config for DCB") already disallow setting less queues than TCs.

Another case is if we first set less queues, and later update more TCs config due to LLDP, ice_vsi_cfg_tc() will failed but left dirty num_txq/rxq and tc_cfg in vsi, that will cause invalid pointer access.

[   95.968089] ice 0000:3b:00.1: More TCs defined than queues/rings allocated.
[   95.968092] ice 0000:3b:00.1: Trying to use more Rx queues (8), than were allocated (1)!
[   95.968093] ice 0000:3b:00.1: Failed to config TC for VSI index: 0
[   95.969621] general protection fault: 0000 [#1] SMP NOPTI
[   95.969705] CPU: 1 PID: 58405 Comm: lldpad Kdump: loaded Tainted: G     U  W  O     --------- -t - 4.18.0 #1
[   95.969867] Hardware name: O.E.M/BC11SPSCB10, BIOS 8.23 12/30/2021
[   95.969992] RIP: 0010:devm_kmalloc+0xa/0x60
[   95.970052] Code: 5c ff ff ff 31 c0 5b 5d 41 5c c3 b8 f4 ff ff ff eb f4 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 89 d1 <8b> 97 60 02 00 00 48 8d 7e 18 48 39 f7 72 3f 55 89 ce 53 48 8b 4c
[   95.970344] RSP: 0018:ffffc9003f553888 EFLAGS: 00010206
[   95.970425] RAX: dead000000000200 RBX: ffffea003c425b00 RCX: 00000000006080c0
[   95.970536] RDX: 00000000006080c0 RSI: 0000000000000200 RDI: dead000000000200
[   95.970648] RBP: dead000000000200 R08: 00000000000463c0 R09: ffff888ffa900000
[   95.970760] R10: 0000000000000000 R11: 0000000000000002 R12: ffff888ff6b40100
[   95.970870] R13: ffff888ff6a55018 R14: 0000000000000000 R15: ffff888ff6a55460
[   95.970981] FS:  00007f51b7d24700(0000) GS:ffff88903ee80000(0000) knlGS:0000000000000000
[   95.971108] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   95.971197] CR2: 00007fac5410d710 CR3: 0000000f2c1de002 CR4: 00000000007606e0
[   95.971309] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   95.971419] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   95.971530] PKRU: 55555554
[   95.971573] Call Trace:
[   95.971622]  ice_setup_rx_ring+0x39/0x110 [ice]
[   95.971695]  ice_vsi_setup_rx_rings+0x54/0x90 [ice]
[   95.971774]  ice_vsi_open+0x25/0x120 [ice]
[   95.971843]  ice_open_internal+0xb8/0x1f0 [ice]
[   95.971919]  ice_ena_vsi+0x4f/0xd0 [ice]
[   95.971987]  ice_dcb_ena_dis_vsi.constprop.5+0x29/0x90 [ice]
[   95.972082]  ice_pf_dcb_cfg+0x29a/0x380 [ice]
[   95.972154]  ice_dcbnl_setets+0x174/0x1b0 [ice]
[   95.972220]  dcbnl_ieee_set+0x89/0x230
[   95.972279]  ? dcbnl_ieee_del+0x150/0x150
[   95.972341]  dcb_doit+0x124/0x1b0
[   95.972392]  rtnetlink_rcv_msg+0x243/0x2f0
[   95.972457]  ? dcb_doit+0x14d/0x1b0
[   95.972510]  ? __kmalloc_node_track_caller+0x1d3/0x280
[   95.972591]  ? rtnl_calcit.isra.31+0x100/0x100
[   95.972661]  netlink_rcv_skb+0xcf/0xf0
[   95.972720]  netlink_unicast+0x16d/0x220
[   95.972781]  netlink_sendmsg+0x2ba/0x3a0
[   95.975891]  sock_sendmsg+0x4c/0x50
[   95.979032]  ___sys_sendmsg+0x2e4/0x300
[   95.982147]  ? kmem_cache_alloc+0x13e/0x190
[   95.985242]  ? __wake_up_common_lock+0x79/0x90
[   95.988338]  ? __check_object_size+0xac/0x1b0
[   95.991440]  ? _copy_to_user+0x22/0x30
[   95.994539]  ? move_addr_to_user+0xbb/0xd0
[   95.997619]  ? __sys_sendmsg+0x53/0x80
[   96.000664]  __sys_sendmsg+0x53/0x80
[   96.003747]  do_syscall_64+0x5b/0x1d0
[   96.006862]  entry_SYSCALL_64_after_hwframe+0x65/0xca

Only update num_txq/rxq when passed check, and restore tc_cfg if setup queue map failed.

Fixes a632b2a4c920 ("ice: ethtool: Prohibit improper channel config for DCB")
---
 drivers/net/ethernet/intel/ice/ice_lib.c | 42 +++++++++++++++---------
 1 file changed, 26 insertions(+), 16 deletions(-)
drivers/net/ethernet/intel/ice/ice_lib.c +26 -16
index 6c4e1d45235e..1169fd7811b0 100644
@@ -911,7 +911,7 @@ static void ice_set_dflt_vsi_ctx(struct ice_hw *hw, struct ice_vsi_ctx *ctxt)
  */
 static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
 {
-	u16 offset = 0, qmap = 0, tx_count = 0, pow = 0;
+	u16 offset = 0, qmap = 0, tx_count = 0, rx_count = 0, pow = 0;
 	u16 num_txq_per_tc, num_rxq_per_tc;
 	u16 qcount_tx = vsi->alloc_txq;
 	u16 qcount_rx = vsi->alloc_rxq;
@@ -978,23 +978,25 @@ static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
 	 * at least 1)
 	 */
 	if (offset)
-		vsi->num_rxq = offset;
+		rx_count = offset;
 	else
-		vsi->num_rxq = num_rxq_per_tc;
+		rx_count = num_rxq_per_tc;
 
-	if (vsi->num_rxq > vsi->alloc_rxq) {
+	if (rx_count > vsi->alloc_rxq) {
 		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
-			vsi->num_rxq, vsi->alloc_rxq);
+			rx_count, vsi->alloc_rxq);
 		return -EINVAL;
 	}
 
-	vsi->num_txq = tx_count;
-	if (vsi->num_txq > vsi->alloc_txq) {
+	if (tx_count > vsi->alloc_txq) {
 		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
-			vsi->num_txq, vsi->alloc_txq);
+			tx_count, vsi->alloc_txq);
 		return -EINVAL;
 	}
 
+	vsi->num_txq = tx_count;
+	vsi->num_rxq = rx_count;
+
 	if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) {
 		dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n");
 		/* since there is a chance that num_rxq could have been changed
@@ -3487,6 +3489,7 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,
 	u16 pow, offset = 0, qcount_tx = 0, qcount_rx = 0, qmap;
 	u16 tc0_offset = vsi->mqprio_qopt.qopt.offset[0];
 	int tc0_qcount = vsi->mqprio_qopt.qopt.count[0];
+	u16 new_txq, new_rxq;
 	u8 netdev_tc = 0;
 	int i;
 
@@ -3527,21 +3530,24 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,
 		}
 	}
 
-	/* Set actual Tx/Rx queue pairs */
-	vsi->num_txq = offset + qcount_tx;
-	if (vsi->num_txq > vsi->alloc_txq) {
+	new_txq = offset + qcount_tx;
+	if (new_txq > vsi->alloc_txq) {
 		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
-			vsi->num_txq, vsi->alloc_txq);
+			new_txq, vsi->alloc_txq);
 		return -EINVAL;
 	}
 
-	vsi->num_rxq = offset + qcount_rx;
-	if (vsi->num_rxq > vsi->alloc_rxq) {
+	new_rxq = offset + qcount_rx;
+	if (new_rxq > vsi->alloc_rxq) {
 		dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
-			vsi->num_rxq, vsi->alloc_rxq);
+			new_rxq, vsi->alloc_rxq);
 		return -EINVAL;
 	}
 
+	/* Set actual Tx/Rx queue pairs */
+	vsi->num_txq = new_txq;
+	vsi->num_rxq = new_rxq;
+
 	/* Setup queue TC[0].qmap for given VSI context */
 	ctxt->info.tc_mapping[0] = cpu_to_le16(qmap);
 	ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]);
@@ -3573,6 +3579,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
 {
 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
 	struct ice_pf *pf = vsi->back;
+	struct ice_tc_cfg old_tc_cfg;
 	struct ice_vsi_ctx *ctx;
 	struct device *dev;
 	int i, ret = 0;
@@ -3597,6 +3604,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
 			max_txqs[i] = vsi->num_txq;
 	}
 
+	memcpy(&old_tc_cfg, &vsi->tc_cfg, sizeof(old_tc_cfg));
 	vsi->tc_cfg.ena_tc = ena_tc;
 	vsi->tc_cfg.numtc = num_tc;
 
@@ -3613,8 +3621,10 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
 	else
 		ret = ice_vsi_setup_q_map(vsi, ctx);
 
-	if (ret)
+	if (ret) {
+		memcpy(&vsi->tc_cfg, &old_tc_cfg, sizeof(vsi->tc_cfg));
 		goto out;
+	}
 
 	/* must to indicate which section of VSI context are being modified */
 	ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID);
Signature · 1 line
2.35.1
author maintainer
#97 lore raw

PATCH 92/207 iavf: Fix cached head and tail value for iavf_get_tx_pending

In reply to Greg Kroah-Hartman

From: Brett Creeley <[email protected]>

[ Upstream commit 809f23c0423a43266e47a7dc67e95b5cb4d1cbfc ]

The underlying hardware may or may not allow reading of the head or tail registers and it really makes no difference if we use the software cached values. So, always used the software cached values.

Fixes 9c6c12595b73 ("i40e: Detection and recovery of TX queue hung logic moved to service_task from tx_timeout")
---
 drivers/net/ethernet/intel/iavf/iavf_txrx.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_txrx.c +4 -1
index 06d18797d25a..4c3f3f419110 100644
@@ -114,8 +114,11 @@ u32 iavf_get_tx_pending(struct iavf_ring *ring, bool in_sw)
 {
 	u32 head, tail;
 
+	/* underlying hardware might not allow access and/or always return
+	 * 0 for the head/tail registers so just use the cached values
+	 */
 	head = ring->next_to_clean;
-	tail = readl(ring->tail);
+	tail = ring->next_to_use;
 
 	if (head != tail)
 		return (head < tail) ?
Signature · 1 line
2.35.1
author maintainer
#98 lore raw

PATCH 93/207 ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header

In reply to Greg Kroah-Hartman

From: Lu Wei <[email protected]>

[ Upstream commit 81225b2ea161af48e093f58e8dfee6d705b16af4 ]

If an AF_PACKET socket is used to send packets through ipvlan and the default xmit function of the AF_PACKET socket is changed from dev_queue_xmit() to packet_direct_xmit() via setsockopt() with the option name of PACKET_QDISC_BYPASS, the skb->mac_header may not be reset and remains as the initial value of 65535, this may trigger slab-out-of-bounds bugs as following:

=================================================================
UG: KASAN: slab-out-of-bounds in ipvlan_xmit_mode_l2+0xdb/0x330 [ipvlan]
PU: 2 PID: 1768 Comm: raw_send Kdump: loaded Not tainted 6.0.0-rc4+ #6 ardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 all Trace:

print_address_description.constprop.0+0x1d/0x160
print_report.cold+0x4f/0x112
kasan_report+0xa3/0x130
ipvlan_xmit_mode_l2+0xdb/0x330 [ipvlan]
ipvlan_start_xmit+0x29/0xa0 [ipvlan]
__dev_direct_xmit+0x2e2/0x380
packet_direct_xmit+0x22/0x60
packet_snd+0x7c9/0xc40
sock_sendmsg+0x9a/0xa0
__sys_sendto+0x18a/0x230
__x64_sys_sendto+0x74/0x90
do_syscall_64+0x3b/0x90
entry_SYSCALL_64_after_hwframe+0x63/0xcd

The root cause is:
1. packet_snd() only reset skb->mac_header when sock->type is SOCK_RAW

     and skb->protocol is not specified as in packet_parse_headers()

2. packet_direct_xmit() doesn't reset skb->mac_header as dev_queue_xmit()

In this case, skb->mac_header is 65535 when ipvlan_xmit_mode_l2() is called. So when ipvlan_xmit_mode_l2() gets mac header with eth_hdr() which use "skb->head + skb->mac_header", out-of-bound access occurs.

This patch replaces eth_hdr() with skb_eth_hdr() in ipvlan_xmit_mode_l2() and reset mac header in multicast to solve this out-of-bound bug.

Fixes 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
---
 drivers/net/ipvlan/ipvlan_core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ipvlan/ipvlan_core.c +4 -2
index 6ffb27419e64..c58123e13689 100644
@@ -495,7 +495,6 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
 
 static int ipvlan_process_outbound(struct sk_buff *skb)
 {
-	struct ethhdr *ethh = eth_hdr(skb);
 	int ret = NET_XMIT_DROP;
 
 	/* The ipvlan is a pseudo-L2 device, so the packets that we receive
@@ -505,6 +504,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb)
 	if (skb_mac_header_was_set(skb)) {
 		/* In this mode we dont care about
 		 * multicast and broadcast traffic */
+		struct ethhdr *ethh = eth_hdr(skb);
+
 		if (is_multicast_ether_addr(ethh->h_dest)) {
 			pr_debug_ratelimited(
 				"Dropped {multi|broad}cast of type=[%x]\n",
@@ -589,7 +590,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
 static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
 {
 	const struct ipvl_dev *ipvlan = netdev_priv(dev);
-	struct ethhdr *eth = eth_hdr(skb);
+	struct ethhdr *eth = skb_eth_hdr(skb);
 	struct ipvl_addr *addr;
 	void *lyr3h;
 	int addr_type;
@@ -619,6 +620,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
 		return dev_forward_skb(ipvlan->phy_dev, skb);
 
 	} else if (is_multicast_ether_addr(eth->h_dest)) {
+		skb_reset_mac_header(skb);
 		ipvlan_skb_crossing_ns(skb, NULL);
 		ipvlan_multicast_enqueue(ipvlan->port, skb, true);
 		return NET_XMIT_SUCCESS;
Signature · 1 line
2.35.1
author maintainer
#99 lore raw

PATCH 94/207 net: core: fix flow symmetric hash

In reply to Greg Kroah-Hartman

From: Ludovic Cintrat <[email protected]>

[ Upstream commit 64ae13ed478428135cddc2f1113dff162d8112d4 ]

__flow_hash_consistentify() wrongly swaps ipv4 addresses in few cases. This function is indirectly used by __skb_get_hash_symmetric(), which is used to fanout packets in AF_PACKET.
Intrusion detection systems may be impacted by this issue.

__flow_hash_consistentify() computes the addresses difference then swaps them if the difference is negative. In few cases src - dst and dst - src are both negative.

The following snippet mimics __flow_hash_consistentify():

```
 #include <stdio.h>
 #include <stdint.h>

 int main(int argc, char** argv) {

     int diffs_d, diffd_s;
     uint32_t dst  = 0xb225a8c0; /* 178.37.168.192 --> 192.168.37.178 */
     uint32_t src  = 0x3225a8c0; /*  50.37.168.192 --> 192.168.37.50  */
     uint32_t dst2 = 0x3325a8c0; /*  51.37.168.192 --> 192.168.37.51  */

     diffs_d = src - dst;
     diffd_s = dst - src;

     printf("src:%08x dst:%08x, diff(s-d)=%d(0x%x) diff(d-s)=%d(0x%x)\n",
             src, dst, diffs_d, diffs_d, diffd_s, diffd_s);

     diffs_d = src - dst2;
     diffd_s = dst2 - src;

     printf("src:%08x dst:%08x, diff(s-d)=%d(0x%x) diff(d-s)=%d(0x%x)\n",
             src, dst2, diffs_d, diffs_d, diffd_s, diffd_s);

     return 0;
 }
```

Results:

src:3225a8c0 dst:b225a8c0, \
    diff(s-d)=-2147483648(0x80000000) \
    diff(d-s)=-2147483648(0x80000000)
src:3225a8c0 dst:3325a8c0, \
    diff(s-d)=-16777216(0xff000000) \
    diff(d-s)=16777216(0x1000000)

In the first case the addresses differences are always < 0, therefore __flow_hash_consistentify() always swaps, thus dst->src and src->dst packets have differents hashes.

Fixes c3f8324188fa8 ("net: Add full IPv6 addresses to flow_keys")
---
 net/core/flow_dissector.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
net/core/flow_dissector.c +2 -3
index 6aee04f75e3e..bcba61ef5b37 100644
@@ -1572,9 +1572,8 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys)
 
 	switch (keys->control.addr_type) {
 	case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
-		addr_diff = (__force u32)keys->addrs.v4addrs.dst -
-			    (__force u32)keys->addrs.v4addrs.src;
-		if (addr_diff < 0)
+		if ((__force u32)keys->addrs.v4addrs.dst <
+		    (__force u32)keys->addrs.v4addrs.src)
 			swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
 
 		if ((__force u16)keys->ports.dst <
Signature · 1 line
2.35.1
author maintainer
#100 lore raw

PATCH 95/207 wifi: iwlwifi: Mark IWLMEI as broken

In reply to Greg Kroah-Hartman

From: Toke Høiland-Jørgensen <[email protected]>

[ Upstream commit 8997f5c8a62760db69fd5c56116705796322c8ed ]

The iwlmei driver breaks iwlwifi when returning from suspend. The interface ends up in the 'down' state after coming back from suspend. And iwd doesn't touch the interface state, but wpa_supplicant does, so the bug only happens on iwd.

The bug report[0] has been open for four months now, and no fix seems to be forthcoming. Since just disabling the iwlmei driver works as a workaround, let's mark the config option as broken until it can be fixed properly.

[0] https://bugzilla.kernel.org/show_bug.cgi?id=215937

Fixes 2da4366f9e2c ("iwlwifi: mei: add the driver to allow cooperation with CSME")
---
 drivers/net/wireless/intel/iwlwifi/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/intel/iwlwifi/Kconfig +1 -0
index a647a406b87b..b20409f8c13a 100644
@@ -140,6 +140,7 @@ config IWLMEI
 	depends on INTEL_MEI
 	depends on PM
 	depends on CFG80211
+	depends on BROKEN
 	help
 	  Enables the iwlmei kernel module.
 
Signature · 1 line
2.35.1
author maintainer
#101 lore raw

PATCH 96/207 arm64: dts: tqma8mqml: Include phy-imx8-pcie.h header

In reply to Greg Kroah-Hartman

From: Fabio Estevam <[email protected]>

[ Upstream commit 70ae49c5ac876f0f4689889588544104209c09c4 ]

imx8mm-tqma8mqml.dtsi has PCIe support, so it should include <dt-bindings/phy/phy-imx8-pcie.h>.

Otherwise, there are build errors when this SoM dtsi is included on customers' carrier boards.

While at it, remove the PCI header from imx8mm-tqma8mqml-mba8mx.dts, which is now unneeded.

Fixes 1d84283101fc ("arm64: dts: tqma8mqml: add PCIe support")
---
 arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts | 1 -
 arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi       | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts +0 -1
index 286d2df01cfa..7e0aeb2db305 100644
@@ -5,7 +5,6 @@
 
 /dts-v1/;
 
-#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include "imx8mm-tqma8mqml.dtsi"
 #include "mba8mx.dtsi"
 
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi +1 -0
index 16ee9b5179e6..f649dfacb4b6 100644
@@ -3,6 +3,7 @@
  * Copyright 2020-2021 TQ-Systems GmbH
  */
 
+#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include "imx8mm.dtsi"
 
 / {
Signature · 1 line
2.35.1
author maintainer
#102 lore raw

PATCH 97/207 drm/mediatek: Fix wrong dither settings

In reply to Greg Kroah-Hartman

From: Allen-KH Cheng <[email protected]>

[ Upstream commit 87fd9294e63e8fa7532b5e65b534c3001c654ef8 ]

The width and height arguments in the cmdq packet for mtk_dither_config() are inverted. We fix the incorrect width and height for dither settings in mtk_dither_config().

---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +1 -1
index 5d7504a72b11..e244aa408d9d 100644
@@ -151,7 +151,7 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
 	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_DITHER_CFG);
 	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
Signature · 1 line
2.35.1
author maintainer
#103 lore raw

PATCH 98/207 arm64: dts: imx8mp-venice-gw74xx: fix CAN STBY polarity

In reply to Greg Kroah-Hartman

From: Tim Harvey <[email protected]>

[ Upstream commit e4ef0885632ed485961ac0962ad01be4ec9ec658 ]

The CAN STBY poarlity is active-low. Specify it as such by removing the 'enable-active-high' property and updating the gpio property.

Fixes 7899eb6cb15d ("arm64: dts: imx: Add i.MX8M Plus Gateworks gw7400 dts support")
---
 arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +1 -2
index 6630ec561dc2..4c729ac89625 100644
@@ -123,8 +123,7 @@ reg_can2_stby: regulator-can2-stby {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_reg_can>;
 		regulator-name = "can2_stby";
-		gpio = <&gpio3 19 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
+		gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
Signature · 1 line
2.35.1
author maintainer
#104 lore raw

PATCH 99/207 arm64: dts: imx8mp-venice-gw74xx: fix ksz9477 cpu port

In reply to Greg Kroah-Hartman

From: Tim Harvey <[email protected]>

[ Upstream commit c3681de3b8f2e8aff0306e2d6c129ca15b70b79d ]

The CPU uplink port on the KSZ9477 is P5 not P6 - fix this.

Fixes 7899eb6cb15d ("arm64: dts: imx: Add i.MX8M Plus Gateworks gw7400 dts support")
---
 arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +2 -2
index 4c729ac89625..3df7ee9a2fe1 100644
@@ -510,8 +510,8 @@ lan5: port@4 {
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
-			port@6 {
-				reg = <6>;
+			port@5 {
+				reg = <5>;
 				label = "cpu";
 				ethernet = <&fec>;
 				phy-mode = "rgmii-id";
Signature · 1 line
2.35.1
author maintainer
#105 lore raw

PATCH 100/207 ARM: dts: lan966x: Fix the interrupt number for internal PHYs

In reply to Greg Kroah-Hartman

From: Horatiu Vultur <[email protected]>

[ Upstream commit f5fc22cbbdcd349402faaddf1a07eb8403658ae8 ]

According to the datasheet the interrupts for internal PHYs are 80 and 81.

Fixes 6ad69e07def67c ("ARM: dts: lan966x: add MIIM nodes")
---
 arch/arm/boot/dts/lan966x.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/lan966x.dtsi +2 -2
index 38e90a31d2dd..25c19f9d0a12 100644
@@ -515,13 +515,13 @@ mdio1: mdio@e200413c {
 
 			phy0: ethernet-phy@1 {
 				reg = <1>;
-				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
 
 			phy1: ethernet-phy@2 {
 				reg = <2>;
-				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
 		};
Signature · 1 line
2.35.1
author maintainer
#106 lore raw

PATCH 101/207 net: phy: aquantia: wait for the suspend/resume operations to finish

In reply to Greg Kroah-Hartman

From: Ioana Ciornei <[email protected]>

[ Upstream commit ca2dccdeeb49a7e408112d681bf447984c845292 ]

The Aquantia datasheet notes that after issuing a Processor-Intensive MDIO operation, like changing the low-power state of the device, the driver should wait for the operation to finish before issuing a new MDIO command.

The new aqr107_wait_processor_intensive_op() function is added which can be used after these kind of MDIO operations. At the moment, we are only adding it at the end of the suspend/resume calls.

The issue was identified on a board featuring the AQR113C PHY, on which commands like 'ip link (..) up / down' issued without any delays between them would render the link on the PHY to remain down. The issue was easy to reproduce with a one-liner:

 $ ip link set dev ethX down; ip link set dev ethX up; \
 ip link set dev ethX down; ip link set dev ethX up;
Fixes ac9e81c230eb ("net: phy: aquantia: add suspend / resume callbacks for AQR107 family")
---
 drivers/net/phy/aquantia_main.c | 53 ++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)
drivers/net/phy/aquantia_main.c +49 -4
index c7047f5d7a9b..8bc0957a0f6d 100644
@@ -90,6 +90,9 @@
 #define VEND1_GLOBAL_FW_ID_MAJOR		GENMASK(15, 8)
 #define VEND1_GLOBAL_FW_ID_MINOR		GENMASK(7, 0)
 
+#define VEND1_GLOBAL_GEN_STAT2			0xc831
+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG	BIT(15)
+
 #define VEND1_GLOBAL_RSVD_STAT1			0xc885
 #define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID	GENMASK(7, 4)
 #define VEND1_GLOBAL_RSVD_STAT1_PROV_ID		GENMASK(3, 0)
@@ -124,6 +127,12 @@
 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2	BIT(1)
 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3	BIT(0)
 
+/* Sleep and timeout for checking if the Processor-Intensive
+ * MDIO operation is finished
+ */
+#define AQR107_OP_IN_PROG_SLEEP		1000
+#define AQR107_OP_IN_PROG_TIMEOUT	100000
+
 struct aqr107_hw_stat {
 	const char *name;
 	int reg;
@@ -596,16 +605,52 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
 		phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
 }
 
+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
+{
+	int val, err;
+
+	/* The datasheet notes to wait at least 1ms after issuing a
+	 * processor intensive operation before checking.
+	 * We cannot use the 'sleep_before_read' parameter of read_poll_timeout
+	 * because that just determines the maximum time slept, not the minimum.
+	 */
+	usleep_range(1000, 5000);
+
+	err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+					VEND1_GLOBAL_GEN_STAT2, val,
+					!(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
+					AQR107_OP_IN_PROG_SLEEP,
+					AQR107_OP_IN_PROG_TIMEOUT, false);
+	if (err) {
+		phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
+		return err;
+	}
+
+	return 0;
+}
+
 static int aqr107_suspend(struct phy_device *phydev)
 {
-	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-				MDIO_CTRL1_LPOWER);
+	int err;
+
+	err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
+			       MDIO_CTRL1_LPOWER);
+	if (err)
+		return err;
+
+	return aqr107_wait_processor_intensive_op(phydev);
 }
 
 static int aqr107_resume(struct phy_device *phydev)
 {
-	return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
-				  MDIO_CTRL1_LPOWER);
+	int err;
+
+	err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
+				 MDIO_CTRL1_LPOWER);
+	if (err)
+		return err;
+
+	return aqr107_wait_processor_intensive_op(phydev);
 }
 
 static int aqr107_probe(struct phy_device *phydev)
Signature · 1 line
2.35.1
author maintainer
#107 lore raw

PATCH 102/207 arm64: dts: imx8mp-venice-gw74xx: fix port/phy validation

In reply to Greg Kroah-Hartman

From: Tim Harvey <[email protected]>

[ Upstream commit f7fc391a5e28216150ab5390df35032309ead7e5 ]

Since commit 65ac79e18120 ("net: dsa: microchip: add the phylink get_caps") the phy-mode must be set otherwise the switch driver will assume "NA" mode and invalidate the port.

Fixes 7899eb6cb15d ("arm64: dts: imx: Add i.MX8M Plus Gateworks gw7400 dts support")
---
 arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +5 -0
index 3df7ee9a2fe1..211e6a1b296e 100644
@@ -483,30 +483,35 @@ ports {
 			lan1: port@0 {
 				reg = <0>;
 				label = "lan1";
+				phy-mode = "internal";
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
 			lan2: port@1 {
 				reg = <1>;
 				label = "lan2";
+				phy-mode = "internal";
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
 			lan3: port@2 {
 				reg = <2>;
 				label = "lan3";
+				phy-mode = "internal";
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
 			lan4: port@3 {
 				reg = <3>;
 				label = "lan4";
+				phy-mode = "internal";
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
 			lan5: port@4 {
 				reg = <4>;
 				label = "lan5";
+				phy-mode = "internal";
 				local-mac-address = [00 00 00 00 00 00];
 			};
 
Signature · 1 line
2.35.1
author maintainer
#108 lore raw

PATCH 103/207 scsi: qla2xxx: Fix memory leak in __qlt_24xx_handle_abts()

In reply to Greg Kroah-Hartman

From: Rafael Mendonca <[email protected]>

[ Upstream commit 601be20fc6a1b762044d2398befffd6bf236cebf ]

Commit 8f394da36a36 ("scsi: qla2xxx: Drop TARGET_SCF_LOOKUP_LUN_FROM_TAG") made the __qlt_24xx_handle_abts() function return early if tcm_qla2xxx_find_cmd_by_tag() didn't find a command, but it missed to clean up the allocated memory for the management command.

Fixes 8f394da36a36 ("scsi: qla2xxx: Drop TARGET_SCF_LOOKUP_LUN_FROM_TAG")
---
 drivers/scsi/qla2xxx/qla_target.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_target.c +3 -1
index 62666df1a59e..4acff4e84b90 100644
@@ -2151,8 +2151,10 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
 
 	abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
 				le32_to_cpu(abts->exchange_addr_to_abort));
-	if (!abort_cmd)
+	if (!abort_cmd) {
+		mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool);
 		return -EIO;
+	}
 	mcmd->unpacked_lun = abort_cmd->se_cmd.orig_fe_lun;
 
 	if (abort_cmd->qpair) {
Signature · 1 line
2.35.1
author maintainer
#109 lore raw

PATCH 104/207 scsi: mpt3sas: Fix return value check of dma_get_required_mask()

In reply to Greg Kroah-Hartman

From: Sreekanth Reddy <[email protected]>

[ Upstream commit e0e0747de0ea3dd87cdbb0393311e17471a9baf1 ]

Fix the incorrect return value check of dma_get_required_mask(). Due to this incorrect check, the driver was always setting the DMA mask to 63 bit.

Fixes ba27c5cf286d ("scsi: mpt3sas: Don't change the DMA coherent mask after allocations")
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/mpt3sas/mpt3sas_base.c +1 -1
index 9a1ae52bb621..a6d3471a6105 100644
@@ -2993,7 +2993,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
 
 	if (ioc->is_mcpu_endpoint ||
 	    sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma ||
-	    dma_get_required_mask(&pdev->dev) <= 32)
+	    dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32))
 		ioc->dma_mask = 32;
 	/* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
 	else if (ioc->hba_mpi_version_belonged > MPI2_VERSION)
Signature · 1 line
2.35.1
author maintainer
#110 lore raw

PATCH 105/207 net: bonding: Share lacpdu_mcast_addr definition

In reply to Greg Kroah-Hartman

From: Benjamin Poirier <[email protected]>

[ Upstream commit 1d9a143ee3408349700f44a9197b7ae0e4faae5d ]

There are already a few definitions of arrays containing MULTICAST_LACPDU_ADDR and the next patch will add one more use. These all contain the same constant data so define one common instance for all bonding code.

Stable-dep-of: 86247aba599e ("net: bonding: Unsync device addresses on ndo_stop")

---
 drivers/net/bonding/bond_3ad.c  |  5 +++--
 drivers/net/bonding/bond_main.c | 16 ++++------------
 include/net/bond_3ad.h          |  2 --
 include/net/bonding.h           |  3 +++
 4 files changed, 10 insertions(+), 16 deletions(-)
drivers/net/bonding/bond_3ad.c +3 -2
index 1f0120cbe9e8..8ad095c19f27 100644
@@ -87,8 +87,9 @@ static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = {
 static u16 ad_ticks_per_sec;
 static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
 
-static const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned =
-	MULTICAST_LACPDU_ADDR;
+const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned = {
+	0x01, 0x80, 0xC2, 0x00, 0x00, 0x02
+};
 
 /* ================= main 802.3ad protocol functions ================== */
 static int ad_lacpdu_send(struct port *port);
drivers/net/bonding/bond_main.c +4 -12
index bff0bfd10e23..b159b73f2969 100644
@@ -865,12 +865,8 @@ static void bond_hw_addr_flush(struct net_device *bond_dev,
 	dev_uc_unsync(slave_dev, bond_dev);
 	dev_mc_unsync(slave_dev, bond_dev);
 
-	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-		/* del lacpdu mc addr from mc list */
-		u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-
-		dev_mc_del(slave_dev, lacpdu_multicast);
-	}
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		dev_mc_del(slave_dev, lacpdu_mcast_addr);
 }
 
 /*--------------------------- Active slave change ---------------------------*/
@@ -2144,12 +2140,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 		dev_uc_sync_multiple(slave_dev, bond_dev);
 		netif_addr_unlock_bh(bond_dev);
 
-		if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-			/* add lacpdu mc addr to mc list */
-			u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-
-			dev_mc_add(slave_dev, lacpdu_multicast);
-		}
+		if (BOND_MODE(bond) == BOND_MODE_8023AD)
+			dev_mc_add(slave_dev, lacpdu_mcast_addr);
 	}
 
 	bond->slave_cnt++;
include/net/bond_3ad.h +0 -2
index 184105d68294..f2273bd5a4c5 100644
@@ -15,8 +15,6 @@
 #define PKT_TYPE_LACPDU         cpu_to_be16(ETH_P_SLOW)
 #define AD_TIMER_INTERVAL       100 /*msec*/
 
-#define MULTICAST_LACPDU_ADDR    {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
-
 #define AD_LACP_SLOW 0
 #define AD_LACP_FAST 1
 
include/net/bonding.h +3 -0
index 3b816ae8b1f3..7ac1773b9922 100644
@@ -785,6 +785,9 @@ extern struct rtnl_link_ops bond_link_ops;
 /* exported from bond_sysfs_slave.c */
 extern const struct sysfs_ops slave_sysfs_ops;
 
+/* exported from bond_3ad.c */
+extern const u8 lacpdu_mcast_addr[];
+
 static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
 {
 	dev_core_stats_tx_dropped_inc(dev);
Signature · 1 line
2.35.1
author maintainer
#111 lore raw

PATCH 106/207 net: bonding: Unsync device addresses on ndo_stop

In reply to Greg Kroah-Hartman

From: Benjamin Poirier <[email protected]>

[ Upstream commit 86247aba599e5b07d7e828e6edaaebb0ef2b1158 ]

Netdev drivers are expected to call dev_{uc,mc}_sync() in their ndo_set_rx_mode method and dev_{uc,mc}_unsync() in their ndo_stop method. This is mentioned in the kerneldoc for those dev_* functions.

The bonding driver calls dev_{uc,mc}_unsync() during ndo_uninit instead of ndo_stop. This is ineffective because address lists (dev->{uc,mc}) have already been emptied in unregister_netdevice_many() before ndo_uninit is called. This mistake can result in addresses being leftover on former bond slaves after a bond has been deleted; see test_LAG_cleanup() in the last patch in this series.

Add unsync calls, via bond_hw_addr_flush(), at their expected location, bond_close().
Add dev_mc_add() call to bond_open() to match the above change.

v3:
* When adding or deleting a slave, only sync/unsync, add/del addresses if the bond is up. In other cases, it is taken care of at the right time by ndo_open/ndo_set_rx_mode/ndo_stop.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 drivers/net/bonding/bond_main.c | 47 ++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 12 deletions(-)
drivers/net/bonding/bond_main.c +35 -12
index b159b73f2969..83852e6719e2 100644
@@ -886,7 +886,8 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
 		if (bond->dev->flags & IFF_ALLMULTI)
 			dev_set_allmulti(old_active->dev, -1);
 
-		bond_hw_addr_flush(bond->dev, old_active->dev);
+		if (bond->dev->flags & IFF_UP)
+			bond_hw_addr_flush(bond->dev, old_active->dev);
 	}
 
 	if (new_active) {
@@ -897,10 +898,12 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
 		if (bond->dev->flags & IFF_ALLMULTI)
 			dev_set_allmulti(new_active->dev, 1);
 
-		netif_addr_lock_bh(bond->dev);
-		dev_uc_sync(new_active->dev, bond->dev);
-		dev_mc_sync(new_active->dev, bond->dev);
-		netif_addr_unlock_bh(bond->dev);
+		if (bond->dev->flags & IFF_UP) {
+			netif_addr_lock_bh(bond->dev);
+			dev_uc_sync(new_active->dev, bond->dev);
+			dev_mc_sync(new_active->dev, bond->dev);
+			netif_addr_unlock_bh(bond->dev);
+		}
 	}
 }
 
@@ -2135,13 +2138,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 			}
 		}
 
-		netif_addr_lock_bh(bond_dev);
-		dev_mc_sync_multiple(slave_dev, bond_dev);
-		dev_uc_sync_multiple(slave_dev, bond_dev);
-		netif_addr_unlock_bh(bond_dev);
+		if (bond_dev->flags & IFF_UP) {
+			netif_addr_lock_bh(bond_dev);
+			dev_mc_sync_multiple(slave_dev, bond_dev);
+			dev_uc_sync_multiple(slave_dev, bond_dev);
+			netif_addr_unlock_bh(bond_dev);
 
-		if (BOND_MODE(bond) == BOND_MODE_8023AD)
-			dev_mc_add(slave_dev, lacpdu_mcast_addr);
+			if (BOND_MODE(bond) == BOND_MODE_8023AD)
+				dev_mc_add(slave_dev, lacpdu_mcast_addr);
+		}
 	}
 
 	bond->slave_cnt++;
@@ -2412,7 +2417,8 @@ static int __bond_release_one(struct net_device *bond_dev,
 		if (old_flags & IFF_ALLMULTI)
 			dev_set_allmulti(slave_dev, -1);
 
-		bond_hw_addr_flush(bond_dev, slave_dev);
+		if (old_flags & IFF_UP)
+			bond_hw_addr_flush(bond_dev, slave_dev);
 	}
 
 	slave_disable_netpoll(slave);
@@ -4186,6 +4192,9 @@ static int bond_open(struct net_device *bond_dev)
 		/* register to receive LACPDUs */
 		bond->recv_probe = bond_3ad_lacpdu_recv;
 		bond_3ad_initiate_agg_selection(bond, 1);
+
+		bond_for_each_slave(bond, slave, iter)
+			dev_mc_add(slave->dev, lacpdu_mcast_addr);
 	}
 
 	if (bond_mode_can_use_xmit_hash(bond))
@@ -4197,6 +4206,7 @@ static int bond_open(struct net_device *bond_dev)
 static int bond_close(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
+	struct slave *slave;
 
 	bond_work_cancel_all(bond);
 	bond->send_peer_notif = 0;
@@ -4204,6 +4214,19 @@ static int bond_close(struct net_device *bond_dev)
 		bond_alb_deinitialize(bond);
 	bond->recv_probe = NULL;
 
+	if (bond_uses_primary(bond)) {
+		rcu_read_lock();
+		slave = rcu_dereference(bond->curr_active_slave);
+		if (slave)
+			bond_hw_addr_flush(bond_dev, slave->dev);
+		rcu_read_unlock();
+	} else {
+		struct list_head *iter;
+
+		bond_for_each_slave(bond, slave, iter)
+			bond_hw_addr_flush(bond_dev, slave->dev);
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.35.1
author maintainer
#112 lore raw

PATCH 107/207 net: team: Unsync device addresses on ndo_stop

In reply to Greg Kroah-Hartman

From: Benjamin Poirier <[email protected]>

[ Upstream commit bd60234222b2fd5573526da7bcd422801f271f5f ]

Netdev drivers are expected to call dev_{uc,mc}_sync() in their ndo_set_rx_mode method and dev_{uc,mc}_unsync() in their ndo_stop method. This is mentioned in the kerneldoc for those dev_* functions.

The team driver calls dev_{uc,mc}_unsync() during ndo_uninit instead of ndo_stop. This is ineffective because address lists (dev->{uc,mc}) have already been emptied in unregister_netdevice_many() before ndo_uninit is called. This mistake can result in addresses being leftover on former team ports after a team device has been deleted; see test_LAG_cleanup() in the last patch in this series.

Add unsync calls at their expected location, team_close().

v3:
* When adding or deleting a port, only sync/unsync addresses if the team device is up. In other cases, it is taken care of at the right time by ndo_open/ndo_set_rx_mode/ndo_stop.

Fixes 3d249d4ca7d0 ("net: introduce ethernet teaming device")
---
 drivers/net/team/team.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/net/team/team.c +18 -6
index b07dde6f0abf..b9899913d246 100644
@@ -1275,10 +1275,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
 		}
 	}
 
-	netif_addr_lock_bh(dev);
-	dev_uc_sync_multiple(port_dev, dev);
-	dev_mc_sync_multiple(port_dev, dev);
-	netif_addr_unlock_bh(dev);
+	if (dev->flags & IFF_UP) {
+		netif_addr_lock_bh(dev);
+		dev_uc_sync_multiple(port_dev, dev);
+		dev_mc_sync_multiple(port_dev, dev);
+		netif_addr_unlock_bh(dev);
+	}
 
 	port->index = -1;
 	list_add_tail_rcu(&port->list, &team->port_list);
@@ -1349,8 +1351,10 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
 	netdev_rx_handler_unregister(port_dev);
 	team_port_disable_netpoll(port);
 	vlan_vids_del_by_dev(port_dev, dev);
-	dev_uc_unsync(port_dev, dev);
-	dev_mc_unsync(port_dev, dev);
+	if (dev->flags & IFF_UP) {
+		dev_uc_unsync(port_dev, dev);
+		dev_mc_unsync(port_dev, dev);
+	}
 	dev_close(port_dev);
 	team_port_leave(team, port);
 
@@ -1700,6 +1704,14 @@ static int team_open(struct net_device *dev)
 
 static int team_close(struct net_device *dev)
 {
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+
+	list_for_each_entry(port, &team->port_list, list) {
+		dev_uc_unsync(port->dev, dev);
+		dev_mc_unsync(port->dev, dev);
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.35.1
author maintainer
#113 lore raw

PATCH 108/207 drm/panel: simple: Fix innolux_g121i1_l01 bus_format

In reply to Greg Kroah-Hartman

From: Heiko Schocher <[email protected]>

[ Upstream commit a7c48a0ab87ae52c087d663e83e56b8225ac4cce ]

innolux_g121i1_l01 sets bpc to 6, so use the corresponding bus format:
MEDIA_BUS_FMT_RGB666_1X7X3_SPWG.

Fixes 4ae13e486866 ("drm/panel: simple: Add more properties to Innolux G121I1-L01")
---
 drivers/gpu/drm/panel/panel-simple.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/panel/panel-simple.c +1 -1
index 4a2e580a2f7b..0e001ce8a40f 100644
@@ -2136,7 +2136,7 @@ static const struct panel_desc innolux_g121i1_l01 = {
 		.enable = 200,
 		.disable = 20,
 	},
-	.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+	.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
Signature · 1 line
2.35.1
author maintainer
#114 lore raw

PATCH 109/207 mm/slab_common: fix possible double free of kmem_cache

In reply to Greg Kroah-Hartman

From: Feng Tang <[email protected]>

[ Upstream commit d71608a877362becdc94191f190902fac1e64d35 ]

When doing slub_debug test, kfence's 'test_memcache_typesafe_by_rcu' kunit test case cause a use-after-free error:

  BUG: KASAN: use-after-free in kobject_del+0x14/0x30
  Read of size 8 at addr ffff888007679090 by task kunit_try_catch/261

  CPU: 1 PID: 261 Comm: kunit_try_catch Tainted: G    B            N 6.0.0-rc5-next-20220916 #17
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
  Call Trace:
   <TASK>
   dump_stack_lvl+0x34/0x48
   print_address_description.constprop.0+0x87/0x2a5
   print_report+0x103/0x1ed
   kasan_report+0xb7/0x140
   kobject_del+0x14/0x30
   kmem_cache_destroy+0x130/0x170
   test_exit+0x1a/0x30
   kunit_try_run_case+0xad/0xc0
   kunit_generic_run_threadfn_adapter+0x26/0x50
   kthread+0x17b/0x1b0
   </TASK>

The cause is inside kmem_cache_destroy():

kmem_cache_destroy
acquire lock/mutex
shutdown_cache
schedule_work(kmem_cache_release) (if RCU flag set)
release lock/mutex
kmem_cache_release (if RCU flag not set)

In some certain timing, the scheduled work could be run before the next RCU flag checking, which can then get a wrong value and lead to double kmem_cache_release().

Fix it by caching the RCU flag inside protected area, just like 'refcnt'

Fixes 0495e337b703 ("mm/slab_common: Deleting kobject in kmem_cache_destroy() without holding slab_mutex/cpu_hotplug_lock")
---
 mm/slab_common.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
mm/slab_common.c +4 -1
index dbd4b6f9b0e7..29ae1358d5f0 100644
@@ -503,6 +503,7 @@ void slab_kmem_cache_release(struct kmem_cache *s)
 void kmem_cache_destroy(struct kmem_cache *s)
 {
 	int refcnt;
+	bool rcu_set;
 
 	if (unlikely(!s) || !kasan_check_byte(s))
 		return;
@@ -510,6 +511,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
 	cpus_read_lock();
 	mutex_lock(&slab_mutex);
 
+	rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU;
+
 	refcnt = --s->refcount;
 	if (refcnt)
 		goto out_unlock;
@@ -520,7 +523,7 @@ void kmem_cache_destroy(struct kmem_cache *s)
 out_unlock:
 	mutex_unlock(&slab_mutex);
 	cpus_read_unlock();
-	if (!refcnt && !(s->flags & SLAB_TYPESAFE_BY_RCU))
+	if (!refcnt && !rcu_set)
 		kmem_cache_release(s);
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
Signature · 1 line
2.35.1
author maintainer
#115 lore raw

PATCH 110/207 MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

[ Upstream commit 502550123bee6a2ffa438409b5b9aad4d6db3a8c ]

The lantiq WDT driver uses clk_get_io(), which is not exported, so export it to fix a build error:

ERROR: modpost: "clk_get_io" [drivers/watchdog/lantiq_wdt.ko] undefined!

Fixes 287e3f3f4e68 ("MIPS: lantiq: implement support for clkdev api")
Cc Thomas Bogendoerfer <[email protected]>
Cc John Crispin <[email protected]>
---
 arch/mips/lantiq/clk.c | 1 +
 1 file changed, 1 insertion(+)
arch/mips/lantiq/clk.c +1 -0
index 7a623684d9b5..2d5a0bcb0cec 100644
@@ -50,6 +50,7 @@ struct clk *clk_get_io(void)
 {
 	return &cpu_clk_generic[2];
 }
+EXPORT_SYMBOL_GPL(clk_get_io);
 
 struct clk *clk_get_ppe(void)
 {
Signature · 1 line
2.35.1
author maintainer
#116 lore raw

PATCH 111/207 MIPS: Loongson32: Fix PHY-mode being left unspecified

In reply to Greg Kroah-Hartman

From: Serge Semin <[email protected]>

[ Upstream commit e9f3f8f488005f6da3cfb66070706770ecaef747 ]

commit 0060c8783330 ("net: stmmac: implement support for passive mode converters via dt") has changed the plat->interface field semantics from containing the PHY-mode to specifying the MAC-PCS interface mode. Due to that the loongson32 platform code will leave the phylink interface uninitialized with the PHY-mode intended by the means of the actual platform setup. The commit-author most likely has just missed the arch-specific code to fix. Let's mend the Loongson32 platform code then by assigning the PHY-mode to the phy_interface field of the STMMAC platform data.

Fixes 0060c8783330 ("net: stmmac: implement support for passive mode converters via dt")
---
 arch/mips/loongson32/common/platform.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/mips/loongson32/common/platform.c +8 -8
index 794c96c2a4cd..311dc1580bbd 100644
@@ -98,7 +98,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
 	if (plat_dat->bus_id) {
 		__raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
 			     GMAC1_USE_UART0, LS1X_MUX_CTRL0);
-		switch (plat_dat->interface) {
+		switch (plat_dat->phy_interface) {
 		case PHY_INTERFACE_MODE_RGMII:
 			val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
 			break;
@@ -107,12 +107,12 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
 			break;
 		default:
 			pr_err("unsupported mii mode %d\n",
-			       plat_dat->interface);
+			       plat_dat->phy_interface);
 			return -ENOTSUPP;
 		}
 		val &= ~GMAC1_SHUT;
 	} else {
-		switch (plat_dat->interface) {
+		switch (plat_dat->phy_interface) {
 		case PHY_INTERFACE_MODE_RGMII:
 			val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
 			break;
@@ -121,7 +121,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
 			break;
 		default:
 			pr_err("unsupported mii mode %d\n",
-			       plat_dat->interface);
+			       plat_dat->phy_interface);
 			return -ENOTSUPP;
 		}
 		val &= ~GMAC0_SHUT;
@@ -131,7 +131,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
 	plat_dat = dev_get_platdata(&pdev->dev);
 
 	val &= ~PHY_INTF_SELI;
-	if (plat_dat->interface == PHY_INTERFACE_MODE_RMII)
+	if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII)
 		val |= 0x4 << PHY_INTF_SELI_SHIFT;
 	__raw_writel(val, LS1X_MUX_CTRL1);
 
@@ -146,9 +146,9 @@ static struct plat_stmmacenet_data ls1x_eth0_pdata = {
 	.bus_id			= 0,
 	.phy_addr		= -1,
 #if defined(CONFIG_LOONGSON1_LS1B)
-	.interface		= PHY_INTERFACE_MODE_MII,
+	.phy_interface		= PHY_INTERFACE_MODE_MII,
 #elif defined(CONFIG_LOONGSON1_LS1C)
-	.interface		= PHY_INTERFACE_MODE_RMII,
+	.phy_interface		= PHY_INTERFACE_MODE_RMII,
 #endif
 	.mdio_bus_data		= &ls1x_mdio_bus_data,
 	.dma_cfg		= &ls1x_eth_dma_cfg,
@@ -186,7 +186,7 @@ struct platform_device ls1x_eth0_pdev = {
 static struct plat_stmmacenet_data ls1x_eth1_pdata = {
 	.bus_id			= 1,
 	.phy_addr		= -1,
-	.interface		= PHY_INTERFACE_MODE_MII,
+	.phy_interface		= PHY_INTERFACE_MODE_MII,
 	.mdio_bus_data		= &ls1x_mdio_bus_data,
 	.dma_cfg		= &ls1x_eth_dma_cfg,
 	.has_gmac		= 1,
Signature · 1 line
2.35.1
author maintainer
#117 lore raw

PATCH 112/207 um: fix default console kernel parameter

In reply to Greg Kroah-Hartman

From: Christian Lamparter <[email protected]>

[ Upstream commit 782b1f70f8a8b28571949d2ba43fe88b96d75ec3 ]

OpenWrt's UML with 5.15 was producing odd errors/warnings during preinit part of the early userspace portion:

|[    0.000000] Kernel command line: ubd0=root.img root=98:0 console=tty
|[...]
|[    0.440000] random: jshn: uninitialized urandom read (4 bytes read)
|[    0.460000] random: jshn: uninitialized urandom read (4 bytes read)
|/etc/preinit: line 47: can't create /dev/tty: No such device or address
|/etc/preinit: line 48: can't create /dev/tty: No such device or address
|/etc/preinit: line 58: can't open /dev/tty: No such device or address
|[...] repeated many times

That "/dev/tty" came from the command line (which is automatically added if no console= parameter was specified for the uml binary).

The TLDP project tells the following about the /dev/tty:
<https://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3>

| /dev/tty stands for the controlling terminal (if any) for the current
| process.[...]
| /dev/tty is something like a link to the actually terminal device[..]

The "(if any)" is important here, since it's possible for processes to not have a controlling terminal.

I think this was a simple typo and the author wanted tty0 there.

CC Thomas Meyer <[email protected]>
Fixes d7ffac33631b ("um: stdio_console: Make preferred console")
---
 arch/um/kernel/um_arch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/kernel/um_arch.c +1 -1
index e0de60e503b9..d9e023c78f56 100644
@@ -33,7 +33,7 @@
 #include "um_arch.h"
 
 #define DEFAULT_COMMAND_LINE_ROOT "root=98:0"
-#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty"
+#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty0"
 
 /* Changed in add_arg and setup_arch, which run before SMP is started */
 static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 };
Signature · 1 line
2.35.1
author maintainer
#118 lore raw

PATCH 113/207 iavf: Fix bad page state

In reply to Greg Kroah-Hartman

From: Norbert Zulinski <[email protected]>

[ Upstream commit 66039eb9015eee4f7ff0c99b83c65c7ecb3c8190 ]

Fix bad page state, free inappropriate page in handling dummy descriptor. iavf_build_skb now has to check not only if rx_buffer is NULL but also if size is zero, same thing in iavf_clean_rx_irq. Without this patch driver would free page that will be used by napi_build_skb.

Fixes a9f49e006030 ("iavf: Fix handling of dummy receive descriptors")
---
 drivers/net/ethernet/intel/iavf/iavf_txrx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_txrx.c +2 -2
index 4c3f3f419110..18b6a702a1d6 100644
@@ -1393,7 +1393,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring,
 #endif
 	struct sk_buff *skb;
 
-	if (!rx_buffer)
+	if (!rx_buffer || !size)
 		return NULL;
 	/* prefetch first cache line of first page */
 	va = page_address(rx_buffer->page) + rx_buffer->page_offset;
@@ -1551,7 +1551,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
 		/* exit if we failed to retrieve a buffer */
 		if (!skb) {
 			rx_ring->rx_stats.alloc_buff_failed++;
-			if (rx_buffer)
+			if (rx_buffer && size)
 				rx_buffer->pagecnt_bias++;
 			break;
 		}
Signature · 1 line
2.35.1
author maintainer
#119 lore raw

PATCH 114/207 mlxbf_gige: clear MDIO gateway lock after read

In reply to Greg Kroah-Hartman

From: David Thompson <[email protected]>

[ Upstream commit 182447b12144b7be9b63a273d27c5a11bd54960a ]

The MDIO gateway (GW) lock in BlueField-2 GIGE logic is set after read. This patch adds logic to make sure the lock is always cleared at the end of each MDIO transaction.

Fixes f92e1869d74e ("Add Mellanox BlueField Gigabit Ethernet driver")
---
 drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c +6 -0
index 85155cd9405c..4aeb927c3715 100644
@@ -179,6 +179,9 @@ static int mlxbf_gige_mdio_read(struct mii_bus *bus, int phy_add, int phy_reg)
 	/* Only return ad bits of the gw register */
 	ret &= MLXBF_GIGE_MDIO_GW_AD_MASK;
 
+	/* The MDIO lock is set on read. To release it, clear gw register */
+	writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET);
+
 	return ret;
 }
 
@@ -203,6 +206,9 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
 					temp, !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK),
 					5, 1000000);
 
+	/* The MDIO lock is set on read. To release it, clear gw register */
+	writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET);
+
 	return ret;
 }
 
Signature · 1 line
2.35.1
author maintainer
#120 lore raw

PATCH 115/207 iavf: Fix set max MTU size with port VLAN and jumbo frames

In reply to Greg Kroah-Hartman

From: Michal Jaron <[email protected]>

[ Upstream commit 399c98c4dc50b7eb7e9f24da7ffdda6f025676ef ]

After setting port VLAN and MTU to 9000 on VF with ice driver there was an iavf error
"PF returned error -5 (IAVF_ERR_PARAM) to our request 6".

During queue configuration, VF's max packet size was set to IAVF_MAX_RXBUFFER but on ice max frame size was smaller by VLAN_HLEN due to making some space for port VLAN as VF is not aware whether it's in a port VLAN. This mismatch in sizes caused ice to reject queue configuration with ERR_PARAM error. Proper max_mtu is sent from ice PF to VF with GET_VF_RESOURCES msg but VF does not look at this.

In iavf change max_frame from IAVF_MAX_RXBUFFER to max_mtu received from pf with GET_VF_RESOURCES msg to make vf's max_frame_size dependent from pf. Add check if received max_mtu is not in eligible range then set it to IAVF_MAX_RXBUFFER.

Fixes dab86afdbbd1 ("i40e/i40evf: Change the way we limit the maximum frame size for Rx")
---
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +5 -2
index 1603e99bae4a..498797a0a0a9 100644
@@ -273,11 +273,14 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
 void iavf_configure_queues(struct iavf_adapter *adapter)
 {
 	struct virtchnl_vsi_queue_config_info *vqci;
-	struct virtchnl_queue_pair_info *vqpi;
+	int i, max_frame = adapter->vf_res->max_mtu;
 	int pairs = adapter->num_active_queues;
-	int i, max_frame = IAVF_MAX_RXBUFFER;
+	struct virtchnl_queue_pair_info *vqpi;
 	size_t len;
 
+	if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
+		max_frame = IAVF_MAX_RXBUFFER;
+
 	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
 		dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
Signature · 1 line
2.35.1
author maintainer
#121 lore raw

PATCH 116/207 i40e: Fix VF set max MTU size

In reply to Greg Kroah-Hartman

From: Michal Jaron <[email protected]>

[ Upstream commit 372539def2824c43b6afe2403045b140f65c5acc ]

Max MTU sent to VF is set to 0 during memory allocation. It cause that max MTU on VF is changed to IAVF_MAX_RXBUFFER and does not depend on data from HW.

Set max_mtu field in virtchnl_vf_resource struct to inform VF in GET_VF_RESOURCES msg what size should be max frame.

Fixes dab86afdbbd1 ("i40e/i40evf: Change the way we limit the maximum frame size for Rx")
---
 .../ethernet/intel/i40e/i40e_virtchnl_pf.c    | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +20 -0
index 86b0f21287dc..67fbaaad3985 100644
@@ -2038,6 +2038,25 @@ static void i40e_del_qch(struct i40e_vf *vf)
 	}
 }
 
+/**
+ * i40e_vc_get_max_frame_size
+ * @vf: pointer to the VF
+ *
+ * Max frame size is determined based on the current port's max frame size and
+ * whether a port VLAN is configured on this VF. The VF is not aware whether
+ * it's in a port VLAN so the PF needs to account for this in max frame size
+ * checks and sending the max frame size to the VF.
+ **/
+static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf)
+{
+	u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size;
+
+	if (vf->port_vlan_id)
+		max_frame_size -= VLAN_HLEN;
+
+	return max_frame_size;
+}
+
 /**
  * i40e_vc_get_vf_resources_msg
  * @vf: pointer to the VF info
@@ -2139,6 +2158,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
 	vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
 	vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;
 	vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE;
+	vfres->max_mtu = i40e_vc_get_max_frame_size(vf);
 
 	if (vf->lan_vsi_idx) {
 		vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;
Signature · 1 line
2.35.1
author maintainer
#122 lore raw

PATCH 117/207 i40e: Fix set max_tx_rate when it is lower than 1 Mbps

In reply to Greg Kroah-Hartman

From: Michal Jaron <[email protected]>

[ Upstream commit 198eb7e1b81d8ba676d0f4f120c092032ae69a8e ]

While converting max_tx_rate from bytes to Mbps, this value was set to 0, if the original value was lower than 125000 bytes (1 Mbps). This would cause no transmission rate limiting to occur. This happened due to lack of check of max_tx_rate against the 1 Mbps value for max_tx_rate and the following division by 125000. Fix this issue by adding a helper i40e_bw_bytes_to_mbits() which sets max_tx_rate to minimum usable value of 50 Mbps, if its value is less than 1 Mbps, otherwise do the required conversion by dividing by 125000.

Fixes 5ecae4120a6b ("i40e: Refactor VF BW rate limiting")
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 32 +++++++++++++++++----
 1 file changed, 26 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +26 -6
index 1aaf0c5ddf6c..57e27f2024d3 100644
@@ -5785,6 +5785,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)
 	}
 }
 
+/**
+ * i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits
+ * @vsi: Pointer to vsi structure
+ * @max_tx_rate: max TX rate in bytes to be converted into Mbits
+ *
+ * Helper function to convert units before send to set BW limit
+ **/
+static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate)
+{
+	if (max_tx_rate < I40E_BW_MBPS_DIVISOR) {
+		dev_warn(&vsi->back->pdev->dev,
+			 "Setting max tx rate to minimum usable value of 50Mbps.\n");
+		max_tx_rate = I40E_BW_CREDIT_DIVISOR;
+	} else {
+		do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
+	}
+
+	return max_tx_rate;
+}
+
 /**
  * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
  * @vsi: VSI to be configured
@@ -5807,10 +5827,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
 			max_tx_rate, seid);
 		return -EINVAL;
 	}
-	if (max_tx_rate && max_tx_rate < 50) {
+	if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {
 		dev_warn(&pf->pdev->dev,
 			 "Setting max tx rate to minimum usable value of 50Mbps.\n");
-		max_tx_rate = 50;
+		max_tx_rate = I40E_BW_CREDIT_DIVISOR;
 	}
 
 	/* Tx rate credits are in values of 50Mbps, 0 is disabled */
@@ -8101,9 +8121,9 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data)
 
 	if (i40e_is_tc_mqprio_enabled(pf)) {
 		if (vsi->mqprio_qopt.max_rate[0]) {
-			u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
+			u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
+						  vsi->mqprio_qopt.max_rate[0]);
 
-			do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
 			ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
 			if (!ret) {
 				u64 credits = max_tx_rate;
@@ -10848,10 +10868,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
 	}
 
 	if (vsi->mqprio_qopt.max_rate[0]) {
-		u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
+		u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
+						  vsi->mqprio_qopt.max_rate[0]);
 		u64 credits = 0;
 
-		do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
 		ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
 		if (ret)
 			goto end_unlock;
Signature · 1 line
2.35.1
author maintainer
#123 lore raw

PATCH 118/207 netdevsim: Fix hwstats debugfs file permissions

In reply to Greg Kroah-Hartman

From: Ido Schimmel <[email protected]>

[ Upstream commit 34513ada53eb3e3f711250d8dbc2de4de493d510 ]

The hwstats debugfs files are only writeable, but they are created with read and write permissions, causing certain selftests to fail [1].

Fix by creating the files with write permission only.

[1]

 # ./test_offload.py
 Test destruction of generic XDP...
 Traceback (most recent call last):
   File "/home/idosch/code/linux/tools/testing/selftests/bpf/./test_offload.py", line 810, in <module>
     simdev = NetdevSimDev()
 [...]
 Exception: Command failed: cat /sys/kernel/debug/netdevsim/netdevsim0//ports/0/dev/hwstats/l3/disable_ifindex

cat: /sys/kernel/debug/netdevsim/netdevsim0//ports/0/dev/hwstats/l3/disable_ifindex: Invalid argument

---
 drivers/net/netdevsim/hwstats.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/netdevsim/hwstats.c +3 -3
index 605a38e16db0..0e58aa7f0374 100644
@@ -433,11 +433,11 @@ int nsim_dev_hwstats_init(struct nsim_dev *nsim_dev)
 		goto err_remove_hwstats_recursive;
 	}
 
-	debugfs_create_file("enable_ifindex", 0600, hwstats->l3_ddir, hwstats,
+	debugfs_create_file("enable_ifindex", 0200, hwstats->l3_ddir, hwstats,
 			    &nsim_dev_hwstats_l3_enable_fops.fops);
-	debugfs_create_file("disable_ifindex", 0600, hwstats->l3_ddir, hwstats,
+	debugfs_create_file("disable_ifindex", 0200, hwstats->l3_ddir, hwstats,
 			    &nsim_dev_hwstats_l3_disable_fops.fops);
-	debugfs_create_file("fail_next_enable", 0600, hwstats->l3_ddir, hwstats,
+	debugfs_create_file("fail_next_enable", 0200, hwstats->l3_ddir, hwstats,
 			    &nsim_dev_hwstats_l3_fail_fops.fops);
 
 	INIT_DELAYED_WORK(&hwstats->traffic_dw,
Signature · 1 line
2.35.1
author maintainer
#124 lore raw

PATCH 119/207 sfc: fix TX channel offset when using legacy interrupts

In reply to Greg Kroah-Hartman

From: Íñigo Huguet <[email protected]>

[ Upstream commit f232af4295653afa4ade3230462b3be15ad16419 ]

In legacy interrupt mode the tx_channel_offset was hardcoded to 1, but that's not correct if efx_sepparate_tx_channels is false. In that case, the offset is 0 because the tx queues are in the single existing channel at index 0, together with the rx queue.

Without this fix, as soon as you try to send any traffic, it tries to get the tx queues from an uninitialized channel getting these errors:

  WARNING: CPU: 1 PID: 0 at drivers/net/ethernet/sfc/tx.c:540 efx_hard_start_xmit+0x12e/0x170 [sfc]
  [...]
  RIP: 0010:efx_hard_start_xmit+0x12e/0x170 [sfc]
  [...]
  Call Trace:
   <IRQ>
   dev_hard_start_xmit+0xd7/0x230
   sch_direct_xmit+0x9f/0x360
   __dev_queue_xmit+0x890/0xa40
  [...]
  BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
  [...]
  RIP: 0010:efx_hard_start_xmit+0x153/0x170 [sfc]
  [...]
  Call Trace:
   <IRQ>
   dev_hard_start_xmit+0xd7/0x230
   sch_direct_xmit+0x9f/0x360
   __dev_queue_xmit+0x890/0xa40
  [...]
Fixes c308dfd1b43e ("sfc: fix wrong tx channel offset with efx_separate_tx_channels")
---
 drivers/net/ethernet/sfc/efx_channels.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sfc/efx_channels.c +1 -1
index 032b8c0bd788..5b4d661ab986 100644
@@ -319,7 +319,7 @@ int efx_probe_interrupts(struct efx_nic *efx)
 		efx->n_channels = 1 + (efx_separate_tx_channels ? 1 : 0);
 		efx->n_rx_channels = 1;
 		efx->n_tx_channels = 1;
-		efx->tx_channel_offset = 1;
+		efx->tx_channel_offset = efx_separate_tx_channels ? 1 : 0;
 		efx->n_xdp_channels = 0;
 		efx->xdp_channel_offset = efx->n_channels;
 		efx->legacy_irq = efx->pci_dev->irq;
Signature · 1 line
2.35.1
author maintainer
#125 lore raw

PATCH 120/207 sfc: fix null pointer dereference in efx_hard_start_xmit

In reply to Greg Kroah-Hartman

From: Íñigo Huguet <[email protected]>

[ Upstream commit 0a242eb2913a4aa3d6fbdb86559f27628e9466f3 ]

Trying to get the channel from the tx_queue variable here is wrong because we can only be here if tx_queue is NULL, so we shouldn't dereference it. As the above comment in the code says, this is very unlikely to happen, but it's wrong anyway so let's fix it.

I hit this issue because of a different bug that caused tx_queue to be NULL. If that happens, this is the error message that we get here:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
  [...]
  RIP: 0010:efx_hard_start_xmit+0x153/0x170 [sfc]
---
 drivers/net/ethernet/sfc/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sfc/tx.c +1 -1
index 138bca611341..80ed7f760bd3 100644
@@ -549,7 +549,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
 		 * previous packets out.
 		 */
 		if (!netdev_xmit_more())
-			efx_tx_send_pending(tx_queue->channel);
+			efx_tx_send_pending(efx_get_tx_channel(efx, index));
 		return NETDEV_TX_OK;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#126 lore raw

PATCH 121/207 bnxt_en: fix flags to check for supported fw version

In reply to Greg Kroah-Hartman

From: Vadim Fedorenko <[email protected]>

[ Upstream commit ae8ffba8baad651af706538e8c47d0a049d406c6 ]

The warning message of unsupported FW appears every time RX timestamps are disabled on the interface. The patch fixes the flags to correct set for the check.

Fixes 66ed81dcedc6 ("bnxt_en: Enable packet timestamping for all RX packets")
Cc Richard Cochran <[email protected]>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +2 -2
index 7f3c0875b6f5..8e316367f6ce 100644
@@ -317,9 +317,9 @@ void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp)
 
 	if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters &
 	    (PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
-	     PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE))) {
+	     PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE))) {
 		ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
-					 PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE);
+					 PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE);
 		netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n");
 	}
 
Signature · 1 line
2.35.1
author maintainer
#127 lore raw

PATCH 122/207 gve: Fix GFP flags when allocing pages

In reply to Greg Kroah-Hartman

From: Shailend Chand <[email protected]>

[ Upstream commit 8ccac4edc8da764389d4fc18b1df740892006557 ]

Use GFP_ATOMIC when allocating pages out of the hotpath, continue to use GFP_KERNEL when allocating pages during setup.

GFP_KERNEL will allow blocking which allows it to succeed more often in a low memory enviornment but in the hotpath we do not want to allow the allocation to block.

---
 drivers/net/ethernet/google/gve/gve_rx_dqo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/google/gve/gve_rx_dqo.c +1 -1
index 8c939628e2d8..2e6461b0ea8b 100644
@@ -157,7 +157,7 @@ static int gve_alloc_page_dqo(struct gve_priv *priv,
 	int err;
 
 	err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page,
-			     &buf_state->addr, DMA_FROM_DEVICE, GFP_KERNEL);
+			     &buf_state->addr, DMA_FROM_DEVICE, GFP_ATOMIC);
 	if (err)
 		return err;
 
Signature · 1 line
2.35.1
author maintainer
#128 lore raw

PATCH 123/207 drm/hisilicon: Add depends on MMU

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

[ Upstream commit d8a79c03054911c375a2252627a429c9bc4615b6 ]

The Kconfig symbol depended on MMU but was dropped by the commit acad3fe650a5 ("drm/hisilicon: Removed the dependency on the mmu") because it already had as a dependency ARM64 that already selects MMU.

But later, commit a0f25a6bb319 ("drm/hisilicon/hibmc: Allow to be built if COMPILE_TEST is enabled") allowed the driver to be built for non-ARM64 when COMPILE_TEST is set but that could lead to unmet direct dependencies and linking errors.

Prevent a kconfig warning when MMU is not enabled by making DRM_HISI_HIBMC depend on MMU.

WARNING: unmet direct dependencies detected for DRM_TTM
Depends on [n]: HAS_IOMEM [=y] && DRM [=m] && MMU [=n]
Selected by [m]:
- DRM_TTM_HELPER [=m] && HAS_IOMEM [=y] && DRM [=m]
- DRM_HISI_HIBMC [=m] && HAS_IOMEM [=y] && DRM [=m] && PCI [=y] && (ARM64 || COMPILE_TEST [=y])

Fixes acad3fe650a5 ("drm/hisilicon: Removed the dependency on the mmu")
Cc Gerd Hoffmann <[email protected]>
Cc Thomas Zimmermann <[email protected]>
Cc Xinliang Liu <[email protected]>
Cc Tian Tao <[email protected]>
Cc John Stultz <[email protected]>
Cc Xinwei Kong <[email protected]>
Cc Chen Feng <[email protected]>
Cc Christian Koenig <[email protected]>
Cc Huang Rui <[email protected]>
Cc David Airlie <[email protected]>
Cc Daniel Vetter <[email protected]>
---
 drivers/gpu/drm/hisilicon/hibmc/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/hisilicon/hibmc/Kconfig +1 -0
index 073adfe438dd..4e41c144a290 100644
@@ -2,6 +2,7 @@
 config DRM_HISI_HIBMC
 	tristate "DRM Support for Hisilicon Hibmc"
 	depends on DRM && PCI && (ARM64 || COMPILE_TEST)
+	depends on MMU
 	select DRM_KMS_HELPER
 	select DRM_VRAM_HELPER
 	select DRM_TTM
Signature · 1 line
2.35.1
author maintainer
#129 lore raw

PATCH 124/207 of: mdio: Add of_node_put() when breaking out of for_each_xx

In reply to Greg Kroah-Hartman

From: Liang He <[email protected]>

[ Upstream commit 1c48709e6d9d353acaaac1d8e33474756b121d78 ]

In of_mdiobus_register(), we should call of_node_put() for 'child' escaped out of for_each_available_child_of_node().

Fixes 66bdede495c7 ("of_mdio: Fix broken PHY IRQ in case of probe deferral")
---
 drivers/net/mdio/of_mdio.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/mdio/of_mdio.c +1 -0
index 9e3c815a070f..796e9c7857d0 100644
@@ -231,6 +231,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 	return 0;
 
 unregister:
+	of_node_put(child);
 	mdiobus_unregister(mdio);
 	return rc;
 }
Signature · 1 line
2.35.1
author maintainer
#130 lore raw

PATCH 125/207 net: ipa: properly limit modem routing table use

In reply to Greg Kroah-Hartman

From: Alex Elder <[email protected]>

[ Upstream commit cf412ec333250cb82bafe57169204e14a9f1c2ac ]

IPA can route packets between IPA-connected entities. The AP and modem are currently the only such entities supported, and no routing is required to transfer packets between them.

The number of entries in each routing table is fixed, and defined at initialization time. Some of these entries are designated for use by the modem, and the rest are available for the AP to use. The AP sends a QMI message to the modem which describes (among other things) information about routing table memory available for the modem to use.

Currently the QMI initialization packet gives wrong information in its description of routing tables. What *should* be supplied is the maximum index that the modem can use for the routing table memory located at a given location. The current code instead supplies the total *number* of routing table entries. Furthermore, the modem is granted the entire table, not just the subset it's supposed to use.

This patch fixes this. First, the ipa_mem_bounds structure is generalized so its "end" field can be interpreted either as a final byte offset, or a final array index. Second, the IPv4 and IPv6 (non-hashed and hashed) table information fields in the QMI ipa_init_modem_driver_req structure are changed to be ipa_mem_bounds rather than ipa_mem_array structures. Third, we set the "end" value for each routing table to be the last index, rather than setting the "count" to be the number of indices. Finally, instead of allowing the modem to use all of a routing table's memory, it is limited to just the portion meant to be used by the modem. In all versions of IPA currently supported, that is IPA_ROUTE_MODEM_COUNT (8) entries.

Update a few comments for clarity.

Fixes 530f9216a9537 ("soc: qcom: ipa: AP/modem communications")
---
 drivers/net/ipa/ipa_qmi.c     |  8 ++++----
 drivers/net/ipa/ipa_qmi_msg.c |  8 ++++----
 drivers/net/ipa/ipa_qmi_msg.h | 37 ++++++++++++++++++++---------------
 drivers/net/ipa/ipa_table.c   |  2 --
 drivers/net/ipa/ipa_table.h   |  3 +++
 5 files changed, 32 insertions(+), 26 deletions(-)
drivers/net/ipa/ipa_qmi.c +4 -4
index ec010cf2e816..6f874f99b910 100644
@@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
 	mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE);
 	req.v4_route_tbl_info_valid = 1;
 	req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
-	req.v4_route_tbl_info.count = mem->size / sizeof(__le64);
+	req.v4_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
 
 	mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE);
 	req.v6_route_tbl_info_valid = 1;
 	req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
-	req.v6_route_tbl_info.count = mem->size / sizeof(__le64);
+	req.v6_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
 
 	mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER);
 	req.v4_filter_tbl_start_valid = 1;
@@ -352,7 +352,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
 		req.v4_hash_route_tbl_info_valid = 1;
 		req.v4_hash_route_tbl_info.start =
 				ipa->mem_offset + mem->offset;
-		req.v4_hash_route_tbl_info.count = mem->size / sizeof(__le64);
+		req.v4_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
 	}
 
 	mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED);
@@ -360,7 +360,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
 		req.v6_hash_route_tbl_info_valid = 1;
 		req.v6_hash_route_tbl_info.start =
 			ipa->mem_offset + mem->offset;
-		req.v6_hash_route_tbl_info.count = mem->size / sizeof(__le64);
+		req.v6_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
 	}
 
 	mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED);
drivers/net/ipa/ipa_qmi_msg.c +4 -4
index 6838e8065072..75d3fc0092e9 100644
@@ -311,7 +311,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
 		.tlv_type	= 0x12,
 		.offset		= offsetof(struct ipa_init_modem_driver_req,
 					   v4_route_tbl_info),
-		.ei_array	= ipa_mem_array_ei,
+		.ei_array	= ipa_mem_bounds_ei,
 	},
 	{
 		.data_type	= QMI_OPT_FLAG,
@@ -332,7 +332,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
 		.tlv_type	= 0x13,
 		.offset		= offsetof(struct ipa_init_modem_driver_req,
 					   v6_route_tbl_info),
-		.ei_array	= ipa_mem_array_ei,
+		.ei_array	= ipa_mem_bounds_ei,
 	},
 	{
 		.data_type	= QMI_OPT_FLAG,
@@ -496,7 +496,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
 		.tlv_type	= 0x1b,
 		.offset		= offsetof(struct ipa_init_modem_driver_req,
 					   v4_hash_route_tbl_info),
-		.ei_array	= ipa_mem_array_ei,
+		.ei_array	= ipa_mem_bounds_ei,
 	},
 	{
 		.data_type	= QMI_OPT_FLAG,
@@ -517,7 +517,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
 		.tlv_type	= 0x1c,
 		.offset		= offsetof(struct ipa_init_modem_driver_req,
 					   v6_hash_route_tbl_info),
-		.ei_array	= ipa_mem_array_ei,
+		.ei_array	= ipa_mem_bounds_ei,
 	},
 	{
 		.data_type	= QMI_OPT_FLAG,
drivers/net/ipa/ipa_qmi_msg.h +21 -16
index 495e85abe50b..9651aa59b596 100644
@@ -86,9 +86,11 @@ enum ipa_platform_type {
 	IPA_QMI_PLATFORM_TYPE_MSM_QNX_V01	= 0x5,	/* QNX MSM */
 };
 
-/* This defines the start and end offset of a range of memory.  Both
- * fields are offsets relative to the start of IPA shared memory.
- * The end value is the last addressable byte *within* the range.
+/* This defines the start and end offset of a range of memory.  The start
+ * value is a byte offset relative to the start of IPA shared memory.  The
+ * end value is the last addressable unit *within* the range.  Typically
+ * the end value is in units of bytes, however it can also be a maximum
+ * array index value.
  */
 struct ipa_mem_bounds {
 	u32 start;
@@ -129,18 +131,19 @@ struct ipa_init_modem_driver_req {
 	u8			hdr_tbl_info_valid;
 	struct ipa_mem_bounds	hdr_tbl_info;
 
-	/* Routing table information.  These define the location and size of
-	 * non-hashable IPv4 and IPv6 filter tables.  The start values are
-	 * offsets relative to the start of IPA shared memory.
+	/* Routing table information.  These define the location and maximum
+	 * *index* (not byte) for the modem portion of non-hashable IPv4 and
+	 * IPv6 routing tables.  The start values are byte offsets relative
+	 * to the start of IPA shared memory.
 	 */
 	u8			v4_route_tbl_info_valid;
-	struct ipa_mem_array	v4_route_tbl_info;
+	struct ipa_mem_bounds	v4_route_tbl_info;
 	u8			v6_route_tbl_info_valid;
-	struct ipa_mem_array	v6_route_tbl_info;
+	struct ipa_mem_bounds	v6_route_tbl_info;
 
 	/* Filter table information.  These define the location of the
 	 * non-hashable IPv4 and IPv6 filter tables.  The start values are
-	 * offsets relative to the start of IPA shared memory.
+	 * byte offsets relative to the start of IPA shared memory.
 	 */
 	u8			v4_filter_tbl_start_valid;
 	u32			v4_filter_tbl_start;
@@ -181,18 +184,20 @@ struct ipa_init_modem_driver_req {
 	u8			zip_tbl_info_valid;
 	struct ipa_mem_bounds	zip_tbl_info;
 
-	/* Routing table information.  These define the location and size
-	 * of hashable IPv4 and IPv6 filter tables.  The start values are
-	 * offsets relative to the start of IPA shared memory.
+	/* Routing table information.  These define the location and maximum
+	 * *index* (not byte) for the modem portion of hashable IPv4 and IPv6
+	 * routing tables (if supported by hardware).  The start values are
+	 * byte offsets relative to the start of IPA shared memory.
 	 */
 	u8			v4_hash_route_tbl_info_valid;
-	struct ipa_mem_array	v4_hash_route_tbl_info;
+	struct ipa_mem_bounds	v4_hash_route_tbl_info;
 	u8			v6_hash_route_tbl_info_valid;
-	struct ipa_mem_array	v6_hash_route_tbl_info;
+	struct ipa_mem_bounds	v6_hash_route_tbl_info;
 
 	/* Filter table information.  These define the location and size
-	 * of hashable IPv4 and IPv6 filter tables.  The start values are
-	 * offsets relative to the start of IPA shared memory.
+	 * of hashable IPv4 and IPv6 filter tables (if supported by hardware).
+	 * The start values are byte offsets relative to the start of IPA
+	 * shared memory.
 	 */
 	u8			v4_hash_filter_tbl_start_valid;
 	u32			v4_hash_filter_tbl_start;
drivers/net/ipa/ipa_table.c +0 -2
index 2f5a58bfc529..69efe672ca52 100644
@@ -108,8 +108,6 @@
 
 /* Assignment of route table entries to the modem and AP */
 #define IPA_ROUTE_MODEM_MIN		0
-#define IPA_ROUTE_MODEM_COUNT		8
-
 #define IPA_ROUTE_AP_MIN		IPA_ROUTE_MODEM_COUNT
 #define IPA_ROUTE_AP_COUNT \
 		(IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)
drivers/net/ipa/ipa_table.h +3 -0
index b6a9a0d79d68..1538e2e1732f 100644
@@ -13,6 +13,9 @@ struct ipa;
 /* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
 #define IPA_FILTER_COUNT_MAX	14
 
+/* The number of route table entries allotted to the modem */
+#define IPA_ROUTE_MODEM_COUNT	8
+
 /* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
 #define IPA_ROUTE_COUNT_MAX	15
 
Signature · 1 line
2.35.1
author maintainer
#131 lore raw

PATCH 126/207 sfc/siena: fix TX channel offset when using legacy interrupts

In reply to Greg Kroah-Hartman

From: Íñigo Huguet <[email protected]>

[ Upstream commit 974bb793aded499491246f6f9826e26c2b127320 ]

As in previous commit for sfc, fix TX channels offset when efx_siena_separate_tx_channels is false (the default)

Fixes 25bde571b4a8 ("sfc/siena: fix wrong tx channel offset with efx_separate_tx_channels")
---
 drivers/net/ethernet/sfc/siena/efx_channels.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sfc/siena/efx_channels.c +1 -1
index 017212a40df3..f54ebd007286 100644
@@ -320,7 +320,7 @@ int efx_siena_probe_interrupts(struct efx_nic *efx)
 		efx->n_channels = 1 + (efx_siena_separate_tx_channels ? 1 : 0);
 		efx->n_rx_channels = 1;
 		efx->n_tx_channels = 1;
-		efx->tx_channel_offset = 1;
+		efx->tx_channel_offset = efx_siena_separate_tx_channels ? 1 : 0;
 		efx->n_xdp_channels = 0;
 		efx->xdp_channel_offset = efx->n_channels;
 		efx->legacy_irq = efx->pci_dev->irq;
Signature · 1 line
2.35.1
author maintainer
#132 lore raw

PATCH 127/207 sfc/siena: fix null pointer dereference in efx_hard_start_xmit

In reply to Greg Kroah-Hartman

From: Íñigo Huguet <[email protected]>

[ Upstream commit 589c6eded10c77a12b7b2cf235b6b19a2bdb91fa ]

Like in previous patch for sfc, prevent potential (but unlikely) NULL pointer dereference.

---
 drivers/net/ethernet/sfc/siena/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sfc/siena/tx.c +1 -1
index e166dcb9b99c..91e87594ed1e 100644
@@ -336,7 +336,7 @@ netdev_tx_t efx_siena_hard_start_xmit(struct sk_buff *skb,
 		 * previous packets out.
 		 */
 		if (!netdev_xmit_more())
-			efx_tx_send_pending(tx_queue->channel);
+			efx_tx_send_pending(efx_get_tx_channel(efx, index));
 		return NETDEV_TX_OK;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#133 lore raw

PATCH 128/207 wireguard: ratelimiter: disable timings test by default

In reply to Greg Kroah-Hartman

From: Jason A. Donenfeld <[email protected]>

[ Upstream commit 684dec3cf45da2b0848298efae4adf3b2aeafeda ]

A previous commit tried to make the ratelimiter timings test more reliable but in the process made it less reliable on other configurations. This is an impossible problem to solve without increasingly ridiculous heuristics. And it's not even a problem that actually needs to be solved in any comprehensive way, since this is only ever used during development. So just cordon this off with a DEBUG_ ifdef, just like we do for the trie's randomized tests, so it can be enabled while hacking on the code, and otherwise disabled in CI. In the process we also revert 151c8e499f47.

Fixes 151c8e499f47 ("wireguard: ratelimiter: use hrtimer in selftest")
Fixes e7096c131e51 ("net: WireGuard secure network tunnel")
---
 drivers/net/wireguard/selftest/ratelimiter.c | 25 ++++++++------------
 1 file changed, 10 insertions(+), 15 deletions(-)
drivers/net/wireguard/selftest/ratelimiter.c +10 -15
index ba87d294604f..d4bb40a695ab 100644
@@ -6,29 +6,28 @@
 #ifdef DEBUG
 
 #include <linux/jiffies.h>
-#include <linux/hrtimer.h>
 
 static const struct {
 	bool result;
-	u64 nsec_to_sleep_before;
+	unsigned int msec_to_sleep_before;
 } expected_results[] __initconst = {
 	[0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
 	[PACKETS_BURSTABLE] = { false, 0 },
-	[PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND },
+	[PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
 	[PACKETS_BURSTABLE + 2] = { false, 0 },
-	[PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
+	[PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
 	[PACKETS_BURSTABLE + 4] = { true, 0 },
 	[PACKETS_BURSTABLE + 5] = { false, 0 }
 };
 
 static __init unsigned int maximum_jiffies_at_index(int index)
 {
-	u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3;
+	unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
 	int i;
 
 	for (i = 0; i <= index; ++i)
-		total_nsecs += expected_results[i].nsec_to_sleep_before;
-	return nsecs_to_jiffies(total_nsecs);
+		total_msecs += expected_results[i].msec_to_sleep_before;
+	return msecs_to_jiffies(total_msecs);
 }
 
 static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
@@ -43,12 +42,8 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 	loop_start_time = jiffies;
 
 	for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
-		if (expected_results[i].nsec_to_sleep_before) {
-			ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3),
-						    ns_to_ktime(expected_results[i].nsec_to_sleep_before));
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME);
-		}
+		if (expected_results[i].msec_to_sleep_before)
+			msleep(expected_results[i].msec_to_sleep_before);
 
 		if (time_is_before_jiffies(loop_start_time +
 					   maximum_jiffies_at_index(i)))
@@ -132,7 +127,7 @@ bool __init wg_ratelimiter_selftest(void)
 	if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
 		return true;
 
-	BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0);
+	BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
 
 	if (wg_ratelimiter_init())
 		goto out;
@@ -172,7 +167,7 @@ bool __init wg_ratelimiter_selftest(void)
 	++test;
 #endif
 
-	for (trials = TRIALS_BEFORE_GIVING_UP;;) {
+	for (trials = TRIALS_BEFORE_GIVING_UP; IS_ENABLED(DEBUG_RATELIMITER_TIMINGS);) {
 		int test_count = 0, ret;
 
 		ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
Signature · 1 line
2.35.1
author maintainer
#134 lore raw

PATCH 129/207 wireguard: netlink: avoid variable-sized memcpy on sockaddr

In reply to Greg Kroah-Hartman

From: Jason A. Donenfeld <[email protected]>

[ Upstream commit 26c013108c12b94bc023bf19198a4300596c98b1 ]

Doing a variable-sized memcpy is slower, and the compiler isn't smart enough to turn this into a constant-size assignment.

Further, Kees' latest fortified memcpy will actually bark, because the destination pointer is type sockaddr, not explicitly sockaddr_in or sockaddr_in6, so it thinks there's an overflow:

memcpy: detected field-spanning write (size 28) of single field "&endpoint.addr" at drivers/net/wireguard/netlink.c:446 (size 16)

Fix this by just assigning by using explicit casts for each checked case.

Fixes e7096c131e51 ("net: WireGuard secure network tunnel")
Reported-by [email protected]
---
 drivers/net/wireguard/netlink.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/net/wireguard/netlink.c +6 -7
index d0f3b6d7f408..5c804bcabfe6 100644
@@ -436,14 +436,13 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
 	if (attrs[WGPEER_A_ENDPOINT]) {
 		struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]);
 		size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]);
+		struct endpoint endpoint = { { { 0 } } };
 
-		if ((len == sizeof(struct sockaddr_in) &&
-		     addr->sa_family == AF_INET) ||
-		    (len == sizeof(struct sockaddr_in6) &&
-		     addr->sa_family == AF_INET6)) {
-			struct endpoint endpoint = { { { 0 } } };
-
-			memcpy(&endpoint.addr, addr, len);
+		if (len == sizeof(struct sockaddr_in) && addr->sa_family == AF_INET) {
+			endpoint.addr4 = *(struct sockaddr_in *)addr;
+			wg_socket_set_peer_endpoint(peer, &endpoint);
+		} else if (len == sizeof(struct sockaddr_in6) && addr->sa_family == AF_INET6) {
+			endpoint.addr6 = *(struct sockaddr_in6 *)addr;
 			wg_socket_set_peer_endpoint(peer, &endpoint);
 		}
 	}
Signature · 1 line
2.35.1
author maintainer
#135 lore raw

PATCH 130/207 net: enetc: move enetc_set_psfp() out of the common enetc_set_features()

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit fed38e64d9b99d65a36c0dbadc3d3f8ddd9ea030 ]

The VF netdev driver shouldn't respond to changes in the NETIF_F_HW_TC flag; only PFs should. Moreover, TSN-specific code should go to enetc_qos.c, which should not be included in the VF driver.

Fixes 79e499829f3f ("net: enetc: add hw tc hw offload features for PSPF capability")
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 32 +------------------
 drivers/net/ethernet/freescale/enetc/enetc.h  |  9 ++++--
 .../net/ethernet/freescale/enetc/enetc_pf.c   | 11 ++++++-
 .../net/ethernet/freescale/enetc/enetc_qos.c  | 23 +++++++++++++
 .../net/ethernet/freescale/enetc/enetc_vf.c   |  4 ++-
 5 files changed, 44 insertions(+), 35 deletions(-)
drivers/net/ethernet/freescale/enetc/enetc.c +1 -31
index 4470a4a3e4c3..3df099f6cbe0 100644
@@ -2600,29 +2600,6 @@ static int enetc_set_rss(struct net_device *ndev, int en)
 	return 0;
 }
 
-static int enetc_set_psfp(struct net_device *ndev, int en)
-{
-	struct enetc_ndev_priv *priv = netdev_priv(ndev);
-	int err;
-
-	if (en) {
-		err = enetc_psfp_enable(priv);
-		if (err)
-			return err;
-
-		priv->active_offloads |= ENETC_F_QCI;
-		return 0;
-	}
-
-	err = enetc_psfp_disable(priv);
-	if (err)
-		return err;
-
-	priv->active_offloads &= ~ENETC_F_QCI;
-
-	return 0;
-}
-
 static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
 {
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -2641,11 +2618,9 @@ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
 		enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
 }
 
-int enetc_set_features(struct net_device *ndev,
-		       netdev_features_t features)
+void enetc_set_features(struct net_device *ndev, netdev_features_t features)
 {
 	netdev_features_t changed = ndev->features ^ features;
-	int err = 0;
 
 	if (changed & NETIF_F_RXHASH)
 		enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH));
@@ -2657,11 +2632,6 @@ int enetc_set_features(struct net_device *ndev,
 	if (changed & NETIF_F_HW_VLAN_CTAG_TX)
 		enetc_enable_txvlan(ndev,
 				    !!(features & NETIF_F_HW_VLAN_CTAG_TX));
-
-	if (changed & NETIF_F_HW_TC)
-		err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));
-
-	return err;
 }
 
 #ifdef CONFIG_FSL_ENETC_PTP_CLOCK
drivers/net/ethernet/freescale/enetc/enetc.h +7 -2
index 29922c20531f..caa12509d06b 100644
@@ -393,8 +393,7 @@ void enetc_start(struct net_device *ndev);
 void enetc_stop(struct net_device *ndev);
 netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
 struct net_device_stats *enetc_get_stats(struct net_device *ndev);
-int enetc_set_features(struct net_device *ndev,
-		       netdev_features_t features);
+void enetc_set_features(struct net_device *ndev, netdev_features_t features);
 int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd);
 int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 		   void *type_data);
@@ -465,6 +464,7 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
 int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data);
 int enetc_psfp_init(struct enetc_ndev_priv *priv);
 int enetc_psfp_clean(struct enetc_ndev_priv *priv);
+int enetc_set_psfp(struct net_device *ndev, bool en);
 
 static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
 {
@@ -540,4 +540,9 @@ static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)
 {
 	return 0;
 }
+
+static inline int enetc_set_psfp(struct net_device *ndev, bool en)
+{
+	return 0;
+}
 #endif
drivers/net/ethernet/freescale/enetc/enetc_pf.c +10 -1
index c4a0e836d4f0..201b5f3f634e 100644
@@ -709,6 +709,13 @@ static int enetc_pf_set_features(struct net_device *ndev,
 {
 	netdev_features_t changed = ndev->features ^ features;
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+	int err;
+
+	if (changed & NETIF_F_HW_TC) {
+		err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));
+		if (err)
+			return err;
+	}
 
 	if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
 		struct enetc_pf *pf = enetc_si_priv(priv->si);
@@ -722,7 +729,9 @@ static int enetc_pf_set_features(struct net_device *ndev,
 	if (changed & NETIF_F_LOOPBACK)
 		enetc_set_loopback(ndev, !!(features & NETIF_F_LOOPBACK));
 
-	return enetc_set_features(ndev, features);
+	enetc_set_features(ndev, features);
+
+	return 0;
 }
 
 static const struct net_device_ops enetc_ndev_ops = {
drivers/net/ethernet/freescale/enetc/enetc_qos.c +23 -0
index 582a663ed0ba..f8a2f02ce22d 100644
@@ -1517,6 +1517,29 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
 	}
 }
 
+int enetc_set_psfp(struct net_device *ndev, bool en)
+{
+	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+	int err;
+
+	if (en) {
+		err = enetc_psfp_enable(priv);
+		if (err)
+			return err;
+
+		priv->active_offloads |= ENETC_F_QCI;
+		return 0;
+	}
+
+	err = enetc_psfp_disable(priv);
+	if (err)
+		return err;
+
+	priv->active_offloads &= ~ENETC_F_QCI;
+
+	return 0;
+}
+
 int enetc_psfp_init(struct enetc_ndev_priv *priv)
 {
 	if (epsfp.psfp_sfi_bitmap)
drivers/net/ethernet/freescale/enetc/enetc_vf.c +3 -1
index 17924305afa2..4048101c42be 100644
@@ -88,7 +88,9 @@ static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
 static int enetc_vf_set_features(struct net_device *ndev,
 				 netdev_features_t features)
 {
-	return enetc_set_features(ndev, features);
+	enetc_set_features(ndev, features);
+
+	return 0;
 }
 
 /* Probing/ Init */
Signature · 1 line
2.35.1
author maintainer
#136 lore raw

PATCH 131/207 net: enetc: deny offload of tc-based TSN features on VF interfaces

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 5641c751fe2f92d3d9e8a8e03c1263ac8caa0b42 ]

TSN features on the ENETC (taprio, cbs, gate, police) are configured through a mix of command BD ring messages and port registers:
enetc_port_rd(), enetc_port_wr().

Port registers are a region of the ENETC memory map which are only accessible from the PCIe Physical Function. They are not accessible from the Virtual Functions.

Moreover, attempting to access these registers crashes the kernel:

$ echo 1 > /sys/bus/pci/devices/0000\:00\:00.0/sriov_numvfs
pci 0000:00:01.0: [1957:ef00] type 00 class 0x020001
fsl_enetc_vf 0000:00:01.0: Adding to iommu group 15
fsl_enetc_vf 0000:00:01.0: enabling device (0000 -> 0002)
fsl_enetc_vf 0000:00:01.0 eno0vf0: renamed from eth0
$ tc qdisc replace dev eno0vf0 root taprio num_tc 8 map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 \
	sched-entry S 0x7f 900000 sched-entry S 0x80 100000 flags 0x2
Unable to handle kernel paging request at virtual address ffff800009551a08
Internal error: Oops: 96000007 [#1] PREEMPT SMP
pc : enetc_setup_tc_taprio+0x170/0x47c
lr : enetc_setup_tc_taprio+0x16c/0x47c
Call trace:
 enetc_setup_tc_taprio+0x170/0x47c
 enetc_setup_tc+0x38/0x2dc
 taprio_change+0x43c/0x970
 taprio_init+0x188/0x1e0
 qdisc_create+0x114/0x470
 tc_modify_qdisc+0x1fc/0x6c0
 rtnetlink_rcv_msg+0x12c/0x390

Split enetc_setup_tc() into separate functions for the PF and for the VF drivers. Also remove enetc_qos.o from being included into enetc-vf.ko, since it serves absolutely no purpose there.

Fixes 34c6adf1977b ("enetc: Configure the Time-Aware Scheduler via tc-taprio offload")
---
 drivers/net/ethernet/freescale/enetc/Makefile |  1 -
 drivers/net/ethernet/freescale/enetc/enetc.c  | 21 +------------------
 drivers/net/ethernet/freescale/enetc/enetc.h  |  3 +--
 .../net/ethernet/freescale/enetc/enetc_pf.c   | 21 ++++++++++++++++++-
 .../net/ethernet/freescale/enetc/enetc_vf.c   | 13 +++++++++++-
 5 files changed, 34 insertions(+), 25 deletions(-)
drivers/net/ethernet/freescale/enetc/Makefile +0 -1
index a139f2e9d59f..e0e8dfd13793 100644
@@ -9,7 +9,6 @@ fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
 
 obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o
 fsl-enetc-vf-y := enetc_vf.o $(common-objs)
-fsl-enetc-vf-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
 
 obj-$(CONFIG_FSL_ENETC_IERB) += fsl-enetc-ierb.o
 fsl-enetc-ierb-y := enetc_ierb.o
drivers/net/ethernet/freescale/enetc/enetc.c +1 -20
index 3df099f6cbe0..9f5b921039bd 100644
@@ -2432,7 +2432,7 @@ int enetc_close(struct net_device *ndev)
 	return 0;
 }
 
-static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
 {
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
 	struct tc_mqprio_qopt *mqprio = type_data;
@@ -2486,25 +2486,6 @@ static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
 	return 0;
 }
 
-int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
-		   void *type_data)
-{
-	switch (type) {
-	case TC_SETUP_QDISC_MQPRIO:
-		return enetc_setup_tc_mqprio(ndev, type_data);
-	case TC_SETUP_QDISC_TAPRIO:
-		return enetc_setup_tc_taprio(ndev, type_data);
-	case TC_SETUP_QDISC_CBS:
-		return enetc_setup_tc_cbs(ndev, type_data);
-	case TC_SETUP_QDISC_ETF:
-		return enetc_setup_tc_txtime(ndev, type_data);
-	case TC_SETUP_BLOCK:
-		return enetc_setup_tc_psfp(ndev, type_data);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
 static int enetc_setup_xdp_prog(struct net_device *dev, struct bpf_prog *prog,
 				struct netlink_ext_ack *extack)
 {
drivers/net/ethernet/freescale/enetc/enetc.h +1 -2
index caa12509d06b..2cfe6944ebd3 100644
@@ -395,8 +395,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
 struct net_device_stats *enetc_get_stats(struct net_device *ndev);
 void enetc_set_features(struct net_device *ndev, netdev_features_t features);
 int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd);
-int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
-		   void *type_data);
+int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data);
 int enetc_setup_bpf(struct net_device *dev, struct netdev_bpf *xdp);
 int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
 		   struct xdp_frame **frames, u32 flags);
drivers/net/ethernet/freescale/enetc/enetc_pf.c +20 -1
index 201b5f3f634e..bb7750222691 100644
@@ -734,6 +734,25 @@ static int enetc_pf_set_features(struct net_device *ndev,
 	return 0;
 }
 
+static int enetc_pf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+			     void *type_data)
+{
+	switch (type) {
+	case TC_SETUP_QDISC_MQPRIO:
+		return enetc_setup_tc_mqprio(ndev, type_data);
+	case TC_SETUP_QDISC_TAPRIO:
+		return enetc_setup_tc_taprio(ndev, type_data);
+	case TC_SETUP_QDISC_CBS:
+		return enetc_setup_tc_cbs(ndev, type_data);
+	case TC_SETUP_QDISC_ETF:
+		return enetc_setup_tc_txtime(ndev, type_data);
+	case TC_SETUP_BLOCK:
+		return enetc_setup_tc_psfp(ndev, type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static const struct net_device_ops enetc_ndev_ops = {
 	.ndo_open		= enetc_open,
 	.ndo_stop		= enetc_close,
@@ -748,7 +767,7 @@ static const struct net_device_ops enetc_ndev_ops = {
 	.ndo_set_vf_spoofchk	= enetc_pf_set_vf_spoofchk,
 	.ndo_set_features	= enetc_pf_set_features,
 	.ndo_eth_ioctl		= enetc_ioctl,
-	.ndo_setup_tc		= enetc_setup_tc,
+	.ndo_setup_tc		= enetc_pf_setup_tc,
 	.ndo_bpf		= enetc_setup_bpf,
 	.ndo_xdp_xmit		= enetc_xdp_xmit,
 };
drivers/net/ethernet/freescale/enetc/enetc_vf.c +12 -1
index 4048101c42be..dfcaac302e24 100644
@@ -93,6 +93,17 @@ static int enetc_vf_set_features(struct net_device *ndev,
 	return 0;
 }
 
+static int enetc_vf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+			     void *type_data)
+{
+	switch (type) {
+	case TC_SETUP_QDISC_MQPRIO:
+		return enetc_setup_tc_mqprio(ndev, type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 /* Probing/ Init */
 static const struct net_device_ops enetc_ndev_ops = {
 	.ndo_open		= enetc_open,
@@ -102,7 +113,7 @@ static const struct net_device_ops enetc_ndev_ops = {
 	.ndo_set_mac_address	= enetc_vf_set_mac_addr,
 	.ndo_set_features	= enetc_vf_set_features,
 	.ndo_eth_ioctl		= enetc_ioctl,
-	.ndo_setup_tc		= enetc_setup_tc,
+	.ndo_setup_tc		= enetc_vf_setup_tc,
 };
 
 static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
Signature · 1 line
2.35.1
author maintainer
#137 lore raw

PATCH 132/207 ipv6: Fix crash when IPv6 is administratively disabled

In reply to Greg Kroah-Hartman

From: Ido Schimmel <[email protected]>

[ Upstream commit 76dd07281338da6951fdab3432ced843fa87839c ]

The global 'raw_v6_hashinfo' variable can be accessed even when IPv6 is administratively disabled via the 'ipv6.disable=1' kernel command line option, leading to a crash [1].

Fix by restoring the original behavior and always initializing the variable, regardless of IPv6 support being administratively disabled or not.

[1]

 BUG: unable to handle page fault for address: ffffffffffffffc8
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x0000) - not-present page
 PGD 173e18067 P4D 173e18067 PUD 173e1a067 PMD 0
 Oops: 0000 [#1] PREEMPT SMP KASAN
 CPU: 3 PID: 271 Comm: ss Not tainted 6.0.0-rc4-custom-00136-g0727a9a5fbc1 #1396
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-1.fc36 04/01/2014
 RIP: 0010:raw_diag_dump+0x310/0x7f0
 [...]
 Call Trace:
  <TASK>
  __inet_diag_dump+0x10f/0x2e0
  netlink_dump+0x575/0xfd0
  __netlink_dump_start+0x67b/0x940
  inet_diag_handler_cmd+0x273/0x2d0
  sock_diag_rcv_msg+0x317/0x440
  netlink_rcv_skb+0x15e/0x430
  sock_diag_rcv+0x2b/0x40
  netlink_unicast+0x53b/0x800
  netlink_sendmsg+0x945/0xe60
  ____sys_sendmsg+0x747/0x960
  ___sys_sendmsg+0x13a/0x1e0
  __sys_sendmsg+0x118/0x1e0
  do_syscall_64+0x34/0x80
  entry_SYSCALL_64_after_hwframe+0x63/0xcd
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes 0daf07e52709 ("raw: convert raw sockets to RCU")
---
 net/ipv6/af_inet6.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv6/af_inet6.c +2 -2
index 9f6f4a41245d..1012012a061f 100644
@@ -1069,13 +1069,13 @@ static int __init inet6_init(void)
 	for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
 		INIT_LIST_HEAD(r);
 
+	raw_hashinfo_init(&raw_v6_hashinfo);
+
 	if (disable_ipv6_mod) {
 		pr_info("Loaded, but administratively disabled, reboot required to enable\n");
 		goto out;
 	}
 
-	raw_hashinfo_init(&raw_v6_hashinfo);
-
 	err = proto_register(&tcpv6_prot, 1);
 	if (err)
 		goto out;
Signature · 1 line
2.35.1
author maintainer
#138 lore raw

PATCH 133/207 net/sched: taprio: avoid disabling offload when it was never enabled

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit db46e3a88a09c5cf7e505664d01da7238cd56c92 ]

In an incredibly strange API design decision, qdisc->destroy() gets called even if qdisc->init() never succeeded, not exclusively since commit 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation"), but apparently also earlier (in the case of qdisc_create_dflt()).

The taprio qdisc does not fully acknowledge this when it attempts full offload, because it starts off with q->flags = TAPRIO_FLAGS_INVALID in taprio_init(), then it replaces q->flags with TCA_TAPRIO_ATTR_FLAGS parsed from netlink (in taprio_change(), tail called from taprio_init()).

But in taprio_destroy(), we call taprio_disable_offload(), and this determines what to do based on FULL_OFFLOAD_IS_ENABLED(q->flags).

But looking at the implementation of FULL_OFFLOAD_IS_ENABLED() (a bitwise check of bit 1 in q->flags), it is invalid to call this macro on q->flags when it contains TAPRIO_FLAGS_INVALID, because that is set to U32_MAX, and therefore FULL_OFFLOAD_IS_ENABLED() will return true on an invalid set of flags.

As a result, it is possible to crash the kernel if user space forces an error between setting q->flags = TAPRIO_FLAGS_INVALID, and the calling of taprio_enable_offload(). This is because drivers do not expect the offload to be disabled when it was never enabled.

The error that we force here is to attach taprio as a non-root qdisc, but instead as child of an mqprio root qdisc:

$ tc qdisc add dev swp0 root handle 1: \
	mqprio num_tc 8 map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 hw 0
$ tc qdisc replace dev swp0 parent 1:1 \
	taprio num_tc 8 map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 \
	sched-entry S 0x7f 990000 sched-entry S 0x80 100000 \
	flags 0x0 clockid CLOCK_TAI
Unable to handle kernel paging request at virtual address fffffffffffffff8
[fffffffffffffff8] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Call trace:
 taprio_dump+0x27c/0x310
 vsc9959_port_setup_tc+0x1f4/0x460
 felix_port_setup_tc+0x24/0x3c
 dsa_slave_setup_tc+0x54/0x27c
 taprio_disable_offload.isra.0+0x58/0xe0
 taprio_destroy+0x80/0x104
 qdisc_create+0x240/0x470
 tc_modify_qdisc+0x1fc/0x6b0
 rtnetlink_rcv_msg+0x12c/0x390
 netlink_rcv_skb+0x5c/0x130
 rtnetlink_rcv+0x1c/0x2c

Fix this by keeping track of the operations we made, and undo the offload only if we actually did it.

I've added "bool offloaded" inside a 4 byte hole between "int clockid" and "atomic64_t picos_per_byte". Now the first cache line looks like below:

$ pahole -C taprio_sched net/sched/sch_taprio.o
struct taprio_sched {
        struct Qdisc * *           qdiscs;               /*     0     8 */
        struct Qdisc *             root;                 /*     8     8 */
        u32                        flags;                /*    16     4 */
        enum tk_offsets            tk_offset;            /*    20     4 */
        int                        clockid;              /*    24     4 */
        bool                       offloaded;            /*    28     1 */

/* XXX 3 bytes hole, try to pack */

atomic64_t picos_per_byte; /* 32 0 */

/* XXX 8 bytes hole, try to pack */

spinlock_t current_entry_lock; /* 40 0 */

/* XXX 8 bytes hole, try to pack */

struct sched_entry * current_entry; /* 48 8 */
struct sched_gate_list * oper_sched; /* 56 8 */
/* --- cacheline 1 boundary (64 bytes) --- */

Fixes 9c66d1564676 ("taprio: Add support for hardware offloading")
---
 net/sched/sch_taprio.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
net/sched/sch_taprio.c +6 -4
index 0b941dd63d26..9bec73019f94 100644
@@ -67,6 +67,7 @@ struct taprio_sched {
 	u32 flags;
 	enum tk_offsets tk_offset;
 	int clockid;
+	bool offloaded;
 	atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
 				    * speeds it's sub-nanoseconds per byte
 				    */
@@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev,
 		goto done;
 	}
 
+	q->offloaded = true;
+
 done:
 	taprio_offload_free(offload);
 
@@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev,
 	struct tc_taprio_qopt_offload *offload;
 	int err;
 
-	if (!FULL_OFFLOAD_IS_ENABLED(q->flags))
+	if (!q->offloaded)
 		return 0;
 
-	if (!ops->ndo_setup_tc)
-		return -EOPNOTSUPP;
-
 	offload = taprio_offload_alloc(0);
 	if (!offload) {
 		NL_SET_ERR_MSG(extack,
@@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev,
 		goto out;
 	}
 
+	q->offloaded = false;
+
 out:
 	taprio_offload_free(offload);
 
Signature · 1 line
2.35.1
author maintainer
#139 lore raw

PATCH 134/207 net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 1461d212ab277d8bba1a753d33e9afe03d81f9d4 ]

taprio can only operate as root qdisc, and to that end, there exists the following check in taprio_init(), just as in mqprio:

	if (sch->parent != TC_H_ROOT)
		return -EOPNOTSUPP;

And indeed, when we try to attach taprio to an mqprio child, it fails as expected:

$ tc qdisc add dev swp0 root handle 1: mqprio num_tc 8 \
	map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 hw 0
$ tc qdisc replace dev swp0 parent 1:2 taprio num_tc 8 \
	map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
	base-time 0 sched-entry S 0x7f 990000 sched-entry S 0x80 100000 \
	flags 0x0 clockid CLOCK_TAI
Error: sch_taprio: Can only be attached as root qdisc.

(extack message added by me)

But when we try to attach a taprio child to a taprio root qdisc, surprisingly it doesn't fail:

$ tc qdisc replace dev swp0 root handle 1: taprio num_tc 8 \
	map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
	base-time 0 sched-entry S 0x7f 990000 sched-entry S 0x80 100000 \
	flags 0x0 clockid CLOCK_TAI
$ tc qdisc replace dev swp0 parent 1:2 taprio num_tc 8 \
	map 0 1 2 3 4 5 6 7 \
	queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
	base-time 0 sched-entry S 0x7f 990000 sched-entry S 0x80 100000 \
	flags 0x0 clockid CLOCK_TAI

This is because tc_modify_qdisc() behaves differently when mqprio is root, vs when taprio is root.

In the mqprio case, it finds the parent qdisc through
p = qdisc_lookup(dev, TC_H_MAJ(clid)), and then the child qdisc through q = qdisc_leaf(p, clid). This leaf qdisc q has handle 0, so it is ignored according to the comment right below ("It may be default qdisc, ignore it"). As a result, tc_modify_qdisc() goes through the qdisc_create() code path, and this gives taprio_init() a chance to check for sch_parent != TC_H_ROOT and error out.

Whereas in the taprio case, the returned q = qdisc_leaf(p, clid) is different. It is not the default qdisc created for each netdev queue (both taprio and mqprio call qdisc_create_dflt() and keep them in a private q->qdiscs[], or priv->qdiscs[], respectively). Instead, taprio makes qdisc_leaf() return the _root_ qdisc, aka itself.

When taprio does that, tc_modify_qdisc() goes through the qdisc_change() code path, because the qdisc layer never finds out about the child qdisc of the root. And through the ->change() ops, taprio has no reason to check whether its parent is root or not, just through ->init(), which is not called.

The problem is the taprio_leaf() implementation. Even though code wise, it does the exact same thing as mqprio_leaf() which it is copied from, it works with different input data. This is because mqprio does not attach itself (the root) to each device TX queue, but one of the default qdiscs from its private array.

In fact, since commit 13511704f8d7 ("net: taprio offload: enforce qdisc to netdev queue mapping"), taprio does this too, but just for the full offload case. So if we tried to attach a taprio child to a fully offloaded taprio root qdisc, it would properly fail too; just not to a software root taprio.

To fix the problem, stop looking at the Qdisc that's attached to the TX queue, and instead, always return the default qdiscs that we've allocated (and to which we privately enqueue and dequeue, in software scheduling mode).

Since Qdisc_class_ops :: leaf is only called from tc_modify_qdisc(), the risk of unforeseen side effects introduced by this change is minimal.

Fixes 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")
---
 net/sched/sch_taprio.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
net/sched/sch_taprio.c +5 -3
index 9bec73019f94..86675a79da1e 100644
@@ -1951,12 +1951,14 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
 
 static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl)
 {
-	struct netdev_queue *dev_queue = taprio_queue_get(sch, cl);
+	struct taprio_sched *q = qdisc_priv(sch);
+	struct net_device *dev = qdisc_dev(sch);
+	unsigned int ntx = cl - 1;
 
-	if (!dev_queue)
+	if (ntx >= dev->num_tx_queues)
 		return NULL;
 
-	return dev_queue->qdisc_sleeping;
+	return q->qdiscs[ntx];
 }
 
 static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
Signature · 1 line
2.35.1
author maintainer
#140 lore raw

PATCH 135/207 ice: config netdev tc before setting queues number

In reply to Greg Kroah-Hartman

From: Michal Swiatkowski <[email protected]>

[ Upstream commit 122045ca770492660005c22379995506f13efea8 ]

After lowering number of tx queues the warning appears:
"Number of in use tx queues changed invalidating tc mappings. Priority traffic classification disabled!"
Example command to reproduce:
ethtool -L enp24s0f0 tx 36 rx 36

Fix this by setting correct tc mapping before setting real number of queues on netdev.

Fixes 0754d65bd4be5 ("ice: Add infrastructure for mqprio support via ndo_setup_tc")
---
 drivers/net/ethernet/intel/ice/ice_main.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ethernet/intel/ice/ice_main.c +2 -0
index 0b567e8e3674..f963036571e0 100644
@@ -6836,6 +6836,8 @@ int ice_vsi_open(struct ice_vsi *vsi)
 	if (err)
 		goto err_setup_rx;
 
+	ice_vsi_cfg_netdev_tc(vsi, vsi->tc_cfg.ena_tc);
+
 	if (vsi->type == ICE_VSI_PF) {
 		/* Notify the stack of the actual queue counts. */
 		err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_txq);
Signature · 1 line
2.35.1
author maintainer
#141 lore raw

PATCH 136/207 ice: Fix interface being down after reset with link-down-on-close flag on

In reply to Greg Kroah-Hartman

From: Mateusz Palczewski <[email protected]>

[ Upstream commit 8ac7132704f3fbd2095abb9459e5303ce8c9e559 ]

When performing a reset on ice driver with link-down-on-close flag on interface would always stay down. Fix this by moving a check of this flag to ice_stop() that is called only when user wants to bring interface down.

Fixes ab4ab73fc1ec ("ice: Add ethtool private flag to make forcing link down optional")
---
 drivers/net/ethernet/intel/ice/ice_main.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/net/ethernet/intel/ice/ice_main.c +12 -9
index f963036571e0..48befe1e2872 100644
@@ -6627,7 +6627,7 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
  */
 int ice_down(struct ice_vsi *vsi)
 {
-	int i, tx_err, rx_err, link_err = 0, vlan_err = 0;
+	int i, tx_err, rx_err, vlan_err = 0;
 
 	WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state));
 
@@ -6661,20 +6661,13 @@ int ice_down(struct ice_vsi *vsi)
 
 	ice_napi_disable_all(vsi);
 
-	if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
-		link_err = ice_force_phys_link_state(vsi, false);
-		if (link_err)
-			netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n",
-				   vsi->vsi_num, link_err);
-	}
-
 	ice_for_each_txq(vsi, i)
 		ice_clean_tx_ring(vsi->tx_rings[i]);
 
 	ice_for_each_rxq(vsi, i)
 		ice_clean_rx_ring(vsi->rx_rings[i]);
 
-	if (tx_err || rx_err || link_err || vlan_err) {
+	if (tx_err || rx_err || vlan_err) {
 		netdev_err(vsi->netdev, "Failed to close VSI 0x%04X on switch 0x%04X\n",
 			   vsi->vsi_num, vsi->vsw->sw_id);
 		return -EIO;
@@ -8876,6 +8869,16 @@ int ice_stop(struct net_device *netdev)
 		return -EBUSY;
 	}
 
+	if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
+		int link_err = ice_force_phys_link_state(vsi, false);
+
+		if (link_err) {
+			netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n",
+				   vsi->vsi_num, link_err);
+			return -EIO;
+		}
+	}
+
 	ice_vsi_close(vsi);
 
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#142 lore raw

PATCH 137/207 netfilter: nf_tables: fix nft_counters_enabled underflow at nf_tables_addchain()

In reply to Greg Kroah-Hartman

From: Tetsuo Handa <[email protected]>

[ Upstream commit 921ebde3c0d22c8cba74ce8eb3cc4626abff1ccd ]

syzbot is reporting underflow of nft_counters_enabled counter at nf_tables_addchain() [1], for commit 43eb8949cfdffa76 ("netfilter:
nf_tables: do not leave chain stats enabled on error") missed that nf_tables_chain_destroy() after nft_basechain_init() in the error path of nf_tables_addchain() decrements the counter because nft_basechain_init() makes nft_is_base_chain() return true by setting NFT_CHAIN_BASE flag.

Increment the counter immediately after returning from nft_basechain_init().

Fixes 43eb8949cfdffa76 ("netfilter: nf_tables: do not leave chain stats enabled on error")
---
 net/netfilter/nf_tables_api.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +3 -4
index 848cc81d6992..3aaf36df69d4 100644
@@ -2197,7 +2197,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 			      struct netlink_ext_ack *extack)
 {
 	const struct nlattr * const *nla = ctx->nla;
-	struct nft_stats __percpu *stats = NULL;
 	struct nft_table *table = ctx->table;
 	struct nft_base_chain *basechain;
 	struct net *net = ctx->net;
@@ -2212,6 +2211,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 		return -EOVERFLOW;
 
 	if (nla[NFTA_CHAIN_HOOK]) {
+		struct nft_stats __percpu *stats = NULL;
 		struct nft_chain_hook hook;
 
 		if (flags & NFT_CHAIN_BINDING)
@@ -2245,6 +2245,8 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 			kfree(basechain);
 			return err;
 		}
+		if (stats)
+			static_branch_inc(&nft_counters_enabled);
 	} else {
 		if (flags & NFT_CHAIN_BASE)
 			return -EINVAL;
@@ -2319,9 +2321,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 		goto err_unregister_hook;
 	}
 
-	if (stats)
-		static_branch_inc(&nft_counters_enabled);
-
 	table->use++;
 
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#143 lore raw

PATCH 138/207 netfilter: nf_tables: fix percpu memory leak at nf_tables_addchain()

In reply to Greg Kroah-Hartman

From: Tetsuo Handa <[email protected]>

[ Upstream commit 9a4d6dd554b86e65581ef6b6638a39ae079b17ac ]

It seems to me that percpu memory for chain stats started leaking since commit 3bc158f8d0330f0a ("netfilter: nf_tables: map basechain priority to hardware priority") when nft_chain_offload_priority() returned an error.

Fixes 3bc158f8d0330f0a ("netfilter: nf_tables: map basechain priority to hardware priority")
---
 net/netfilter/nf_tables_api.c | 1 +
 1 file changed, 1 insertion(+)
net/netfilter/nf_tables_api.c +1 -0
index 3aaf36df69d4..2fde193c3d26 100644
@@ -2243,6 +2243,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 		if (err < 0) {
 			nft_chain_release_hook(&hook);
 			kfree(basechain);
+			free_percpu(stats);
 			return err;
 		}
 		if (stats)
Signature · 1 line
2.35.1
author maintainer
#144 lore raw

PATCH 139/207 netfilter: ebtables: fix memory leak when blob is malformed

In reply to Greg Kroah-Hartman

From: Florian Westphal <[email protected]>

[ Upstream commit 62ce44c4fff947eebdf10bb582267e686e6835c9 ]

The bug fix was incomplete, it "replaced" crash with a memory leak. The old code had an assignment to "ret" embedded into the conditional, restore this.

Fixes 7997eff82828 ("netfilter: ebtables: reject blobs that don't provide all entry points")
Reported-and-tested-by [email protected]
---
 net/bridge/netfilter/ebtables.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/bridge/netfilter/ebtables.c +3 -1
index 9a0ae59cdc50..4f385d52a1c4 100644
@@ -1040,8 +1040,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
 		goto free_iterate;
 	}
 
-	if (repl->valid_hooks != t->valid_hooks)
+	if (repl->valid_hooks != t->valid_hooks) {
+		ret = -EINVAL;
 		goto free_unlock;
+	}
 
 	if (repl->num_counters && repl->num_counters != t->private->nentries) {
 		ret = -EINVAL;
Signature · 1 line
2.35.1
author maintainer
#145 lore raw

PATCH 140/207 netfilter: nf_ct_ftp: fix deadlock when nat rewrite is needed

In reply to Greg Kroah-Hartman

From: Florian Westphal <[email protected]>

[ Upstream commit d25088932227680988a6b794221e031a7232f137 ]

We can't use ct->lock, this is already used by the seqadj internals. When using ftp helper + nat, seqadj will attempt to acquire ct->lock again.

Revert back to a global lock for now.

Fixes c783a29c7e59 ("netfilter: nf_ct_ftp: prefer skb_linearize")
---
 net/netfilter/nf_conntrack_ftp.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/netfilter/nf_conntrack_ftp.c +4 -2
index 0d9332e9cf71..617f744a2e3a 100644
@@ -33,6 +33,7 @@ MODULE_AUTHOR("Rusty Russell <[email protected]>");
 MODULE_DESCRIPTION("ftp connection tracking helper");
 MODULE_ALIAS("ip_conntrack_ftp");
 MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
+static DEFINE_SPINLOCK(nf_ftp_lock);
 
 #define MAX_PORTS 8
 static u_int16_t ports[MAX_PORTS];
@@ -409,7 +410,8 @@ static int help(struct sk_buff *skb,
 	}
 	datalen = skb->len - dataoff;
 
-	spin_lock_bh(&ct->lock);
+	/* seqadj (nat) uses ct->lock internally, nf_nat_ftp would cause deadlock */
+	spin_lock_bh(&nf_ftp_lock);
 	fb_ptr = skb->data + dataoff;
 
 	ends_in_nl = (fb_ptr[datalen - 1] == '\n');
@@ -538,7 +540,7 @@ static int help(struct sk_buff *skb,
 	if (ends_in_nl)
 		update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
  out:
-	spin_unlock_bh(&ct->lock);
+	spin_unlock_bh(&nf_ftp_lock);
 	return ret;
 }
 
Signature · 1 line
2.35.1